Skip to contentSkip to conversation

irqfd fixes and enhancements

PATCH Superseded Gregory Haskins 2 participants 9 messages Jul 1, 2009 – Jul 2, 2009

Subsystems (2)

v8 of 9 Superseded Latest is v9 →

lore
Share & tools
lore
#0 lore raw

v8 cover irqfd fixes and enhancements

(Applies to kvm.git/master:beeaacd1)

The following is the latest attempt to fix the races in irqfd/eventfd, as well as restore DEASSIGN support. For more details, please read the patch headers.

As always, this series has been tested against the kvm-eventfd unit test and everything appears to be functioning properly. You can download this test here:

ftp://ftp.novell.com/dev/ghaskins/kvm-eventfd.tar.bz2

Kind Regards,
-Greg

[Changelog:

v8:
*) Rebased to kvm.git/master:beeaacd1)
*) Dropped Davide's patch (2/5 in v7) since it's now upstream *) Folded v7's 1/5 and 3/5 together, and added a single
eventfd hunk to convert wake_up_locked_polled to wake_up_polled
*) Dropped irqfd->active bit in favor of irqfd_is_active() function *) Cleaned up comments in 1/3
*) Dropped v7's 5/5 (slow-work)
*) Added new patch (3/3) which makes the cleanup-wq's creation
dynamic so to avoid the resource penalty for guests that do not use irqfd.

v7:
*) Addressed minor-nit feedback from Michael
*) Cleaned up patch headers
*) Re-added separate slow-work feature patch to end for comparison

v6:
*) Removed slow-work in favor of using a dedicated single-thread
workqueue.
*) Condensed cleanup path to always use deferred shutdown *) Saved about 56 lines over v5, with the following diffstat:

 	   include/linux/kvm_host.h |    2 
 	   virt/kvm/eventfd.c       |  248 ++++++++++++++++++-----------------------------
 	   2 files changed, 97 insertions(+), 153 deletions(-)
	v5:
           Untracked..

]

---

Gregory Haskins (3):
KVM: create irqfd-cleanup-wq on demand
KVM: add irqfd DEASSIGN feature
KVM: Fix races in irqfd using new eventfd_kref_get interface

 fs/eventfd.c             |    7 -
 include/linux/kvm.h      |    2 
 include/linux/kvm_host.h |    6 +
 virt/kvm/eventfd.c       |  281 ++++++++++++++++++++++++++++++++++++----------
 4 files changed, 229 insertions(+), 67 deletions(-)
Signature · 1 line
Signature
#1 lore raw

PATCH v8 1/3 KVM: Fix races in irqfd using new eventfd_kref_get interface

eventfd currently emits a POLLHUP wakeup on f_ops->release() to generate a "release" callback. This lets eventfd clients know if the eventfd is about to go away and is very useful particularly for in-kernel clients. However, until recently it is not possible to use this feature of eventfd in a race-free way.

This patch utilizes a new eventfd interface to rectify the problem. It also converts the eventfd POLLHUP generation code to use the locked variant of wakeup.

---

 fs/eventfd.c             |    7 --
 include/linux/kvm_host.h |    5 +
 virt/kvm/eventfd.c       |  187 ++++++++++++++++++++++++++++++++--------------
 3 files changed, 134 insertions(+), 65 deletions(-)
fs/eventfd.c +1 -6
index d9849a1..31d12de 100644
@@ -105,12 +105,7 @@ static int eventfd_release(struct inode *inode, struct file *file)
 {
 	struct eventfd_ctx *ctx = file->private_data;
 
-	/*
-	 * No need to hold the lock here, since we are on the file cleanup
-	 * path and the ones still attached to the wait queue will be
-	 * serialized by wake_up_locked_poll().
-	 */
-	wake_up_locked_poll(&ctx->wqh, POLLHUP);
+	wake_up_poll(&ctx->wqh, POLLHUP);
 	eventfd_ctx_put(ctx);
 	return 0;
 }
include/linux/kvm_host.h +4 -1
index 1a8952f..7605bc4 100644
@@ -141,7 +141,10 @@ struct kvm {
 	struct kvm_io_bus mmio_bus;
 	struct kvm_io_bus pio_bus;
 #ifdef CONFIG_HAVE_KVM_EVENTFD
-	struct list_head irqfds;
+	struct {
+		spinlock_t        lock;
+		struct list_head  items;
+	} irqfds;
 #endif
 	struct kvm_vm_stat stat;
 	struct kvm_arch arch;
virt/kvm/eventfd.c +129 -58

285 lines not on this page · raw message

#2 lore raw

Re: [KVM PATCH v8 1/3] KVM: Fix races in irqfd using new eventfd_kref_get interface

virt/kvm/eventfd.c kvm_irqfd(struct kvm *kvm, int fd, int gsi, int flags) · line 196

Quoted 10 lines · Gregory Haskins
virt/kvm/eventfd.c +8 -0
+	eventfd = eventfd_ctx_fileget(file);
+	if (IS_ERR(file)) {
+		ret = PTR_ERR(file);
+		goto fail;
+	}
+
+	irqfd->eventfd = eventfd;
+

<sigh>

Just noticed the typo (return "eventfd" but error-check "file"). Looks like I will need at least a v9. Is there any other feedback before I push out the fix for v8?

-Greg

#3 lore raw

Re: [KVM PATCH v8 1/3] KVM: Fix races in irqfd using new eventfd_kref_get interface

In reply to Gregory Haskins
Quoted 10 lines · Gregory Haskins

eventfd currently emits a POLLHUP wakeup on f_ops->release() to generate a "release" callback. This lets eventfd clients know if the eventfd is about to go away and is very useful particularly for in-kernel clients. However, until recently it is not possible to use this feature of eventfd in a race-free way.

This patch utilizes a new eventfd interface to rectify the problem. It also converts the eventfd POLLHUP generation code to use the locked variant of wakeup.

Quoted 9 lines

---

  fs/eventfd.c             |    7 --
  include/linux/kvm_host.h |    5 +
  virt/kvm/eventfd.c       |  187 ++++++++++++++++++++++++++++++++--------------
  3 files changed, 134 insertions(+), 65 deletions(-)

Please split the eventfd.c hunk into a separate patch. When preparing the 2.6.32 submission, I'll fold that into the patch into its antipatch and they'll disappear.

Signature · 1 line
error compiling committee.c: too many arguments to function
#4 lore raw

Re: [KVM PATCH v8 1/3] KVM: Fix races in irqfd using new eventfd_kref_get interface

Quoted 27 lines · Avi Kivity
Quoted 16 lines · Gregory Haskins

eventfd currently emits a POLLHUP wakeup on f_ops->release() to generate a
"release" callback. This lets eventfd clients know if the eventfd is about
to go away and is very useful particularly for in-kernel clients. However,
until recently it is not possible to use this feature of eventfd in a race-free way.

This patch utilizes a new eventfd interface to rectify the problem. It also
converts the eventfd POLLHUP generation code to use the locked variant of wakeup.

Quoted 8 lines

---

  fs/eventfd.c             |    7 --
  include/linux/kvm_host.h |    5 +
  virt/kvm/eventfd.c       |  187
++++++++++++++++++++++++++++++++--------------
  3 files changed, 134 insertions(+), 65 deletions(-)
Quoted 4 lines

Please split the eventfd.c hunk into a separate patch. When preparing the 2.6.32 submission, I'll fold that into the patch into its antipatch and they'll disappear.

Ok, but note that that means I should probably split 1/3 back out into 1/5 (prepare), 2/5 (eventfd hunk), 3/5 (fix irqfd) again like I had in v7 so that the series is bisectable. Is that ok?

-Greg

#5 lore raw

Re: [KVM PATCH v8 1/3] KVM: Fix races in irqfd using new eventfd_kref_get interface

Quoted 12 lines · Gregory Haskins
Quoted 7 lines

Please split the eventfd.c hunk into a separate patch. When preparing the 2.6.32 submission, I'll fold that into the patch into its antipatch and they'll disappear.

Ok, but note that that means I should probably split 1/3 back out into 1/5 (prepare), 2/5 (eventfd hunk), 3/5 (fix irqfd) again like I had in v7 so that the series is bisectable. Is that ok?

Sure.

Signature · 1 line
error compiling committee.c: too many arguments to function
#6 lore raw

PATCH v8 2/3 KVM: add irqfd DEASSIGN feature

In reply to Gregory Haskins

DEASSIGN allows us to optionally disassociate an IRQFD from its underlying eventfd without destroying the eventfd in the process. This is useful for conditions like live-migration which may have an eventfd associated with a device and an IRQFD. We need to be able to decouple the guest from the event source while not perturbing the event source itself.

CC Michael S. Tsirkin <[email protected]>

---

 include/linux/kvm.h |    2 ++
 virt/kvm/eventfd.c  |   46 ++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 46 insertions(+), 2 deletions(-)
include/linux/kvm.h +2 -0
index 69d3d73..76c6408 100644
@@ -461,6 +461,8 @@ struct kvm_x86_mce {
 };
 #endif
 
+#define KVM_IRQFD_FLAG_DEASSIGN (1 << 0)
+
 struct kvm_irqfd {
 	__u32 fd;
 	__u32 gsi;
virt/kvm/eventfd.c +44 -2

58 lines not on this page · raw message

#7 lore raw

PATCH v8 3/3 KVM: create irqfd-cleanup-wq on demand

In reply to Gregory Haskins

We currently create this wq on module_init, which may be wasteful if the host never creates a guest that uses irqfd. This patch changes the algorithm so that the workqueue is only created when at least one guest is using irqfd. The queue is cleaned up when the last guest using irqfd is shutdown.

To keep things simple, we only check whether the guest has tried to create an irqfd, not whether there are actually irqfds active.

---

 include/linux/kvm_host.h |    1 
 virt/kvm/eventfd.c       |  100 ++++++++++++++++++++++++++++++++++------------
 2 files changed, 75 insertions(+), 26 deletions(-)
include/linux/kvm_host.h +1 -0
index 7605bc4..0b0b6ac 100644
@@ -144,6 +144,7 @@ struct kvm {
 	struct {
 		spinlock_t        lock;
 		struct list_head  items;
+		int               init:1;
 	} irqfds;
 #endif
 	struct kvm_vm_stat stat;
virt/kvm/eventfd.c +74 -26

135 lines not on this page · raw message

#8 lore raw

Re: [KVM PATCH v8 3/3] KVM: create irqfd-cleanup-wq on demand

Quoted 12 lines · Gregory Haskins

We currently create this wq on module_init, which may be wasteful if the host never creates a guest that uses irqfd. This patch changes the algorithm so that the workqueue is only created when at least one guest is using irqfd. The queue is cleaned up when the last guest using irqfd is shutdown.

To keep things simple, we only check whether the guest has tried to create an irqfd, not whether there are actually irqfds active.

+++ b/include/linux/kvm_host.h

include/linux/kvm_host.h struct kvm { · line 148

Quoted 5 lines
include/linux/kvm_host.h +1 -0
@@ -144,6 +144,7 @@ struct kvm {
  	struct {
  		spinlock_t        lock;
  		struct list_head  items;
+		int               init:1;
 

Since you're rebasing anyway... change the bitfield to a bool.

Signature · 1 line
error compiling committee.c: too many arguments to function