Commit 6472a2dc authored by Heiko Carstens's avatar Heiko Carstens

s390/irq,idle: simplify idle check

Use the per-cpu CIF_ENABLED_WAIT flag to decide if an interrupt
occurred while a cpu was idle, instead of checking two conditions
within the old psw.

Also move clearing of the CIF_ENABLED_WAIT bit to the early interrupt
handler, which in turn makes arch_vcpu_is_preempted() also a bit more
precise, since the flag is now cleared before interrupt handlers have
been called.
Reviewed-by: default avatarSven Schnelle <svens@linux.ibm.com>
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
parent f96f41aa
...@@ -23,6 +23,5 @@ extern struct device_attribute dev_attr_idle_count; ...@@ -23,6 +23,5 @@ extern struct device_attribute dev_attr_idle_count;
extern struct device_attribute dev_attr_idle_time_us; extern struct device_attribute dev_attr_idle_time_us;
void psw_idle(struct s390_idle_data *data, unsigned long psw_mask); void psw_idle(struct s390_idle_data *data, unsigned long psw_mask);
void psw_idle_exit(void);
#endif /* _S390_IDLE_H */ #endif /* _S390_IDLE_H */
...@@ -28,7 +28,6 @@ void account_idle_time_irq(void) ...@@ -28,7 +28,6 @@ void account_idle_time_irq(void)
u64 cycles_new[8]; u64 cycles_new[8];
int i; int i;
clear_cpu_flag(CIF_ENABLED_WAIT);
if (smp_cpu_mtid) { if (smp_cpu_mtid) {
stcctm(MT_DIAG, smp_cpu_mtid, cycles_new); stcctm(MT_DIAG, smp_cpu_mtid, cycles_new);
for (i = 0; i < smp_cpu_mtid; i++) for (i = 0; i < smp_cpu_mtid; i++)
......
...@@ -136,7 +136,7 @@ void noinstr do_io_irq(struct pt_regs *regs) ...@@ -136,7 +136,7 @@ void noinstr do_io_irq(struct pt_regs *regs)
{ {
irqentry_state_t state = irqentry_enter(regs); irqentry_state_t state = irqentry_enter(regs);
struct pt_regs *old_regs = set_irq_regs(regs); struct pt_regs *old_regs = set_irq_regs(regs);
int from_idle; bool from_idle;
irq_enter_rcu(); irq_enter_rcu();
...@@ -146,7 +146,7 @@ void noinstr do_io_irq(struct pt_regs *regs) ...@@ -146,7 +146,7 @@ void noinstr do_io_irq(struct pt_regs *regs)
current->thread.last_break = regs->last_break; current->thread.last_break = regs->last_break;
} }
from_idle = !user_mode(regs) && regs->psw.addr == (unsigned long)psw_idle_exit; from_idle = test_and_clear_cpu_flag(CIF_ENABLED_WAIT);
if (from_idle) if (from_idle)
account_idle_time_irq(); account_idle_time_irq();
...@@ -171,7 +171,7 @@ void noinstr do_ext_irq(struct pt_regs *regs) ...@@ -171,7 +171,7 @@ void noinstr do_ext_irq(struct pt_regs *regs)
{ {
irqentry_state_t state = irqentry_enter(regs); irqentry_state_t state = irqentry_enter(regs);
struct pt_regs *old_regs = set_irq_regs(regs); struct pt_regs *old_regs = set_irq_regs(regs);
int from_idle; bool from_idle;
irq_enter_rcu(); irq_enter_rcu();
...@@ -185,7 +185,7 @@ void noinstr do_ext_irq(struct pt_regs *regs) ...@@ -185,7 +185,7 @@ void noinstr do_ext_irq(struct pt_regs *regs)
regs->int_parm = S390_lowcore.ext_params; regs->int_parm = S390_lowcore.ext_params;
regs->int_parm_long = S390_lowcore.ext_params2; regs->int_parm_long = S390_lowcore.ext_params2;
from_idle = !user_mode(regs) && regs->psw.addr == (unsigned long)psw_idle_exit; from_idle = test_and_clear_cpu_flag(CIF_ENABLED_WAIT);
if (from_idle) if (from_idle)
account_idle_time_irq(); account_idle_time_irq();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment