diff options
author | Renato Botelho <renato@netgate.com> | 2017-04-26 17:58:09 -0300 |
---|---|---|
committer | Renato Botelho <renato@netgate.com> | 2017-04-26 17:58:09 -0300 |
commit | 07324460536d4fea98778edbb99e88f512dd3a6c (patch) | |
tree | 7abe9cde8c3df456554a2e29b40a39ffd4a1e9c0 /sys/dev | |
parent | 1d2c919ef6b6d7b9e78890cea95a129a17d61930 (diff) | |
parent | b8126de23e957978b4d0403097cd8402f0c1d82a (diff) | |
download | FreeBSD-src-07324460536d4fea98778edbb99e88f512dd3a6c.zip FreeBSD-src-07324460536d4fea98778edbb99e88f512dd3a6c.tar.gz |
Merge remote-tracking branch 'origin/releng/10.3' into RELENG_2_3
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/xen/blkfront/blkfront.c | 5 | ||||
-rw-r--r-- | sys/dev/xen/control/control.c | 20 | ||||
-rw-r--r-- | sys/dev/xen/netfront/netfront.c | 54 |
3 files changed, 74 insertions, 5 deletions
diff --git a/sys/dev/xen/blkfront/blkfront.c b/sys/dev/xen/blkfront/blkfront.c index e9650f0..3c5606c 100644 --- a/sys/dev/xen/blkfront/blkfront.c +++ b/sys/dev/xen/blkfront/blkfront.c @@ -1503,6 +1503,11 @@ xbd_resume(device_t dev) { struct xbd_softc *sc = device_get_softc(dev); + if (xen_suspend_cancelled) { + sc->xbd_state = XBD_STATE_CONNECTED; + return (0); + } + DPRINTK("xbd_resume: %s\n", xenbus_get_node(dev)); xbd_free(sc); diff --git a/sys/dev/xen/control/control.c b/sys/dev/xen/control/control.c index 60e448a..b8d41ba 100644 --- a/sys/dev/xen/control/control.c +++ b/sys/dev/xen/control/control.c @@ -151,6 +151,7 @@ __FBSDID("$FreeBSD$"); #include <machine/xen/xenvar.h> #include <machine/xen/xenfunc.h> +bool xen_suspend_cancelled; /*--------------------------- Forward Declarations --------------------------*/ /** Function signature for shutdown event handlers. */ typedef void (xctrl_shutdown_handler_t)(void); @@ -341,8 +342,11 @@ xctrl_suspend() #ifdef SMP cpuset_t cpu_suspend_map; #endif - int suspend_cancelled; + EVENTHANDLER_INVOKE(power_suspend_early); + xs_lock(); + stop_all_proc(); + xs_unlock(); EVENTHANDLER_INVOKE(power_suspend); if (smp_started) { @@ -392,16 +396,20 @@ xctrl_suspend() intr_suspend(); xen_hvm_suspend(); - suspend_cancelled = HYPERVISOR_suspend(0); + xen_suspend_cancelled = !!HYPERVISOR_suspend(0); - xen_hvm_resume(suspend_cancelled != 0); - intr_resume(suspend_cancelled != 0); + if (!xen_suspend_cancelled) { + xen_hvm_resume(false); + } + intr_resume(xen_suspend_cancelled != 0); enable_intr(); /* * Reset grant table info. */ - gnttab_resume(); + if (!xen_suspend_cancelled) { + gnttab_resume(); + } #ifdef SMP /* Send an IPI_BITMAP in case there are pending bitmap IPIs. */ @@ -429,6 +437,8 @@ xctrl_suspend() thread_unlock(curthread); } + resume_all_proc(); + EVENTHANDLER_INVOKE(power_resume); if (bootverbose) diff --git a/sys/dev/xen/netfront/netfront.c b/sys/dev/xen/netfront/netfront.c index 71965ac..7110533 100644 --- a/sys/dev/xen/netfront/netfront.c +++ b/sys/dev/xen/netfront/netfront.c @@ -509,6 +509,15 @@ netfront_resume(device_t dev) { struct netfront_info *info = device_get_softc(dev); + if (xen_suspend_cancelled) { + XN_RX_LOCK(info); + XN_TX_LOCK(info); + netfront_carrier_on(info); + XN_TX_UNLOCK(info); + XN_RX_UNLOCK(info); + return (0); + } + info->xn_resume = true; netif_disconnect_backend(info); return (0); @@ -796,6 +805,45 @@ netif_release_tx_bufs(struct netfront_info *np) } static void +netif_release_rx_bufs_copy(struct netfront_info *np) +{ + struct mbuf *m; + grant_ref_t ref; + unsigned int i, busy, inuse; + + XN_RX_LOCK(np); + + for (busy = inuse = i = 0; i < NET_RX_RING_SIZE; i++) { + ref = np->grant_rx_ref[i]; + + if (ref == GRANT_REF_INVALID) + continue; + + inuse++; + + m = np->rx_mbufs[i]; + + if (!gnttab_end_foreign_access_ref(ref)) { + busy++; + continue; + } + + gnttab_release_grant_reference(&np->gref_rx_head, ref); + np->grant_rx_ref[i] = GRANT_REF_INVALID; + add_id_to_freelist(np->rx_mbufs, i); + + m_freem(m); + } + + if (busy != 0) + device_printf(np->xbdev, + "Unable to release %u of %u in use grant references out of %zu total.\n", + busy, inuse, NET_RX_RING_SIZE); + + XN_RX_UNLOCK(np); +} + +static void network_alloc_rx_buffers(struct netfront_info *sc) { int otherend_id = xenbus_get_otherend_id(sc->xbdev); @@ -2190,6 +2238,12 @@ netif_free(struct netfront_info *info) info->xn_ifp = NULL; } ifmedia_removeall(&info->sc_media); + netif_release_tx_bufs(info); + if (info->copying_receiver) + netif_release_rx_bufs_copy(info); + + gnttab_free_grant_references(info->gref_tx_head); + gnttab_free_grant_references(info->gref_rx_head); } static void |