Commit 21e4543a authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull slab fix from Vlastimil Babka:

 - Stable fix for kmem_cache_destroy() called from a WQ_MEM_RECLAIM
   workqueue causing a warning due to the new kvfree_rcu_barrier()
   (Uladzislau Rezki)

* tag 'slab-for-6.14-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab:
  mm/slab/kvfree_rcu: Switch to WQ_MEM_RECLAIM wq
parents d4fd25b6 dfd3df31
Loading
Loading
Loading
Loading
+10 −4
Original line number Diff line number Diff line
@@ -1304,6 +1304,8 @@ module_param(rcu_min_cached_objs, int, 0444);
static int rcu_delay_page_cache_fill_msec = 5000;
module_param(rcu_delay_page_cache_fill_msec, int, 0444);

static struct workqueue_struct *rcu_reclaim_wq;

/* Maximum number of jiffies to wait before draining a batch. */
#define KFREE_DRAIN_JIFFIES (5 * HZ)
#define KFREE_N_BATCHES 2
@@ -1632,10 +1634,10 @@ __schedule_delayed_monitor_work(struct kfree_rcu_cpu *krcp)
	if (delayed_work_pending(&krcp->monitor_work)) {
		delay_left = krcp->monitor_work.timer.expires - jiffies;
		if (delay < delay_left)
			mod_delayed_work(system_unbound_wq, &krcp->monitor_work, delay);
			mod_delayed_work(rcu_reclaim_wq, &krcp->monitor_work, delay);
		return;
	}
	queue_delayed_work(system_unbound_wq, &krcp->monitor_work, delay);
	queue_delayed_work(rcu_reclaim_wq, &krcp->monitor_work, delay);
}

static void
@@ -1733,7 +1735,7 @@ kvfree_rcu_queue_batch(struct kfree_rcu_cpu *krcp)
			// "free channels", the batch can handle. Break
			// the loop since it is done with this CPU thus
			// queuing an RCU work is _always_ success here.
			queued = queue_rcu_work(system_unbound_wq, &krwp->rcu_work);
			queued = queue_rcu_work(rcu_reclaim_wq, &krwp->rcu_work);
			WARN_ON_ONCE(!queued);
			break;
		}
@@ -1883,7 +1885,7 @@ run_page_cache_worker(struct kfree_rcu_cpu *krcp)
	if (rcu_scheduler_active == RCU_SCHEDULER_RUNNING &&
			!atomic_xchg(&krcp->work_in_progress, 1)) {
		if (atomic_read(&krcp->backoff_page_cache_fill)) {
			queue_delayed_work(system_unbound_wq,
			queue_delayed_work(rcu_reclaim_wq,
				&krcp->page_cache_work,
					msecs_to_jiffies(rcu_delay_page_cache_fill_msec));
		} else {
@@ -2120,6 +2122,10 @@ void __init kvfree_rcu_init(void)
	int i, j;
	struct shrinker *kfree_rcu_shrinker;

	rcu_reclaim_wq = alloc_workqueue("kvfree_rcu_reclaim",
			WQ_UNBOUND | WQ_MEM_RECLAIM, 0);
	WARN_ON(!rcu_reclaim_wq);

	/* Clamp it to [0:100] seconds interval. */
	if (rcu_delay_page_cache_fill_msec < 0 ||
		rcu_delay_page_cache_fill_msec > 100 * MSEC_PER_SEC) {