Skip to content

Commit c87488a

Browse files
etsalhtejun
authored andcommitted
sched/ext: convert scx_tasks_lock to raw spinlock
Update scx_task_locks so that it's safe to lock/unlock in a non-sleepable context in PREEMPT_RT kernels. scx_task_locks is (non-raw) spinlock used to protect the list of tasks under SCX. This list is updated during from finish_task_switch(), which cannot sleep. Regular spinlocks can be locked in such a context in non-RT kernels, but are sleepable under when CONFIG_PREEMPT_RT=y. Convert scx_task_locks into a raw spinlock, which is not sleepable even on RT kernels. Sample backtrace: <TASK> dump_stack_lvl+0x83/0xa0 __might_resched+0x14a/0x200 rt_spin_lock+0x61/0x1c0 ? sched_ext_dead+0x2d/0xf0 ? lock_release+0xc6/0x280 sched_ext_dead+0x2d/0xf0 ? srso_alias_return_thunk+0x5/0xfbef5 finish_task_switch.isra.0+0x254/0x360 __schedule+0x584/0x11d0 ? srso_alias_return_thunk+0x5/0xfbef5 ? srso_alias_return_thunk+0x5/0xfbef5 ? tick_nohz_idle_exit+0x7e/0x120 schedule_idle+0x23/0x40 cpu_startup_entry+0x29/0x30 start_secondary+0xf8/0x100 common_startup_64+0x13e/0x148 </TASK> Signed-off-by: Emil Tsalapatis <[email protected]> Signed-off-by: Tejun Heo <[email protected]>
1 parent 5f02151 commit c87488a

File tree

1 file changed

+8
-8
lines changed

1 file changed

+8
-8
lines changed

kernel/sched/ext.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ static struct scx_sched __rcu *scx_root;
2525
* guarantee system safety. Maintain a dedicated task list which contains every
2626
* task between its fork and eventual free.
2727
*/
28-
static DEFINE_SPINLOCK(scx_tasks_lock);
28+
static DEFINE_RAW_SPINLOCK(scx_tasks_lock);
2929
static LIST_HEAD(scx_tasks);
3030

3131
/* ops enable/disable */
@@ -476,7 +476,7 @@ static void scx_task_iter_start(struct scx_task_iter *iter)
476476
BUILD_BUG_ON(__SCX_DSQ_ITER_ALL_FLAGS &
477477
((1U << __SCX_DSQ_LNODE_PRIV_SHIFT) - 1));
478478

479-
spin_lock_irq(&scx_tasks_lock);
479+
raw_spin_lock_irq(&scx_tasks_lock);
480480

481481
iter->cursor = (struct sched_ext_entity){ .flags = SCX_TASK_CURSOR };
482482
list_add(&iter->cursor.tasks_node, &scx_tasks);
@@ -507,14 +507,14 @@ static void scx_task_iter_unlock(struct scx_task_iter *iter)
507507
__scx_task_iter_rq_unlock(iter);
508508
if (iter->list_locked) {
509509
iter->list_locked = false;
510-
spin_unlock_irq(&scx_tasks_lock);
510+
raw_spin_unlock_irq(&scx_tasks_lock);
511511
}
512512
}
513513

514514
static void __scx_task_iter_maybe_relock(struct scx_task_iter *iter)
515515
{
516516
if (!iter->list_locked) {
517-
spin_lock_irq(&scx_tasks_lock);
517+
raw_spin_lock_irq(&scx_tasks_lock);
518518
iter->list_locked = true;
519519
}
520520
}
@@ -2940,9 +2940,9 @@ void scx_post_fork(struct task_struct *p)
29402940
}
29412941
}
29422942

2943-
spin_lock_irq(&scx_tasks_lock);
2943+
raw_spin_lock_irq(&scx_tasks_lock);
29442944
list_add_tail(&p->scx.tasks_node, &scx_tasks);
2945-
spin_unlock_irq(&scx_tasks_lock);
2945+
raw_spin_unlock_irq(&scx_tasks_lock);
29462946

29472947
percpu_up_read(&scx_fork_rwsem);
29482948
}
@@ -2966,9 +2966,9 @@ void sched_ext_free(struct task_struct *p)
29662966
{
29672967
unsigned long flags;
29682968

2969-
spin_lock_irqsave(&scx_tasks_lock, flags);
2969+
raw_spin_lock_irqsave(&scx_tasks_lock, flags);
29702970
list_del_init(&p->scx.tasks_node);
2971-
spin_unlock_irqrestore(&scx_tasks_lock, flags);
2971+
raw_spin_unlock_irqrestore(&scx_tasks_lock, flags);
29722972

29732973
/*
29742974
* @p is off scx_tasks and wholly ours. scx_enable()'s READY -> ENABLED

0 commit comments

Comments
 (0)