From owner-freebsd-xen@freebsd.org Tue Dec 13 13:51:38 2016 Return-Path: Delivered-To: freebsd-xen@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5B6AFC74743 for ; Tue, 13 Dec 2016 13:51:38 +0000 (UTC) (envelope-from liuyingdong@huawei.com) Received: from szxga01-in.huawei.com (szxga01-in.huawei.com [58.251.152.64]) (using TLSv1 with cipher RC4-SHA (128/128 bits)) (Client CN "myname.my.domain", Issuer "www.mirapoint.com" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 17883E16 for ; Tue, 13 Dec 2016 13:51:34 +0000 (UTC) (envelope-from liuyingdong@huawei.com) Received: from 172.24.1.47 (EHLO SZXEML429-HUB.china.huawei.com) ([172.24.1.47]) by szxrg01-dlp.huawei.com (MOS 4.3.7-GA FastPath queued) with ESMTP id DWK45626; Tue, 13 Dec 2016 21:48:38 +0800 (CST) Received: from [127.0.0.1] (10.177.20.238) by SZXEML429-HUB.china.huawei.com (10.82.67.184) with Microsoft SMTP Server id 14.3.235.1; Tue, 13 Dec 2016 21:48:30 +0800 To: freebsd xen , , , , , From: liuyingdong Subject: [PATCH] introduce frontend suspend_cancel mechanism Message-ID: <584FFC2B.1080309@huawei.com> Date: Tue, 13 Dec 2016 21:48:27 +0800 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.1.0 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Originating-IP: [10.177.20.238] X-CFilter-Loop: Reflected X-BeenThere: freebsd-xen@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Discussion of the freebsd port to xen - implementation and usage List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 13 Dec 2016 13:51:38 -0000 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 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 #include +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 */