svn commit: r342852 - in head/sys/powerpc: include powernv powerpc ps3 pseries

Conrad Meyer cem at FreeBSD.org
Mon Jan 7 19:39:33 UTC 2019


Author: cem
Date: Mon Jan  7 19:39:31 2019
New Revision: 342852
URL: https://svnweb.freebsd.org/changeset/base/342852

Log:
  powerpc: Fix regression introduced in r342771
  
  In r342771, I introduced a regression in Power by abusing the platform
  smp_topo() method as a shortcut for providing the MI information needed for
  the stated sysctls.  The smp_topo() method was already called later by
  sched_ule (under the name cpu_topo()), and initializes a static array of
  scheduler topology information.  I had skimmed the smp_topo_foo() functions
  and assumed they were idempotent; empirically, they are not (or at least,
  detect re-initialization and panic).
  
  Do the cleaner thing I should have done in the first place and add a
  platform method specifically for core- and thread-count probing.
  
  Reported by:	luporl via jhibbits
  Reviewed by:	luporl
  X-MFC-With:	r342771
  Differential Revision:	https://reviews.freebsd.org/D18777

Modified:
  head/sys/powerpc/include/platform.h
  head/sys/powerpc/powernv/platform_powernv.c
  head/sys/powerpc/powerpc/mp_machdep.c
  head/sys/powerpc/powerpc/platform.c
  head/sys/powerpc/powerpc/platform_if.m
  head/sys/powerpc/ps3/platform_ps3.c
  head/sys/powerpc/pseries/platform_chrp.c

Modified: head/sys/powerpc/include/platform.h
==============================================================================
--- head/sys/powerpc/include/platform.h	Mon Jan  7 17:35:09 2019	(r342851)
+++ head/sys/powerpc/include/platform.h	Mon Jan  7 19:39:31 2019	(r342852)
@@ -58,6 +58,7 @@ int	platform_smp_get_bsp(struct cpuref *);
 int	platform_smp_start_cpu(struct pcpu *);
 void	platform_smp_timebase_sync(u_long tb, int ap);
 void	platform_smp_ap_init(void);
+void	platform_smp_probe_threads(void);
   
 const char *installed_platform(void);
 void platform_probe_and_attach(void);

Modified: head/sys/powerpc/powernv/platform_powernv.c
==============================================================================
--- head/sys/powerpc/powernv/platform_powernv.c	Mon Jan  7 17:35:09 2019	(r342851)
+++ head/sys/powerpc/powernv/platform_powernv.c	Mon Jan  7 19:39:31 2019	(r342852)
@@ -71,6 +71,7 @@ static int powernv_smp_get_bsp(platform_t, struct cpur
 static void powernv_smp_ap_init(platform_t);
 #ifdef SMP
 static int powernv_smp_start_cpu(platform_t, struct pcpu *cpu);
+static void powernv_smp_probe_threads(platform_t);
 static struct cpu_group *powernv_smp_topo(platform_t plat);
 #endif
 static void powernv_reset(platform_t);
@@ -89,6 +90,7 @@ static platform_method_t powernv_methods[] = {
 	PLATFORMMETHOD(platform_smp_get_bsp,	powernv_smp_get_bsp),
 #ifdef SMP
 	PLATFORMMETHOD(platform_smp_start_cpu,	powernv_smp_start_cpu),
+	PLATFORMMETHOD(platform_smp_probe_threads,	powernv_smp_probe_threads),
 	PLATFORMMETHOD(platform_smp_topo,	powernv_smp_topo),
 #endif
 
@@ -403,8 +405,8 @@ powernv_smp_start_cpu(platform_t plat, struct pcpu *pc
 	return (0);
 }
 
-static struct cpu_group *
-powernv_smp_topo(platform_t plat)
+static void
+powernv_smp_probe_threads(platform_t plat)
 {
 	char buf[8];
 	phandle_t cpu, dev, root;
@@ -436,21 +438,26 @@ powernv_smp_topo(platform_t plat)
 	}
 
 	smp_threads_per_core = nthreads;
+	if (mp_ncpus % nthreads == 0)
+		mp_ncores = mp_ncpus / nthreads;
+}
 
-	if (mp_ncpus % nthreads != 0) {
+static struct cpu_group *
+powernv_smp_topo(platform_t plat)
+{
+	if (mp_ncpus % smp_threads_per_core != 0) {
 		printf("WARNING: Irregular SMP topology. Performance may be "
 		     "suboptimal (%d threads, %d on first core)\n",
-		     mp_ncpus, nthreads);
+		     mp_ncpus, smp_threads_per_core);
 		return (smp_topo_none());
 	}
 
-	mp_ncores = mp_ncpus / nthreads;
-
 	/* Don't do anything fancier for non-threaded SMP */
-	if (nthreads == 1)
+	if (smp_threads_per_core == 1)
 		return (smp_topo_none());
 
-	return (smp_topo_1level(CG_SHARE_L1, nthreads, CG_FLAG_SMT));
+	return (smp_topo_1level(CG_SHARE_L1, smp_threads_per_core,
+	    CG_FLAG_SMT));
 }
 
 #endif

Modified: head/sys/powerpc/powerpc/mp_machdep.c
==============================================================================
--- head/sys/powerpc/powerpc/mp_machdep.c	Mon Jan  7 17:35:09 2019	(r342851)
+++ head/sys/powerpc/powerpc/mp_machdep.c	Mon Jan  7 19:39:31 2019	(r342852)
@@ -188,8 +188,7 @@ next:
 	}
 
 #ifdef SMP
-	/* Probe mp_ncores and smp_threads_per_core as a side effect. */
-	(void)cpu_topo();
+	platform_smp_probe_threads();
 #endif
 }
 

Modified: head/sys/powerpc/powerpc/platform.c
==============================================================================
--- head/sys/powerpc/powerpc/platform.c	Mon Jan  7 17:35:09 2019	(r342851)
+++ head/sys/powerpc/powerpc/platform.c	Mon Jan  7 19:39:31 2019	(r342852)
@@ -242,6 +242,12 @@ platform_smp_ap_init()
 	PLATFORM_SMP_AP_INIT(plat_obj);
 }
 
+void
+platform_smp_probe_threads(void)
+{
+	PLATFORM_SMP_PROBE_THREADS(plat_obj);
+}
+
 #ifdef SMP
 struct cpu_group *
 cpu_topo(void)

Modified: head/sys/powerpc/powerpc/platform_if.m
==============================================================================
--- head/sys/powerpc/powerpc/platform_if.m	Mon Jan  7 17:35:09 2019	(r342851)
+++ head/sys/powerpc/powerpc/platform_if.m	Mon Jan  7 19:39:31 2019	(r342852)
@@ -84,6 +84,10 @@ CODE {
 	{
 		return;
 	}
+	static void platform_null_smp_probe_threads(void)
+	{
+		return;
+	}
 };
 
 /**
@@ -195,6 +199,13 @@ METHOD int smp_start_cpu {
 METHOD void smp_ap_init {
 	platform_t	_plat;
 } DEFAULT platform_null_smp_ap_init;
+
+/**
+ * @brief Probe mp_ncores and smp_threads_per_core for early MI code
+ */
+METHOD void smp_probe_threads {
+	platform_t	_plat;
+} DEFAULT platform_null_smp_probe_threads;
 
 /**
  * @brief Return SMP topology

Modified: head/sys/powerpc/ps3/platform_ps3.c
==============================================================================
--- head/sys/powerpc/ps3/platform_ps3.c	Mon Jan  7 17:35:09 2019	(r342851)
+++ head/sys/powerpc/ps3/platform_ps3.c	Mon Jan  7 19:39:31 2019	(r342852)
@@ -70,6 +70,7 @@ static int ps3_smp_first_cpu(platform_t, struct cpuref
 static int ps3_smp_next_cpu(platform_t, struct cpuref *cpuref);
 static int ps3_smp_get_bsp(platform_t, struct cpuref *cpuref);
 static int ps3_smp_start_cpu(platform_t, struct pcpu *cpu);
+static void ps3_smp_probe_threads(platform_t);
 static struct cpu_group *ps3_smp_topo(platform_t);
 #endif
 static void ps3_reset(platform_t);
@@ -87,6 +88,7 @@ static platform_method_t ps3_methods[] = {
 	PLATFORMMETHOD(platform_smp_next_cpu,	ps3_smp_next_cpu),
 	PLATFORMMETHOD(platform_smp_get_bsp,	ps3_smp_get_bsp),
 	PLATFORMMETHOD(platform_smp_start_cpu,	ps3_smp_start_cpu),
+	PLATFORMMETHOD(platform_smp_probe_threads,	ps3_smp_probe_threads),
 	PLATFORMMETHOD(platform_smp_topo,	ps3_smp_topo),
 #endif
 
@@ -243,11 +245,16 @@ ps3_smp_start_cpu(platform_t plat, struct pcpu *pc)
 	return ((pc->pc_awake) ? 0 : EBUSY);
 }
 
-static struct cpu_group *
-ps3_smp_topo(platform_t plat)
+static void
+ps3_smp_probe_threads(platform_t plat)
 {
 	mp_ncores = 1;
 	smp_threads_per_core = 2;
+}
+
+static struct cpu_group *
+ps3_smp_topo(platform_t plat)
+{
 	return (smp_topo_1level(CG_SHARE_L1, 2, CG_FLAG_SMT));
 }
 #endif

Modified: head/sys/powerpc/pseries/platform_chrp.c
==============================================================================
--- head/sys/powerpc/pseries/platform_chrp.c	Mon Jan  7 17:35:09 2019	(r342851)
+++ head/sys/powerpc/pseries/platform_chrp.c	Mon Jan  7 19:39:31 2019	(r342852)
@@ -78,6 +78,7 @@ static void chrp_smp_ap_init(platform_t);
 static int chrp_cpuref_init(void);
 #ifdef SMP
 static int chrp_smp_start_cpu(platform_t, struct pcpu *cpu);
+static void chrp_smp_probe_threads(platform_t plat);
 static struct cpu_group *chrp_smp_topo(platform_t plat);
 #endif
 static void chrp_reset(platform_t);
@@ -103,6 +104,7 @@ static platform_method_t chrp_methods[] = {
 	PLATFORMMETHOD(platform_smp_get_bsp,	chrp_smp_get_bsp),
 #ifdef SMP
 	PLATFORMMETHOD(platform_smp_start_cpu,	chrp_smp_start_cpu),
+	PLATFORMMETHOD(platform_smp_probe_threads,	chrp_smp_probe_threads),
 	PLATFORMMETHOD(platform_smp_topo,	chrp_smp_topo),
 #endif
 
@@ -499,13 +501,13 @@ chrp_smp_start_cpu(platform_t plat, struct pcpu *pc)
 	return ((pc->pc_awake) ? 0 : EBUSY);
 }
 
-static struct cpu_group *
-chrp_smp_topo(platform_t plat)
+static void
+chrp_smp_probe_threads(platform_t plat)
 {
 	struct pcpu *pc, *last_pc;
-	int i, ncores, ncpus;
+	int i, ncores;
 
-	ncores = ncpus = 0;
+	ncores = 0;
 	last_pc = NULL;
 	for (i = 0; i <= mp_maxid; i++) {
 		pc = pcpu_find(i);
@@ -514,23 +516,29 @@ chrp_smp_topo(platform_t plat)
 		if (last_pc == NULL || pc->pc_hwref != last_pc->pc_hwref)
 			ncores++;
 		last_pc = pc;
-		ncpus++;
 	}
 
 	mp_ncores = ncores;
+	if (mp_ncpus % ncores == 0)
+		smp_threads_per_core = mp_ncpus / ncores;
+}
 
-	if (ncpus % ncores != 0) {
+static struct cpu_group *
+chrp_smp_topo(platform_t plat)
+{
+
+	if (mp_ncpus % mp_ncores != 0) {
 		printf("WARNING: Irregular SMP topology. Performance may be "
-		     "suboptimal (%d CPUS, %d cores)\n", ncpus, ncores);
+		     "suboptimal (%d CPUS, %d cores)\n", mp_ncpus, mp_ncores);
 		return (smp_topo_none());
 	}
 
 	/* Don't do anything fancier for non-threaded SMP */
-	if (ncpus == ncores)
+	if (mp_ncpus == mp_ncores)
 		return (smp_topo_none());
 
-	smp_threads_per_core = ncpus / ncores;
-	return (smp_topo_1level(CG_SHARE_L1, ncpus / ncores, CG_FLAG_SMT));
+	return (smp_topo_1level(CG_SHARE_L1, smp_threads_per_core,
+	    CG_FLAG_SMT));
 }
 #endif
 


More information about the svn-src-all mailing list