Received: by 2002:a25:8b12:0:0:0:0:0 with SMTP id i18csp724735ybl; Tue, 13 Aug 2019 01:26:16 -0700 (PDT) X-Google-Smtp-Source: APXvYqwo1QjiDLRS2jCKHwY0x3EYx7RwPWOMyUiICCDROyFSSGhr/ugzi91We5Ig2EjuT8+idkPN X-Received: by 2002:a17:902:145:: with SMTP id 63mr37673361plb.55.1565684776387; Tue, 13 Aug 2019 01:26:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1565684776; cv=none; d=google.com; s=arc-20160816; b=ocCCaOAQzOJSnwq4QvJQ3wbHp2bYttGshnqK+LrqQN7Wa1shBHvyhPCEArEZPRHCHg vCUGLixZsu481/zmos/Op9P+mWCjy9otC1vhy4EDHvsHfwcjaLBXsmWFICm28PzIyjvg hZzpHmuuqh2lf8MAl4R3UjIj1Qv50M6X4i1mvMkssuMBTFrs3PxWD/88R3XEjkP6Sova 4kjQugeQJdAzgiUetnoqidWX8NiiAIzhxcVVJdbgz7HX+HMhYO3OqeehZDD8izDTXnw+ 2npp7bUB1JypERuFfk3jCTIj3VIIt/maanej7ZMs1A+NCI2nBDZuuO7990IE3iQWtuDp ma6A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=2xgugli+kMyP0NxBJiufklqKjGgIF6czSq9L/jf8fyM=; b=AMRozpKSa2S4lpsSp1W3IUF+wwF8IDLbLcniNPQj8/ur8NLk1R63eo7xfuHfIFWjas UY8PWvG9UBKRKa4JuMInvLBo6CmixljvHfMFAFisWuwShEgkhlF/jMSo/cmpBg8Efl1d mXohpzeL2PsB8aOSELLxjJ6iBijyGJ1SW9zdVYn54xnK02Us7qgnqi6PbABDmgCSdPdW YQPyRwHKmdi4k0o4ATbKS1K80aTSJBU8BJOcelJqRk/BScil6S6E7AxSlUp9tyz5qPhA GGIx9b6j/D/svgTk/f2UftsD2D8Q+1ayVGQGPiNcE/MJkHqgl5F+tkC+nCxNz7ihdAeX CrUg== ARC-Authentication-Results: i=1; mx.google.com; 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=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 11si59554720pla.248.2019.08.13.01.26.00; Tue, 13 Aug 2019 01:26:16 -0700 (PDT) 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; 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=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727859AbfHMIZP (ORCPT + 99 others); Tue, 13 Aug 2019 04:25:15 -0400 Received: from mx1.redhat.com ([209.132.183.28]:57558 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727166AbfHMIZO (ORCPT ); Tue, 13 Aug 2019 04:25:14 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 16CBE30832DC; Tue, 13 Aug 2019 08:25:14 +0000 (UTC) Received: from sirius.home.kraxel.org (ovpn-116-144.ams2.redhat.com [10.36.116.144]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5E067600C1; Tue, 13 Aug 2019 08:25:10 +0000 (UTC) Received: by sirius.home.kraxel.org (Postfix, from userid 1000) id 7D05E9D00; Tue, 13 Aug 2019 10:25:09 +0200 (CEST) From: Gerd Hoffmann To: dri-devel@lists.freedesktop.org Cc: olvaffe@gmail.com, Gerd Hoffmann , David Airlie , Daniel Vetter , virtualization@lists.linux-foundation.org (open list:VIRTIO GPU DRIVER), linux-kernel@vger.kernel.org (open list) Subject: [PATCH 2/2] drm/virtio: notify virtqueues without holding spinlock Date: Tue, 13 Aug 2019 10:25:09 +0200 Message-Id: <20190813082509.29324-3-kraxel@redhat.com> In-Reply-To: <20190813082509.29324-1-kraxel@redhat.com> References: <20190813082509.29324-1-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.44]); Tue, 13 Aug 2019 08:25:14 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Split virtqueue_kick() call into virtqueue_kick_prepare(), which requires serialization, and virtqueue_notify(), which does not. Move the virtqueue_notify() call out of the critical section protected by the queue lock. This avoids triggering a vmexit while holding the lock and thereby fixes a rather bad spinlock contention. Suggested-by: Chia-I Wu Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/virtio/virtgpu_vq.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index ca91e83ffaef..e41c96143342 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -252,7 +252,7 @@ void virtio_gpu_dequeue_cursor_func(struct work_struct *work) wake_up(&vgdev->cursorq.ack_queue); } -static void virtio_gpu_queue_ctrl_buffer_locked(struct virtio_gpu_device *vgdev, +static bool virtio_gpu_queue_ctrl_buffer_locked(struct virtio_gpu_device *vgdev, struct virtio_gpu_vbuffer *vbuf) __releases(&vgdev->ctrlq.qlock) __acquires(&vgdev->ctrlq.qlock) @@ -260,10 +260,11 @@ static void virtio_gpu_queue_ctrl_buffer_locked(struct virtio_gpu_device *vgdev, struct virtqueue *vq = vgdev->ctrlq.vq; struct scatterlist *sgs[3], vcmd, vout, vresp; int outcnt = 0, incnt = 0; + bool notify = false; int ret; if (!vgdev->vqs_ready) - return; + return notify; sg_init_one(&vcmd, vbuf->buf, vbuf->size); sgs[outcnt + incnt] = &vcmd; @@ -292,16 +293,21 @@ static void virtio_gpu_queue_ctrl_buffer_locked(struct virtio_gpu_device *vgdev, trace_virtio_gpu_cmd_queue(vq, (struct virtio_gpu_ctrl_hdr *)vbuf->buf); - virtqueue_kick(vq); + notify = virtqueue_kick_prepare(vq); } + return notify; } static void virtio_gpu_queue_ctrl_buffer(struct virtio_gpu_device *vgdev, struct virtio_gpu_vbuffer *vbuf) { + bool notify; + spin_lock(&vgdev->ctrlq.qlock); - virtio_gpu_queue_ctrl_buffer_locked(vgdev, vbuf); + notify = virtio_gpu_queue_ctrl_buffer_locked(vgdev, vbuf); spin_unlock(&vgdev->ctrlq.qlock); + if (notify) + virtqueue_notify(vgdev->ctrlq.vq); } static void virtio_gpu_queue_fenced_ctrl_buffer(struct virtio_gpu_device *vgdev, @@ -310,6 +316,7 @@ static void virtio_gpu_queue_fenced_ctrl_buffer(struct virtio_gpu_device *vgdev, struct virtio_gpu_fence *fence) { struct virtqueue *vq = vgdev->ctrlq.vq; + bool notify; again: spin_lock(&vgdev->ctrlq.qlock); @@ -330,8 +337,10 @@ static void virtio_gpu_queue_fenced_ctrl_buffer(struct virtio_gpu_device *vgdev, if (fence) virtio_gpu_fence_emit(vgdev, hdr, fence); - virtio_gpu_queue_ctrl_buffer_locked(vgdev, vbuf); + notify = virtio_gpu_queue_ctrl_buffer_locked(vgdev, vbuf); spin_unlock(&vgdev->ctrlq.qlock); + if (notify) + virtqueue_notify(vgdev->ctrlq.vq); } static void virtio_gpu_queue_cursor(struct virtio_gpu_device *vgdev, @@ -339,6 +348,7 @@ static void virtio_gpu_queue_cursor(struct virtio_gpu_device *vgdev, { struct virtqueue *vq = vgdev->cursorq.vq; struct scatterlist *sgs[1], ccmd; + bool notify; int ret; int outcnt; @@ -361,10 +371,13 @@ static void virtio_gpu_queue_cursor(struct virtio_gpu_device *vgdev, trace_virtio_gpu_cmd_queue(vq, (struct virtio_gpu_ctrl_hdr *)vbuf->buf); - virtqueue_kick(vq); + notify = virtqueue_kick_prepare(vq); } spin_unlock(&vgdev->cursorq.qlock); + + if (notify) + virtqueue_notify(vq); } /* just create gem objects for userspace and long lived objects, -- 2.18.1