From owner-freebsd-current@FreeBSD.ORG Wed Nov 10 16:15:20 2004 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 066BC16A4CE for ; Wed, 10 Nov 2004 16:15:20 +0000 (GMT) Received: from duchess.speedfactory.net (duchess.speedfactory.net [66.23.201.84]) by mx1.FreeBSD.org (Postfix) with SMTP id 82E3843D41 for ; Wed, 10 Nov 2004 16:15:19 +0000 (GMT) (envelope-from ups@tree.com) Received: (qmail 13456 invoked by uid 89); 10 Nov 2004 16:15:18 -0000 Received: from duchess.speedfactory.net (66.23.201.84) by duchess.speedfactory.net with SMTP; 10 Nov 2004 16:15:18 -0000 Received: (qmail 13437 invoked by uid 89); 10 Nov 2004 16:15:17 -0000 Received: from unknown (HELO palm.tree.com) (66.23.216.49) by duchess.speedfactory.net with SMTP; 10 Nov 2004 16:15:17 -0000 Received: from [127.0.0.1] (localhost.tree.com [127.0.0.1]) by palm.tree.com (8.12.10/8.12.10) with ESMTP id iAAGFG5R053229; Wed, 10 Nov 2004 11:15:16 -0500 (EST) (envelope-from ups@tree.com) From: Stephan Uphoff To: Nik Azim Azam In-Reply-To: <20041110160508.49470.qmail@web54607.mail.yahoo.com> References: <20041110160508.49470.qmail@web54607.mail.yahoo.com> Content-Type: multipart/mixed; boundary="=-4bOjKT3gzB+HvEcwjHKv" Message-Id: <1100103316.49430.32.camel@palm.tree.com> Mime-Version: 1.0 X-Mailer: Ximian Evolution 1.4.6 Date: Wed, 10 Nov 2004 11:15:16 -0500 cc: freebsd-current@freebsd.org Subject: Re: number of CPUs and IPI panic X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 10 Nov 2004 16:15:20 -0000 --=-4bOjKT3gzB+HvEcwjHKv Content-Type: text/plain Content-Transfer-Encoding: 7bit On Wed, 2004-11-10 at 11:05, Nik Azim Azam wrote: > hmm, you've forgotten to include the patch with the > mail? > > --- Stephan Uphoff wrote: > > OK - lets try this again. > > The attached patch should prevent blocking on > > redundant IPIs caused by > > the apic not being able to queue the request. > > If this does not work we will have to instrument the > > code. > > > > Stephan Sight - one more time ... --=-4bOjKT3gzB+HvEcwjHKv Content-Disposition: attachment; filename=ipi2_patch Content-Type: text/x-patch; name=ipi2_patch; charset=ASCII Content-Transfer-Encoding: 7bit Index: sys/i386/i386/apic_vector.s =================================================================== RCS file: /cvsroot/src/sys/i386/i386/apic_vector.s,v retrieving revision 1.101 diff -u -r1.101 apic_vector.s --- sys/i386/i386/apic_vector.s 26 May 2004 07:43:41 -0000 1.101 +++ sys/i386/i386/apic_vector.s 3 Nov 2004 15:43:07 -0000 @@ -286,7 +286,11 @@ movl %eax, %es movl $KPSEL, %eax movl %eax, %fs - + + movl PCPU(CPUID), %edx + lock + btrl %edx,CNAME(ipi_ast_pending) + movl lapic, %edx movl $0, LA_EOI(%edx) /* End Of Interrupt to APIC */ Index: sys/i386/i386/local_apic.c =================================================================== RCS file: /cvsroot/src/sys/i386/i386/local_apic.c,v retrieving revision 1.9 diff -u -r1.9 local_apic.c --- sys/i386/i386/local_apic.c 14 Jul 2004 18:12:15 -0000 1.9 +++ sys/i386/i386/local_apic.c 4 Oct 2004 02:24:17 -0000 @@ -693,6 +693,62 @@ intr_restore(eflags); } + +static void +lapic_ipi_wait_and_raw(int delay,register_t icrlo, u_int dest) +{ + int x, incr,idle; + register_t value, eflags; + + +/* XXX: Need more sanity checking of icrlo? */ + KASSERT(lapic != NULL, ("%s called too early", __func__)); + KASSERT((dest & ~(APIC_ID_MASK >> APIC_ID_SHIFT)) == 0, + ("%s: invalid dest field", __func__)); + KASSERT((icrlo & APIC_ICRLO_RESV_MASK) == 0, + ("%s: reserved bits set in ICR LO register", __func__)); + + if (delay == -1) { + incr = 0; + delay = 1; + } else + incr = 1; + + /* Set destination in ICR HI register if it is being used. */ + eflags = intr_disable(); + + idle = 0; + + for (x = 0; x < delay; x += incr) { + if ((lapic->icr_lo & APIC_DELSTAT_MASK) == APIC_DELSTAT_IDLE) + { + idle = 1; + break; + } + intr_restore(eflags); + ia32_pause(); + eflags = intr_disable(); + + } + + if (!idle) panic("APIC: Previous IPI is stuck"); + + if ((icrlo & APIC_DEST_MASK) == APIC_DEST_DESTFLD) { + value = lapic->icr_hi; + value &= ~APIC_ID_MASK; + value |= dest << APIC_ID_SHIFT; + lapic->icr_hi = value; + } + + /* Program the contents of the IPI and dispatch it. */ + value = lapic->icr_lo; + value &= APIC_ICRLO_RESV_MASK; + value |= icrlo; + lapic->icr_lo = value; + intr_restore(eflags); +} + + #define BEFORE_SPIN 1000000 #ifdef DETECT_DEADLOCK #define AFTER_SPIN 1000 @@ -725,11 +781,8 @@ destfield = dest; } - /* Wait for an earlier IPI to finish. */ - if (!lapic_ipi_wait(BEFORE_SPIN)) - panic("APIC: Previous IPI is stuck"); - - lapic_ipi_raw(icrlo, destfield); + + lapic_ipi_wait_and_raw(BEFORE_SPIN,icrlo, destfield); #ifdef DETECT_DEADLOCK /* Wait for IPI to be delivered. */ Index: sys/i386/i386/mp_machdep.c =================================================================== RCS file: /cvsroot/src/sys/i386/i386/mp_machdep.c,v retrieving revision 1.240 diff -u -r1.240 mp_machdep.c --- sys/i386/i386/mp_machdep.c 1 Nov 2004 22:11:27 -0000 1.240 +++ sys/i386/i386/mp_machdep.c 10 Nov 2004 01:48:57 -0000 @@ -212,6 +212,14 @@ static int hlt_logical_cpus; static struct sysctl_ctx_list logical_cpu_clist; + +static int ipi_statclock_pending; +static int ipi_hardclock_pending; +int ipi_ast_pending; + + + + static void mem_range_AP_init(void) { @@ -1017,12 +1025,24 @@ smp_tlb_addr1 = addr1; smp_tlb_addr2 = addr2; atomic_store_rel_int(&smp_tlb_wait, 0); + + + /* Enable interrupts */ + /* Thread switching still disabled */ + + enable_intr(); + if (mask == (u_int)-1) ipi_all_but_self(vector); else ipi_selected(mask, vector); + while (smp_tlb_wait < ncpu) ia32_pause(); + + /* disable interrupts */ + disable_intr(); + } void @@ -1104,6 +1124,9 @@ struct thread *td; CTR0(KTR_SMP, "forwarded_statclock"); + + atomic_clear_int(&ipi_statclock_pending,PCPU_GET(cpumask)); + td = curthread; td->td_intr_nesting_level++; if (profprocs != 0) @@ -1123,9 +1146,11 @@ if (!smp_started || cold || panicstr) return; - map = PCPU_GET(other_cpus) & ~(stopped_cpus|hlt_cpus_mask); - if (map != 0) + map = PCPU_GET(other_cpus) & ~(stopped_cpus|hlt_cpus_mask|ipi_statclock_pending); + if (map != 0) { + atomic_set_int(&ipi_statclock_pending,map); ipi_selected(map, IPI_STATCLOCK); + } } /* @@ -1141,6 +1166,9 @@ struct thread *td; CTR0(KTR_SMP, "forwarded_hardclock"); + + atomic_clear_int(&ipi_hardclock_pending,PCPU_GET(cpumask)); + td = curthread; td->td_intr_nesting_level++; hardclock_process(&frame); @@ -1157,9 +1185,11 @@ if (!smp_started || cold || panicstr) return; - map = PCPU_GET(other_cpus) & ~(stopped_cpus|hlt_cpus_mask); - if (map != 0) + map = PCPU_GET(other_cpus) & ~(stopped_cpus|hlt_cpus_mask|ipi_hardclock_pending); + if (map != 0) { + atomic_set_int(&ipi_hardclock_pending,map); ipi_selected(map, IPI_HARDCLOCK); + } } /* @@ -1169,6 +1199,12 @@ ipi_selected(u_int32_t cpus, u_int ipi) { int cpu; + + if (ipi == IPI_AST) { + cpus &= ~(ipi_ast_pending); /* XXX Needs memory barrier */ + atomic_set_int(&ipi_ast_pending,cpus); + } + CTR3(KTR_SMP, "%s: cpus: %x ipi: %x", __func__, cpus, ipi); while ((cpu = ffs(cpus)) != 0) { Index: sys/i386/i386/pmap.c =================================================================== RCS file: /cvsroot/src/sys/i386/i386/pmap.c,v retrieving revision 1.514 diff -u -r1.514 pmap.c --- sys/i386/i386/pmap.c 29 Oct 2004 19:10:46 -0000 1.514 +++ sys/i386/i386/pmap.c 1 Nov 2004 19:29:08 -0000 @@ -1328,12 +1328,20 @@ atomic_store_rel_int((u_int *)&lazymask, (u_int)&pmap->pm_active); atomic_store_rel_int(&lazywait, 0); + /* Enable interrupts */ + /* Thread switching still disabled */ + + enable_intr(); ipi_selected(mask, IPI_LAZYPMAP); while (lazywait == 0) { ia32_pause(); if (--spins == 0) break; } + + /* disable interrupts */ + disable_intr(); + } mtx_unlock_spin(&smp_ipi_mtx); if (spins == 0) --=-4bOjKT3gzB+HvEcwjHKv--