From owner-svn-src-head@freebsd.org Fri Jul 29 16:34:56 2016 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 29420BA77C1; Fri, 29 Jul 2016 16:34:56 +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 D054618CC; Fri, 29 Jul 2016 16:34:55 +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 u6TGYtjZ068192; Fri, 29 Jul 2016 16:34:55 GMT (envelope-from royger@FreeBSD.org) Received: (from royger@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u6TGYt3L068191; Fri, 29 Jul 2016 16:34:55 GMT (envelope-from royger@FreeBSD.org) Message-Id: <201607291634.u6TGYt3L068191@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: Fri, 29 Jul 2016 16:34:55 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r303490 - head/sys/x86/xen 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.22 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: Fri, 29 Jul 2016 16:34:56 -0000 Author: royger Date: Fri Jul 29 16:34:54 2016 New Revision: 303490 URL: https://svnweb.freebsd.org/changeset/base/303490 Log: xen-intr: fix removal of event channels during resume Event channel handlers cannot be removed during resume because there might be an interrupt thread running on a CPU currently blocked in the cpususpend_handler, which prevents the call to intr_remove_handler from finishing and completely freezes the system during resume. r291022 tried to fix this by allowing recursion in intr_remove_handler, but that's clearly not enough. Instead don't remove the handlers at the interrupt resume phase, and let each driver remove the handler by itself during resume. In order to do this, change the opaque event channel handler cookie to use the global interrupt vector instead of the event channel port. The event channel port cannot be used because after resume all event channels are reset, and the port numbers can change. Sponsored by: Citrix Systems R&D MFC after: 5 days Modified: head/sys/x86/xen/xen_intr.c Modified: head/sys/x86/xen/xen_intr.c ============================================================================== --- head/sys/x86/xen/xen_intr.c Fri Jul 29 16:34:16 2016 (r303489) +++ head/sys/x86/xen/xen_intr.c Fri Jul 29 16:34:54 2016 (r303490) @@ -130,8 +130,6 @@ struct xenisrc { u_int xi_masked:1; }; -#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) - static void xen_intr_suspend(struct pic *); static void xen_intr_resume(struct pic *, bool suspend_cancelled); static void xen_intr_enable_source(struct intsrc *isrc); @@ -422,7 +420,7 @@ xen_intr_bind_isrc(struct xenisrc **isrc mtx_unlock(&xen_intr_isrc_lock); /* Assign the opaque handler (the event channel port) */ - *port_handlep = &isrc->xi_port; + *port_handlep = &isrc->xi_vector; #ifdef SMP if (type == EVTCHN_TYPE_PORT) { @@ -468,16 +466,17 @@ xen_intr_bind_isrc(struct xenisrc **isrc static struct xenisrc * xen_intr_isrc(xen_intr_handle_t handle) { - evtchn_port_t port; + int vector; if (handle == NULL) return (NULL); - port = *(evtchn_port_t *)handle; - if (!is_valid_evtchn(port) || port >= NR_EVENT_CHANNELS) - return (NULL); + vector = *(int *)handle; + KASSERT(vector >= FIRST_EVTCHN_INT && + vector < (FIRST_EVTCHN_INT + xen_intr_auto_vector_count), + ("Xen interrupt vector is out of range")); - return (xen_intr_port_to_isrc[port]); + return ((struct xenisrc *)intr_lookup_source(vector)); } /** @@ -780,10 +779,6 @@ xen_intr_resume(struct pic *unused, bool xen_rebind_virq(isrc); break; default: - intr_remove_handler(isrc->xi_cookie); - isrc->xi_cpu = 0; - isrc->xi_type = EVTCHN_TYPE_UNBOUND; - isrc->xi_cookie = NULL; break; } }