ia64/xen-unstable

changeset 2221:7bac86571809

bitkeeper revision 1.1159.1.49 (411c8497ap7IGVG_YiU6BUkRUaSarw)

Merge labyrinth.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into labyrinth.cl.cam.ac.uk:/auto/anfs/scratch/labyrinth/iap10/xeno-clone/xeno.bk
author iap10@labyrinth.cl.cam.ac.uk
date Fri Aug 13 09:06:31 2004 +0000 (2004-08-13)
parents 9166d5ce37f3 c48fd545583a
children 79f922fe70cb 59b1da265f6b a628543fb437
files tools/python/xen/lowlevel/xu/xu.c xen/include/xen/event.h
line diff
     1.1 --- a/tools/python/xen/lowlevel/xu/xu.c	Fri Aug 13 09:06:20 2004 +0000
     1.2 +++ b/tools/python/xen/lowlevel/xu/xu.c	Fri Aug 13 09:06:31 2004 +0000
     1.3 @@ -57,6 +57,19 @@
     1.4  #endif
     1.5  
     1.6  
     1.7 +/* Set the close-on-exec flag on a file descriptor.  Doesn't currently bother
     1.8 + * to check for errors. */
     1.9 +static void set_cloexec(int fd)
    1.10 +{
    1.11 +    int flags = fcntl(fd, F_GETFD, 0);
    1.12 +
    1.13 +    if ( flags < 0 )
    1.14 +	return;
    1.15 +
    1.16 +    flags |= FD_CLOEXEC;
    1.17 +    fcntl(fd, F_SETFD, flags);
    1.18 +}
    1.19 +
    1.20  /*
    1.21   * *********************** NOTIFIER ***********************
    1.22   */
    1.23 @@ -197,6 +210,7 @@ static PyObject *xu_notifier_new(PyObjec
    1.24          PyObject_Del((PyObject *)xun);
    1.25          return PyErr_SetFromErrno(PyExc_IOError);
    1.26      }
    1.27 +    set_cloexec(xun->evtchn_fd);
    1.28  
    1.29      return (PyObject *)xun;
    1.30  }
    1.31 @@ -896,6 +910,7 @@ static int __xu_port_connect(xu_port_obj
    1.32          PyErr_SetString(port_error, "Could not open '/dev/mem'");
    1.33          return -1;
    1.34      }
    1.35 +    set_cloexec(xup->mem_fd);
    1.36  
    1.37      /* Set the General-Purpose Subject whose page frame will be mapped. */
    1.38      (void)ioctl(xup->mem_fd, _IO('M', 1), (unsigned long)xup->remote_dom);
     2.1 --- a/xen/include/xen/event.h	Fri Aug 13 09:06:20 2004 +0000
     2.2 +++ b/xen/include/xen/event.h	Fri Aug 13 09:06:31 2004 +0000
     2.3 @@ -14,19 +14,6 @@
     2.4  #include <asm/bitops.h>
     2.5  
     2.6  /*
     2.7 - * GENERIC SCHEDULING CALLBACK MECHANISMS
     2.8 - */
     2.9 -
    2.10 -/* Schedule an asynchronous callback for the specified domain. */
    2.11 -static inline void guest_async_callback(struct domain *d)
    2.12 -{
    2.13 -    int running = test_bit(DF_RUNNING, &d->flags);
    2.14 -    domain_unblock(d);
    2.15 -    if ( running )
    2.16 -        smp_send_event_check_cpu(d->processor);
    2.17 -}
    2.18 -
    2.19 -/*
    2.20   * EVENT-CHANNEL NOTIFICATIONS
    2.21   * NB. On x86, the atomic bit operations also act as memory barriers. There
    2.22   * is therefore sufficiently strict ordering for this architecture -- others
    2.23 @@ -36,13 +23,29 @@ static inline void guest_async_callback(
    2.24  static inline void evtchn_set_pending(struct domain *d, int port)
    2.25  {
    2.26      shared_info_t *s = d->shared_info;
    2.27 +    int            running;
    2.28 +
    2.29 +    /* These three operations must happen in strict order. */
    2.30      if ( !test_and_set_bit(port,    &s->evtchn_pending[0]) &&
    2.31           !test_bit        (port,    &s->evtchn_mask[0])    &&
    2.32           !test_and_set_bit(port>>5, &s->evtchn_pending_sel) )
    2.33      {
    2.34          /* The VCPU pending flag must be set /after/ update to evtchn-pend. */
    2.35 -        s->vcpu_data[0].evtchn_upcall_pending = 1;
    2.36 -        guest_async_callback(d);
    2.37 +        set_bit(0, &s->vcpu_data[0].evtchn_upcall_pending);
    2.38 +
    2.39 +        /*
    2.40 +         * NB1. 'flags' and 'processor' must be checked /after/ update of
    2.41 +         * pending flag. These values may fluctuate (after all, we hold no
    2.42 +         * locks) but the key insight is that each change will cause
    2.43 +         * evtchn_upcall_pending to be polled.
    2.44 +         * 
    2.45 +         * NB2. We save DF_RUNNING across the unblock to avoid a needless
    2.46 +         * IPI for domains that we IPI'd to unblock.
    2.47 +         */
    2.48 +        running = test_bit(DF_RUNNING, &d->flags);
    2.49 +        domain_unblock(d);
    2.50 +        if ( running )
    2.51 +            smp_send_event_check_cpu(d->processor);
    2.52      }
    2.53  }
    2.54