diff options
author | Stewart Smith <stewart@linux.ibm.com> | 2018-10-30 00:34:23 -0500 |
---|---|---|
committer | Stewart Smith <stewart@linux.ibm.com> | 2018-10-31 17:33:34 +1100 |
commit | fc7af9ac4efdaf97ef188ac1b4a0984ce19a207f (patch) | |
tree | 083b1241d32159a8b134651c4d118bb4218c48ed | |
parent | 77ac2fe061b8dec467eedfa778088626d797617c (diff) | |
download | skiboot-fc7af9ac4efdaf97ef188ac1b4a0984ce19a207f.zip skiboot-fc7af9ac4efdaf97ef188ac1b4a0984ce19a207f.tar.gz skiboot-fc7af9ac4efdaf97ef188ac1b4a0984ce19a207f.tar.bz2 |
Run pollers in time_wait() when not booting
[ Upstream commit d10862e40cd8ef36fe49b298f3c615ac73dd3c4e ]
This only bit us hard with hiomap in one scenario.
Our OPAL API has been OPAL_POLL_EVENTS may be needed to make forward
progress on ongoing operations, and the internal to skiboot API has been
that time_wait() of a suitable time will run pollers (on at least one
CPU) to help ensure forward progress can be made.
In a perfect world, interrupts are used but they may a) be disabled, or
b) the thing we're doing can't use interrupts because computers are
generally terrible.
Back in 3db397ea5892a (circa 2015), we changed skiboot so that we'd run
pollers only on the boot CPU, and not if we held any locks. This was to
reduce the chance of programming code that could deadlock, as well as to
ensure that we didn't just thrash all the cachelines for running pollers
all over a large system during boot, or hard spin on the same locks on
all secondary CPUs.
The problem arises if the OS we're booting makes an OPAL call early on,
with interrupts disabled, that requires a poller to run to make forward
progress. An example of this would be OPAL_WRITE_NVRAM early in Linux
boot (where Linux sets up the partitions it wants) - something that
occurs iff we've had to reformat NVRAM this boot (i.e. first boot or
corrupted NVRAM).
The hiomap implementation should arguably *not* rely on synchronous IPMI
messages, but this is a future improvement (as was for mbox before it).
The mbox-flash code solved this problem by spinning on check_timers().
More generically though, the approach of running the pollers when no
longer booting means we behave more in line with what the API is meant
to be, rather than have this odd case of "time_wait() for a condition
that could also be tripped by an interrupt works fine unless the OS is
up and running but hasn't set interrupts up yet".
Fixes: 529bdca0bc546a7ae3ecbd2c3134b7260072d8b0
Fixes: 3db397ea5892a8b348cf412739996731884561b3
Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
-rw-r--r-- | core/timebase.c | 3 |
1 files changed, 1 insertions, 2 deletions
diff --git a/core/timebase.c b/core/timebase.c index 777e4ba..ce958d1 100644 --- a/core/timebase.c +++ b/core/timebase.c @@ -1,4 +1,3 @@ - /* Copyright 2013-2014 IBM Corp. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -58,7 +57,7 @@ void time_wait(unsigned long duration) return; } - if (c != boot_cpu) + if (c != boot_cpu && opal_booting()) time_wait_nopoll(duration); else time_wait_poll(duration); |