Commit 61706251 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'sched-urgent-2026-03-01' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull scheduler fixes from Ingo Molnar:

 - Fix zero_vruntime tracking when there's a single task running

 - Fix slice protection logic

 - Fix the ->vprot logic for reniced tasks

 - Fix lag clamping in mixed slice workloads

 - Fix objtool uaccess warning (and bug) in the
   !CONFIG_RSEQ_SLICE_EXTENSION case caused by unexpected un-inlining,
   which triggers with older compilers

 - Fix a comment in the rseq registration rseq_size bound check code

 - Fix a legacy RSEQ ABI quirk that handled 32-byte area sizes
   differently, which special size we now reached naturally and want to
   avoid. The visible ugliness of the new reserved field will be avoided
   the next time the RSEQ area is extended.

* tag 'sched-urgent-2026-03-01' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  rseq: slice ext: Ensure rseq feature size differs from original rseq size
  rseq: Clarify rseq registration rseq_size bound check comment
  sched/core: Fix wakeup_preempt's next_class tracking
  rseq: Mark rseq_arm_slice_extension_timer() __always_inline
  sched/fair: Fix lag clamp
  sched/eevdf: Update se->vprot in reweight_entity()
  sched/fair: Only set slice protection at pick time
  sched/fair: Fix zero_vruntime tracking
parents cb36eabc 3b68df97
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@
#include <linux/dax.h>
#include <linux/uaccess.h>
#include <uapi/linux/rseq.h>
#include <linux/rseq.h>
#include <asm/param.h>
#include <asm/page.h>

@@ -286,7 +287,7 @@ create_elf_tables(struct linux_binprm *bprm, const struct elfhdr *exec,
	}
#ifdef CONFIG_RSEQ
	NEW_AUX_ENT(AT_RSEQ_FEATURE_SIZE, offsetof(struct rseq, end));
	NEW_AUX_ENT(AT_RSEQ_ALIGN, __alignof__(struct rseq));
	NEW_AUX_ENT(AT_RSEQ_ALIGN, rseq_alloc_align());
#endif
#undef NEW_AUX_ENT
	/* AT_NULL is zero; clear the rest too */
+12 −0
Original line number Diff line number Diff line
@@ -146,6 +146,18 @@ static inline void rseq_fork(struct task_struct *t, u64 clone_flags)
		t->rseq = current->rseq;
}

/*
 * Value returned by getauxval(AT_RSEQ_ALIGN) and expected by rseq
 * registration. This is the active rseq area size rounded up to next
 * power of 2, which guarantees that the rseq structure will always be
 * aligned on the nearest power of two large enough to contain it, even
 * as it grows.
 */
static inline unsigned int rseq_alloc_align(void)
{
	return 1U << get_count_order(offsetof(struct rseq, end));
}

#else /* CONFIG_RSEQ */
static inline void rseq_handle_slowpath(struct pt_regs *regs) { }
static inline void rseq_signal_deliver(struct ksignal *ksig, struct pt_regs *regs) { }
+4 −4
Original line number Diff line number Diff line
@@ -216,10 +216,10 @@ static __always_inline bool rseq_grant_slice_extension(bool work_pending)
}

#else /* CONFIG_RSEQ_SLICE_EXTENSION */
static inline bool rseq_slice_extension_enabled(void) { return false; }
static inline bool rseq_arm_slice_extension_timer(void) { return false; }
static inline void rseq_slice_clear_grant(struct task_struct *t) { }
static inline bool rseq_grant_slice_extension(bool work_pending) { return false; }
static __always_inline bool rseq_slice_extension_enabled(void) { return false; }
static __always_inline bool rseq_arm_slice_extension_timer(void) { return false; }
static __always_inline void rseq_slice_clear_grant(struct task_struct *t) { }
static __always_inline bool rseq_grant_slice_extension(bool work_pending) { return false; }
#endif /* !CONFIG_RSEQ_SLICE_EXTENSION */

bool rseq_debug_update_user_cs(struct task_struct *t, struct pt_regs *regs, unsigned long csaddr);
+1 −0
Original line number Diff line number Diff line
@@ -579,6 +579,7 @@ struct sched_entity {
	u64				deadline;
	u64				min_vruntime;
	u64				min_slice;
	u64				max_slice;

	struct list_head		group_node;
	unsigned char			on_rq;
+22 −4
Original line number Diff line number Diff line
@@ -87,10 +87,17 @@ struct rseq_slice_ctrl {
};

/*
 * struct rseq is aligned on 4 * 8 bytes to ensure it is always
 * contained within a single cache-line.
 * The original size and alignment of the allocation for struct rseq is
 * 32 bytes.
 *
 * A single struct rseq per thread is allowed.
 * The allocation size needs to be greater or equal to
 * max(getauxval(AT_RSEQ_FEATURE_SIZE), 32), and the allocation needs to
 * be aligned on max(getauxval(AT_RSEQ_ALIGN), 32).
 *
 * As an alternative, userspace is allowed to use both the original size
 * and alignment of 32 bytes for backward compatibility.
 *
 * A single active struct rseq registration per thread is allowed.
 */
struct rseq {
	/*
@@ -180,10 +187,21 @@ struct rseq {
	 */
	struct rseq_slice_ctrl slice_ctrl;

	/*
	 * Before rseq became extensible, its original size was 32 bytes even
	 * though the active rseq area was only 20 bytes.
	 * Exposing a 32 bytes feature size would make life needlessly painful
	 * for userspace. Therefore, add a reserved byte after byte 32
	 * to bump the rseq feature size from 32 to 33.
	 * The next field to be added to the rseq area will be larger
	 * than one byte, and will replace this reserved byte.
	 */
	__u8 __reserved;

	/*
	 * Flexible array member at end of structure, after last feature field.
	 */
	char end[];
} __attribute__((aligned(4 * sizeof(__u64))));
} __attribute__((aligned(32)));

#endif /* _UAPI_LINUX_RSEQ_H */
Loading