Skip to content

Commit ec9d4f1

Browse files
kudureranganathPeter Zijlstra
authored andcommitted
sched/proxy: Remove PROXY_WAKING
Now that the proxy path uses ->is_blocked, use the '->is_blocked && !->blocked_on' state instead of PROXY_WAKING. Notably, this is where a blocked_on relation is broken but the donor task might still need a return migration. Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://patch.msgid.link/20260526113322.596522894%40infradead.org
1 parent be365ce commit ec9d4f1

4 files changed

Lines changed: 7 additions & 53 deletions

File tree

include/linux/sched.h

Lines changed: 2 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2205,19 +2205,10 @@ extern int __cond_resched_rwlock_write(rwlock_t *lock) __must_hold(lock);
22052205

22062206
#ifndef CONFIG_PREEMPT_RT
22072207

2208-
/*
2209-
* With proxy exec, if a task has been proxy-migrated, it may be a donor
2210-
* on a cpu that it can't actually run on. Thus we need a special state
2211-
* to denote that the task is being woken, but that it needs to be
2212-
* evaluated for return-migration before it is run. So if the task is
2213-
* blocked_on PROXY_WAKING, return migrate it before running it.
2214-
*/
2215-
#define PROXY_WAKING ((struct mutex *)(-1L))
2216-
22172208
static inline struct mutex *__get_task_blocked_on(struct task_struct *p)
22182209
{
22192210
lockdep_assert_held_once(&p->blocked_lock);
2220-
return p->blocked_on == PROXY_WAKING ? NULL : p->blocked_on;
2211+
return p->blocked_on;
22212212
}
22222213

22232214
static inline void __set_task_blocked_on(struct task_struct *p, struct mutex *m)
@@ -2245,7 +2236,7 @@ static inline void __clear_task_blocked_on(struct task_struct *p, struct mutex *
22452236
* blocked_on relationships, but make sure we are not
22462237
* clearing the relationship with a different lock.
22472238
*/
2248-
WARN_ON_ONCE(m && p->blocked_on && p->blocked_on != m && p->blocked_on != PROXY_WAKING);
2239+
WARN_ON_ONCE(m && p->blocked_on && p->blocked_on != m);
22492240
p->blocked_on = NULL;
22502241
}
22512242

@@ -2254,35 +2245,6 @@ static inline void clear_task_blocked_on(struct task_struct *p, struct mutex *m)
22542245
guard(raw_spinlock_irqsave)(&p->blocked_lock);
22552246
__clear_task_blocked_on(p, m);
22562247
}
2257-
2258-
static inline void __set_task_blocked_on_waking(struct task_struct *p, struct mutex *m)
2259-
{
2260-
/* Currently we serialize blocked_on under the task::blocked_lock */
2261-
lockdep_assert_held_once(&p->blocked_lock);
2262-
2263-
if (!sched_proxy_exec()) {
2264-
__clear_task_blocked_on(p, m);
2265-
return;
2266-
}
2267-
2268-
/* Don't set PROXY_WAKING if blocked_on was already cleared */
2269-
if (!p->blocked_on)
2270-
return;
2271-
/*
2272-
* There may be cases where we set PROXY_WAKING on tasks that were
2273-
* already set to waking, but make sure we are not changing
2274-
* the relationship with a different lock.
2275-
*/
2276-
WARN_ON_ONCE(m && p->blocked_on != m && p->blocked_on != PROXY_WAKING);
2277-
p->blocked_on = PROXY_WAKING;
2278-
}
2279-
2280-
static inline void set_task_blocked_on_waking(struct task_struct *p, struct mutex *m)
2281-
{
2282-
guard(raw_spinlock_irqsave)(&p->blocked_lock);
2283-
__set_task_blocked_on_waking(p, m);
2284-
}
2285-
22862248
#else
22872249
static inline void __clear_task_blocked_on(struct task_struct *p, struct rt_mutex *m)
22882250
{
@@ -2291,14 +2253,6 @@ static inline void __clear_task_blocked_on(struct task_struct *p, struct rt_mute
22912253
static inline void clear_task_blocked_on(struct task_struct *p, struct rt_mutex *m)
22922254
{
22932255
}
2294-
2295-
static inline void __set_task_blocked_on_waking(struct task_struct *p, struct rt_mutex *m)
2296-
{
2297-
}
2298-
2299-
static inline void set_task_blocked_on_waking(struct task_struct *p, struct rt_mutex *m)
2300-
{
2301-
}
23022256
#endif /* !CONFIG_PREEMPT_RT */
23032257

23042258
static __always_inline bool need_resched(void)

kernel/locking/mutex.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,7 +1044,7 @@ static noinline void __sched __mutex_unlock_slowpath(struct mutex *lock, unsigne
10441044
next_lock = __get_task_blocked_on(donor);
10451045
if (next_lock == lock) {
10461046
next = get_task_struct(donor);
1047-
__set_task_blocked_on_waking(donor, next_lock);
1047+
__clear_task_blocked_on(next, lock);
10481048
current->blocked_donor = NULL;
10491049
}
10501050
raw_spin_unlock(&donor->blocked_lock);
@@ -1060,7 +1060,7 @@ static noinline void __sched __mutex_unlock_slowpath(struct mutex *lock, unsigne
10601060

10611061
raw_spin_lock_nested(&next->blocked_lock, SINGLE_DEPTH_NESTING);
10621062
debug_mutex_wake_waiter(lock, waiter);
1063-
__set_task_blocked_on_waking(next, lock);
1063+
__clear_task_blocked_on(next, lock);
10641064
raw_spin_unlock(&next->blocked_lock);
10651065

10661066
}

kernel/locking/ww_mutex.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ __ww_mutex_die(struct MUTEX *lock, struct MUTEX_WAITER *waiter,
324324
* blocked_on to PROXY_WAKING. Otherwise we can see
325325
* circular blocked_on relationships that can't resolve.
326326
*/
327-
set_task_blocked_on_waking(waiter->task, lock);
327+
clear_task_blocked_on(waiter->task, lock);
328328
wake_q_add(wake_q, waiter->task);
329329
}
330330

@@ -383,7 +383,7 @@ static bool __ww_mutex_wound(struct MUTEX *lock,
383383
* are waking the mutex owner, who may be currently
384384
* blocked on a different mutex.
385385
*/
386-
set_task_blocked_on_waking(owner, NULL);
386+
clear_task_blocked_on(owner, NULL);
387387
wake_q_add(wake_q, owner);
388388
}
389389
return true;

kernel/sched/core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6872,7 +6872,7 @@ find_proxy_task(struct rq *rq, struct task_struct *donor, struct rq_flags *rf)
68726872
for (p = donor; p->is_blocked; p = owner) {
68736873
/* if its PROXY_WAKING, do return migration or run if current */
68746874
struct mutex *mutex = p->blocked_on;
6875-
if (!mutex || mutex == PROXY_WAKING) {
6875+
if (!mutex) {
68766876
clear_task_blocked_on(p, mutex);
68776877
if (task_current(rq, p)) {
68786878
p->is_blocked = 0;

0 commit comments

Comments
 (0)