From owner-svn-src-head@freebsd.org Tue Mar 7 09:16:53 2017 Return-Path: Delivered-To: svn-src-head@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 9C165D00371; Tue, 7 Mar 2017 09:16:53 +0000 (UTC) (envelope-from royger@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 5CCDD1FB4; Tue, 7 Mar 2017 09:16:53 +0000 (UTC) (envelope-from royger@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v279GqlB061705; Tue, 7 Mar 2017 09:16:52 GMT (envelope-from royger@FreeBSD.org) Received: (from royger@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v279Gqgn061700; Tue, 7 Mar 2017 09:16:52 GMT (envelope-from royger@FreeBSD.org) Message-Id: <201703070916.v279Gqgn061700@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: royger set sender to royger@FreeBSD.org using -f From: =?UTF-8?Q?Roger_Pau_Monn=c3=a9?= Date: Tue, 7 Mar 2017 09:16:52 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r314840 - in head/sys: dev/xen/blkfront dev/xen/control dev/xen/netfront xen xen/xenbus X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 07 Mar 2017 09:16:53 -0000 Author: royger Date: Tue Mar 7 09:16:51 2017 New Revision: 314840 URL: https://svnweb.freebsd.org/changeset/base/314840 Log: xen: add support for canceled suspend When running on Xen, it's possible that a suspend request to the hypervisor fails (return from HYPERVISOR_suspend different than 0). This means that the suspend hasn't succeed, and the resume procedure needs to properly handle this case. First of all, when such situation happens there's no need to reset the vector callback, hypercall page, shared info, event channels or grant table, because it's state is preserved. Also, the PV drivers don't need to be reset to the initial state, since the connection with the backed has not been interrupted. Submitted by: Liuyingdong Reviewed by: royger MFC after: 2 weeks Differential revision: https://reviews.freebsd.org/D9635 Modified: head/sys/dev/xen/blkfront/blkfront.c head/sys/dev/xen/control/control.c head/sys/dev/xen/netfront/netfront.c head/sys/xen/xen-os.h head/sys/xen/xenbus/xenbusb.c Modified: head/sys/dev/xen/blkfront/blkfront.c ============================================================================== --- head/sys/dev/xen/blkfront/blkfront.c Tue Mar 7 07:49:25 2017 (r314839) +++ head/sys/dev/xen/blkfront/blkfront.c Tue Mar 7 09:16:51 2017 (r314840) @@ -1537,6 +1537,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); Modified: head/sys/dev/xen/control/control.c ============================================================================== --- head/sys/dev/xen/control/control.c Tue Mar 7 07:49:25 2017 (r314839) +++ head/sys/dev/xen/control/control.c Tue Mar 7 09:16:51 2017 (r314840) @@ -148,6 +148,7 @@ __FBSDID("$FreeBSD$"); #include +bool xen_suspend_cancelled; /*--------------------------- Forward Declarations --------------------------*/ /** Function signature for shutdown event handlers. */ typedef void (xctrl_shutdown_handler_t)(void); @@ -196,7 +197,6 @@ xctrl_suspend() #ifdef SMP cpuset_t cpu_suspend_map; #endif - int suspend_cancelled; EVENTHANDLER_INVOKE(power_suspend_early); stop_all_proc(); @@ -267,16 +267,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(NULL); + if (!xen_suspend_cancelled) { + gnttab_resume(NULL); + } #ifdef SMP if (!CPU_EMPTY(&cpu_suspend_map)) { Modified: head/sys/dev/xen/netfront/netfront.c ============================================================================== --- head/sys/dev/xen/netfront/netfront.c Tue Mar 7 07:49:25 2017 (r314839) +++ head/sys/dev/xen/netfront/netfront.c Tue Mar 7 09:16:51 2017 (r314840) @@ -439,6 +439,20 @@ static int netfront_resume(device_t dev) { struct netfront_info *info = device_get_softc(dev); + u_int i; + + if (xen_suspend_cancelled) { + for (i = 0; i < info->num_queues; i++) { + XN_RX_LOCK(&info->rxq[i]); + XN_TX_LOCK(&info->txq[i]); + } + netfront_carrier_on(info); + for (i = 0; i < info->num_queues; i++) { + XN_RX_UNLOCK(&info->rxq[i]); + XN_TX_UNLOCK(&info->txq[i]); + } + return (0); + } netif_disconnect_backend(info); return (0); Modified: head/sys/xen/xen-os.h ============================================================================== --- head/sys/xen/xen-os.h Tue Mar 7 07:49:25 2017 (r314839) +++ head/sys/xen/xen-os.h Tue Mar 7 09:16:51 2017 (r314840) @@ -56,6 +56,8 @@ extern char *console_page; extern int xen_disable_pv_disks; extern int xen_disable_pv_nics; +extern bool xen_suspend_cancelled; + enum xen_domain_type { XEN_NATIVE, /* running on bare hardware */ XEN_PV_DOMAIN, /* running in a PV domain */ Modified: head/sys/xen/xenbus/xenbusb.c ============================================================================== --- head/sys/xen/xenbus/xenbusb.c Tue Mar 7 07:49:25 2017 (r314839) +++ head/sys/xen/xenbus/xenbusb.c Tue Mar 7 09:16:51 2017 (r314840) @@ -791,6 +791,11 @@ xenbusb_resume(device_t dev) if (device_get_state(kids[i]) == DS_NOTPRESENT) continue; + if (xen_suspend_cancelled) { + DEVICE_RESUME(kids[i]); + continue; + } + ivars = device_get_ivars(kids[i]); xs_unregister_watch(&ivars->xd_otherend_watch);