diff options
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/lparcfg.c | 166 |
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 | ||
170 | static void h_pic(unsigned long *pool_idle_time, unsigned long *num_procs) | 170 | static 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 | */ | ||
188 | static 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 | ||
382 | static 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(¤t_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 = ¤t_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 = ¤t_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(¤t_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; |