Skip to content

Commit 0d3eb74

Browse files
committed
Merge tag 'urgent-rcu.2023.04.07a' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu
Pull RCU fix from Paul McKenney: "This fixes a pair of bugs in which an improbable but very real sequence of events can cause kfree_rcu() to be a bit too quick about freeing the memory passed to it. It turns out that this pair of bugs is about two years old, and so this is not a v6.3 regression. However: (1) It just started showing up in the wild and (2) Its consequences are dire, so its fix needs to go in sooner rather than later. Testing is of course being upgraded, and the upgraded tests detect this situation very quickly. But to the best of my knowledge right now, the tests are not particularly urgent and will thus most likely show up in the v6.5 merge window (the one after this coming one). Kudos to Ziwei Dai and his group for tracking this one down the hard way!" * tag 'urgent-rcu.2023.04.07a' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu: rcu/kvfree: Avoid freeing new kfree_rcu() memory after old grace period
2 parents dfc1915 + 5da7cb1 commit 0d3eb74

File tree

1 file changed

+19
-8
lines changed

1 file changed

+19
-8
lines changed

kernel/rcu/tree.c

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3024,6 +3024,18 @@ need_offload_krc(struct kfree_rcu_cpu *krcp)
30243024
return !!READ_ONCE(krcp->head);
30253025
}
30263026

3027+
static bool
3028+
need_wait_for_krwp_work(struct kfree_rcu_cpu_work *krwp)
3029+
{
3030+
int i;
3031+
3032+
for (i = 0; i < FREE_N_CHANNELS; i++)
3033+
if (!list_empty(&krwp->bulk_head_free[i]))
3034+
return true;
3035+
3036+
return !!krwp->head_free;
3037+
}
3038+
30273039
static int krc_count(struct kfree_rcu_cpu *krcp)
30283040
{
30293041
int sum = atomic_read(&krcp->head_count);
@@ -3107,15 +3119,14 @@ static void kfree_rcu_monitor(struct work_struct *work)
31073119
for (i = 0; i < KFREE_N_BATCHES; i++) {
31083120
struct kfree_rcu_cpu_work *krwp = &(krcp->krw_arr[i]);
31093121

3110-
// Try to detach bulk_head or head and attach it over any
3111-
// available corresponding free channel. It can be that
3112-
// a previous RCU batch is in progress, it means that
3113-
// immediately to queue another one is not possible so
3114-
// in that case the monitor work is rearmed.
3115-
if ((!list_empty(&krcp->bulk_head[0]) && list_empty(&krwp->bulk_head_free[0])) ||
3116-
(!list_empty(&krcp->bulk_head[1]) && list_empty(&krwp->bulk_head_free[1])) ||
3117-
(READ_ONCE(krcp->head) && !krwp->head_free)) {
3122+
// Try to detach bulk_head or head and attach it, only when
3123+
// all channels are free. Any channel is not free means at krwp
3124+
// there is on-going rcu work to handle krwp's free business.
3125+
if (need_wait_for_krwp_work(krwp))
3126+
continue;
31183127

3128+
// kvfree_rcu_drain_ready() might handle this krcp, if so give up.
3129+
if (need_offload_krc(krcp)) {
31193130
// Channel 1 corresponds to the SLAB-pointer bulk path.
31203131
// Channel 2 corresponds to vmalloc-pointer bulk path.
31213132
for (j = 0; j < FREE_N_CHANNELS; j++) {

0 commit comments

Comments
 (0)