Re: [Xen-devel] [PATCH 5/6] libxl: events: Deregister evtchn fd when not needed

2014-12-09 Thread Ian Jackson
Ian Campbell writes (Re: [PATCH 5/6] libxl: events: Deregister evtchn fd when 
not needed):
 On Fri, 2014-11-28 at 14:47 +, Ian Jackson wrote:
  libxl__ev_evtchn_* is always called with the ctx lock held.
 
 For the most part this is implicit due to the caller being in an ao
 callback, right?

Yes.

  However, that they don't take the lock is contrary to the rules stated
  for libxl__ev_* in the doc comment.  That should be fixed for 4.6.
 
 OK.

Should I take this as an ack ?

Thanks,
Ian.

___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH 5/6] libxl: events: Deregister evtchn fd when not needed [and 1 more messages]

2014-12-09 Thread Ian Jackson
Ian Campbell writes (Re: [PATCH 5/6] libxl: events: Deregister evtchn fd when 
not needed):
 There were other comments further down my original review which you
 haven't answered. I don't think they were (all) predicated on a
 particular answer to the first question (although some were).

Sorry, I didn't see those buried in down the patch ...

Ian Campbell writes (Re: [PATCH 5/6] libxl: events: Deregister evtchn fd when 
not needed):
 On Thu, 2014-11-27 at 18:27 +, Ian Jackson wrote:
  @@ -733,14 +733,10 @@ int libxl__ctx_evtchn_init(libxl__gc *gc) {
   goto out;
   }
   
  -fd = xc_evtchn_fd(xce);
  -assert(fd = 0);
  +CTX-evtchn_fd = xc_evtchn_fd(xce);
  +assert(CTX-evtchn_fd = 0);
 
 Given that you can always retrieve this no demand with xc_evtchn_fd(xce)
 and that it is cheap do you need to stash it in the ctx?

Good point.

  @@ -758,6 +760,13 @@ int libxl__ev_evtchn_wait(libxl__gc *gc, 
  libxl__ev_evtchn *evev)
   DBG(ev_evtchn=%p port=%d wait (was waiting=%d),
   evev, evev-port, evev-waiting);
   
  +rc = libxl__ctx_evtchn_init(gc);
  +if (rc) goto out;
  +
  +rc = libxl__ev_fd_register(gc, CTX-evtchn_efd,
  +   evtchn_fd_callback, CTX-evtchn_fd, POLLIN);
  +if (rc) goto out;
 
 Do you not need to do this only if evtchns_waiting is currently empty or
 the efd is idle?

In fact, I should check libxl__ev_fd_isregistered.  That makes the
fragment idempotent.  I'm surprised this worked for you as it was...

   if (evev-waiting)
   return 0;
 
 If you hit this you leave the stuff above done. Which may or may not 
 matter depending on the answer above.

Given the change above, I don't think it matters, because if
evev-waiting, all of the other stuff is definitely already set up
anyway.  It is clearest to put the new initialisation fragment next to
the existing one.

I will resend with the two changes above.  The diff between the
previous version of this patch and the forthcoming new one is below.

Thanks for the careful review.

Ian.


diff --git a/tools/libxl/libxl_event.c b/tools/libxl/libxl_event.c
index 716f318..a36e6d9 100644
--- a/tools/libxl/libxl_event.c
+++ b/tools/libxl/libxl_event.c
@@ -721,7 +721,7 @@ static void evtchn_fd_callback(libxl__egc *egc, 
libxl__ev_fd *ev,
 
 int libxl__ctx_evtchn_init(libxl__gc *gc) {
 xc_evtchn *xce;
-int rc;
+int rc, fd;
 
 if (CTX-xce)
 return 0;
@@ -733,10 +733,10 @@ int libxl__ctx_evtchn_init(libxl__gc *gc) {
 goto out;
 }
 
-CTX-evtchn_fd = xc_evtchn_fd(xce);
-assert(CTX-evtchn_fd = 0);
+fd = xc_evtchn_fd(xce);
+assert(fd = 0);
 
-rc = libxl_fd_set_nonblock(CTX, CTX-evtchn_fd, 1);
+rc = libxl_fd_set_nonblock(CTX, fd, 1);
 if (rc) goto out;
 
 CTX-xce = xce;
@@ -763,9 +763,11 @@ int libxl__ev_evtchn_wait(libxl__gc *gc, libxl__ev_evtchn 
*evev)
 rc = libxl__ctx_evtchn_init(gc);
 if (rc) goto out;
 
-rc = libxl__ev_fd_register(gc, CTX-evtchn_efd,
-   evtchn_fd_callback, CTX-evtchn_fd, POLLIN);
-if (rc) goto out;
+if (!libxl__ev_fd_isregistered(CTX-evtchn_efd)) {
+rc = libxl__ev_fd_register(gc, CTX-evtchn_efd, evtchn_fd_callback,
+   xc_evtchn_fd(CTX-xce), POLLIN);
+if (rc) goto out;
+}
 
 if (evev-waiting)
 return 0;
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 2eeba1e..9695f18 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -359,7 +359,6 @@ struct libxl__ctx {
 
 xc_evtchn *xce; /* waiting must be done only with libxl__ev_evtchn* */
 LIBXL_LIST_HEAD(, libxl__ev_evtchn) evtchns_waiting;
-int evtchn_fd;
 libxl__ev_fd evtchn_efd;
 
 LIBXL_TAILQ_HEAD(libxl__evgen_domain_death_list, libxl_evgen_domain_death)

___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH 5/6] libxl: events: Deregister evtchn fd when not needed

2014-12-09 Thread Ian Campbell
On Tue, 2014-12-09 at 15:54 +, Ian Jackson wrote:
 We want to have no fd events registered when we are idle.
 In this patch, deal with the evtchn fd:
 
  * Defer setup of the evtchn handle to the first use.
  * Defer registration of the evtchn fd; register as needed on use.
  * When cancelling an evtchn wait, or when wait setup fails, check
whether there are now no evtchn waits and if so deregister the fd.
  * On libxl teardown, the evtchn fd should therefore be unregistered.
assert that this is the case.
 
 Signed-off-by: Ian Jackson ian.jack...@eu.citrix.com
 Release-Acked-by: Konrad Rzeszutek Wilk konrad.w...@oracle.com

Acked-by: Ian Campbell ian.campb...@citrix.com



___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


[Xen-devel] [PATCH 5/6] libxl: events: Deregister evtchn fd when not needed

2014-12-09 Thread Ian Jackson
We want to have no fd events registered when we are idle.
In this patch, deal with the evtchn fd:

 * Defer setup of the evtchn handle to the first use.
 * Defer registration of the evtchn fd; register as needed on use.
 * When cancelling an evtchn wait, or when wait setup fails, check
   whether there are now no evtchn waits and if so deregister the fd.
 * On libxl teardown, the evtchn fd should therefore be unregistered.
   assert that this is the case.

Signed-off-by: Ian Jackson ian.jack...@eu.citrix.com
Release-Acked-by: Konrad Rzeszutek Wilk konrad.w...@oracle.com

---
v2: Do not bother putting evtchn_fd in the ctx; instead, get it
 from xc_evtchn_fd when we need it.  (Cosmetic.)
Do not register the evtchn fd multiple times: check it's not
 registered before we call libxl__ev_fd_register.  (Bugfix.)
---
 tools/libxl/libxl.c   |4 +---
 tools/libxl/libxl_event.c |   21 +
 2 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index 8f06043..50a8928 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -118,8 +118,6 @@ int libxl_ctx_alloc(libxl_ctx **pctx, int version,
 rc = ERROR_FAIL; goto out;
 }
 
-rc = libxl__ctx_evtchn_init(gc);
-
 *pctx = ctx;
 return 0;
 
@@ -166,7 +164,7 @@ int libxl_ctx_free(libxl_ctx *ctx)
 for (i = 0; i  ctx-watch_nslots; i++)
 assert(!libxl__watch_slot_contents(gc, i));
 assert(!libxl__ev_fd_isregistered(ctx-watch_efd));
-libxl__ev_fd_deregister(gc, ctx-evtchn_efd);
+assert(!libxl__ev_fd_isregistered(ctx-evtchn_efd));
 assert(!libxl__ev_fd_isregistered(ctx-sigchld_selfpipe_efd));
 
 /* Now there should be no more events requested from the application: */
diff --git a/tools/libxl/libxl_event.c b/tools/libxl/libxl_event.c
index da0a20e..a36e6d9 100644
--- a/tools/libxl/libxl_event.c
+++ b/tools/libxl/libxl_event.c
@@ -739,10 +739,6 @@ int libxl__ctx_evtchn_init(libxl__gc *gc) {
 rc = libxl_fd_set_nonblock(CTX, fd, 1);
 if (rc) goto out;
 
-rc = libxl__ev_fd_register(gc, CTX-evtchn_efd,
-   evtchn_fd_callback, fd, POLLIN);
-if (rc) goto out;
-
 CTX-xce = xce;
 return 0;
 
@@ -751,6 +747,12 @@ int libxl__ctx_evtchn_init(libxl__gc *gc) {
 return rc;
 }
 
+static void evtchn_check_fd_deregister(libxl__gc *gc)
+{
+if (CTX-xce  LIBXL_LIST_EMPTY(CTX-evtchns_waiting))
+libxl__ev_fd_deregister(gc, CTX-evtchn_efd);
+}
+
 int libxl__ev_evtchn_wait(libxl__gc *gc, libxl__ev_evtchn *evev)
 {
 int r, rc;
@@ -758,6 +760,15 @@ int libxl__ev_evtchn_wait(libxl__gc *gc, libxl__ev_evtchn 
*evev)
 DBG(ev_evtchn=%p port=%d wait (was waiting=%d),
 evev, evev-port, evev-waiting);
 
+rc = libxl__ctx_evtchn_init(gc);
+if (rc) goto out;
+
+if (!libxl__ev_fd_isregistered(CTX-evtchn_efd)) {
+rc = libxl__ev_fd_register(gc, CTX-evtchn_efd, evtchn_fd_callback,
+   xc_evtchn_fd(CTX-xce), POLLIN);
+if (rc) goto out;
+}
+
 if (evev-waiting)
 return 0;
 
@@ -773,6 +784,7 @@ int libxl__ev_evtchn_wait(libxl__gc *gc, libxl__ev_evtchn 
*evev)
 return 0;
 
  out:
+evtchn_check_fd_deregister(gc);
 return rc;
 }
 
@@ -786,6 +798,7 @@ void libxl__ev_evtchn_cancel(libxl__gc *gc, 
libxl__ev_evtchn *evev)
 
 evev-waiting = 0;
 LIBXL_LIST_REMOVE(evev, entry);
+evtchn_check_fd_deregister(gc);
 }
 
 /*
-- 
1.7.10.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH 5/6] libxl: events: Deregister evtchn fd when not needed

2014-11-28 Thread Ian Campbell
On Thu, 2014-11-27 at 18:27 +, Ian Jackson wrote:
 We want to have no fd events registered when we are idle.
 In this patch, deal with the evtchn fd:
 
  * Defer setup of the evtchn handle to the first use.
  * Defer registration of the evtchn fd; register as needed on use.
  * When cancelling an evtchn wait, or when wait setup fails, check
whether there are now no evtchn waits and if so deregister the fd.
  * On libxl teardown, the evtchn fd should therefore be unregistered.
assert that this is the case.

Is there no locking required when registering/deregistering? Since there
are list manipulations in most of these places I presume it already
exists, but I thought I should check.

 
 Signed-off-by: Ian Jackson ian.jack...@eu.citrix.com
 ---
  tools/libxl/libxl.c  |4 +---
  tools/libxl/libxl_event.c|   27 +++
  tools/libxl/libxl_internal.h |1 +
  3 files changed, 21 insertions(+), 11 deletions(-)
 
 diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
 index 785253d..e0db4eb 100644
 --- a/tools/libxl/libxl.c
 +++ b/tools/libxl/libxl.c
 @@ -118,8 +118,6 @@ int libxl_ctx_alloc(libxl_ctx **pctx, int version,
  rc = ERROR_FAIL; goto out;
  }
  
 -rc = libxl__ctx_evtchn_init(gc);
 -
  *pctx = ctx;
  return 0;
  
 @@ -166,7 +164,7 @@ int libxl_ctx_free(libxl_ctx *ctx)
  for (i = 0; i  ctx-watch_nslots; i++)
  assert(!libxl__watch_slot_contents(gc, i));
  assert(!libxl__ev_fd_isregistered(ctx-watch_efd));
 -libxl__ev_fd_deregister(gc, ctx-evtchn_efd);
 +assert(!libxl__ev_fd_isregistered(ctx-evtchn_efd));
  assert(!libxl__ev_fd_isregistered(ctx-sigchld_selfpipe_efd));
  
  /* Now there should be no more events requested from the application: */
 diff --git a/tools/libxl/libxl_event.c b/tools/libxl/libxl_event.c
 index da0a20e..716f318 100644
 --- a/tools/libxl/libxl_event.c
 +++ b/tools/libxl/libxl_event.c
 @@ -721,7 +721,7 @@ static void evtchn_fd_callback(libxl__egc *egc, 
 libxl__ev_fd *ev,
  
  int libxl__ctx_evtchn_init(libxl__gc *gc) {
  xc_evtchn *xce;
 -int rc, fd;
 +int rc;
  
  if (CTX-xce)
  return 0;
 @@ -733,14 +733,10 @@ int libxl__ctx_evtchn_init(libxl__gc *gc) {
  goto out;
  }
  
 -fd = xc_evtchn_fd(xce);
 -assert(fd = 0);
 +CTX-evtchn_fd = xc_evtchn_fd(xce);
 +assert(CTX-evtchn_fd = 0);

Given that you can always retrieve this no demand with xc_evtchn_fd(xce)
and that it is cheap do you need to stash it in the ctx?

 -rc = libxl_fd_set_nonblock(CTX, fd, 1);
 -if (rc) goto out;
 -
 -rc = libxl__ev_fd_register(gc, CTX-evtchn_efd,
 -   evtchn_fd_callback, fd, POLLIN);
 +rc = libxl_fd_set_nonblock(CTX, CTX-evtchn_fd, 1);
  if (rc) goto out;
  
  CTX-xce = xce;
 @@ -751,6 +747,12 @@ int libxl__ctx_evtchn_init(libxl__gc *gc) {
  return rc;
  }
  
 +static void evtchn_check_fd_deregister(libxl__gc *gc)
 +{
 +if (CTX-xce  LIBXL_LIST_EMPTY(CTX-evtchns_waiting))
 +libxl__ev_fd_deregister(gc, CTX-evtchn_efd);
 +}
 +
  int libxl__ev_evtchn_wait(libxl__gc *gc, libxl__ev_evtchn *evev)
  {
  int r, rc;
 @@ -758,6 +760,13 @@ int libxl__ev_evtchn_wait(libxl__gc *gc, 
 libxl__ev_evtchn *evev)
  DBG(ev_evtchn=%p port=%d wait (was waiting=%d),
  evev, evev-port, evev-waiting);
  
 +rc = libxl__ctx_evtchn_init(gc);
 +if (rc) goto out;
 +
 +rc = libxl__ev_fd_register(gc, CTX-evtchn_efd,
 +   evtchn_fd_callback, CTX-evtchn_fd, POLLIN);
 +if (rc) goto out;

Do you not need to do this only if evtchns_waiting is currently empty or
the efd is idle?

 +
  if (evev-waiting)
  return 0;

If you hit this you leave the stuff above done. Which may or may not 
matter depending on the answer above.


Ian.


___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH 5/6] libxl: events: Deregister evtchn fd when not needed

2014-11-28 Thread Ian Jackson
Ian Campbell writes (Re: [PATCH 5/6] libxl: events: Deregister evtchn fd when 
not needed):
 On Thu, 2014-11-27 at 18:27 +, Ian Jackson wrote:
  We want to have no fd events registered when we are idle.
  In this patch, deal with the evtchn fd:
  
   * Defer setup of the evtchn handle to the first use.
   * Defer registration of the evtchn fd; register as needed on use.
   * When cancelling an evtchn wait, or when wait setup fails, check
 whether there are now no evtchn waits and if so deregister the fd.
   * On libxl teardown, the evtchn fd should therefore be unregistered.
 assert that this is the case.
 
 Is there no locking required when registering/deregistering? Since there
 are list manipulations in most of these places I presume it already
 exists, but I thought I should check.

libxl__ev_evtchn_* is always called with the ctx lock held.

However, that they don't take the lock is contrary to the rules stated
for libxl__ev_* in the doc comment.  That should be fixed for 4.6.

libxl__ev_fd_* already take and release the lock to protect their own
data structures etc.

Ian.

___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH 5/6] libxl: events: Deregister evtchn fd when not needed

2014-11-28 Thread Ian Campbell
On Fri, 2014-11-28 at 14:47 +, Ian Jackson wrote:
 Ian Campbell writes (Re: [PATCH 5/6] libxl: events: Deregister evtchn fd 
 when not needed):
  On Thu, 2014-11-27 at 18:27 +, Ian Jackson wrote:
   We want to have no fd events registered when we are idle.
   In this patch, deal with the evtchn fd:
   
* Defer setup of the evtchn handle to the first use.
* Defer registration of the evtchn fd; register as needed on use.
* When cancelling an evtchn wait, or when wait setup fails, check
  whether there are now no evtchn waits and if so deregister the fd.
* On libxl teardown, the evtchn fd should therefore be unregistered.
  assert that this is the case.
  
  Is there no locking required when registering/deregistering? Since there
  are list manipulations in most of these places I presume it already
  exists, but I thought I should check.
 
 libxl__ev_evtchn_* is always called with the ctx lock held.

For the most part this is implicit due to the caller being in an ao
callback, right?

 However, that they don't take the lock is contrary to the rules stated
 for libxl__ev_* in the doc comment.  That should be fixed for 4.6.

OK.

 libxl__ev_fd_* already take and release the lock to protect their own
 data structures etc.
 
 Ian.



___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


[Xen-devel] [PATCH 5/6] libxl: events: Deregister evtchn fd when not needed

2014-11-27 Thread Ian Jackson
We want to have no fd events registered when we are idle.
In this patch, deal with the evtchn fd:

 * Defer setup of the evtchn handle to the first use.
 * Defer registration of the evtchn fd; register as needed on use.
 * When cancelling an evtchn wait, or when wait setup fails, check
   whether there are now no evtchn waits and if so deregister the fd.
 * On libxl teardown, the evtchn fd should therefore be unregistered.
   assert that this is the case.

Signed-off-by: Ian Jackson ian.jack...@eu.citrix.com
---
 tools/libxl/libxl.c  |4 +---
 tools/libxl/libxl_event.c|   27 +++
 tools/libxl/libxl_internal.h |1 +
 3 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index 785253d..e0db4eb 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -118,8 +118,6 @@ int libxl_ctx_alloc(libxl_ctx **pctx, int version,
 rc = ERROR_FAIL; goto out;
 }
 
-rc = libxl__ctx_evtchn_init(gc);
-
 *pctx = ctx;
 return 0;
 
@@ -166,7 +164,7 @@ int libxl_ctx_free(libxl_ctx *ctx)
 for (i = 0; i  ctx-watch_nslots; i++)
 assert(!libxl__watch_slot_contents(gc, i));
 assert(!libxl__ev_fd_isregistered(ctx-watch_efd));
-libxl__ev_fd_deregister(gc, ctx-evtchn_efd);
+assert(!libxl__ev_fd_isregistered(ctx-evtchn_efd));
 assert(!libxl__ev_fd_isregistered(ctx-sigchld_selfpipe_efd));
 
 /* Now there should be no more events requested from the application: */
diff --git a/tools/libxl/libxl_event.c b/tools/libxl/libxl_event.c
index da0a20e..716f318 100644
--- a/tools/libxl/libxl_event.c
+++ b/tools/libxl/libxl_event.c
@@ -721,7 +721,7 @@ static void evtchn_fd_callback(libxl__egc *egc, 
libxl__ev_fd *ev,
 
 int libxl__ctx_evtchn_init(libxl__gc *gc) {
 xc_evtchn *xce;
-int rc, fd;
+int rc;
 
 if (CTX-xce)
 return 0;
@@ -733,14 +733,10 @@ int libxl__ctx_evtchn_init(libxl__gc *gc) {
 goto out;
 }
 
-fd = xc_evtchn_fd(xce);
-assert(fd = 0);
+CTX-evtchn_fd = xc_evtchn_fd(xce);
+assert(CTX-evtchn_fd = 0);
 
-rc = libxl_fd_set_nonblock(CTX, fd, 1);
-if (rc) goto out;
-
-rc = libxl__ev_fd_register(gc, CTX-evtchn_efd,
-   evtchn_fd_callback, fd, POLLIN);
+rc = libxl_fd_set_nonblock(CTX, CTX-evtchn_fd, 1);
 if (rc) goto out;
 
 CTX-xce = xce;
@@ -751,6 +747,12 @@ int libxl__ctx_evtchn_init(libxl__gc *gc) {
 return rc;
 }
 
+static void evtchn_check_fd_deregister(libxl__gc *gc)
+{
+if (CTX-xce  LIBXL_LIST_EMPTY(CTX-evtchns_waiting))
+libxl__ev_fd_deregister(gc, CTX-evtchn_efd);
+}
+
 int libxl__ev_evtchn_wait(libxl__gc *gc, libxl__ev_evtchn *evev)
 {
 int r, rc;
@@ -758,6 +760,13 @@ int libxl__ev_evtchn_wait(libxl__gc *gc, libxl__ev_evtchn 
*evev)
 DBG(ev_evtchn=%p port=%d wait (was waiting=%d),
 evev, evev-port, evev-waiting);
 
+rc = libxl__ctx_evtchn_init(gc);
+if (rc) goto out;
+
+rc = libxl__ev_fd_register(gc, CTX-evtchn_efd,
+   evtchn_fd_callback, CTX-evtchn_fd, POLLIN);
+if (rc) goto out;
+
 if (evev-waiting)
 return 0;
 
@@ -773,6 +782,7 @@ int libxl__ev_evtchn_wait(libxl__gc *gc, libxl__ev_evtchn 
*evev)
 return 0;
 
  out:
+evtchn_check_fd_deregister(gc);
 return rc;
 }
 
@@ -786,6 +796,7 @@ void libxl__ev_evtchn_cancel(libxl__gc *gc, 
libxl__ev_evtchn *evev)
 
 evev-waiting = 0;
 LIBXL_LIST_REMOVE(evev, entry);
+evtchn_check_fd_deregister(gc);
 }
 
 /*
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 728fe2c..481fbd5 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -359,6 +359,7 @@ struct libxl__ctx {
 
 xc_evtchn *xce; /* waiting must be done only with libxl__ev_evtchn* */
 LIBXL_LIST_HEAD(, libxl__ev_evtchn) evtchns_waiting;
+int evtchn_fd;
 libxl__ev_fd evtchn_efd;
 
 LIBXL_TAILQ_HEAD(libxl__evgen_domain_death_list, libxl_evgen_domain_death)
-- 
1.7.10.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel