[S390] Make sure enabled wait psw is loaded in default_idle.
If both NO_IDLE_HZ and VIRT_TIMER are disabled default_idle won't load an enabled wait psw and busy loop instead. This is because the idle_chain is empty and the return value of atomic_notifier_call_chain will be NOTIFY_DONE, which causes default_idle to return instead of loading an enabled wait psw. Fix this by calling __atomic_notifier_call_chain instead and add proper return value handling. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
committed by
Martin Schwidefsky
parent
057c5cb35e
commit
11ab244c9f
@@ -114,24 +114,27 @@ extern void s390_handle_mcck(void);
|
|||||||
static void default_idle(void)
|
static void default_idle(void)
|
||||||
{
|
{
|
||||||
int cpu, rc;
|
int cpu, rc;
|
||||||
|
int nr_calls = 0;
|
||||||
|
void *hcpu;
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
struct s390_idle_data *idle;
|
struct s390_idle_data *idle;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* CPU is going idle. */
|
/* CPU is going idle. */
|
||||||
cpu = smp_processor_id();
|
cpu = smp_processor_id();
|
||||||
|
hcpu = (void *)(long)cpu;
|
||||||
local_irq_disable();
|
local_irq_disable();
|
||||||
if (need_resched()) {
|
if (need_resched()) {
|
||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = atomic_notifier_call_chain(&idle_chain,
|
rc = __atomic_notifier_call_chain(&idle_chain, S390_CPU_IDLE, hcpu, -1,
|
||||||
S390_CPU_IDLE, (void *)(long) cpu);
|
&nr_calls);
|
||||||
if (rc != NOTIFY_OK && rc != NOTIFY_DONE)
|
if (rc == NOTIFY_BAD) {
|
||||||
BUG();
|
nr_calls--;
|
||||||
if (rc != NOTIFY_OK) {
|
__atomic_notifier_call_chain(&idle_chain, S390_CPU_NOT_IDLE,
|
||||||
|
hcpu, nr_calls, NULL);
|
||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user