aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/lparcfg.c166
1 files changed, 88 insertions, 78 deletions
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c
index 20278ece31dc..a0ca90ab5e39 100644
--- a/arch/powerpc/kernel/lparcfg.c
+++ b/arch/powerpc/kernel/lparcfg.c
@@ -167,7 +167,8 @@ static unsigned int h_get_ppp(unsigned long *entitled,
167 return rc; 167 return rc;
168} 168}
169 169
170static void h_pic(unsigned long *pool_idle_time, unsigned long *num_procs) 170static unsigned h_pic(unsigned long *pool_idle_time,
171 unsigned long *num_procs)
171{ 172{
172 unsigned long rc; 173 unsigned long rc;
173 unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; 174 unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
@@ -176,6 +177,51 @@ static void h_pic(unsigned long *pool_idle_time, unsigned long *num_procs)
176 177
177 *pool_idle_time = retbuf[0]; 178 *pool_idle_time = retbuf[0];
178 *num_procs = retbuf[1]; 179 *num_procs = retbuf[1];
180
181 return rc;
182}
183
184/*
185 * parse_ppp_data
186 * Parse out the data returned from h_get_ppp and h_pic
187 */
188static void parse_ppp_data(struct seq_file *m)
189{
190 unsigned long h_entitled, h_unallocated;
191 unsigned long h_aggregation, h_resource;
192 int rc;
193
194 rc = h_get_ppp(&h_entitled, &h_unallocated, &h_aggregation,
195 &h_resource);
196 if (rc)
197 return;
198
199 seq_printf(m, "partition_entitled_capacity=%ld\n", h_entitled);
200 seq_printf(m, "group=%ld\n", (h_aggregation >> 2 * 8) & 0xffff);
201 seq_printf(m, "system_active_processors=%ld\n",
202 (h_resource >> 0 * 8) & 0xffff);
203
204 /* pool related entries are apropriate for shared configs */
205 if (lppaca[0].shared_proc) {
206 unsigned long pool_idle_time, pool_procs;
207
208 seq_printf(m, "pool=%ld\n", (h_aggregation >> 0 * 8) & 0xffff);
209
210 /* report pool_capacity in percentage */
211 seq_printf(m, "pool_capacity=%ld\n",
212 ((h_resource >> 2 * 8) & 0xffff) * 100);
213
214 h_pic(&pool_idle_time, &pool_procs);
215 seq_printf(m, "pool_idle_time=%ld\n", pool_idle_time);
216 seq_printf(m, "pool_num_procs=%ld\n", pool_procs);
217 }
218
219 seq_printf(m, "unallocated_capacity_weight=%ld\n",
220 (h_resource >> 4 * 8) & 0xFF);
221
222 seq_printf(m, "capacity_weight=%ld\n", (h_resource >> 5 * 8) & 0xFF);
223 seq_printf(m, "capped=%ld\n", (h_resource >> 6 * 8) & 0x01);
224 seq_printf(m, "unallocated_capacity=%ld\n", h_unallocated);
179} 225}
180 226
181#define SPLPAR_CHARACTERISTICS_TOKEN 20 227#define SPLPAR_CHARACTERISTICS_TOKEN 20
@@ -302,60 +348,11 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v)
302 partition_active_processors = lparcfg_count_active_processors(); 348 partition_active_processors = lparcfg_count_active_processors();
303 349
304 if (firmware_has_feature(FW_FEATURE_SPLPAR)) { 350 if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
305 unsigned long h_entitled, h_unallocated;
306 unsigned long h_aggregation, h_resource;
307 unsigned long pool_idle_time, pool_procs;
308 unsigned long purr;
309
310 h_get_ppp(&h_entitled, &h_unallocated, &h_aggregation,
311 &h_resource);
312
313 seq_printf(m, "R4=0x%lx\n", h_entitled);
314 seq_printf(m, "R5=0x%lx\n", h_unallocated);
315 seq_printf(m, "R6=0x%lx\n", h_aggregation);
316 seq_printf(m, "R7=0x%lx\n", h_resource);
317
318 purr = get_purr();
319
320 /* this call handles the ibm,get-system-parameter contents */ 351 /* this call handles the ibm,get-system-parameter contents */
321 parse_system_parameter_string(m); 352 parse_system_parameter_string(m);
353 parse_ppp_data(m);
322 354
323 seq_printf(m, "partition_entitled_capacity=%ld\n", h_entitled); 355 seq_printf(m, "purr=%ld\n", get_purr());
324
325 seq_printf(m, "group=%ld\n", (h_aggregation >> 2 * 8) & 0xffff);
326
327 seq_printf(m, "system_active_processors=%ld\n",
328 (h_resource >> 0 * 8) & 0xffff);
329
330 /* pool related entries are apropriate for shared configs */
331 if (lppaca[0].shared_proc) {
332
333 h_pic(&pool_idle_time, &pool_procs);
334
335 seq_printf(m, "pool=%ld\n",
336 (h_aggregation >> 0 * 8) & 0xffff);
337
338 /* report pool_capacity in percentage */
339 seq_printf(m, "pool_capacity=%ld\n",
340 ((h_resource >> 2 * 8) & 0xffff) * 100);
341
342 seq_printf(m, "pool_idle_time=%ld\n", pool_idle_time);
343
344 seq_printf(m, "pool_num_procs=%ld\n", pool_procs);
345 }
346
347 seq_printf(m, "unallocated_capacity_weight=%ld\n",
348 (h_resource >> 4 * 8) & 0xFF);
349
350 seq_printf(m, "capacity_weight=%ld\n",
351 (h_resource >> 5 * 8) & 0xFF);
352
353 seq_printf(m, "capped=%ld\n", (h_resource >> 6 * 8) & 0x01);
354
355 seq_printf(m, "unallocated_capacity=%ld\n", h_unallocated);
356
357 seq_printf(m, "purr=%ld\n", purr);
358
359 } else { /* non SPLPAR case */ 356 } else { /* non SPLPAR case */
360 357
361 seq_printf(m, "system_active_processors=%d\n", 358 seq_printf(m, "system_active_processors=%d\n",
@@ -382,6 +379,41 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v)
382 return 0; 379 return 0;
383} 380}
384 381
382static ssize_t update_ppp(u64 *entitlement, u8 *weight)
383{
384 unsigned long current_entitled;
385 unsigned long dummy;
386 unsigned long resource;
387 u8 current_weight, new_weight;
388 u64 new_entitled;
389 ssize_t retval;
390
391 /* Get our current parameters */
392 retval = h_get_ppp(&current_entitled, &dummy, &dummy, &resource);
393 if (retval)
394 return retval;
395
396 current_weight = (resource >> 5 * 8) & 0xFF;
397
398 if (entitlement) {
399 new_weight = current_weight;
400 new_entitled = *entitlement;
401 } else if (weight) {
402 new_weight = *weight;
403 new_entitled = current_entitled;
404 } else
405 return -EINVAL;
406
407 pr_debug("%s: current_entitled = %lu, current_weight = %u\n",
408 __FUNCTION__, current_entitled, current_weight);
409
410 pr_debug("%s: new_entitled = %lu, new_weight = %u\n",
411 __FUNCTION__, new_entitled, new_weight);
412
413 retval = plpar_hcall_norets(H_SET_PPP, new_entitled, new_weight);
414 return retval;
415}
416
385/* 417/*
386 * Interface for changing system parameters (variable capacity weight 418 * Interface for changing system parameters (variable capacity weight
387 * and entitled capacity). Format of input is "param_name=value"; 419 * and entitled capacity). Format of input is "param_name=value";
@@ -399,12 +431,6 @@ static ssize_t lparcfg_write(struct file *file, const char __user * buf,
399 char *tmp; 431 char *tmp;
400 u64 new_entitled, *new_entitled_ptr = &new_entitled; 432 u64 new_entitled, *new_entitled_ptr = &new_entitled;
401 u8 new_weight, *new_weight_ptr = &new_weight; 433 u8 new_weight, *new_weight_ptr = &new_weight;
402
403 unsigned long current_entitled; /* parameters for h_get_ppp */
404 unsigned long dummy;
405 unsigned long resource;
406 u8 current_weight;
407
408 ssize_t retval = -ENOMEM; 434 ssize_t retval = -ENOMEM;
409 435
410 if (!firmware_has_feature(FW_FEATURE_SPLPAR) || 436 if (!firmware_has_feature(FW_FEATURE_SPLPAR) ||
@@ -432,33 +458,17 @@ static ssize_t lparcfg_write(struct file *file, const char __user * buf,
432 *new_entitled_ptr = (u64) simple_strtoul(tmp, &endp, 10); 458 *new_entitled_ptr = (u64) simple_strtoul(tmp, &endp, 10);
433 if (endp == tmp) 459 if (endp == tmp)
434 goto out; 460 goto out;
435 new_weight_ptr = &current_weight; 461
462 retval = update_ppp(new_entitled_ptr, NULL);
436 } else if (!strcmp(kbuf, "capacity_weight")) { 463 } else if (!strcmp(kbuf, "capacity_weight")) {
437 char *endp; 464 char *endp;
438 *new_weight_ptr = (u8) simple_strtoul(tmp, &endp, 10); 465 *new_weight_ptr = (u8) simple_strtoul(tmp, &endp, 10);
439 if (endp == tmp) 466 if (endp == tmp)
440 goto out; 467 goto out;
441 new_entitled_ptr = &current_entitled;
442 } else
443 goto out;
444 468
445 /* Get our current parameters */ 469 retval = update_ppp(NULL, new_weight_ptr);
446 retval = h_get_ppp(&current_entitled, &dummy, &dummy, &resource); 470 } else
447 if (retval) {
448 retval = -EIO;
449 goto out; 471 goto out;
450 }
451
452 current_weight = (resource >> 5 * 8) & 0xFF;
453
454 pr_debug("%s: current_entitled = %lu, current_weight = %u\n",
455 __func__, current_entitled, current_weight);
456
457 pr_debug("%s: new_entitled = %lu, new_weight = %u\n",
458 __func__, *new_entitled_ptr, *new_weight_ptr);
459
460 retval = plpar_hcall_norets(H_SET_PPP, *new_entitled_ptr,
461 *new_weight_ptr);
462 472
463 if (retval == H_SUCCESS || retval == H_CONSTRAINED) { 473 if (retval == H_SUCCESS || retval == H_CONSTRAINED) {
464 retval = count; 474 retval = count;