Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'rcu/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu

Pull RCU fixes from Paul McKenney:
"I must confess that this past merge window was not RCU's best showing.
This series contains three more fixes for RCU regressions:

1. A fix to __DECLARE_TRACE_RCU() that causes it to act as an
interrupt from idle rather than as a task switch from idle.
This change is needed due to the recent use of _rcuidle()
tracepoints that can be invoked from interrupt handlers as well
as from idle. Without this fix, invoking _rcuidle() tracepoints
from interrupt handlers results in splats and (more seriously)
confusion on RCU's part as to whether a given CPU is idle or not.
This confusion can in turn result in too-short grace periods and
therefore random memory corruption.

2. A fix to a subtle deadlock that could result due to RCU doing
a wakeup while holding one of its rcu_node structure's locks.
Although the probability of occurrence is low, it really
does happen. The fix, courtesy of Steven Rostedt, uses
irq_work_queue() to avoid the deadlock.

3. A fix to a silent deadlock (invisible to lockdep) due to the
interaction of timeouts posted by RCU debug code enabled by
CONFIG_PROVE_RCU_DELAY=y, grace-period initialization, and CPU
hotplug operations. This will not occur in production kernels,
but really does occur in randconfig testing. Diagnosis courtesy
of Steven Rostedt"

* 'rcu/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu:
rcu: Fix deadlock with CPU hotplug, RCU GP init, and timer migration
rcu: Don't call wakeup() with rcu_node structure ->lock held
trace: Allow idle-safe tracepoints to be called from irq

+22 -6
+2 -2
include/linux/tracepoint.h
··· 145 145 TP_PROTO(data_proto), \ 146 146 TP_ARGS(data_args), \ 147 147 TP_CONDITION(cond), \ 148 - rcu_idle_exit(), \ 149 - rcu_idle_enter()); \ 148 + rcu_irq_enter(), \ 149 + rcu_irq_exit()); \ 150 150 } 151 151 #else 152 152 #define __DECLARE_TRACE_RCU(name, proto, args, cond, data_proto, data_args)
+1
init/Kconfig
··· 431 431 config TREE_RCU 432 432 bool "Tree-based hierarchical RCU" 433 433 depends on !PREEMPT && SMP 434 + select IRQ_WORK 434 435 help 435 436 This option selects the RCU implementation that is 436 437 designed for very large SMP system with hundreds or
+17 -4
kernel/rcutree.c
··· 1451 1451 rnp->grphi, rnp->qsmask); 1452 1452 raw_spin_unlock_irq(&rnp->lock); 1453 1453 #ifdef CONFIG_PROVE_RCU_DELAY 1454 - if ((prandom_u32() % (rcu_num_nodes * 8)) == 0 && 1454 + if ((prandom_u32() % (rcu_num_nodes + 1)) == 0 && 1455 1455 system_state == SYSTEM_RUNNING) 1456 - schedule_timeout_uninterruptible(2); 1456 + udelay(200); 1457 1457 #endif /* #ifdef CONFIG_PROVE_RCU_DELAY */ 1458 1458 cond_resched(); 1459 1459 } ··· 1613 1613 } 1614 1614 } 1615 1615 1616 + static void rsp_wakeup(struct irq_work *work) 1617 + { 1618 + struct rcu_state *rsp = container_of(work, struct rcu_state, wakeup_work); 1619 + 1620 + /* Wake up rcu_gp_kthread() to start the grace period. */ 1621 + wake_up(&rsp->gp_wq); 1622 + } 1623 + 1616 1624 /* 1617 1625 * Start a new RCU grace period if warranted, re-initializing the hierarchy 1618 1626 * in preparation for detecting the next grace period. The caller must hold ··· 1645 1637 } 1646 1638 rsp->gp_flags = RCU_GP_FLAG_INIT; 1647 1639 1648 - /* Wake up rcu_gp_kthread() to start the grace period. */ 1649 - wake_up(&rsp->gp_wq); 1640 + /* 1641 + * We can't do wakeups while holding the rnp->lock, as that 1642 + * could cause possible deadlocks with the rq->lock. Deter 1643 + * the wakeup to interrupt context. 1644 + */ 1645 + irq_work_queue(&rsp->wakeup_work); 1650 1646 } 1651 1647 1652 1648 /* ··· 3247 3235 3248 3236 rsp->rda = rda; 3249 3237 init_waitqueue_head(&rsp->gp_wq); 3238 + init_irq_work(&rsp->wakeup_work, rsp_wakeup); 3250 3239 rnp = rsp->level[rcu_num_lvls - 1]; 3251 3240 for_each_possible_cpu(i) { 3252 3241 while (i > rnp->grphi)
+2
kernel/rcutree.h
··· 27 27 #include <linux/threads.h> 28 28 #include <linux/cpumask.h> 29 29 #include <linux/seqlock.h> 30 + #include <linux/irq_work.h> 30 31 31 32 /* 32 33 * Define shape of hierarchy based on NR_CPUS, CONFIG_RCU_FANOUT, and ··· 443 442 char *name; /* Name of structure. */ 444 443 char abbr; /* Abbreviated name. */ 445 444 struct list_head flavors; /* List of RCU flavors. */ 445 + struct irq_work wakeup_work; /* Postponed wakeups */ 446 446 }; 447 447 448 448 /* Values for rcu_state structure's gp_flags field. */