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: Split schedule_deferred() into locked and unlocked variants

schedule_deferred() currently requires the rq lock to be held so that it can
use scheduler hooks for efficiency when available. However, there are cases
where deferred actions need to be scheduled from contexts that don't hold the
rq lock.

Split into schedule_deferred() which can be called from any context and just
queues irq_work, and schedule_deferred_locked() which requires the rq lock and
can optimize by using scheduler hooks when available. Update the existing call
site to use the _locked variant.

Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
Signed-off-by: Tejun Heo <tj@kernel.org>

Tejun Heo 180b4ac3 2d697e5f

+24 -9
+24 -9
kernel/sched/ext.c
··· 775 775 * schedule_deferred - Schedule execution of deferred actions on an rq 776 776 * @rq: target rq 777 777 * 778 - * Schedule execution of deferred actions on @rq. Must be called with @rq 779 - * locked. Deferred actions are executed with @rq locked but unpinned, and thus 780 - * can unlock @rq to e.g. migrate tasks to other rqs. 778 + * Schedule execution of deferred actions on @rq. Deferred actions are executed 779 + * with @rq locked but unpinned, and thus can unlock @rq to e.g. migrate tasks 780 + * to other rqs. 781 781 */ 782 782 static void schedule_deferred(struct rq *rq) 783 + { 784 + /* 785 + * Queue an irq work. They are executed on IRQ re-enable which may take 786 + * a bit longer than the scheduler hook in schedule_deferred_locked(). 787 + */ 788 + irq_work_queue(&rq->scx.deferred_irq_work); 789 + } 790 + 791 + /** 792 + * schedule_deferred_locked - Schedule execution of deferred actions on an rq 793 + * @rq: target rq 794 + * 795 + * Schedule execution of deferred actions on @rq. Equivalent to 796 + * schedule_deferred() but requires @rq to be locked and can be more efficient. 797 + */ 798 + static void schedule_deferred_locked(struct rq *rq) 783 799 { 784 800 lockdep_assert_rq_held(rq); 785 801 ··· 828 812 } 829 813 830 814 /* 831 - * No scheduler hooks available. Queue an irq work. They are executed on 832 - * IRQ re-enable which may take a bit longer than the scheduler hooks. 833 - * The above WAKEUP and BALANCE paths should cover most of the cases and 834 - * the time to IRQ re-enable shouldn't be long. 815 + * No scheduler hooks available. Use the generic irq_work path. The 816 + * above WAKEUP and BALANCE paths should cover most of the cases and the 817 + * time to IRQ re-enable shouldn't be long. 835 818 */ 836 - irq_work_queue(&rq->scx.deferred_irq_work); 819 + schedule_deferred(rq); 837 820 } 838 821 839 822 /** ··· 1226 1211 WARN_ON_ONCE(p->scx.dsq || !list_empty(&p->scx.dsq_list.node)); 1227 1212 list_add_tail(&p->scx.dsq_list.node, 1228 1213 &rq->scx.ddsp_deferred_locals); 1229 - schedule_deferred(rq); 1214 + schedule_deferred_locked(rq); 1230 1215 return; 1231 1216 } 1232 1217