Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 22 Mar 2009 10:33:10 +0000 (UTC)
From:      Marius Strobl <marius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org
Subject:   svn commit: r190257 - in stable/7/sys: . contrib/pf dev/ath/ath_hal dev/cxgb sparc64/include sparc64/sparc64
Message-ID:  <200903221033.n2MAXBme066193@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200903221033.n2MAXBme066193>