diff options
author | Ian Munsie <imunsie@au1.ibm.com> | 2012-11-08 00:03:14 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2012-11-14 23:08:08 -0500 |
commit | fc8effa4e46fb7bd8a3c5e293efc56b74a54b7a5 (patch) | |
tree | 22a3c24c567c69939a72ed0e280ac040072a16c3 /arch | |
parent | cca55d9ddf6d431114ab9f7cad3e761b74255c9c (diff) |
powerpc: Enable relocation on during exceptions at boot
We currently do this synchronously at boot from setup_arch. On a large
system this could hypothetically take a little while to complete, so
currently we will give up if we are asked to wait for more than a second
in total.
If we actually start hitting that timeout in practice we can always move
this code into a kernel thread to take care of it in the background.
Signed-off-by: Ian Munsie <imunsie@au1.ibm.com>
Signed-off-by: Michael Neuling <mikey@neuling.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/platforms/pseries/setup.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index e1a5b8a32d25..5d97553e5c22 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
@@ -367,6 +367,36 @@ static void pSeries_idle(void) | |||
367 | } | 367 | } |
368 | } | 368 | } |
369 | 369 | ||
370 | /* | ||
371 | * Enable relocation on during exceptions. This has partition wide scope and | ||
372 | * may take a while to complete, if it takes longer than one second we will | ||
373 | * just give up rather than wasting any more time on this - if that turns out | ||
374 | * to ever be a problem in practice we can move this into a kernel thread to | ||
375 | * finish off the process later in boot. | ||
376 | */ | ||
377 | static int __init pSeries_enable_reloc_on_exc(void) | ||
378 | { | ||
379 | long rc; | ||
380 | unsigned int delay, total_delay = 0; | ||
381 | |||
382 | while (1) { | ||
383 | rc = enable_reloc_on_exceptions(); | ||
384 | if (!H_IS_LONG_BUSY(rc)) | ||
385 | return rc; | ||
386 | |||
387 | delay = get_longbusy_msecs(rc); | ||
388 | total_delay += delay; | ||
389 | if (total_delay > 1000) { | ||
390 | pr_warn("Warning: Giving up waiting to enable " | ||
391 | "relocation on exceptions (%u msec)!\n", | ||
392 | total_delay); | ||
393 | return rc; | ||
394 | } | ||
395 | |||
396 | mdelay(delay); | ||
397 | } | ||
398 | } | ||
399 | |||
370 | static void __init pSeries_setup_arch(void) | 400 | static void __init pSeries_setup_arch(void) |
371 | { | 401 | { |
372 | panic_timeout = 10; | 402 | panic_timeout = 10; |
@@ -402,6 +432,14 @@ static void __init pSeries_setup_arch(void) | |||
402 | ppc_md.enable_pmcs = pseries_lpar_enable_pmcs; | 432 | ppc_md.enable_pmcs = pseries_lpar_enable_pmcs; |
403 | else | 433 | else |
404 | ppc_md.enable_pmcs = power4_enable_pmcs; | 434 | ppc_md.enable_pmcs = power4_enable_pmcs; |
435 | |||
436 | if (firmware_has_feature(FW_FEATURE_SET_MODE)) { | ||
437 | long rc; | ||
438 | if ((rc = pSeries_enable_reloc_on_exc()) != H_SUCCESS) { | ||
439 | pr_warn("Unable to enable relocation on exceptions: " | ||
440 | "%ld\n", rc); | ||
441 | } | ||
442 | } | ||
405 | } | 443 | } |
406 | 444 | ||
407 | static int __init pSeries_init_panel(void) | 445 | static int __init pSeries_init_panel(void) |