Date: Wed, 10 Nov 2004 11:15:16 -0500 From: Stephan Uphoff <ups@tree.com> To: Nik Azim Azam <nskyline_r35@yahoo.com> Cc: freebsd-current@freebsd.org Subject: Re: number of CPUs and IPI panic Message-ID: <1100103316.49430.32.camel@palm.tree.com> In-Reply-To: <20041110160508.49470.qmail@web54607.mail.yahoo.com> References: <20041110160508.49470.qmail@web54607.mail.yahoo.com>
next in thread | previous in thread | raw e-mail | index | archive | help
--=-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 <ups@tree.com> 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--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1100103316.49430.32.camel>
