Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp6399730ybl; Wed, 15 Jan 2020 04:07:15 -0800 (PST) X-Google-Smtp-Source: APXvYqwjexNrt1Nm8EgiFBiUL4E3acRawXrL7Rw1fLhj1tRfNqSZ1+8YiNi4AXuYdn07/Fe3Pt9K X-Received: by 2002:aca:1913:: with SMTP id l19mr19604634oii.47.1579090035738; Wed, 15 Jan 2020 04:07:15 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1579090035; cv=none; d=google.com; s=arc-20160816; b=hRdGAbdedhE8rd2o6x0Cv0FLNJZTgFyapqFc+8yKEzqP6Hi8nqYZCIVrg+hrUqG+Qo 82QUPrVHBRIybdbNkndsf0057iFC9iRXCZFECdgM6WHqtIJvE5cvEVovs/GIJRgDrXjo u8ZWyq6bvCehdN0P9ad2z9/S0XVD2jihnVqaMWnVxxMBR4K2KiOgFc267Rbq954i/sqP YB+qvVlMyQnLLkhP1tzVHhRWIq3dxNgKj22S3wONVCBWkQZ4Runeuw0oY2Qu0EcghyM1 Dc0TkjCwCpv7/Z6Wcs7O8lE7dvBYdnpUzPzYH1/3kTG3tUxmlViH5A5Tz1dTvYJcJ6wO 0fhg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dkim-signature:dkim-filter; bh=6lzn2l0dYP+0ASaZ1AFTvqX7NmUFTFeakMQsyeR7hHs=; b=kBF/d191CuEOljv6hiY3zD9IDAWp9PPURyIA/puw1A25qHrunwajuO1vSO3rXNRu1K PCUdlaPN59ZUJaRBlYnmoL994jlCYBpwU990jZXvGKbFeaOFoIqmXh/Qlycce/nPivdS K0it30FyPr9NrwT+0o3nQxiEiYX+7j3zWWpKzKo2gm4pIUluIcXmZb8YhbgkPQPXgxQ2 GPmikEjJ80EmTYPnlvBLdg12ufWLNh50hG+PSo8TR8ArjTS+HWEF0y6sFBDUuZvQPwlm tny80bQmxmCe1M+P95gQHDCCv1r4b5pJ1xGpJpQFQCYTVA8uw2n2trs+cDmxXs/hQ6GO BWzg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kalray.eu header.s=32AE1B44-9502-11E5-BA35-3734643DEF29 header.b=FbqhuDju; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=kalray.eu Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r4si10850853otq.188.2020.01.15.04.07.02; Wed, 15 Jan 2020 04:07:15 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kalray.eu header.s=32AE1B44-9502-11E5-BA35-3734643DEF29 header.b=FbqhuDju; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=kalray.eu Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730197AbgAOMF7 (ORCPT + 99 others); Wed, 15 Jan 2020 07:05:59 -0500 Received: from zimbra2.kalray.eu ([92.103.151.219]:53212 "EHLO zimbra2.kalray.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729758AbgAOMF7 (ORCPT ); Wed, 15 Jan 2020 07:05:59 -0500 Received: from localhost (localhost [127.0.0.1]) by zimbra2.kalray.eu (Postfix) with ESMTP id CB66F27E0BA4; Wed, 15 Jan 2020 13:05:57 +0100 (CET) Received: from zimbra2.kalray.eu ([127.0.0.1]) by localhost (zimbra2.kalray.eu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id 9H-gUyI46-Z3; Wed, 15 Jan 2020 13:05:57 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by zimbra2.kalray.eu (Postfix) with ESMTP id 5E54A27E0A5D; Wed, 15 Jan 2020 13:05:57 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.10.3 zimbra2.kalray.eu 5E54A27E0A5D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kalray.eu; s=32AE1B44-9502-11E5-BA35-3734643DEF29; t=1579089957; bh=6lzn2l0dYP+0ASaZ1AFTvqX7NmUFTFeakMQsyeR7hHs=; h=From:To:Date:Message-Id; b=FbqhuDjuk2130JSGH+9ERNx6mF16muyBUZxh5EpFXbxgdIi9RKCr7KE9w9FVdGTuU fg9X68hm1083IRQbZmolRemQpG1b1btt4jJhZ9BTYmdYDvuTwwKCTe6A6FWJ3j603y G0bekXgy7LpTFmB08sAAOThATM3AYcFkdGBAl2DM= X-Virus-Scanned: amavisd-new at zimbra2.kalray.eu Received: from zimbra2.kalray.eu ([127.0.0.1]) by localhost (zimbra2.kalray.eu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id CaaC1VAcHASq; Wed, 15 Jan 2020 13:05:57 +0100 (CET) Received: from triton.lin.mbt.kalray.eu (unknown [192.168.37.25]) by zimbra2.kalray.eu (Postfix) with ESMTPSA id 4956827E031E; Wed, 15 Jan 2020 13:05:57 +0100 (CET) From: Clement Leger To: Jason Wang , "Michael S. Tsirkin" Cc: virtualization@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Clement Leger Subject: [PATCH] virtio_ring: Use workqueue to execute virtqueue callback Date: Wed, 15 Jan 2020 13:05:35 +0100 Message-Id: <20200115120535.17454-1-cleger@kalray.eu> X-Mailer: git-send-email 2.15.0.276.g89ea799 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Currently, in vring_interrupt, the vq callbacks are called directly. However, these callbacks are not meant to be executed in IRQ context. They do not return any irq_return_t value and some of them can do locking (rpmsg_recv_done -> rpmsg_recv_single -> mutex_lock). When compiled with DEBUG_ATOMIC_SLEEP, the kernel will spit out warnings when such case shappen. In order to allow calling these callbacks safely (without sleeping in IRQ context), execute them in a workqueue if needed. Signed-off-by: Clement Leger --- drivers/virtio/virtio_ring.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 867c7ebd3f10..0e4d0e5ca227 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -183,6 +183,9 @@ struct vring_virtqueue { /* DMA, allocation, and size information */ bool we_own_ring; + /* Work struct for vq callback handling */ + struct work_struct work; + #ifdef DEBUG /* They're supposed to lock for us. */ unsigned int in_use; @@ -2029,6 +2032,16 @@ static inline bool more_used(const struct vring_virtqueue *vq) return vq->packed_ring ? more_used_packed(vq) : more_used_split(vq); } +static void vring_work_handler(struct work_struct *work_struct) +{ + struct vring_virtqueue *vq = container_of(work_struct, + struct vring_virtqueue, + work); + pr_debug("virtqueue callback for %p (%p)\n", vq, vq->vq.callback); + + vq->vq.callback(&vq->vq); +} + irqreturn_t vring_interrupt(int irq, void *_vq) { struct vring_virtqueue *vq = to_vvq(_vq); @@ -2041,9 +2054,8 @@ irqreturn_t vring_interrupt(int irq, void *_vq) if (unlikely(vq->broken)) return IRQ_HANDLED; - pr_debug("virtqueue callback for %p (%p)\n", vq, vq->vq.callback); if (vq->vq.callback) - vq->vq.callback(&vq->vq); + schedule_work(&vq->work); return IRQ_HANDLED; } @@ -2110,6 +2122,8 @@ struct virtqueue *__vring_new_virtqueue(unsigned int index, vq->split.avail_flags_shadow); } + INIT_WORK(&vq->work, vring_work_handler); + vq->split.desc_state = kmalloc_array(vring.num, sizeof(struct vring_desc_state_split), GFP_KERNEL); if (!vq->split.desc_state) { @@ -2179,6 +2193,8 @@ void vring_del_virtqueue(struct virtqueue *_vq) { struct vring_virtqueue *vq = to_vvq(_vq); + cancel_work_sync(&vq->work); + if (vq->we_own_ring) { if (vq->packed_ring) { vring_free_queue(vq->vq.vdev, -- 2.15.0.276.g89ea799