Port-xen archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: xbd detachment



On Sat, Jul 25, 2009 at 03:50:39PM -0500, David Young wrote:
> > > Should this routine follow some other protocol in order to close down
> > > and revoke the grant_ref_t?
> >
> > Hardly, revocation will end in panic() (you cannot free a grant table  
> > entry while there is a read/write lock acquired by the other end on the  
> > referenced page).
> 
> What I mean is that xbd_xenbus_detach() may not use the correct
> protocol, and that is why the transfer/write/read status does not
> clear.  For example, what if xbd(4) indicates to the dom0 that it is
> finished with the ring, and then queues a transfer on the ring due to a
> programming mistake?
> 
> It seems to me that xbd_xenbus_detach() may not be used very much, if at
> all.  Moreover, if it has ever been used before, then I think that the
> Dom0, not the DomU, had initiated the device's detachment.  That may, in
> fact, make a difference, even if it should not.

Actually it does. xbd_xenbus_detach() is called by the xenbus handler
though config_detach(); at this point the backed has switched to
XenbusStateClosing then XenbusStateClosed.
For a locally-initiated detach, the frontend need to switch to
XenbusStateClosing, then wait for the backend to switch to XenbusStateClosing
then XenbusStateClosed. This will cause config_detach() to be called
a second time. 

Would the (untested) attached patch help ?

-- 
Manuel Bouyer, LIP6, Universite Paris VI.           
Manuel.Bouyer%lip6.fr@localhost
     NetBSD: 26 ans d'experience feront toujours la difference
--
Index: xbd_xenbus.c
===================================================================
RCS file: /cvsroot/src/sys/arch/xen/xen/xbd_xenbus.c,v
retrieving revision 1.39
diff -u -p -u -r1.39 xbd_xenbus.c
--- xbd_xenbus.c        3 Mar 2009 19:04:41 -0000       1.39
+++ xbd_xenbus.c        28 Jul 2009 16:30:42 -0000
@@ -110,6 +110,9 @@ struct xbd_xenbus_softc {
 #define BLKIF_STATE_CONNECTED    1
 #define BLKIF_STATE_SUSPENDED    2
        int sc_shutdown;
+#define BLKIF_SHUTDOWN_RUN    0 /* no shutdown */
+#define BLKIF_SHUTDOWN_REMOTE 1 /* backend-initiated shutdown in progress */
+#define BLKIF_SHUTDOWN_LOCAL  2 /* locally-initiated shutdown in progress */
 
        uint64_t sc_sectors; /* number of sectors for this device */
        u_long sc_secsize; /* sector size */
@@ -249,7 +252,7 @@ xbd_xenbus_attach(device_t parent, devic
        }
 
        sc->sc_backend_status = BLKIF_STATE_DISCONNECTED;
-       sc->sc_shutdown = 1;
+       sc->sc_shutdown = BLKIF_SHUTDOWN_REMOTE;
        /* initialise shared structures and tell backend that we are ready */
        xbd_xenbus_resume(sc);
 
@@ -266,12 +269,22 @@ xbd_xenbus_detach(device_t dev, int flag
        int s, bmaj, cmaj, i, mn;
        s = splbio();
        DPRINTF(("%s: xbd_detach\n", device_xname(dev)));
-       if (sc->sc_shutdown == 0) {
-               sc->sc_shutdown = 1;
+       if (sc->sc_shutdown == BLKIF_SHUTDOWN_LOCAL) {
+               /* xbd_xenbus_detach already in progress */
+               wakeup(xbd_xenbus_detach);
+               splx(s);
+               return EALREADY;
+       }
+       if (sc->sc_shutdown == BLKIF_SHUTDOWN_RUN) {
+               sc->sc_shutdown = BLKIF_SHUTDOWN_LOCAL;
                /* wait for requests to complete */
                while (sc->sc_backend_status == BLKIF_STATE_CONNECTED &&
                    sc->sc_dksc.sc_dkdev.dk_stats->io_busy > 0)
                        tsleep(xbd_xenbus_detach, PRIBIO, "xbddetach", hz/2);
+               xenbus_switch_state(sc->sc_xbusd, NULL, XenbusStateClosing);
+               while (xenbus_read_driver_state(sc->sc_xbusd->xbusd_otherend)
+                   != XenbusStateClosed)
+                       tsleep(xbd_xenbus_detach, PRIBIO, "xbddetach2", hz/2);
        }
        splx(s);
 
@@ -412,7 +425,7 @@ static void xbd_backend_changed(void *ar
                break;
        case XenbusStateClosing:
                s = splbio();
-               sc->sc_shutdown = 1;
+               sc->sc_shutdown = BLKIF_SHUTDOWN_REMOTE;
                /* wait for requests to complete */
                while (sc->sc_backend_status == BLKIF_STATE_CONNECTED &&
                    sc->sc_dksc.sc_dkdev.dk_stats->io_busy > 0)
@@ -432,7 +445,7 @@ static void xbd_backend_changed(void *ar
                        return;
 
                xbd_connect(sc);
-               sc->sc_shutdown = 0;
+               sc->sc_shutdown = BLKIF_SHUTDOWN_RUN;
                hypervisor_enable_event(sc->sc_evtchn);
 
                sc->sc_xbdsize =


Home | Main Index | Thread Index | Old Index