public inbox for virtualization@lists.linux-foundation.org
 help / color / mirror / Atom feed
From: Peter Zijlstra <peterz@infradead.org>
To: Thomas Gleixner <tglx@kernel.org>
Cc: "Jiri Slaby" <jirislaby@kernel.org>,
	"Matthieu Baerts" <matttbe@kernel.org>,
	"Stefan Hajnoczi" <stefanha@redhat.com>,
	"Stefano Garzarella" <sgarzare@redhat.com>,
	kvm@vger.kernel.org, virtualization@lists.linux.dev,
	Netdev <netdev@vger.kernel.org>,
	rcu@vger.kernel.org, "MPTCP Linux" <mptcp@lists.linux.dev>,
	"Linux Kernel" <linux-kernel@vger.kernel.org>,
	"Shinichiro Kawasaki" <shinichiro.kawasaki@wdc.com>,
	"Paul E. McKenney" <paulmck@kernel.org>,
	"Dave Hansen" <dave.hansen@linux.intel.com>,
	"luto@kernel.org" <luto@kernel.org>,
	"Michal Koutný" <MKoutny@suse.com>,
	"Waiman Long" <longman@redhat.com>,
	"Marco Elver" <elver@google.com>
Subject: Re: Stalls when starting a VSOCK listening socket: soft lockups, RCU stalls, timeout
Date: Fri, 6 Mar 2026 16:24:58 +0100	[thread overview]
Message-ID: <20260306152458.GT606826@noisy.programming.kicks-ass.net> (raw)
In-Reply-To: <87qzpx2sck.ffs@tglx>

On Fri, Mar 06, 2026 at 10:57:15AM +0100, Thomas Gleixner wrote:

> I tried with tons of test cases which stress test mmcid with threads and
> failed.

Are some of those in tools/testing/selftests ?

Anyway, I was going over that code, and I noticed that there seems to be
inconsistent locking for mm_mm_cid::pcpu.

There's a bunch of sites that state we need rq->lock for remote access;
but then things like sched_mm_cid_fork() and sched_mm_cid_exit() seem to
think that holding mm_cid->lock is sufficient.

This doesn't make sense to me, but maybe I missed something.

Anyway, I cobbled together the below, and that builds and boots and
passes everything in tools/testing/selftests/rseq.


YMMV

---
diff --git a/include/linux/rseq_types.h b/include/linux/rseq_types.h
index da5fa6f40294..df2b4629cbfd 100644
--- a/include/linux/rseq_types.h
+++ b/include/linux/rseq_types.h
@@ -2,9 +2,12 @@
 #ifndef _LINUX_RSEQ_TYPES_H
 #define _LINUX_RSEQ_TYPES_H
 
+#include <linux/compiler_types.h>
 #include <linux/irq_work_types.h>
 #include <linux/types.h>
 #include <linux/workqueue_types.h>
+#include <linux/mutex.h>
+#include <asm/percpu.h>
 
 #ifdef CONFIG_RSEQ
 struct rseq;
@@ -145,8 +148,14 @@ struct sched_mm_cid {
  *		while a task with a CID is running
  */
 struct mm_cid_pcpu {
-	unsigned int	cid;
-}____cacheline_aligned_in_smp;
+	unsigned int		cid;
+} ____cacheline_aligned_in_smp;
+
+/*
+ * See helpers in kernel/sched/sched.h that convert
+ * from __rq_lockp(rq) to RQ_LOCK.
+ */
+token_context_lock(RQ_LOCK);
 
 /**
  * struct mm_mm_cid - Storage for per MM CID data
@@ -167,7 +176,7 @@ struct mm_cid_pcpu {
  */
 struct mm_mm_cid {
 	/* Hotpath read mostly members */
-	struct mm_cid_pcpu	__percpu *pcpu;
+	struct mm_cid_pcpu	__percpu *pcpu __guarded_by(RQ_LOCK);
 	unsigned int		mode;
 	unsigned int		max_cids;
 
@@ -179,11 +188,11 @@ struct mm_mm_cid {
 	struct mutex		mutex;
 
 	/* Low frequency modified */
-	unsigned int		nr_cpus_allowed;
-	unsigned int		users;
-	unsigned int		pcpu_thrs;
-	unsigned int		update_deferred;
-}____cacheline_aligned_in_smp;
+	unsigned int		nr_cpus_allowed __guarded_by(&lock);
+	unsigned int		users		__guarded_by(&lock);
+	unsigned int		pcpu_thrs	__guarded_by(&lock);
+	unsigned int		update_deferred __guarded_by(&lock);
+} ____cacheline_aligned_in_smp;
 #else /* CONFIG_SCHED_MM_CID */
 struct mm_mm_cid { };
 struct sched_mm_cid { };
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 2b571e640372..f7c03c9c4fd0 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -5335,7 +5335,7 @@ context_switch(struct rq *rq, struct task_struct *prev,
 		}
 	}
 
-	mm_cid_switch_to(prev, next);
+	mm_cid_switch_to(rq, prev, next);
 
 	/*
 	 * Tell rseq that the task was scheduled in. Must be after
@@ -10511,6 +10511,7 @@ void call_trace_sched_update_nr_running(struct rq *rq, int count)
  * fork(), exit() and affinity changes
  */
 static void __mm_update_max_cids(struct mm_mm_cid *mc)
+	__must_hold(&mc->lock)
 {
 	unsigned int opt_cids, max_cids;
 
@@ -10523,15 +10524,17 @@ static void __mm_update_max_cids(struct mm_mm_cid *mc)
 }
 
 static inline unsigned int mm_cid_calc_pcpu_thrs(struct mm_mm_cid *mc)
+	__must_hold(&mc->lock)
 {
 	unsigned int opt_cids;
 
 	opt_cids = min(mc->nr_cpus_allowed, mc->users);
 	/* Has to be at least 1 because 0 indicates PCPU mode off */
-	return max(min(opt_cids - opt_cids / 4, num_possible_cpus() / 2), 1);
+	return max(min(opt_cids - (opt_cids / 4), num_possible_cpus() / 2), 1);
 }
 
 static bool mm_update_max_cids(struct mm_struct *mm)
+	__must_hold(&mm->mm_cid.lock)
 {
 	struct mm_mm_cid *mc = &mm->mm_cid;
 	bool percpu = cid_on_cpu(mc->mode);
@@ -10558,6 +10561,7 @@ static bool mm_update_max_cids(struct mm_struct *mm)
 		return false;
 
 	/* Flip the mode and set the transition flag to bridge the transfer */
+	WARN_ON_ONCE(mc->mode & MM_CID_TRANSIT);
 	WRITE_ONCE(mc->mode, mc->mode ^ (MM_CID_TRANSIT | MM_CID_ONCPU));
 	/*
 	 * Order the store against the subsequent fixups so that
@@ -10568,16 +10572,28 @@ static bool mm_update_max_cids(struct mm_struct *mm)
 	return true;
 }
 
+/*
+ * Silly helper because we cannot express that mm_mm_cid::users is updated
+ * while holding both mutex and lock and can thus be read while holding
+ * either.
+ */
+static __always_inline unsigned int mm_cid_users(struct mm_struct *mm)
+	__must_hold(&mm->mm_cid.mutex)
+{
+	__assume_ctx_lock(&mm->mm_cid.lock);
+	return mm->mm_cid.users;
+}
+
 static inline void mm_update_cpus_allowed(struct mm_struct *mm, const struct cpumask *affmsk)
 {
 	struct cpumask *mm_allowed;
 	struct mm_mm_cid *mc;
 	unsigned int weight;
 
-	if (!mm || !READ_ONCE(mm->mm_cid.users))
+	if (!mm || !data_race(READ_ONCE(mm->mm_cid.users)))
 		return;
 	/*
-	 * mm::mm_cid::mm_cpus_allowed is the superset of each threads
+	 * mm::mm_cid::mm_cpus_allowed is the superset of each thread's
 	 * allowed CPUs mask which means it can only grow.
 	 */
 	mc = &mm->mm_cid;
@@ -10609,6 +10625,7 @@ static inline void mm_update_cpus_allowed(struct mm_struct *mm, const struct cpu
 
 static inline void mm_cid_complete_transit(struct mm_struct *mm, unsigned int mode)
 {
+	WARN_ON_ONCE(!(mm->mm_cid.mode & MM_CID_TRANSIT));
 	/*
 	 * Ensure that the store removing the TRANSIT bit cannot be
 	 * reordered by the CPU before the fixups have been completed.
@@ -10633,11 +10650,12 @@ static void mm_cid_fixup_cpus_to_tasks(struct mm_struct *mm)
 
 	/* Walk the CPUs and fixup all stale CIDs */
 	for_each_possible_cpu(cpu) {
-		struct mm_cid_pcpu *pcp = per_cpu_ptr(mm->mm_cid.pcpu, cpu);
 		struct rq *rq = cpu_rq(cpu);
+		struct mm_cid_pcpu *pcp;
 
 		/* Remote access to mm::mm_cid::pcpu requires rq_lock */
 		guard(rq_lock_irq)(rq);
+		pcp = mm_cid_pcpu(&mm->mm_cid, rq);
 		/* Is the CID still owned by the CPU? */
 		if (cid_on_cpu(pcp->cid)) {
 			/*
@@ -10675,6 +10693,7 @@ static bool mm_cid_fixup_task_to_cpu(struct task_struct *t, struct mm_struct *mm
 {
 	/* Remote access to mm::mm_cid::pcpu requires rq_lock */
 	guard(task_rq_lock)(t);
+	__assume_ctx_lock(RQ_LOCK);
 	/* If the task is not active it is not in the users count */
 	if (!t->mm_cid.active)
 		return false;
@@ -10689,6 +10708,7 @@ static bool mm_cid_fixup_task_to_cpu(struct task_struct *t, struct mm_struct *mm
 }
 
 static void mm_cid_do_fixup_tasks_to_cpus(struct mm_struct *mm)
+	__must_hold(&mm->mm_cid.mutex)
 {
 	struct task_struct *p, *t;
 	unsigned int users;
@@ -10703,7 +10723,7 @@ static void mm_cid_do_fixup_tasks_to_cpus(struct mm_struct *mm)
 	 * The caller has already transferred. The newly incoming task is
 	 * already accounted for, but not yet visible.
 	 */
-	users = mm->mm_cid.users - 2;
+	users = mm_cid_users(mm) - 2;
 	if (!users)
 		return;
 
@@ -10727,18 +10747,19 @@ static void mm_cid_do_fixup_tasks_to_cpus(struct mm_struct *mm)
 	}
 }
 
-static void mm_cid_fixup_tasks_to_cpus(void)
+static void mm_cid_fixup_tasks_to_cpus(struct mm_struct *mm)
+	__must_hold(mm->mm_cid.mutex)
 {
-	struct mm_struct *mm = current->mm;
-
 	mm_cid_do_fixup_tasks_to_cpus(mm);
 	mm_cid_complete_transit(mm, MM_CID_ONCPU);
 }
 
 static bool sched_mm_cid_add_user(struct task_struct *t, struct mm_struct *mm)
+	__must_hold(&mm->mm_cid.mutex)
+	__must_hold(&mm->mm_cid.lock)
 {
 	t->mm_cid.active = 1;
-	mm->mm_cid.users++;
+	mm->mm_cid.users++; /* mutex && lock */
 	return mm_update_max_cids(mm);
 }
 
@@ -10750,8 +10771,9 @@ void sched_mm_cid_fork(struct task_struct *t)
 	WARN_ON_ONCE(!mm || t->mm_cid.cid != MM_CID_UNSET);
 
 	guard(mutex)(&mm->mm_cid.mutex);
-	scoped_guard(raw_spinlock_irq, &mm->mm_cid.lock) {
-		struct mm_cid_pcpu *pcp = this_cpu_ptr(mm->mm_cid.pcpu);
+	scoped_guard(rq_lock_irq, this_rq()) {
+		struct mm_cid_pcpu *pcp = mm_cid_pcpu(&mm->mm_cid, this_rq());
+		guard(raw_spinlock)(&mm->mm_cid.lock);
 
 		/* First user ? */
 		if (!mm->mm_cid.users) {
@@ -10777,7 +10799,7 @@ void sched_mm_cid_fork(struct task_struct *t)
 	}
 
 	if (percpu) {
-		mm_cid_fixup_tasks_to_cpus();
+		mm_cid_fixup_tasks_to_cpus(mm);
 	} else {
 		mm_cid_fixup_cpus_to_tasks(mm);
 		t->mm_cid.cid = mm_get_cid(mm);
@@ -10785,6 +10807,8 @@ void sched_mm_cid_fork(struct task_struct *t)
 }
 
 static bool sched_mm_cid_remove_user(struct task_struct *t)
+	__must_hold(t->mm->mm_cid.mutex)
+	__must_hold(t->mm->mm_cid.lock)
 {
 	t->mm_cid.active = 0;
 	scoped_guard(preempt) {
@@ -10792,11 +10816,13 @@ static bool sched_mm_cid_remove_user(struct task_struct *t)
 		t->mm_cid.cid = cid_from_transit_cid(t->mm_cid.cid);
 		mm_unset_cid_on_task(t);
 	}
-	t->mm->mm_cid.users--;
+	t->mm->mm_cid.users--; /* mutex && lock */
 	return mm_update_max_cids(t->mm);
 }
 
 static bool __sched_mm_cid_exit(struct task_struct *t)
+	__must_hold(t->mm->mm_cid.mutex)
+	__must_hold(t->mm->mm_cid.lock)
 {
 	struct mm_struct *mm = t->mm;
 
@@ -10837,8 +10863,9 @@ void sched_mm_cid_exit(struct task_struct *t)
 	 */
 	scoped_guard(mutex, &mm->mm_cid.mutex) {
 		/* mm_cid::mutex is sufficient to protect mm_cid::users */
-		if (likely(mm->mm_cid.users > 1)) {
-			scoped_guard(raw_spinlock_irq, &mm->mm_cid.lock) {
+		if (likely(mm_cid_users(mm) > 1)) {
+			scoped_guard(rq_lock_irq, this_rq()) {
+				guard(raw_spinlock)(&mm->mm_cid.lock);
 				if (!__sched_mm_cid_exit(t))
 					return;
 				/*
@@ -10847,16 +10874,17 @@ void sched_mm_cid_exit(struct task_struct *t)
 				 * TRANSIT bit. If the CID is owned by the CPU
 				 * then drop it.
 				 */
-				mm_drop_cid_on_cpu(mm, this_cpu_ptr(mm->mm_cid.pcpu));
+				mm_drop_cid_on_cpu(mm, mm_cid_pcpu(&mm->mm_cid, this_rq()));
 			}
 			mm_cid_fixup_cpus_to_tasks(mm);
 			return;
 		}
 		/* Last user */
-		scoped_guard(raw_spinlock_irq, &mm->mm_cid.lock) {
+		scoped_guard(rq_lock_irq, this_rq()) {
+			guard(raw_spinlock)(&mm->mm_cid.lock);
 			/* Required across execve() */
 			if (t == current)
-				mm_cid_transit_to_task(t, this_cpu_ptr(mm->mm_cid.pcpu));
+				mm_cid_transit_to_task(t, mm_cid_pcpu(&mm->mm_cid, this_rq()));
 			/* Ignore mode change. There is nothing to do. */
 			sched_mm_cid_remove_user(t);
 		}
@@ -10893,7 +10921,7 @@ static void mm_cid_work_fn(struct work_struct *work)
 
 	guard(mutex)(&mm->mm_cid.mutex);
 	/* Did the last user task exit already? */
-	if (!mm->mm_cid.users)
+	if (!mm_cid_users(mm))
 		return;
 
 	scoped_guard(raw_spinlock_irq, &mm->mm_cid.lock) {
@@ -10924,13 +10952,14 @@ static void mm_cid_irq_work(struct irq_work *work)
 
 void mm_init_cid(struct mm_struct *mm, struct task_struct *p)
 {
-	mm->mm_cid.max_cids = 0;
 	mm->mm_cid.mode = 0;
-	mm->mm_cid.nr_cpus_allowed = p->nr_cpus_allowed;
-	mm->mm_cid.users = 0;
-	mm->mm_cid.pcpu_thrs = 0;
-	mm->mm_cid.update_deferred = 0;
-	raw_spin_lock_init(&mm->mm_cid.lock);
+	mm->mm_cid.max_cids = 0;
+	scoped_guard (raw_spinlock_init, &mm->mm_cid.lock) {
+		mm->mm_cid.nr_cpus_allowed = p->nr_cpus_allowed;
+		mm->mm_cid.users = 0;
+		mm->mm_cid.pcpu_thrs = 0;
+		mm->mm_cid.update_deferred = 0;
+	}
 	mutex_init(&mm->mm_cid.mutex);
 	mm->mm_cid.irq_work = IRQ_WORK_INIT_HARD(mm_cid_irq_work);
 	INIT_WORK(&mm->mm_cid.work, mm_cid_work_fn);
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index fd36ae390520..8c761822d6b2 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -3870,13 +3870,39 @@ static __always_inline void mm_cid_update_task_cid(struct task_struct *t, unsign
 	}
 }
 
-static __always_inline void mm_cid_update_pcpu_cid(struct mm_struct *mm, unsigned int cid)
+/*
+ * Helpers to convert from __rq_lockp(rq) to RQ_LOCK intermediate.
+ */
+static __always_inline
+void mm_cid_update_pcpu_cid(struct rq *rq, struct mm_struct *mm, unsigned int cid)
+	__must_hold(__rq_lockp(rq))
 {
+	__assume_ctx_lock(RQ_LOCK);
+	lockdep_assert(rq->cpu == smp_processor_id());
 	__this_cpu_write(mm->mm_cid.pcpu->cid, cid);
 }
 
-static __always_inline void mm_cid_from_cpu(struct task_struct *t, unsigned int cpu_cid,
-					    unsigned int mode)
+static __always_inline
+unsigned int mm_cid_pcpu_cid(struct rq *rq, struct mm_struct *mm)
+	__must_hold(__rq_lockp(rq))
+{
+	__assume_ctx_lock(RQ_LOCK);
+	lockdep_assert(rq->cpu == smp_processor_id());
+	return __this_cpu_read(mm->mm_cid.pcpu->cid);
+}
+
+static __always_inline
+struct mm_cid_pcpu *mm_cid_pcpu(struct mm_mm_cid *mc, struct rq *rq)
+	__must_hold(__rq_lockp(rq))
+
+{
+	__assume_ctx_lock(RQ_LOCK);
+	return per_cpu_ptr(mc->pcpu, rq->cpu);
+}
+
+static __always_inline void mm_cid_from_cpu(struct rq *rq, struct task_struct *t,
+					    unsigned int cpu_cid, unsigned int mode)
+	__must_hold(__rq_lockp(rq))
 {
 	unsigned int max_cids, tcid = t->mm_cid.cid;
 	struct mm_struct *mm = t->mm;
@@ -3906,12 +3932,13 @@ static __always_inline void mm_cid_from_cpu(struct task_struct *t, unsigned int
 		if (mode & MM_CID_TRANSIT)
 			cpu_cid = cpu_cid_to_cid(cpu_cid) | MM_CID_TRANSIT;
 	}
-	mm_cid_update_pcpu_cid(mm, cpu_cid);
+	mm_cid_update_pcpu_cid(rq, mm, cpu_cid);
 	mm_cid_update_task_cid(t, cpu_cid);
 }
 
-static __always_inline void mm_cid_from_task(struct task_struct *t, unsigned int cpu_cid,
-					     unsigned int mode)
+static __always_inline void mm_cid_from_task(struct rq *rq, struct task_struct *t,
+					     unsigned int cpu_cid, unsigned int mode)
+	__must_hold(__rq_lockp(rq))
 {
 	unsigned int max_cids, tcid = t->mm_cid.cid;
 	struct mm_struct *mm = t->mm;
@@ -3920,7 +3947,7 @@ static __always_inline void mm_cid_from_task(struct task_struct *t, unsigned int
 	/* Optimize for the common case, where both have the ONCPU bit clear */
 	if (likely(cid_on_task(tcid | cpu_cid))) {
 		if (likely(tcid < max_cids)) {
-			mm_cid_update_pcpu_cid(mm, tcid);
+			mm_cid_update_pcpu_cid(rq, mm, tcid);
 			return;
 		}
 		/* Try to converge into the optimal CID space */
@@ -3929,7 +3956,7 @@ static __always_inline void mm_cid_from_task(struct task_struct *t, unsigned int
 		/* Hand over or drop the CPU owned CID */
 		if (cid_on_cpu(cpu_cid)) {
 			if (cid_on_task(tcid))
-				mm_drop_cid_on_cpu(mm, this_cpu_ptr(mm->mm_cid.pcpu));
+				mm_drop_cid_on_cpu(mm, mm_cid_pcpu(&mm->mm_cid, rq));
 			else
 				tcid = cpu_cid_to_cid(cpu_cid);
 		}
@@ -3939,11 +3966,12 @@ static __always_inline void mm_cid_from_task(struct task_struct *t, unsigned int
 		/* Set the transition mode flag if required */
 		tcid |= mode & MM_CID_TRANSIT;
 	}
-	mm_cid_update_pcpu_cid(mm, tcid);
+	mm_cid_update_pcpu_cid(rq, mm, tcid);
 	mm_cid_update_task_cid(t, tcid);
 }
 
-static __always_inline void mm_cid_schedin(struct task_struct *next)
+static __always_inline void mm_cid_schedin(struct rq *rq, struct task_struct *next)
+	__must_hold(__rq_lockp(rq))
 {
 	struct mm_struct *mm = next->mm;
 	unsigned int cpu_cid, mode;
@@ -3951,15 +3979,16 @@ static __always_inline void mm_cid_schedin(struct task_struct *next)
 	if (!next->mm_cid.active)
 		return;
 
-	cpu_cid = __this_cpu_read(mm->mm_cid.pcpu->cid);
+	cpu_cid = mm_cid_pcpu_cid(rq, mm);
 	mode = READ_ONCE(mm->mm_cid.mode);
 	if (likely(!cid_on_cpu(mode)))
-		mm_cid_from_task(next, cpu_cid, mode);
+		mm_cid_from_task(rq, next, cpu_cid, mode);
 	else
-		mm_cid_from_cpu(next, cpu_cid, mode);
+		mm_cid_from_cpu(rq, next, cpu_cid, mode);
 }
 
-static __always_inline void mm_cid_schedout(struct task_struct *prev)
+static __always_inline void mm_cid_schedout(struct rq *rq, struct task_struct *prev)
+	__must_hold(__rq_lockp(rq))
 {
 	struct mm_struct *mm = prev->mm;
 	unsigned int mode, cid;
@@ -3980,7 +4009,7 @@ static __always_inline void mm_cid_schedout(struct task_struct *prev)
 			cid = cid_to_cpu_cid(cid);
 
 		/* Update both so that the next schedule in goes into the fast path */
-		mm_cid_update_pcpu_cid(mm, cid);
+		mm_cid_update_pcpu_cid(rq, mm, cid);
 		prev->mm_cid.cid = cid;
 	} else {
 		mm_drop_cid(mm, cid);
@@ -3988,10 +4017,12 @@ static __always_inline void mm_cid_schedout(struct task_struct *prev)
 	}
 }
 
-static inline void mm_cid_switch_to(struct task_struct *prev, struct task_struct *next)
+static inline void mm_cid_switch_to(struct rq *rq, struct task_struct *prev,
+				    struct task_struct *next)
+	__must_hold(__rq_lockp(rq))
 {
-	mm_cid_schedout(prev);
-	mm_cid_schedin(next);
+	mm_cid_schedout(rq, prev);
+	mm_cid_schedin(rq, next);
 }
 
 #else /* !CONFIG_SCHED_MM_CID: */

  parent reply	other threads:[~2026-03-06 15:25 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-06 11:54 Stalls when starting a VSOCK listening socket: soft lockups, RCU stalls, timeout Matthieu Baerts
2026-02-06 16:38 ` Stefano Garzarella
2026-02-06 17:13   ` Matthieu Baerts
2026-02-26 10:37 ` Jiri Slaby
2026-03-02  5:28   ` Jiri Slaby
2026-03-02 11:46     ` Peter Zijlstra
2026-03-02 14:30       ` Waiman Long
2026-03-05  7:00       ` Jiri Slaby
2026-03-05 11:53         ` Jiri Slaby
2026-03-05 12:20           ` Jiri Slaby
2026-03-05 16:16             ` Thomas Gleixner
2026-03-05 17:33               ` Jiri Slaby
2026-03-05 19:25                 ` Thomas Gleixner
2026-03-06  5:48                   ` Jiri Slaby
2026-03-06  9:57                     ` Thomas Gleixner
2026-03-06 10:16                       ` Jiri Slaby
2026-03-06 16:28                         ` Thomas Gleixner
2026-03-06 11:06                       ` Matthieu Baerts
2026-03-06 16:57                         ` Matthieu Baerts
2026-03-06 18:31                           ` Jiri Slaby
2026-03-06 18:44                             ` Matthieu Baerts
2026-03-06 21:40                           ` Matthieu Baerts
2026-03-06 15:24                       ` Peter Zijlstra [this message]
2026-03-07  9:01                         ` Thomas Gleixner
2026-03-07 22:29                           ` Thomas Gleixner
2026-03-08  9:15                             ` Thomas Gleixner
2026-03-08 16:55                               ` Jiri Slaby
2026-03-08 16:58                               ` Thomas Gleixner
2026-03-08 17:23                                 ` Matthieu Baerts
2026-03-09  8:43                                   ` Thomas Gleixner
2026-03-09 12:23                                     ` Matthieu Baerts
2026-03-10  8:09                                       ` Thomas Gleixner
2026-03-10  8:20                                         ` Thomas Gleixner
2026-03-10  8:56                                         ` Jiri Slaby
2026-03-10  9:00                                           ` Jiri Slaby
2026-03-10 10:03                                             ` Thomas Gleixner
2026-03-10 10:06                                               ` Thomas Gleixner
2026-03-10 11:24                                                 ` Matthieu Baerts
2026-03-10 11:54                                                   ` Peter Zijlstra
2026-03-10 12:28                                                     ` Thomas Gleixner
2026-03-10 13:40                                                       ` Matthieu Baerts
2026-03-10 13:47                                                         ` Thomas Gleixner
2026-03-10 15:51                                                           ` Matthieu Baerts
2026-03-03 13:23   ` Matthieu Baerts
2026-03-05  6:46     ` Jiri Slaby

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260306152458.GT606826@noisy.programming.kicks-ass.net \
    --to=peterz@infradead.org \
    --cc=MKoutny@suse.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=elver@google.com \
    --cc=jirislaby@kernel.org \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=longman@redhat.com \
    --cc=luto@kernel.org \
    --cc=matttbe@kernel.org \
    --cc=mptcp@lists.linux.dev \
    --cc=netdev@vger.kernel.org \
    --cc=paulmck@kernel.org \
    --cc=rcu@vger.kernel.org \
    --cc=sgarzare@redhat.com \
    --cc=shinichiro.kawasaki@wdc.com \
    --cc=stefanha@redhat.com \
    --cc=tglx@kernel.org \
    --cc=virtualization@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox