svn commit: r190257 - in stable/7/sys: . contrib/pf dev/ath/ath_hal
dev/cxgb sparc64/include sparc64/sparc64
Marius Strobl
marius at FreeBSD.org
Sun Mar 22 03:33:12 PDT 2009
Author: marius
Date: Sun Mar 22 10:33:10 2009
New Revision: 190257
URL: http://svn.freebsd.org/changeset/base/190257
Log:
MFC: r183142, r186395, 190106
- Newer firmware versions no longer provide SUNW,stop-self so just
disable interrupts and loop forever instead. We still could use
SUNW,stop-self if implemented but acording to comments in OpenBSD,
E{2,4}50 tend to have fragile firmware versions which wedge when
using the OFW test service, so given that we don't really depend
on SUNW,stop-self just nuke it altogether instead of risking
problems.
- Hide all MP-related bits in <machine/smp.h> underneath #ifdef SMP.
- Inline ipi_all_but_self(9) and ipi_selected(9). We don't expose any
additional bits but save a few cycles by doing so.
- Remove ipi_all(9), which actually only called panic(9). It can't be
implemented natively anyway and having it removed at least causes
MI users to already fail when linking.
- At least Fire V880 have a small hardware glitch which causes the
reception of IDR_NACKs for CPUs we actually haven't tried to send
an IPI to, even not as part of the initial try. According to tests
this apparently can be safely ignored though, so just return if
checking for the individual IDR_NACKs indicates no outstanding
dispatch. Serializing the sending of IPIs between MD and MI code
by the combined usage of smp_ipi_mtx makes no difference to this
phenomenon. [1]
- Provide relevant debugging bits already with the initial panic
in case of problems with the IPI dispatch, which would have
allowed to diagnose the above problem without a specially built
kernel.
- In case of cheetah_ipi_selected() base the delay we wait for
other CPUs which also might want to dispatch IPIs on the total
amount of CPUs instead of just the number of CPUs we let this
CPU send IPIs to because in the worst case all CPUs also want
to IPI us at the same time.
- There's no need to wrap kdb_active in #ifdef KDB as it's always
available.
Reported and access for extensive tests provided by: beat [1]
Modified:
stable/7/sys/ (props changed)
stable/7/sys/contrib/pf/ (props changed)
stable/7/sys/dev/ath/ath_hal/ (props changed)
stable/7/sys/dev/cxgb/ (props changed)
stable/7/sys/sparc64/include/smp.h
stable/7/sys/sparc64/sparc64/genassym.c
stable/7/sys/sparc64/sparc64/mp_machdep.c
Modified: stable/7/sys/sparc64/include/smp.h
==============================================================================
--- stable/7/sys/sparc64/include/smp.h Sun Mar 22 10:08:41 2009 (r190256)
+++ stable/7/sys/sparc64/include/smp.h Sun Mar 22 10:33:10 2009 (r190257)
@@ -29,6 +29,8 @@
#ifndef _MACHINE_SMP_H_
#define _MACHINE_SMP_H_
+#ifdef SMP
+
#define CPU_TICKSYNC 1
#define CPU_STICKSYNC 2
#define CPU_INIT 3
@@ -91,10 +93,6 @@ void cpu_mp_shutdown(void);
typedef void cpu_ipi_selected_t(u_int, u_long, u_long, u_long);
extern cpu_ipi_selected_t *cpu_ipi_selected;
-void ipi_selected(u_int cpus, u_int ipi);
-void ipi_all(u_int ipi);
-void ipi_all_but_self(u_int ipi);
-
void mp_init(void);
extern struct mtx ipi_mtx;
@@ -117,7 +115,19 @@ extern char tl_ipi_tlb_context_demap[];
extern char tl_ipi_tlb_page_demap[];
extern char tl_ipi_tlb_range_demap[];
-#ifdef SMP
+static __inline void
+ipi_all_but_self(u_int ipi)
+{
+
+ cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)tl_ipi_level, ipi);
+}
+
+static __inline void
+ipi_selected(u_int cpus, u_int ipi)
+{
+
+ cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_level, ipi);
+}
#if defined(_MACHINE_PMAP_H_) && defined(_SYS_MUTEX_H_)
@@ -224,8 +234,12 @@ ipi_wait(void *cookie)
#endif /* _MACHINE_PMAP_H_ && _SYS_MUTEX_H_ */
+#endif /* !LOCORE */
+
#else
+#ifndef LOCORE
+
static __inline void *
ipi_dcache_page_inval(void *func, vm_paddr_t pa)
{
@@ -267,8 +281,26 @@ ipi_wait(void *cookie)
}
-#endif /* SMP */
+static __inline void
+tl_ipi_cheetah_dcache_page_inval(void)
+{
+
+}
+
+static __inline void
+tl_ipi_spitfire_dcache_page_inval(void)
+{
+
+}
+
+static __inline void
+tl_ipi_spitfire_icache_page_inval(void)
+{
+
+}
#endif /* !LOCORE */
+#endif /* SMP */
+
#endif /* !_MACHINE_SMP_H_ */
Modified: stable/7/sys/sparc64/sparc64/genassym.c
==============================================================================
--- stable/7/sys/sparc64/sparc64/genassym.c Sun Mar 22 10:08:41 2009 (r190256)
+++ stable/7/sys/sparc64/sparc64/genassym.c Sun Mar 22 10:33:10 2009 (r190257)
@@ -83,6 +83,7 @@ ASSYM(PAGE_SHIFT_4M, PAGE_SHIFT_4M);
ASSYM(PAGE_SIZE, PAGE_SIZE);
ASSYM(PAGE_SIZE_4M, PAGE_SIZE_4M);
+#ifdef SMP
ASSYM(CSA_PCPU, offsetof(struct cpu_start_args, csa_pcpu));
ASSYM(CSA_STATE, offsetof(struct cpu_start_args, csa_state));
#ifdef SUN4U
@@ -95,6 +96,7 @@ ASSYM(CSA_VER, offsetof(struct cpu_start
#ifdef SUN4V
ASSYM(CSA_CPUID, offsetof(struct cpu_start_args, csa_cpuid));
#endif
+#endif
#ifdef SUN4U
ASSYM(DC_SIZE, offsetof(struct cacheinfo, dc_size));
@@ -103,7 +105,9 @@ ASSYM(IC_SIZE, offsetof(struct cacheinfo
ASSYM(IC_LINESIZE, offsetof(struct cacheinfo, ic_linesize));
#endif
+#ifdef SMP
ASSYM(ICA_PA, offsetof(struct ipi_cache_args, ica_pa));
+#endif
ASSYM(KTR_SIZEOF, sizeof(struct ktr_entry));
ASSYM(KTR_LINE, offsetof(struct ktr_entry, ktr_line));
@@ -210,11 +214,13 @@ ASSYM(IR_ARG, offsetof(struct intr_reque
ASSYM(IR_PRI, offsetof(struct intr_request, ir_pri));
ASSYM(IR_VEC, offsetof(struct intr_request, ir_vec));
+#ifdef SMP
ASSYM(ITA_MASK, offsetof(struct ipi_tlb_args, ita_mask));
ASSYM(ITA_PMAP, offsetof(struct ipi_tlb_args, ita_pmap));
ASSYM(ITA_START, offsetof(struct ipi_tlb_args, ita_start));
ASSYM(ITA_END, offsetof(struct ipi_tlb_args, ita_end));
ASSYM(ITA_VA, offsetof(struct ipi_tlb_args, ita_va));
+#endif
ASSYM(IV_FUNC, offsetof(struct intr_vector, iv_func));
ASSYM(IV_ARG, offsetof(struct intr_vector, iv_arg));
Modified: stable/7/sys/sparc64/sparc64/mp_machdep.c
==============================================================================
--- stable/7/sys/sparc64/sparc64/mp_machdep.c Sun Mar 22 10:08:41 2009 (r190256)
+++ stable/7/sys/sparc64/sparc64/mp_machdep.c Sun Mar 22 10:33:10 2009 (r190257)
@@ -92,6 +92,9 @@ __FBSDID("$FreeBSD$");
#include <machine/tte.h>
#include <machine/ver.h>
+#define SUNW_STARTCPU "SUNW,start-cpu"
+#define SUNW_STOPSELF "SUNW,stop-self"
+
static ih_func_t cpu_ipi_ast;
static ih_func_t cpu_ipi_preempt;
static ih_func_t cpu_ipi_stop;
@@ -119,7 +122,6 @@ static volatile u_int shutdown_cpus;
static void cpu_mp_unleash(void *v);
static void spitfire_ipi_send(u_int mid, u_long d0, u_long d1, u_long d2);
static void sun4u_startcpu(phandle_t cpu, void *func, u_long arg);
-static void sun4u_stopself(void);
static cpu_ipi_selected_t cheetah_ipi_selected;
static cpu_ipi_selected_t spitfire_ipi_selected;
@@ -203,7 +205,7 @@ sun4u_startcpu(phandle_t cpu, void *func
cell_t func;
cell_t arg;
} args = {
- (cell_t)"SUNW,start-cpu",
+ (cell_t)SUNW_STARTCPU,
3,
};
@@ -214,24 +216,6 @@ sun4u_startcpu(phandle_t cpu, void *func
}
/*
- * Stop the calling CPU.
- */
-static void
-sun4u_stopself(void)
-{
- static struct {
- cell_t name;
- cell_t nargs;
- cell_t nreturns;
- } args = {
- (cell_t)"SUNW,stop-self",
- };
-
- openfirmware_exit(&args);
- panic("%s: failed.", __func__);
-}
-
-/*
* Fire up any non-boot processors.
*/
void
@@ -422,8 +406,6 @@ cpu_mp_shutdown(void)
break;
}
}
- /* XXX: delay a bit to allow the CPUs to actually enter the PROM. */
- DELAY(100000);
critical_exit();
}
@@ -443,7 +425,9 @@ cpu_ipi_stop(struct trapframe *tf)
while ((started_cpus & PCPU_GET(cpumask)) == 0) {
if ((shutdown_cpus & PCPU_GET(cpumask)) != 0) {
atomic_clear_int(&shutdown_cpus, PCPU_GET(cpumask));
- sun4u_stopself();
+ (void)intr_disable();
+ for (;;)
+ ;
}
}
atomic_clear_rel_int(&started_cpus, PCPU_GET(cpumask));
@@ -519,15 +503,12 @@ spitfire_ipi_send(u_int mid, u_long d0,
*/
DELAY(2);
}
- if (
-#ifdef KDB
- kdb_active ||
-#endif
- panicstr != NULL)
+ if (kdb_active != 0 || panicstr != NULL)
printf("%s: couldn't send IPI to module 0x%u\n",
__func__, mid);
else
- panic("%s: couldn't send IPI", __func__);
+ panic("%s: couldn't send IPI to module 0x%u",
+ __func__, mid);
}
static void
@@ -581,40 +562,23 @@ cheetah_ipi_selected(u_int cpus, u_long
}
}
/*
+ * On at least Fire V880 we may receive IDR_NACKs for
+ * CPUs we actually haven't tried to send an IPI to,
+ * but which apparently can be safely ignored.
+ */
+ if (cpus == 0)
+ return;
+ /*
* Leave interrupts enabled for a bit before retrying
* in order to avoid deadlocks if the other CPUs are
* also trying to send IPIs.
*/
- DELAY(2 * bnp);
+ DELAY(2 * mp_ncpus);
}
- if (
-#ifdef KDB
- kdb_active ||
-#endif
- panicstr != NULL)
+ if (kdb_active != 0 || panicstr != NULL)
printf("%s: couldn't send IPI (cpus=0x%u ids=0x%lu)\n",
__func__, cpus, ids);
else
- panic("%s: couldn't send IPI", __func__);
-}
-
-void
-ipi_selected(u_int cpus, u_int ipi)
-{
-
- cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_level, ipi);
-}
-
-void
-ipi_all(u_int ipi)
-{
-
- panic("%s", __func__);
-}
-
-void
-ipi_all_but_self(u_int ipi)
-{
-
- cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)tl_ipi_level, ipi);
+ panic("%s: couldn't send IPI (cpus=0x%u ids=0x%lu)",
+ __func__, cpus, ids);
}
More information about the svn-src-stable
mailing list