From owner-svn-src-head@FreeBSD.ORG Mon Mar 22 03:55:18 2010 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E5BD31065677; Mon, 22 Mar 2010 03:55:18 +0000 (UTC) (envelope-from marcel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id CE0D18FC1E; Mon, 22 Mar 2010 03:55:18 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o2M3tIhX006026; Mon, 22 Mar 2010 03:55:18 GMT (envelope-from marcel@svn.freebsd.org) Received: (from marcel@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o2M3tIQE006021; Mon, 22 Mar 2010 03:55:18 GMT (envelope-from marcel@svn.freebsd.org) Message-Id: <201003220355.o2M3tIQE006021@svn.freebsd.org> From: Marcel Moolenaar Date: Mon, 22 Mar 2010 03:55:18 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r205433 - head/sys/ia64/ia64 X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 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: Mon, 22 Mar 2010 03:55:19 -0000 Author: marcel Date: Mon Mar 22 03:55:18 2010 New Revision: 205433 URL: http://svn.freebsd.org/changeset/base/205433 Log: Fix interrupt handling by extending the critical region so that preemption doesn't happen until after all pending interrupt have been services. While here again, simplify the EOI handling by doing it after we call the XIV-specific handlers, rather than in each of them. The original thought was that we may want to do an EOI first and the actual IPI handling next, but that's mostly a micro-optimization. Modified: head/sys/ia64/ia64/clock.c head/sys/ia64/ia64/exception.S head/sys/ia64/ia64/interrupt.c head/sys/ia64/ia64/mp_machdep.c Modified: head/sys/ia64/ia64/clock.c ============================================================================== --- head/sys/ia64/ia64/clock.c Mon Mar 22 03:06:11 2010 (r205432) +++ head/sys/ia64/ia64/clock.c Mon Mar 22 03:55:18 2010 (r205433) @@ -90,13 +90,9 @@ ia64_ih_clock(struct thread *td, u_int x int64_t delta; int count; - ia64_set_eoi(0); - PCPU_INC(md.stats.pcs_nclks); intrcnt[INTRCNT_CLOCK]++; - ia64_srlz_d(); - itc = ia64_get_itc(); adj = PCPU_GET(md.clockadj); @@ -120,6 +116,7 @@ ia64_ih_clock(struct thread *td, u_int x count++; } ia64_set_itm(ia64_get_itc() + ia64_clock_reload - adj); + ia64_srlz_d(); if (count > 0) { adjust_lost += count - 1; if (delta > (ia64_clock_reload >> 3)) { @@ -134,7 +131,6 @@ ia64_ih_clock(struct thread *td, u_int x } PCPU_SET(md.clock, clk); PCPU_SET(md.clockadj, adj); - ia64_srlz_d(); return (0); } @@ -150,7 +146,7 @@ pcpu_initclock(void) } /* - * Start the real-time and statistics clocks. We use cr.itc and cr.itm + * Start the real-time and statistics clocks. We use ar.itc and cr.itm * to implement a 1000hz clock. */ void Modified: head/sys/ia64/ia64/exception.S ============================================================================== --- head/sys/ia64/ia64/exception.S Mon Mar 22 03:06:11 2010 (r205432) +++ head/sys/ia64/ia64/exception.S Mon Mar 22 03:55:18 2010 (r205433) @@ -1303,7 +1303,7 @@ IVT_END(Break_Instruction) IVT_ENTRY(External_Interrupt, 0x3000) { .mib - mov r17=cr.ivr // Put the XIV in the trapframe. + mov r17=ar.itc // Put the ITC in the trapframe. mov r16=ip br.sptk exception_save ;; Modified: head/sys/ia64/ia64/interrupt.c ============================================================================== --- head/sys/ia64/ia64/interrupt.c Mon Mar 22 03:06:11 2010 (r205432) +++ head/sys/ia64/ia64/interrupt.c Mon Mar 22 03:55:18 2010 (r205433) @@ -288,30 +288,32 @@ void ia64_handle_intr(struct trapframe *tf) { struct thread *td; - u_int rfi, xiv; + u_int xiv; td = curthread; ia64_set_fpsr(IA64_FPSR_DEFAULT); PCPU_INC(cnt.v_intr); - xiv = tf->tf_special.ifa; + xiv = ia64_get_ivr(); + ia64_srlz_d(); if (xiv == 15) { PCPU_INC(md.stats.pcs_nstrays); goto out; } - while (xiv != 15) { - CTR1(KTR_INTR, "INTR: XIV=%u", xiv); - critical_enter(); - rfi = (ia64_handler[xiv])(td, xiv, tf); - if (rfi) { - critical_exit(); - return; - } + critical_enter(); + + do { + CTR2(KTR_INTR, "INTR: ITC=%u, XIV=%u", + (u_int)tf->tf_special.ifa, xiv); + (ia64_handler[xiv])(td, xiv, tf); + ia64_set_eoi(0); + ia64_srlz_d(); xiv = ia64_get_ivr(); - critical_exit(); ia64_srlz_d(); - } + } while (xiv != 15); + + critical_exit(); out: if (TRAPF_USERMODE(tf)) { @@ -327,10 +329,8 @@ static u_int ia64_ih_invalid(struct thread *td, u_int xiv, struct trapframe *tf) { - ia64_set_eoi(0); - ia64_srlz_d(); panic("invalid XIV: %u", xiv); - return (1); + return (0); } static u_int @@ -354,8 +354,7 @@ ia64_ih_irq(struct thread *td, u_int xiv ia64_intr_mask((void *)(uintptr_t)xiv); log(LOG_ERR, "stray irq%u\n", i->irq); } - ia64_set_eoi(0); - ia64_srlz_d(); + return (0); } Modified: head/sys/ia64/ia64/mp_machdep.c ============================================================================== --- head/sys/ia64/ia64/mp_machdep.c Mon Mar 22 03:06:11 2010 (r205432) +++ head/sys/ia64/ia64/mp_machdep.c Mon Mar 22 03:55:18 2010 (r205433) @@ -90,10 +90,8 @@ static u_int ia64_ih_ast(struct thread *td, u_int xiv, struct trapframe *tf) { - ia64_set_eoi(0); PCPU_INC(md.stats.pcs_nasts); CTR1(KTR_SMP, "IPI_AST, cpuid=%d", PCPU_GET(cpuid)); - ia64_srlz_d(); return (0); } @@ -101,10 +99,8 @@ static u_int ia64_ih_highfp(struct thread *td, u_int xiv, struct trapframe *tf) { - ia64_set_eoi(0); PCPU_INC(md.stats.pcs_nhighfps); ia64_highfp_save_ipi(); - ia64_srlz_d(); return (0); } @@ -112,11 +108,9 @@ static u_int ia64_ih_preempt(struct thread *td, u_int xiv, struct trapframe *tf) { - ia64_set_eoi(0); PCPU_INC(md.stats.pcs_npreempts); CTR1(KTR_SMP, "IPI_PREEMPT, cpuid=%d", PCPU_GET(cpuid)); sched_preempt(curthread); - ia64_srlz_d(); return (0); } @@ -124,11 +118,9 @@ static u_int ia64_ih_rndzvs(struct thread *td, u_int xiv, struct trapframe *tf) { - ia64_set_eoi(0); PCPU_INC(md.stats.pcs_nrdvs); CTR1(KTR_SMP, "IPI_RENDEZVOUS, cpuid=%d", PCPU_GET(cpuid)); smp_rendezvous_action(); - ia64_srlz_d(); return (0); } @@ -137,10 +129,8 @@ ia64_ih_stop(struct thread *td, u_int xi { cpumask_t mybit; - ia64_set_eoi(0); PCPU_INC(md.stats.pcs_nstops); mybit = PCPU_GET(cpumask); - ia64_srlz_d(); savectx(PCPU_PTR(md.pcb));