summaryrefslogtreecommitdiffstats
path: root/drivers/vfio/virqfd.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 10:15:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 10:15:43 +0000
commit4a1c948bc688e5ab5e51d12d2f6dd6746e3ac2d9 (patch)
tree7ee50e6ccf13f75f02fd343cf90750cbd9950194 /drivers/vfio/virqfd.c
parentReleasing progress-linux version 6.1.82-1~progress6.99u1. (diff)
downloadlinux-4a1c948bc688e5ab5e51d12d2f6dd6746e3ac2d9.tar.xz
linux-4a1c948bc688e5ab5e51d12d2f6dd6746e3ac2d9.zip
Merging upstream version 6.1.85.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'drivers/vfio/virqfd.c')
-rw-r--r--drivers/vfio/virqfd.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/drivers/vfio/virqfd.c b/drivers/vfio/virqfd.c
index 414e98d82..e06b32dde 100644
--- a/drivers/vfio/virqfd.c
+++ b/drivers/vfio/virqfd.c
@@ -104,6 +104,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 *),
@@ -115,7 +122,7 @@ int vfio_virqfd_enable(void *opaque,
int ret = 0;
__poll_t events;
- virqfd = kzalloc(sizeof(*virqfd), GFP_KERNEL);
+ virqfd = kzalloc(sizeof(*virqfd), GFP_KERNEL_ACCOUNT);
if (!virqfd)
return -ENOMEM;
@@ -127,6 +134,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) {
@@ -217,6 +225,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);