From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BBC844C630 for ; Mon, 1 Apr 2024 16:53:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711990399; cv=none; b=Kdv60IcLeKV1jVX6dsooYNSsopWnAylUdxTlAasfSX3mbuzQ+sIb3rlyrslSQtxqn4O1+9PGz3hboLpMHxwKAdFgqk4x+6nKtJczm1vH0ho2Oe0FP/Rwqcptq7Syz2liK2IhKjekaUHQA/KlJk0eOU0o4oH0r9b1xhZbs1nficE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711990399; c=relaxed/simple; bh=YnjZZU6powCMab0vWKOORaCgRtiZE5iJPFUlkmPWezo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hzdUCKAUWjolD0UOdSeT0M9ilfkvvEAYHr4setLCLM7eAH9ZycF2ADHI2DjMM1RgXJ8Mcz2l35kGI3XckbE2GBWcKQC68JgTwC0ZCSY67wvADumYmUbSKaDcOE+Cbp6yeZK4F6kAWoPKv8QLQs0qP1SVPLSPcI1PY0hLDTOLZYY= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=Q6me40WI; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Q6me40WI" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1711990396; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Y4aZvd5tDLZDRzrMsHWwvFSlj9LePnW5EkBE1TwamoQ=; b=Q6me40WINa53sEXgity+UJauvKYM+4/Curo+iugRx2uvF4tSdW3ju95kOvjUp6NU0vjT1K b5MdWrp6EMfE3Fr3wZr6FrHC9fmYwhE00Qg0zTOUg3IDoyEcyG3lMW2c3GEevZxX6JQ1a0 oBfmxRaWMNBLti9Fhpm5MjNrSj0411g= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-251-MPpuVa7sMpq4Gw9Eosxktg-1; Mon, 01 Apr 2024 12:53:13 -0400 X-MC-Unique: MPpuVa7sMpq4Gw9Eosxktg-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id C33663803504; Mon, 1 Apr 2024 16:53:12 +0000 (UTC) Received: from omen.home.shazbot.org (unknown [10.22.34.212]) by smtp.corp.redhat.com (Postfix) with ESMTP id C8AA03C22; Mon, 1 Apr 2024 16:53:11 +0000 (UTC) From: Alex Williamson To: stable@vger.kernel.org Cc: Alex Williamson , sashal@kernel.org, gregkh@linuxfoundation.org, eric.auger@redhat.com, Kevin Tian , Reinette Chatre Subject: [PATCH 5.10.y 5.4.y 3/6] vfio: Introduce interface to flush virqfd inject workqueue Date: Mon, 1 Apr 2024 10:52:57 -0600 Message-ID: <20240401165302.3699643-4-alex.williamson@redhat.com> In-Reply-To: <20240401165302.3699643-1-alex.williamson@redhat.com> References: <20240401165302.3699643-1-alex.williamson@redhat.com> Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.1 [ Upstream commit b620ecbd17a03cacd06f014a5d3f3a11285ce053 ] In order to synchronize changes that can affect the thread callback, introduce an interface to force a flush of the inject workqueue. The irqfd pointer is only valid under spinlock, but the workqueue cannot be flushed under spinlock. Therefore the flush work for the irqfd is queued under spinlock. The vfio_irqfd_cleanup_wq workqueue is re-used for queuing this work such that flushing the workqueue is also ordered relative to shutdown. Reviewed-by: Kevin Tian Reviewed-by: Reinette Chatre Reviewed-by: Eric Auger Link: https://lore.kernel.org/r/20240308230557.805580-4-alex.williamson@redhat.com Signed-off-by: Alex Williamson --- drivers/vfio/virqfd.c | 21 +++++++++++++++++++++ include/linux/vfio.h | 2 ++ 2 files changed, 23 insertions(+) diff --git a/drivers/vfio/virqfd.c b/drivers/vfio/virqfd.c index 997cb5d0a657..1cff533017ab 100644 --- a/drivers/vfio/virqfd.c +++ b/drivers/vfio/virqfd.c @@ -101,6 +101,13 @@ static void virqfd_inject(struct work_struct *work) virqfd->thread(virqfd->opaque, virqfd->data); } +static void virqfd_flush_inject(struct work_struct *work) +{ + struct virqfd *virqfd = container_of(work, struct virqfd, flush_inject); + + flush_work(&virqfd->inject); +} + int vfio_virqfd_enable(void *opaque, int (*handler)(void *, void *), void (*thread)(void *, void *), @@ -124,6 +131,7 @@ int vfio_virqfd_enable(void *opaque, INIT_WORK(&virqfd->shutdown, virqfd_shutdown); INIT_WORK(&virqfd->inject, virqfd_inject); + INIT_WORK(&virqfd->flush_inject, virqfd_flush_inject); irqfd = fdget(fd); if (!irqfd.file) { @@ -214,6 +222,19 @@ void vfio_virqfd_disable(struct virqfd **pvirqfd) } EXPORT_SYMBOL_GPL(vfio_virqfd_disable); +void vfio_virqfd_flush_thread(struct virqfd **pvirqfd) +{ + unsigned long flags; + + spin_lock_irqsave(&virqfd_lock, flags); + if (*pvirqfd && (*pvirqfd)->thread) + queue_work(vfio_irqfd_cleanup_wq, &(*pvirqfd)->flush_inject); + spin_unlock_irqrestore(&virqfd_lock, flags); + + flush_workqueue(vfio_irqfd_cleanup_wq); +} +EXPORT_SYMBOL_GPL(vfio_virqfd_flush_thread); + module_init(vfio_virqfd_init); module_exit(vfio_virqfd_exit); diff --git a/include/linux/vfio.h b/include/linux/vfio.h index f479c5d7f2c3..56d18912c41a 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h @@ -221,6 +221,7 @@ struct virqfd { wait_queue_entry_t wait; poll_table pt; struct work_struct shutdown; + struct work_struct flush_inject; struct virqfd **pvirqfd; }; @@ -229,5 +230,6 @@ extern int vfio_virqfd_enable(void *opaque, void (*thread)(void *, void *), void *data, struct virqfd **pvirqfd, int fd); extern void vfio_virqfd_disable(struct virqfd **pvirqfd); +void vfio_virqfd_flush_thread(struct virqfd **pvirqfd); #endif /* VFIO_H */ -- 2.44.0