topology.c 9.8 KB
Newer Older
1
/*
2
 *    Copyright IBM Corp. 2007, 2011
3 4 5
 *    Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
 */

6 7 8
#define KMSG_COMPONENT "cpu"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt

9
#include <linux/workqueue.h>
10
#include <linux/bootmem.h>
11 12 13
#include <linux/cpuset.h>
#include <linux/device.h>
#include <linux/kernel.h>
14
#include <linux/sched.h>
15 16
#include <linux/init.h>
#include <linux/delay.h>
17 18
#include <linux/cpu.h>
#include <linux/smp.h>
19
#include <linux/mm.h>
20
#include <asm/sysinfo.h>
21

H
Heiko Carstens 已提交
22 23 24
#define PTF_HORIZONTAL	(0UL)
#define PTF_VERTICAL	(1UL)
#define PTF_CHECK	(2UL)
25

26 27
struct mask_info {
	struct mask_info *next;
28
	unsigned char id;
29 30 31
	cpumask_t mask;
};

H
Heiko Carstens 已提交
32
static int topology_enabled = 1;
33
static void topology_work_fn(struct work_struct *work);
34
static struct sysinfo_15_1_x *tl_info;
35 36
static void set_topology_timer(void);
static DECLARE_WORK(topology_work, topology_work_fn);
H
Heiko Carstens 已提交
37 38
/* topology_lock protects the core linked list */
static DEFINE_SPINLOCK(topology_lock);
39

40
static struct mask_info core_info;
41
cpumask_t cpu_core_map[NR_CPUS];
42
unsigned char cpu_core_id[NR_CPUS];
43
unsigned char cpu_socket_id[NR_CPUS];
44

45 46 47
static struct mask_info book_info;
cpumask_t cpu_book_map[NR_CPUS];
unsigned char cpu_book_id[NR_CPUS];
48

49
static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu)
50 51 52
{
	cpumask_t mask;

53
	cpumask_clear(&mask);
54 55 56 57
	if (!topology_enabled || !MACHINE_HAS_TOPOLOGY) {
		cpumask_copy(&mask, cpumask_of(cpu));
		return mask;
	}
58
	while (info) {
59
		if (cpumask_test_cpu(cpu, &info->mask)) {
60
			mask = info->mask;
61 62
			break;
		}
63
		info = info->next;
64
	}
65 66
	if (cpumask_empty(&mask))
		cpumask_copy(&mask, cpumask_of(cpu));
67 68 69
	return mask;
}

70 71 72
static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu,
					  struct mask_info *book,
					  struct mask_info *core,
73
					  int one_core_per_cpu)
74 75 76
{
	unsigned int cpu;

77
	for_each_set_bit(cpu, &tl_cpu->mask[0], TOPOLOGY_CPU_BITS) {
M
Martin Schwidefsky 已提交
78 79
		unsigned int rcpu;
		int lcpu;
80

81
		rcpu = TOPOLOGY_CPU_BITS - 1 - cpu + tl_cpu->origin;
M
Martin Schwidefsky 已提交
82 83
		lcpu = smp_find_processor_id(rcpu);
		if (lcpu >= 0) {
84
			cpumask_set_cpu(lcpu, &book->mask);
85
			cpu_book_id[lcpu] = book->id;
86
			cpumask_set_cpu(lcpu, &core->mask);
87
			cpu_core_id[lcpu] = rcpu;
88
			if (one_core_per_cpu) {
89
				cpu_socket_id[lcpu] = rcpu;
90 91
				core = core->next;
			} else {
92
				cpu_socket_id[lcpu] = core->id;
93
			}
94
			smp_cpu_set_polarization(lcpu, tl_cpu->pp);
95 96
		}
	}
97
	return core;
98 99
}

100
static void clear_masks(void)
101
{
102
	struct mask_info *info;
103

104 105
	info = &core_info;
	while (info) {
106
		cpumask_clear(&info->mask);
107 108 109 110
		info = info->next;
	}
	info = &book_info;
	while (info) {
111
		cpumask_clear(&info->mask);
112
		info = info->next;
113 114 115
	}
}

116
static union topology_entry *next_tle(union topology_entry *tle)
117
{
118 119 120
	if (!tle->nl)
		return (union topology_entry *)((struct topology_cpu *)tle + 1);
	return (union topology_entry *)((struct topology_container *)tle + 1);
121 122
}

123
static void __tl_to_cores_generic(struct sysinfo_15_1_x *info)
124
{
125
	struct mask_info *core = &core_info;
126
	struct mask_info *book = &book_info;
127
	union topology_entry *tle, *end;
128

H
Heiko Carstens 已提交
129
	tle = info->tle;
130
	end = (union topology_entry *)((unsigned long)info + info->length);
131 132 133
	while (tle < end) {
		switch (tle->nl) {
		case 2:
134 135
			book = book->next;
			book->id = tle->container.id;
136 137 138
			break;
		case 1:
			core = core->next;
139
			core->id = tle->container.id;
140 141
			break;
		case 0:
142
			add_cpus_to_mask(&tle->cpu, book, core, 0);
143 144
			break;
		default:
145
			clear_masks();
146
			return;
147 148 149
		}
		tle = next_tle(tle);
	}
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
}

static void __tl_to_cores_z10(struct sysinfo_15_1_x *info)
{
	struct mask_info *core = &core_info;
	struct mask_info *book = &book_info;
	union topology_entry *tle, *end;

	tle = info->tle;
	end = (union topology_entry *)((unsigned long)info + info->length);
	while (tle < end) {
		switch (tle->nl) {
		case 1:
			book = book->next;
			book->id = tle->container.id;
			break;
		case 0:
			core = add_cpus_to_mask(&tle->cpu, book, core, 1);
			break;
		default:
			clear_masks();
			return;
		}
		tle = next_tle(tle);
	}
}

static void tl_to_cores(struct sysinfo_15_1_x *info)
{
	struct cpuid cpu_id;

	get_cpu_id(&cpu_id);
	spin_lock_irq(&topology_lock);
	clear_masks();
	switch (cpu_id.machine) {
	case 0x2097:
	case 0x2098:
		__tl_to_cores_z10(info);
		break;
	default:
		__tl_to_cores_generic(info);
	}
H
Heiko Carstens 已提交
192
	spin_unlock_irq(&topology_lock);
193 194
}

H
Heiko Carstens 已提交
195 196 197 198 199
static void topology_update_polarization_simple(void)
{
	int cpu;

	mutex_lock(&smp_cpu_state_mutex);
200
	for_each_possible_cpu(cpu)
201
		smp_cpu_set_polarization(cpu, POLARIZATION_HRZ);
H
Heiko Carstens 已提交
202 203 204 205
	mutex_unlock(&smp_cpu_state_mutex);
}

static int ptf(unsigned long fc)
206 207 208 209 210 211 212 213
{
	int rc;

	asm volatile(
		"	.insn	rre,0xb9a20000,%1,%1\n"
		"	ipm	%0\n"
		"	srl	%0,28\n"
		: "=d" (rc)
H
Heiko Carstens 已提交
214 215 216 217 218 219
		: "d" (fc)  : "cc");
	return rc;
}

int topology_set_cpu_management(int fc)
{
220
	int cpu, rc;
H
Heiko Carstens 已提交
221

222
	if (!MACHINE_HAS_TOPOLOGY)
H
Heiko Carstens 已提交
223 224 225 226 227 228 229
		return -EOPNOTSUPP;
	if (fc)
		rc = ptf(PTF_VERTICAL);
	else
		rc = ptf(PTF_HORIZONTAL);
	if (rc)
		return -EBUSY;
230
	for_each_possible_cpu(cpu)
231
		smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
232 233 234
	return rc;
}

235 236
static void update_cpu_core_map(void)
{
237
	unsigned long flags;
238 239
	int cpu;

240 241 242 243 244 245 246 247
	spin_lock_irqsave(&topology_lock, flags);
	for_each_possible_cpu(cpu) {
		cpu_core_map[cpu] = cpu_group_map(&core_info, cpu);
		cpu_book_map[cpu] = cpu_group_map(&book_info, cpu);
	}
	spin_unlock_irqrestore(&topology_lock, flags);
}

248
void store_topology(struct sysinfo_15_1_x *info)
249
{
250 251 252 253
	if (topology_max_mnest >= 3)
		stsi(info, 15, 1, 3);
	else
		stsi(info, 15, 1, 2);
254 255
}

256
int arch_update_cpu_topology(void)
257
{
258
	struct sysinfo_15_1_x *info = tl_info;
259
	struct device *dev;
260 261
	int cpu;

262
	if (!MACHINE_HAS_TOPOLOGY) {
263
		update_cpu_core_map();
H
Heiko Carstens 已提交
264
		topology_update_polarization_simple();
265
		return 0;
H
Heiko Carstens 已提交
266
	}
267
	store_topology(info);
268
	tl_to_cores(info);
269
	update_cpu_core_map();
270
	for_each_online_cpu(cpu) {
271 272
		dev = get_cpu_device(cpu);
		kobject_uevent(&dev->kobj, KOBJ_CHANGE);
273
	}
274
	return 1;
275 276
}

277 278
static void topology_work_fn(struct work_struct *work)
{
279
	rebuild_sched_domains();
280 281
}

H
Heiko Carstens 已提交
282 283 284 285 286
void topology_schedule_update(void)
{
	schedule_work(&topology_work);
}

287 288
static void topology_timer_fn(unsigned long ignored)
{
H
Heiko Carstens 已提交
289 290
	if (ptf(PTF_CHECK))
		topology_schedule_update();
291 292 293
	set_topology_timer();
}

294 295 296 297 298
static struct timer_list topology_timer =
	TIMER_DEFERRED_INITIALIZER(topology_timer_fn, 0, 0);

static atomic_t topology_poll = ATOMIC_INIT(0);

299 300
static void set_topology_timer(void)
{
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317
	if (atomic_add_unless(&topology_poll, -1, 0))
		mod_timer(&topology_timer, jiffies + HZ / 10);
	else
		mod_timer(&topology_timer, jiffies + HZ * 60);
}

void topology_expect_change(void)
{
	if (!MACHINE_HAS_TOPOLOGY)
		return;
	/* This is racy, but it doesn't matter since it is just a heuristic.
	 * Worst case is that we poll in a higher frequency for a bit longer.
	 */
	if (atomic_read(&topology_poll) > 60)
		return;
	atomic_add(60, &topology_poll);
	set_topology_timer();
318 319
}

320
static int __init early_parse_topology(char *p)
321
{
H
Heiko Carstens 已提交
322
	if (strncmp(p, "off", 3))
323
		return 0;
H
Heiko Carstens 已提交
324
	topology_enabled = 0;
325
	return 0;
326
}
327
early_param("topology", early_parse_topology);
328

329 330
static void __init alloc_masks(struct sysinfo_15_1_x *info,
			       struct mask_info *mask, int offset)
331 332 333
{
	int i, nr_masks;

334
	nr_masks = info->mag[TOPOLOGY_NR_MAG - offset];
335
	for (i = 0; i < info->mnest - offset; i++)
336
		nr_masks *= info->mag[TOPOLOGY_NR_MAG - offset - 1 - i];
337 338 339 340 341 342 343
	nr_masks = max(nr_masks, 1);
	for (i = 0; i < nr_masks; i++) {
		mask->next = alloc_bootmem(sizeof(struct mask_info));
		mask = mask->next;
	}
}

344 345
void __init s390_init_cpu_topology(void)
{
346
	struct sysinfo_15_1_x *info;
347 348
	int i;

349
	if (!MACHINE_HAS_TOPOLOGY)
350 351 352
		return;
	tl_info = alloc_bootmem_pages(PAGE_SIZE);
	info = tl_info;
353
	store_topology(info);
354
	pr_info("The CPU configuration topology of the machine is:");
355
	for (i = 0; i < TOPOLOGY_NR_MAG; i++)
356 357
		printk(KERN_CONT " %d", info->mag[i]);
	printk(KERN_CONT " / %d\n", info->mnest);
358 359
	alloc_masks(info, &core_info, 1);
	alloc_masks(info, &book_info, 2);
360
}
361 362 363

static int cpu_management;

364 365
static ssize_t dispatching_show(struct device *dev,
				struct device_attribute *attr,
366 367 368 369 370 371 372 373 374 375
				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;
}

376 377
static ssize_t dispatching_store(struct device *dev,
				 struct device_attribute *attr,
378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393
				 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;
	get_online_cpus();
	mutex_lock(&smp_cpu_state_mutex);
	if (cpu_management == val)
		goto out;
	rc = topology_set_cpu_management(val);
394 395 396 397
	if (rc)
		goto out;
	cpu_management = val;
	topology_expect_change();
398 399 400 401 402
out:
	mutex_unlock(&smp_cpu_state_mutex);
	put_online_cpus();
	return rc ? rc : count;
}
403
static DEVICE_ATTR(dispatching, 0644, dispatching_show,
404 405
			 dispatching_store);

406 407
static ssize_t cpu_polarization_show(struct device *dev,
				     struct device_attribute *attr, char *buf)
408 409 410 411 412
{
	int cpu = dev->id;
	ssize_t count;

	mutex_lock(&smp_cpu_state_mutex);
413
	switch (smp_cpu_get_polarization(cpu)) {
414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432
	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;
}
433
static DEVICE_ATTR(polarization, 0444, cpu_polarization_show, NULL);
434 435

static struct attribute *topology_cpu_attrs[] = {
436
	&dev_attr_polarization.attr,
437 438 439 440 441 442 443 444 445
	NULL,
};

static struct attribute_group topology_cpu_attr_group = {
	.attrs = topology_cpu_attrs,
};

int topology_cpu_init(struct cpu *cpu)
{
446
	return sysfs_create_group(&cpu->dev.kobj, &topology_cpu_attr_group);
447 448 449 450 451 452 453 454 455 456 457
}

static int __init topology_init(void)
{
	if (!MACHINE_HAS_TOPOLOGY) {
		topology_update_polarization_simple();
		goto out;
	}
	set_topology_timer();
out:
	update_cpu_core_map();
458
	return device_create_file(cpu_subsys.dev_root, &dev_attr_dispatching);
459 460
}
device_initcall(topology_init);