Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

sched_ext: Simplify UP support by enabling sched_class->balance() in UP

On SMP, SCX performs dispatch from sched_class->balance(). As balance() was
not available in UP, it instead called the internal balance function from
put_prev_task_scx() and pick_next_task_scx() to emulate the effect, which is
rather nasty.

Enabling sched_class->balance() on UP shouldn't cause any meaningful
overhead. Enable balance() on UP and drop the ugly workaround.

Signed-off-by: Tejun Heo <tj@kernel.org>
Suggested-by: Peter Zijlstra <peterz@infradead.org>
Acked-by: David Vernet <void@manifault.com>

+3 -44
+1 -3
kernel/sched/core.c
··· 5857 5857 static void put_prev_task_balance(struct rq *rq, struct task_struct *prev, 5858 5858 struct rq_flags *rf) 5859 5859 { 5860 - #ifdef CONFIG_SMP 5861 5860 const struct sched_class *start_class = prev->sched_class; 5862 5861 const struct sched_class *class; 5863 5862 ··· 5879 5880 * a runnable task of @class priority or higher. 5880 5881 */ 5881 5882 for_active_class_range(class, start_class, &idle_sched_class) { 5882 - if (class->balance(rq, prev, rf)) 5883 + if (class->balance && class->balance(rq, prev, rf)) 5883 5884 break; 5884 5885 } 5885 - #endif 5886 5886 5887 5887 put_prev_task(rq, prev); 5888 5888
+1 -40
kernel/sched/ext.c
··· 2616 2616 return has_tasks; 2617 2617 } 2618 2618 2619 - #ifdef CONFIG_SMP 2620 2619 static int balance_scx(struct rq *rq, struct task_struct *prev, 2621 2620 struct rq_flags *rf) 2622 2621 { ··· 2649 2650 2650 2651 return ret; 2651 2652 } 2652 - #endif 2653 2653 2654 2654 static void set_next_task_scx(struct rq *rq, struct task_struct *p, bool first) 2655 2655 { ··· 2717 2719 2718 2720 static void put_prev_task_scx(struct rq *rq, struct task_struct *p) 2719 2721 { 2720 - #ifndef CONFIG_SMP 2721 - /* 2722 - * UP workaround. 2723 - * 2724 - * Because SCX may transfer tasks across CPUs during dispatch, dispatch 2725 - * is performed from its balance operation which isn't called in UP. 2726 - * Let's work around by calling it from the operations which come right 2727 - * after. 2728 - * 2729 - * 1. If the prev task is on SCX, pick_next_task() calls 2730 - * .put_prev_task() right after. As .put_prev_task() is also called 2731 - * from other places, we need to distinguish the calls which can be 2732 - * done by looking at the previous task's state - if still queued or 2733 - * dequeued with %SCX_DEQ_SLEEP, the caller must be pick_next_task(). 2734 - * This case is handled here. 2735 - * 2736 - * 2. If the prev task is not on SCX, the first following call into SCX 2737 - * will be .pick_next_task(), which is covered by calling 2738 - * balance_scx() from pick_next_task_scx(). 2739 - * 2740 - * Note that we can't merge the first case into the second as 2741 - * balance_scx() must be called before the previous SCX task goes 2742 - * through put_prev_task_scx(). 2743 - * 2744 - * @rq is pinned and can't be unlocked. As UP doesn't transfer tasks 2745 - * around, balance_one() doesn't need to. 2746 - */ 2747 - if (p->scx.flags & (SCX_TASK_QUEUED | SCX_TASK_DEQD_FOR_SLEEP)) 2748 - balance_one(rq, p, true); 2749 - #endif 2750 - 2751 2722 update_curr_scx(rq); 2752 2723 2753 2724 /* see dequeue_task_scx() on why we skip when !QUEUED */ ··· 2773 2806 static struct task_struct *pick_next_task_scx(struct rq *rq) 2774 2807 { 2775 2808 struct task_struct *p; 2776 - 2777 - #ifndef CONFIG_SMP 2778 - /* UP workaround - see the comment at the head of put_prev_task_scx() */ 2779 - if (unlikely(rq->curr->sched_class != &ext_sched_class)) 2780 - balance_one(rq, rq->curr, true); 2781 - #endif 2782 2809 2783 2810 p = first_local_task(rq); 2784 2811 if (!p) ··· 3634 3673 3635 3674 .wakeup_preempt = wakeup_preempt_scx, 3636 3675 3676 + .balance = balance_scx, 3637 3677 .pick_next_task = pick_next_task_scx, 3638 3678 3639 3679 .put_prev_task = put_prev_task_scx, ··· 3643 3681 .switch_class = switch_class_scx, 3644 3682 3645 3683 #ifdef CONFIG_SMP 3646 - .balance = balance_scx, 3647 3684 .select_task_rq = select_task_rq_scx, 3648 3685 .task_woken = task_woken_scx, 3649 3686 .set_cpus_allowed = set_cpus_allowed_scx,
+1 -1
kernel/sched/sched.h
··· 2361 2361 2362 2362 void (*wakeup_preempt)(struct rq *rq, struct task_struct *p, int flags); 2363 2363 2364 + int (*balance)(struct rq *rq, struct task_struct *prev, struct rq_flags *rf); 2364 2365 struct task_struct *(*pick_next_task)(struct rq *rq); 2365 2366 2366 2367 void (*put_prev_task)(struct rq *rq, struct task_struct *p); ··· 2370 2369 void (*switch_class)(struct rq *rq, struct task_struct *next); 2371 2370 2372 2371 #ifdef CONFIG_SMP 2373 - int (*balance)(struct rq *rq, struct task_struct *prev, struct rq_flags *rf); 2374 2372 int (*select_task_rq)(struct task_struct *p, int task_cpu, int flags); 2375 2373 2376 2374 struct task_struct * (*pick_task)(struct rq *rq);