public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Martin Schwidefsky <schwidefsky@de.ibm.com>
To: linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>,
	Martin Schwidefsky <schwidefsky@de.ibm.com>
Subject: [patch 07/10] Vertical cpu management.
Date: Wed, 12 Mar 2008 18:32:02 +0100	[thread overview]
Message-ID: <20080312173217.724970802@de.ibm.com> (raw)
In-Reply-To: 20080312173155.703966894@de.ibm.com

[-- Attachment #1: 107-vertical-cpus.diff --]
[-- Type: text/plain, Size: 9167 bytes --]

From: Heiko Carstens <heiko.carstens@de.ibm.com>

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 arch/s390/kernel/smp.c      |   83 ++++++++++++++++++++++++++++++++++++++++++--
 arch/s390/kernel/topology.c |   66 +++++++++++++++++++++++++++++-----
 include/asm-s390/smp.h      |    1 
 include/asm-s390/topology.h |    9 ++++
 4 files changed, 146 insertions(+), 13 deletions(-)

Index: quilt-2.6/arch/s390/kernel/smp.c
===================================================================
--- quilt-2.6.orig/arch/s390/kernel/smp.c
+++ quilt-2.6/arch/s390/kernel/smp.c
@@ -68,7 +68,9 @@ enum s390_cpu_state {
 };
 
 DEFINE_MUTEX(smp_cpu_state_mutex);
+int smp_cpu_polarization[NR_CPUS];
 static int smp_cpu_state[NR_CPUS];
+static int cpu_management;
 
 static DEFINE_PER_CPU(struct cpu, cpu_devices);
 DEFINE_PER_CPU(struct s390_idle_data, s390_idle);
@@ -454,6 +456,7 @@ static int smp_rescan_cpus_sigp(cpumask_
 		if (cpu_known(cpu_id))
 			continue;
 		__cpu_logical_map[logical_cpu] = cpu_id;
+		smp_cpu_polarization[logical_cpu] = POLARIZATION_UNKNWN;
 		if (!cpu_stopped(logical_cpu))
 			continue;
 		cpu_set(logical_cpu, cpu_present_map);
@@ -487,6 +490,7 @@ static int smp_rescan_cpus_sclp(cpumask_
 		if (cpu_known(cpu_id))
 			continue;
 		__cpu_logical_map[logical_cpu] = cpu_id;
+		smp_cpu_polarization[logical_cpu] = POLARIZATION_UNKNWN;
 		cpu_set(logical_cpu, cpu_present_map);
 		if (cpu >= info->configured)
 			smp_cpu_state[logical_cpu] = CPU_STATE_STANDBY;
@@ -844,6 +848,7 @@ void __init smp_prepare_boot_cpu(void)
 	S390_lowcore.percpu_offset = __per_cpu_offset[0];
 	current_set[0] = current;
 	smp_cpu_state[0] = CPU_STATE_CONFIGURED;
+	smp_cpu_polarization[0] = POLARIZATION_UNKNWN;
 	spin_lock_init(&(&__get_cpu_var(s390_idle))->lock);
 }
 
@@ -895,15 +900,19 @@ static ssize_t cpu_configure_store(struc
 	case 0:
 		if (smp_cpu_state[cpu] == CPU_STATE_CONFIGURED) {
 			rc = sclp_cpu_deconfigure(__cpu_logical_map[cpu]);
-			if (!rc)
+			if (!rc) {
 				smp_cpu_state[cpu] = CPU_STATE_STANDBY;
+				smp_cpu_polarization[cpu] = POLARIZATION_UNKNWN;
+			}
 		}
 		break;
 	case 1:
 		if (smp_cpu_state[cpu] == CPU_STATE_STANDBY) {
 			rc = sclp_cpu_configure(__cpu_logical_map[cpu]);
-			if (!rc)
+			if (!rc) {
 				smp_cpu_state[cpu] = CPU_STATE_CONFIGURED;
+				smp_cpu_polarization[cpu] = POLARIZATION_UNKNWN;
+			}
 		}
 		break;
 	default:
@@ -917,6 +926,34 @@ out:
 static SYSDEV_ATTR(configure, 0644, cpu_configure_show, cpu_configure_store);
 #endif /* CONFIG_HOTPLUG_CPU */
 
+static ssize_t cpu_polarization_show(struct sys_device *dev, char *buf)
+{
+	int cpu = dev->id;
+	ssize_t count;
+
+	mutex_lock(&smp_cpu_state_mutex);
+	switch (smp_cpu_polarization[cpu]) {
+	case POLARIZATION_HRZ:
+		count = sprintf(buf, "horizontal\n");
+		break;
+	case POLARIZATION_VL:
+		count = sprintf(buf, "vertical:low\n");
+		break;
+	case POLARIZATION_VM:
+		count = sprintf(buf, "vertical:medium\n");
+		break;
+	case POLARIZATION_VH:
+		count = sprintf(buf, "vertical:high\n");
+		break;
+	default:
+		count = sprintf(buf, "unknown\n");
+		break;
+	}
+	mutex_unlock(&smp_cpu_state_mutex);
+	return count;
+}
+static SYSDEV_ATTR(polarization, 0444, cpu_polarization_show, NULL);
+
 static ssize_t show_cpu_address(struct sys_device *dev, char *buf)
 {
 	return sprintf(buf, "%d\n", __cpu_logical_map[dev->id]);
@@ -929,6 +966,7 @@ static struct attribute *cpu_common_attr
 	&attr_configure.attr,
 #endif
 	&attr_address.attr,
+	&attr_polarization.attr,
 	NULL,
 };
 
@@ -1073,11 +1111,48 @@ static ssize_t __ref rescan_store(struct
 out:
 	put_online_cpus();
 	mutex_unlock(&smp_cpu_state_mutex);
+	if (!cpus_empty(newcpus))
+		topology_schedule_update();
 	return rc ? rc : count;
 }
 static SYSDEV_ATTR(rescan, 0200, NULL, rescan_store);
 #endif /* CONFIG_HOTPLUG_CPU */
 
+static ssize_t dispatching_show(struct sys_device *dev, char *buf)
+{
+	ssize_t count;
+
+	mutex_lock(&smp_cpu_state_mutex);
+	count = sprintf(buf, "%d\n", cpu_management);
+	mutex_unlock(&smp_cpu_state_mutex);
+	return count;
+}
+
+static ssize_t dispatching_store(struct sys_device *dev, const char *buf,
+				 size_t count)
+{
+	int val, rc;
+	char delim;
+
+	if (sscanf(buf, "%d %c", &val, &delim) != 1)
+		return -EINVAL;
+	if (val != 0 && val != 1)
+		return -EINVAL;
+	rc = 0;
+	mutex_lock(&smp_cpu_state_mutex);
+	get_online_cpus();
+	if (cpu_management == val)
+		goto out;
+	rc = topology_set_cpu_management(val);
+	if (!rc)
+		cpu_management = val;
+out:
+	put_online_cpus();
+	mutex_unlock(&smp_cpu_state_mutex);
+	return rc ? rc : count;
+}
+static SYSDEV_ATTR(dispatching, 0644, dispatching_show, dispatching_store);
+
 static int __init topology_init(void)
 {
 	int cpu;
@@ -1091,6 +1166,10 @@ static int __init topology_init(void)
 	if (rc)
 		return rc;
 #endif
+	rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
+			       &attr_dispatching.attr);
+	if (rc)
+		return rc;
 	for_each_present_cpu(cpu) {
 		rc = smp_add_present_cpu(cpu);
 		if (rc)
Index: quilt-2.6/arch/s390/kernel/topology.c
===================================================================
--- quilt-2.6.orig/arch/s390/kernel/topology.c
+++ quilt-2.6/arch/s390/kernel/topology.c
@@ -18,9 +18,17 @@
 #include <asm/s390_ext.h>
 
 #define CPU_BITS 64
+#define NR_MAG 6
+
+#define PTF_HORIZONTAL	(0UL)
+#define PTF_VERTICAL	(1UL)
+#define PTF_CHECK	(2UL)
 
 struct tl_cpu {
-	unsigned char reserved[6];
+	unsigned char reserved0[4];
+	unsigned char :6;
+	unsigned char pp:2;
+	unsigned char reserved1;
 	unsigned short origin;
 	unsigned long mask[CPU_BITS / BITS_PER_LONG];
 };
@@ -35,8 +43,6 @@ union tl_entry {
 	struct tl_container container;
 };
 
-#define NR_MAG 6
-
 struct tl_info {
 	unsigned char reserved0[2];
 	unsigned short length;
@@ -95,8 +101,10 @@ static void add_cpus_to_core(struct tl_c
 
 		rcpu = CPU_BITS - 1 - cpu + tl_cpu->origin;
 		for_each_present_cpu(lcpu) {
-			if (__cpu_logical_map[lcpu] == rcpu)
+			if (__cpu_logical_map[lcpu] == rcpu) {
 				cpu_set(lcpu, core->mask);
+				smp_cpu_polarization[lcpu] = tl_cpu->pp;
+			}
 		}
 	}
 }
@@ -151,7 +159,17 @@ static void tl_to_cores(struct tl_info *
 	mutex_unlock(&smp_cpu_state_mutex);
 }
 
-static int ptf(void)
+static void topology_update_polarization_simple(void)
+{
+	int cpu;
+
+	mutex_lock(&smp_cpu_state_mutex);
+	for_each_present_cpu(cpu)
+		smp_cpu_polarization[cpu] = POLARIZATION_HRZ;
+	mutex_unlock(&smp_cpu_state_mutex);
+}
+
+static int ptf(unsigned long fc)
 {
 	int rc;
 
@@ -160,7 +178,25 @@ static int ptf(void)
 		"	ipm	%0\n"
 		"	srl	%0,28\n"
 		: "=d" (rc)
-		: "d" (2UL)  : "cc");
+		: "d" (fc)  : "cc");
+	return rc;
+}
+
+int topology_set_cpu_management(int fc)
+{
+	int cpu;
+	int rc;
+
+	if (!machine_has_topology)
+		return -EOPNOTSUPP;
+	if (fc)
+		rc = ptf(PTF_VERTICAL);
+	else
+		rc = ptf(PTF_HORIZONTAL);
+	if (rc)
+		return -EBUSY;
+	for_each_present_cpu(cpu)
+		smp_cpu_polarization[cpu] = POLARIZATION_UNKNWN;
 	return rc;
 }
 
@@ -170,9 +206,10 @@ void arch_update_cpu_topology(void)
 	struct sys_device *sysdev;
 	int cpu;
 
-	if (!machine_has_topology)
+	if (!machine_has_topology) {
+		topology_update_polarization_simple();
 		return;
-	ptf();
+	}
 	stsi(info, 15, 1, 2);
 	tl_to_cores(info);
 	for_each_online_cpu(cpu) {
@@ -186,10 +223,15 @@ static void topology_work_fn(struct work
 	arch_reinit_sched_domains();
 }
 
+void topology_schedule_update(void)
+{
+	schedule_work(&topology_work);
+}
+
 static void topology_timer_fn(unsigned long ignored)
 {
-	if (ptf())
-		schedule_work(&topology_work);
+	if (ptf(PTF_CHECK))
+		topology_schedule_update();
 	set_topology_timer();
 }
 
@@ -210,8 +252,10 @@ static int __init init_topology_update(v
 {
 	int rc;
 
-	if (!machine_has_topology)
+	if (!machine_has_topology) {
+		topology_update_polarization_simple();
 		return 0;
+	}
 	init_timer(&topology_timer);
 	if (machine_has_topology_irq) {
 		rc = register_external_interrupt(0x2005, topology_interrupt);
Index: quilt-2.6/include/asm-s390/smp.h
===================================================================
--- quilt-2.6.orig/include/asm-s390/smp.h
+++ quilt-2.6/include/asm-s390/smp.h
@@ -91,6 +91,7 @@ extern void cpu_die (void) __attribute__
 extern int __cpu_up (unsigned int cpu);
 
 extern struct mutex smp_cpu_state_mutex;
+extern int smp_cpu_polarization[];
 
 extern int smp_call_function_mask(cpumask_t mask, void (*func)(void *),
 	void *info, int wait);
Index: quilt-2.6/include/asm-s390/topology.h
===================================================================
--- quilt-2.6.orig/include/asm-s390/topology.h
+++ quilt-2.6/include/asm-s390/topology.h
@@ -9,6 +9,15 @@ cpumask_t cpu_coregroup_map(unsigned int
 
 #define topology_core_siblings(cpu)	(cpu_coregroup_map(cpu))
 
+int topology_set_cpu_management(int fc);
+void topology_schedule_update(void);
+
+#define POLARIZATION_UNKNWN	(-1)
+#define POLARIZATION_HRZ	(0)
+#define POLARIZATION_VL		(1)
+#define POLARIZATION_VM		(2)
+#define POLARIZATION_VH		(3)
+
 #ifdef CONFIG_SMP
 void s390_init_cpu_topology(void);
 #else

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


  parent reply	other threads:[~2008-03-12 17:34 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-03-12 17:31 [patch 00/10] System z10 patches Martin Schwidefsky
2008-03-12 17:31 ` [patch 01/10] Add new fields for System z10 to /proc/sysinfo Martin Schwidefsky
2008-03-12 17:57   ` Josef 'Jeff' Sipek
2008-03-13 10:02     ` Martin Schwidefsky
2008-03-12 17:31 ` [patch 02/10] Export stfle Martin Schwidefsky
2008-03-12 17:31 ` [patch 03/10] sched: add exported arch_reinit_sched_domains() to header file Martin Schwidefsky
2008-03-12 23:03   ` Andrew Morton
2008-03-13  9:48     ` Martin Schwidefsky
2008-03-21 12:29   ` Ingo Molnar
2008-03-12 17:31 ` [patch 04/10] sched: Add arch_update_cpu_topology hook Martin Schwidefsky
2008-03-21 12:30   ` Ingo Molnar
2008-03-12 17:32 ` [patch 05/10] cpu topology: convert siblings_show macro to accept non-lvalues Martin Schwidefsky
2008-03-12 17:32 ` [patch 06/10] cpu topology support for s390 Martin Schwidefsky
2008-03-12 23:11   ` Andrew Morton
2008-03-13 12:28     ` Martin Schwidefsky
2008-03-13 22:40       ` Heiko Carstens
2008-03-12 17:32 ` Martin Schwidefsky [this message]
2008-03-12 17:32 ` [patch 08/10] Add missing TLB flush to hugetlb_cow() Martin Schwidefsky
2008-03-12 17:32 ` [patch 09/10] Hugetlb common code update for System z Martin Schwidefsky
2008-03-12 17:51   ` Dave Hansen
2008-03-12 23:18     ` Gerald Schaefer
2008-03-12 23:43       ` Andrew Morton
2008-03-13 17:49         ` Gerald Schaefer
2008-03-28 14:05         ` Gerald Schaefer
2008-03-28 14:06           ` Ingo Molnar
2008-03-28 14:33             ` Gerald Schaefer
2008-03-28 15:53             ` Martin Schwidefsky
2008-03-28 16:03               ` Ingo Molnar
2008-03-12 17:32 ` [patch 10/10] System z large page support Martin Schwidefsky
2008-03-12 17:52   ` Dave Hansen
2008-03-12 22:14     ` Gerald Schaefer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080312173217.724970802@de.ibm.com \
    --to=schwidefsky@de.ibm.com \
    --cc=heiko.carstens@de.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-s390@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox