powerpc: Provide a way to defer perf counter work until interrupts are enabled
Because 64-bit powerpc uses lazy (soft) interrupt disabling, it is possible for a performance monitor exception to come in when the kernel thinks interrupts are disabled (i.e. when they are soft-disabled but hard-enabled). In such a situation the performance monitor exception handler might have some processing to do (such as process wakeups) which can't be done in what is effectively an NMI handler. This provides a way to defer that work until interrupts get enabled, either in raw_local_irq_restore() or by returning from an interrupt handler to code that had interrupts enabled. We have a per-processor flag that indicates that there is work pending to do when interrupts subsequently get re-enabled. This flag is checked in the interrupt return path and in raw_local_irq_restore(), and if it is set, perf_counter_do_pending() is called to do the pending work. Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
@@ -104,6 +104,13 @@ static inline notrace void set_soft_enabled(unsigned long enable)
|
||||
: : "r" (enable), "i" (offsetof(struct paca_struct, soft_enabled)));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PERF_COUNTERS
|
||||
notrace void __weak perf_counter_do_pending(void)
|
||||
{
|
||||
set_perf_counter_pending(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
notrace void raw_local_irq_restore(unsigned long en)
|
||||
{
|
||||
/*
|
||||
@@ -135,6 +142,9 @@ notrace void raw_local_irq_restore(unsigned long en)
|
||||
iseries_handle_interrupts();
|
||||
}
|
||||
|
||||
if (get_perf_counter_pending())
|
||||
perf_counter_do_pending();
|
||||
|
||||
/*
|
||||
* if (get_paca()->hard_enabled) return;
|
||||
* But again we need to take care that gcc gets hard_enabled directly
|
||||
|
Reference in New Issue
Block a user