Hello Roger,
     I introduce frontend suspend_cancel mechanism.If there are something need 
to be modified please let me know, thanks.
     On the base of the origin/release/10.2.0 branch, I make a patch file as 
fellows:

Signed-off-by: Yingdong Liu<liuyingd...@huawei.com>

 sys/dev/xen/blkfront/blkfront.c | 13 +++++++++++
 sys/dev/xen/control/control.c   |  9 ++++++-
 sys/dev/xen/netfront/netfront.c | 52 ++++++++++++++++++++++++++++++-----------
 sys/x86/xen/hvm.c               | 16 ++++++++-----
 sys/xen/xenbus/xenbusb.c        | 45 ++++++++++++++++++++++-------------
 sys/xen/xenbus/xenbusvar.h      |  4 ++++
 6 files changed, 102 insertions(+), 37 deletions(-)

diff --git a/sys/dev/xen/blkfront/blkfront.c b/sys/dev/xen/blkfront/blkfront.c
index a71251d..8d7c32a 100644
--- a/sys/dev/xen/blkfront/blkfront.c
+++ b/sys/dev/xen/blkfront/blkfront.c
@@ -68,6 +68,8 @@ __FBSDID("$FreeBSD$");

 #include "xenbus_if.h"

+static int blkfront_suspend_cancelled = 0;
+
 /*--------------------------- Forward Declarations 
---------------------------*/
 static void xbd_closing(device_t);
 static void xbd_startio(struct xbd_softc *sc);
@@ -1417,10 +1419,21 @@ xbd_suspend(device_t dev)
        return (retval);
 }

+void xbd_set_suspend_cancel(void)
+{
+       blkfront_suspend_cancelled = 1;
+}
+
 static int
 xbd_resume(device_t dev)
 {
        struct xbd_softc *sc = device_get_softc(dev);
+       
+       if(blkfront_suspend_cancelled == 1) {
+               sc->xbd_state = XBD_STATE_CONNECTED;
+               blkfront_suspend_cancelled = 0;
+               return (0);
+       }

        DPRINTK("xbd_resume: %s\n", xenbus_get_node(dev));

diff --git a/sys/dev/xen/control/control.c b/sys/dev/xen/control/control.c
index bc0609d..b500100 100644
--- a/sys/dev/xen/control/control.c
+++ b/sys/dev/xen/control/control.c
@@ -400,7 +400,9 @@ xctrl_suspend()
        /*
         * Reset grant table info.
         */
-       gnttab_resume();
+       if(suspend_cancelled == 0) {
+               gnttab_resume();
+       }

 #ifdef SMP
        if (smp_started && !CPU_EMPTY(&cpu_suspend_map)) {
@@ -416,6 +418,11 @@ xctrl_suspend()
         * FreeBSD really needs to add DEVICE_SUSPEND_CANCEL or
         * similar.
         */
+       if(suspend_cancelled == 1) {
+               xenbusb_set_suspend_cancel();
+               xbd_set_suspend_cancel();
+               xn_set_suspend_cancel();
+       }
        mtx_lock(&Giant);
        DEVICE_RESUME(root_bus);
        mtx_unlock(&Giant);
diff --git a/sys/dev/xen/netfront/netfront.c b/sys/dev/xen/netfront/netfront.c
index d89c0e0..0caaa2c 100644
--- a/sys/dev/xen/netfront/netfront.c
+++ b/sys/dev/xen/netfront/netfront.c
@@ -98,6 +98,8 @@ __FBSDID("$FreeBSD$");
 #define NET_TX_RING_SIZE __RING_SIZE((netif_tx_sring_t *)0, PAGE_SIZE)
 #define NET_RX_RING_SIZE __RING_SIZE((netif_rx_sring_t *)0, PAGE_SIZE)

+static int netfront_suspend_cancelled = 0;
+
 #if __FreeBSD_version >= 700000
 /*
  * Should the driver do LRO on the RX end
@@ -192,6 +194,10 @@ static int xennet_get_responses(struct netfront_info *np,
        struct netfront_rx_info *rinfo, RING_IDX rp, RING_IDX *cons,
        struct mbuf **list, int *pages_flipped_p);

+#ifdef INET
+static void netfront_send_fake_arp(device_t dev, struct netfront_info *info);
+#endif
+
 #define virt_to_mfn(x) (vtomach(x) >> PAGE_SHIFT)

 #define INVALID_P2M_ENTRY (~0UL)
@@ -493,6 +499,11 @@ netfront_suspend(device_t dev)
        return (0);
 }

+void xn_set_suspend_cancel(void)
+{
+       netfront_suspend_cancelled = 1;
+}
+
 /**
  * We are reconnecting to the backend, due to a suspend/resume, or a backend
  * driver restart.  We tear down our netif structure and recreate it, but
@@ -504,6 +515,19 @@ netfront_resume(device_t dev)
 {
        struct netfront_info *info = device_get_softc(dev);

+       if(netfront_suspend_cancelled == 1) {
+               info->xn_resume = true;
+               XN_RX_LOCK(info);
+               XN_TX_LOCK(info);
+               netfront_carrier_on(info);
+               XN_TX_UNLOCK(info);
+               XN_RX_UNLOCK(info);
+#ifdef INET
+               netfront_send_fake_arp(dev, info);
+#endif
+               netfront_suspend_cancelled = 0;
+               return (0);
+       }
        info->xn_resume = true;
        netif_disconnect_backend(info);
        return (0);
@@ -2108,26 +2132,26 @@ create_netdev(device_t dev)
        
        /* Set up ifnet structure */
        ifp = np->xn_ifp = if_alloc(IFT_ETHER);
-       ifp->if_softc = np;
-       if_initname(ifp, "xn",  device_get_unit(dev));
-       ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
-       ifp->if_ioctl = xn_ioctl;
-       ifp->if_output = ether_output;
-       ifp->if_start = xn_start;
+       ifp->if_softc = np;
+       if_initname(ifp, "xn",  device_get_unit(dev));
+       ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+       ifp->if_ioctl = xn_ioctl;
+       ifp->if_output = ether_output;
+       ifp->if_start = xn_start;
 #ifdef notyet
-       ifp->if_watchdog = xn_watchdog;
+       ifp->if_watchdog = xn_watchdog;
 #endif
-       ifp->if_init = xn_ifinit;
-       ifp->if_snd.ifq_maxlen = NET_TX_RING_SIZE - 1;
-       
-       ifp->if_hwassist = XN_CSUM_FEATURES;
-       ifp->if_capabilities = IFCAP_HWCSUM;
+       ifp->if_init = xn_ifinit;
+       ifp->if_snd.ifq_maxlen = NET_TX_RING_SIZE - 1;
+
+       ifp->if_hwassist = XN_CSUM_FEATURES;
+       ifp->if_capabilities = IFCAP_HWCSUM;
        ifp->if_hw_tsomax = 65536 - (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN);
        ifp->if_hw_tsomaxsegcount = MAX_TX_REQ_FRAGS;
        ifp->if_hw_tsomaxsegsize = PAGE_SIZE;
        
-       ether_ifattach(ifp, np->mac);
-       callout_init(&np->xn_stat_ch, CALLOUT_MPSAFE);
+       ether_ifattach(ifp, np->mac);
+       callout_init(&np->xn_stat_ch, CALLOUT_MPSAFE);
        netfront_carrier_off(np);

        return (0);
diff --git a/sys/x86/xen/hvm.c b/sys/x86/xen/hvm.c
index c386953..1c2ba9d 100644
--- a/sys/x86/xen/hvm.c
+++ b/sys/x86/xen/hvm.c
@@ -517,10 +517,9 @@ xen_hvm_init(enum xen_hvm_init_type init_type)
        int error;
        int i;

-       if (init_type == XEN_HVM_INIT_CANCELLED_SUSPEND)
-               return;
-
-       error = xen_hvm_init_hypercall_stubs();
+       if (init_type != XEN_HVM_INIT_CANCELLED_SUSPEND) {
+               error = xen_hvm_init_hypercall_stubs();
+       }

        switch (init_type) {
        case XEN_HVM_INIT_COLD:
@@ -541,13 +540,17 @@ xen_hvm_init(enum xen_hvm_init_type init_type)
                CPU_FOREACH(i)
                        DPCPU_ID_SET(i, vcpu_info, NULL);
                break;
+       case XEN_HVM_INIT_CANCELLED_SUSPEND:
+               break;
        default:
                panic("Unsupported HVM initialization type");
        }

        xen_vector_callback_enabled = 0;
        xen_domain_type = XEN_HVM_DOMAIN;
-       xen_hvm_init_shared_info_page();
+       if (init_type != XEN_HVM_INIT_CANCELLED_SUSPEND) {
+               xen_hvm_init_shared_info_page();
+       }
        xen_hvm_set_callback(NULL);
        xen_hvm_disable_emulated_devices();
 }
@@ -565,7 +568,8 @@ xen_hvm_resume(bool suspend_cancelled)
            XEN_HVM_INIT_CANCELLED_SUSPEND : XEN_HVM_INIT_RESUME);

        /* Register vcpu_info area for CPU#0. */
-       xen_hvm_cpu_init();
+       if(!suspend_cancelled)
+               xen_hvm_cpu_init();
 }

 static void
diff --git a/sys/xen/xenbus/xenbusb.c b/sys/xen/xenbus/xenbusb.c
index 1f84795..cce83cd 100644
--- a/sys/xen/xenbus/xenbusb.c
+++ b/sys/xen/xenbus/xenbusb.c
@@ -75,6 +75,8 @@ __FBSDID("$FreeBSD$");
 #include <xen/xenbus/xenbusb.h>
 #include <xen/xenbus/xenbusvar.h>

+static int xenbusb_suspend_cancelled = 0;
+
 /*------------------------- Private Functions 
--------------------------------*/
 /**
  * \brief Deallocate XenBus device instance variables.
@@ -776,6 +778,11 @@ xenbusb_attach(device_t dev, char *bus_node, u_int 
id_components)
        return (0);
 }

+void xenbusb_set_suspend_cancel(void)
+{
+       xenbusb_suspend_cancelled = 1;
+}
+
 int
 xenbusb_resume(device_t dev)
 {
@@ -793,29 +800,32 @@ xenbusb_resume(device_t dev)
                        if (device_get_state(kids[i]) == DS_NOTPRESENT)
                                continue;

-                       ivars = device_get_ivars(kids[i]);
+                       if(xenbusb_suspend_cancelled == 0) {
+                               ivars = device_get_ivars(kids[i]);

-                       xs_unregister_watch(&ivars->xd_otherend_watch);
-                       xenbus_set_state(kids[i], XenbusStateInitialising);
+                               xs_unregister_watch(&ivars->xd_otherend_watch);
+                               xenbus_set_state(kids[i], 
XenbusStateInitialising);

-                       /*
-                        * Find the new backend details and
-                        * re-register our watch.
-                        */
-                       error = XENBUSB_GET_OTHEREND_NODE(dev, ivars);
-                       if (error)
-                               return (error);
+                               /*
+                                * Find the new backend details and
+                                * re-register our watch.
+                                */
+                               error = XENBUSB_GET_OTHEREND_NODE(dev, ivars);
+                               if (error)
+                                       return (error);

-                       statepath = malloc(ivars->xd_otherend_path_len
-                           + strlen("/state") + 1, M_XENBUS, M_WAITOK);
-                       sprintf(statepath, "%s/state", ivars->xd_otherend_path);
+                               statepath = malloc(ivars->xd_otherend_path_len
+                                   + strlen("/state") + 1, M_XENBUS, M_WAITOK);
+                               sprintf(statepath, "%s/state", 
ivars->xd_otherend_path);

-                       free(ivars->xd_otherend_watch.node, M_XENBUS);
-                       ivars->xd_otherend_watch.node = statepath;
+                               free(ivars->xd_otherend_watch.node, M_XENBUS);
+                               ivars->xd_otherend_watch.node = statepath;
+                       }

                        DEVICE_RESUME(kids[i]);

-                       xs_register_watch(&ivars->xd_otherend_watch);
+                       if(xenbusb_suspend_cancelled == 0)
+                               xs_register_watch(&ivars->xd_otherend_watch);
 #if 0
                        /*
                         * Can't do this yet since we are running in
@@ -834,6 +844,9 @@ xenbusb_resume(device_t dev)
                free(kids, M_TEMP);
        }

+       if(xenbusb_suspend_cancelled == 1)
+               xenbusb_suspend_cancelled = 0;
+       
        return (0);
 }

diff --git a/sys/xen/xenbus/xenbusvar.h b/sys/xen/xenbus/xenbusvar.h
index ab5d01f..aff3b60 100644
--- a/sys/xen/xenbus/xenbusvar.h
+++ b/sys/xen/xenbus/xenbusvar.h
@@ -272,4 +272,8 @@ void xenbus_localend_changed(device_t dev, const char 
*path);

 #include "xenbus_if.h"

+void xenbusb_set_suspend_cancel(void);
+void xbd_set_suspend_cancel(void);
+void xn_set_suspend_cancel(void);
+
 #endif /* _XEN_XENBUS_XENBUSVAR_H */



_______________________________________________
freebsd-xen@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-xen
To unsubscribe, send any mail to "freebsd-xen-unsubscr...@freebsd.org"

Reply via email to