From owner-svn-src-all@FreeBSD.ORG Mon Feb 16 16:30:43 2015 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 3C1CDD5; Mon, 16 Feb 2015 16:30:43 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::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 1D7C9E31; Mon, 16 Feb 2015 16:30:43 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t1GGUgGq013576; Mon, 16 Feb 2015 16:30:42 GMT (envelope-from royger@FreeBSD.org) Received: (from royger@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t1GGUg43013575; Mon, 16 Feb 2015 16:30:42 GMT (envelope-from royger@FreeBSD.org) Message-Id: <201502161630.t1GGUg43013575@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: royger set sender to royger@FreeBSD.org using -f From: Roger Pau Monné Date: Mon, 16 Feb 2015 16:30:42 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r278854 - 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-all@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 16 Feb 2015 16:30:43 -0000 Author: royger Date: Mon Feb 16 16:30:42 2015 New Revision: 278854 URL: https://svnweb.freebsd.org/changeset/base/278854 Log: xen/intr: improve PIRQ handling Improve and cleanup the Xen PIRQ event channel code: - Remove the xi_shared field as it is unused. - Clean the "pending" bit in the EOI handler, this is more similar to how native interrupts are handled. - Don't mask edge triggered PIRQs, edge trigger interrupts cannot be masked. - Panic if PHYSDEVOP_eoi fails. - Remove the usage of the PHYSDEVOP_alloc_irq_vector hypercall because it's just a no-op in the Xen versions that are supported by FreeBSD Dom0. Sponsored by: Citrix Systems R&D Modified: head/sys/x86/xen/xen_intr.c Modified: head/sys/x86/xen/xen_intr.c ============================================================================== --- head/sys/x86/xen/xen_intr.c Mon Feb 16 15:47:55 2015 (r278853) +++ head/sys/x86/xen/xen_intr.c Mon Feb 16 16:30:42 2015 (r278854) @@ -126,7 +126,6 @@ struct xenisrc { int xi_virq; void *xi_cookie; u_int xi_close:1; /* close on unbind? */ - u_int xi_shared:1; /* Shared with other domains. */ u_int xi_activehi:1; u_int xi_edgetrigger:1; }; @@ -579,11 +578,12 @@ xen_intr_handle_upcall(struct trapframe /* process port */ port = (l1i * LONG_BIT) + l2i; - synch_clear_bit(port, &s->evtchn_pending[0]); isrc = xen_intr_port_to_isrc[port]; - if (__predict_false(isrc == NULL)) + if (__predict_false(isrc == NULL)) { + synch_clear_bit(port, &s->evtchn_pending[0]); continue; + } /* Make sure we are firing on the right vCPU */ KASSERT((isrc->xi_cpu == PCPU_GET(cpuid)), @@ -932,6 +932,9 @@ out: static void xen_intr_disable_source(struct intsrc *isrc, int eoi) { + + if (eoi == PIC_EOI) + xen_intr_eoi_source(isrc); } /* @@ -950,8 +953,13 @@ xen_intr_enable_source(struct intsrc *is * \param isrc The interrupt source to EOI. */ static void -xen_intr_eoi_source(struct intsrc *isrc) +xen_intr_eoi_source(struct intsrc *base_isrc) { + struct xenisrc *isrc; + + isrc = (struct xenisrc *)base_isrc; + synch_clear_bit(isrc->xi_port, + &HYPERVISOR_shared_info->evtchn_pending[0]); } /* @@ -981,8 +989,9 @@ xen_intr_pirq_disable_source(struct ints struct xenisrc *isrc; isrc = (struct xenisrc *)base_isrc; - evtchn_mask_port(isrc->xi_port); + if (isrc->xi_edgetrigger == 0) + evtchn_mask_port(isrc->xi_port); if (eoi == PIC_EOI) xen_intr_pirq_eoi_source(base_isrc); } @@ -998,7 +1007,9 @@ xen_intr_pirq_enable_source(struct intsr struct xenisrc *isrc; isrc = (struct xenisrc *)base_isrc; - evtchn_unmask_port(isrc->xi_port); + + if (isrc->xi_edgetrigger == 0) + evtchn_unmask_port(isrc->xi_port); } /* @@ -1010,13 +1021,19 @@ static void xen_intr_pirq_eoi_source(struct intsrc *base_isrc) { struct xenisrc *isrc; + int error; - /* XXX Use shared page of flags for this. */ isrc = (struct xenisrc *)base_isrc; + + synch_clear_bit(isrc->xi_port, + &HYPERVISOR_shared_info->evtchn_pending[0]); if (test_bit(isrc->xi_pirq, xen_intr_pirq_eoi_map)) { struct physdev_eoi eoi = { .irq = isrc->xi_pirq }; - (void)HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi); + error = HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi); + if (error != 0) + panic("Unable to EOI PIRQ#%d: %d\n", + isrc->xi_pirq, error); } } @@ -1361,7 +1378,6 @@ int xen_register_pirq(int vector, enum intr_trigger trig, enum intr_polarity pol) { struct physdev_map_pirq map_pirq; - struct physdev_irq alloc_pirq; struct xenisrc *isrc; int error; @@ -1382,14 +1398,6 @@ xen_register_pirq(int vector, enum intr_ return (error); } - alloc_pirq.irq = vector; - alloc_pirq.vector = 0; - error = HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &alloc_pirq); - if (error) { - printf("xen: unable to alloc PIRQ for IRQ#%d\n", vector); - return (error); - } - mtx_lock(&xen_intr_isrc_lock); isrc = xen_intr_alloc_isrc(EVTCHN_TYPE_PIRQ, vector); mtx_unlock(&xen_intr_isrc_lock); @@ -1432,6 +1440,8 @@ xen_register_msi(device_t dev, int vecto KASSERT(isrc != NULL, ("xen: unable to allocate isrc for interrupt")); isrc->xi_pirq = msi_irq.pirq + i; + /* MSI interrupts are always edge triggered */ + isrc->xi_edgetrigger = 1; } mtx_unlock(&xen_intr_isrc_lock); @@ -1573,10 +1583,9 @@ xen_intr_dump_port(struct xenisrc *isrc) isrc->xi_port, xen_intr_print_type(isrc->xi_type)); if (isrc->xi_type == EVTCHN_TYPE_PIRQ) { db_printf("\tPirq: %d ActiveHi: %d EdgeTrigger: %d " - "NeedsEOI: %d Shared: %d\n", + "NeedsEOI: %d\n", isrc->xi_pirq, isrc->xi_activehi, isrc->xi_edgetrigger, - !!test_bit(isrc->xi_pirq, xen_intr_pirq_eoi_map), - isrc->xi_shared); + !!test_bit(isrc->xi_pirq, xen_intr_pirq_eoi_map)); } if (isrc->xi_type == EVTCHN_TYPE_VIRQ) db_printf("\tVirq: %d\n", isrc->xi_virq);