mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
rcu: don't process callbacks when holding a rcu_read_lock()
Some keyhandlers are calling process_pending_softirqs() while holding a rcu_read_lock(). This is wrong, as process_pending_softirqs() might activate rcu calls which should not happen inside a rcu_read_lock(). For that purpose modify process_pending_softirqs() to not allow rcu callback processing when a rcu_read_lock() is being held. Signed-off-by: Juergen Gross <jgross@suse.com> Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
53594c7bd1
commit
cef21210fb
1 file changed
+10
-2
+10
-2
@@ -29,6 +29,7 @@ static void __do_softirq(unsigned long ignore_mask)
|
||||
{
|
||||
unsigned int i, cpu;
|
||||
unsigned long pending;
|
||||
bool rcu_allowed = !(ignore_mask & (1ul << RCU_SOFTIRQ));
|
||||
|
||||
for ( ; ; )
|
||||
{
|
||||
@@ -38,7 +39,7 @@ static void __do_softirq(unsigned long ignore_mask)
|
||||
*/
|
||||
cpu = smp_processor_id();
|
||||
|
||||
if ( rcu_pending(cpu) )
|
||||
if ( rcu_allowed && rcu_pending(cpu) )
|
||||
rcu_check_callbacks(cpu);
|
||||
|
||||
if ( ((pending = (softirq_pending(cpu) & ~ignore_mask)) == 0)
|
||||
@@ -53,9 +54,16 @@ static void __do_softirq(unsigned long ignore_mask)
|
||||
|
||||
void process_pending_softirqs(void)
|
||||
{
|
||||
unsigned long ignore_mask = (1ul << SCHEDULE_SOFTIRQ) |
|
||||
(1ul << SCHED_SLAVE_SOFTIRQ);
|
||||
|
||||
/* Block RCU processing in case of rcu_read_lock() held. */
|
||||
if ( preempt_count() )
|
||||
ignore_mask |= 1ul << RCU_SOFTIRQ;
|
||||
|
||||
ASSERT(!in_irq() && local_irq_is_enabled());
|
||||
/* Do not enter scheduler as it can preempt the calling context. */
|
||||
__do_softirq((1ul << SCHEDULE_SOFTIRQ) | (1ul << SCHED_SLAVE_SOFTIRQ));
|
||||
__do_softirq(ignore_mask);
|
||||
}
|
||||
|
||||
void do_softirq(void)
|
||||
|
||||