Commit 04e49d92 authored by Marco Elver's avatar Marco Elver Committed by Peter Zijlstra
Browse files

sched: Enable context analysis for core.c and fair.c



This demonstrates a larger conversion to use Clang's context
analysis. The benefit is additional static checking of locking rules,
along with better documentation.

Notably, kernel/sched contains sufficiently complex synchronization
patterns, and application to core.c & fair.c demonstrates that the
latest Clang version has become powerful enough to start applying this
to more complex subsystems (with some modest annotations and changes).

Signed-off-by: default avatarMarco Elver <elver@google.com>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20251219154418.3592607-37-elver@google.com
parent dc36d55d
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -2094,9 +2094,9 @@ static inline int _cond_resched(void)
	_cond_resched();			\
})

extern int __cond_resched_lock(spinlock_t *lock);
extern int __cond_resched_rwlock_read(rwlock_t *lock);
extern int __cond_resched_rwlock_write(rwlock_t *lock);
extern int __cond_resched_lock(spinlock_t *lock) __must_hold(lock);
extern int __cond_resched_rwlock_read(rwlock_t *lock) __must_hold_shared(lock);
extern int __cond_resched_rwlock_write(rwlock_t *lock) __must_hold(lock);

#define MIGHT_RESCHED_RCU_SHIFT		8
#define MIGHT_RESCHED_PREEMPT_MASK	((1U << MIGHT_RESCHED_RCU_SHIFT) - 1)
+3 −1
Original line number Diff line number Diff line
@@ -738,10 +738,12 @@ static inline int thread_group_empty(struct task_struct *p)
		(thread_group_leader(p) && !thread_group_empty(p))

extern struct sighand_struct *lock_task_sighand(struct task_struct *task,
						unsigned long *flags);
						unsigned long *flags)
	__acquires(&task->sighand->siglock);

static inline void unlock_task_sighand(struct task_struct *task,
						unsigned long *flags)
	__releases(&task->sighand->siglock)
{
	spin_unlock_irqrestore(&task->sighand->siglock, *flags);
}
+5 −1
Original line number Diff line number Diff line
@@ -214,15 +214,19 @@ static inline struct vm_struct *task_stack_vm_area(const struct task_struct *t)
 * write_lock_irq(&tasklist_lock), neither inside nor outside.
 */
static inline void task_lock(struct task_struct *p)
	__acquires(&p->alloc_lock)
{
	spin_lock(&p->alloc_lock);
}

static inline void task_unlock(struct task_struct *p)
	__releases(&p->alloc_lock)
{
	spin_unlock(&p->alloc_lock);
}

DEFINE_GUARD(task_lock, struct task_struct *, task_lock(_T), task_unlock(_T))
DEFINE_LOCK_GUARD_1(task_lock, struct task_struct, task_lock(_T->lock), task_unlock(_T->lock))
DECLARE_LOCK_GUARD_1_ATTRS(task_lock, __acquires(&_T->alloc_lock), __releases(&(*(struct task_struct **)_T)->alloc_lock))
#define class_task_lock_constructor(_T) WITH_LOCK_GUARD_1_ATTRS(task_lock, _T)

#endif /* _LINUX_SCHED_TASK_H */
+3 −0
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ extern void wake_up_q(struct wake_q_head *head);
/* Spin unlock helpers to unlock and call wake_up_q with preempt disabled */
static inline
void raw_spin_unlock_wake(raw_spinlock_t *lock, struct wake_q_head *wake_q)
	__releases(lock)
{
	guard(preempt)();
	raw_spin_unlock(lock);
@@ -77,6 +78,7 @@ void raw_spin_unlock_wake(raw_spinlock_t *lock, struct wake_q_head *wake_q)

static inline
void raw_spin_unlock_irq_wake(raw_spinlock_t *lock, struct wake_q_head *wake_q)
	__releases(lock)
{
	guard(preempt)();
	raw_spin_unlock_irq(lock);
@@ -89,6 +91,7 @@ void raw_spin_unlock_irq_wake(raw_spinlock_t *lock, struct wake_q_head *wake_q)
static inline
void raw_spin_unlock_irqrestore_wake(raw_spinlock_t *lock, unsigned long flags,
				     struct wake_q_head *wake_q)
	__releases(lock)
{
	guard(preempt)();
	raw_spin_unlock_irqrestore(lock, flags);
+3 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0

CONTEXT_ANALYSIS_core.o := y
CONTEXT_ANALYSIS_fair.o := y

# The compilers are complaining about unused variables inside an if(0) scope
# block. This is daft, shut them up.
ccflags-y += $(call cc-disable-warning, unused-but-set-variable)
Loading