| @@ -2268,6 +2268,7 @@ static void move_local_task_to_local_dsq(struct scx_sched *sch, · 2267 unmodified lines |
| 2268 | | 2268 | |
| 2269 | /** | 2269 | /** |
| 2270 | * move_remote_task_to_local_dsq - Move a task from a foreign rq to a local DSQ | 2270 | * move_remote_task_to_local_dsq - Move a task from a foreign rq to a local DSQ |
| | 2271 | * @sch: scheduler placing @p |
| 2271 | * @p: task to move | 2272 | * @p: task to move |
| 2272 | * @enq_flags: %SCX_ENQ_* | 2273 | * @enq_flags: %SCX_ENQ_* |
| 2273 | * @src_rq: rq to move the task from, locked on entry, released on return | 2274 | * @src_rq: rq to move the task from, locked on entry, released on return |
| @@ -2275,7 +2276,8 @@ static void move_local_task_to_local_dsq(struct scx_sched *sch, · 1 unmodified line |
| 2275 | * | 2276 | * |
| 2276 | * Move @p which is currently on @src_rq to @dst_rq's local DSQ. | 2277 | * Move @p which is currently on @src_rq to @dst_rq's local DSQ. |
| 2277 | */ | 2278 | */ |
| 2278 | static void move_remote_task_to_local_dsq(struct task_struct *p, u64 enq_flags, | 2279 | static void move_remote_task_to_local_dsq(struct scx_sched *sch, |
| | 2280 | struct task_struct *p, u64 enq_flags, |
| 2279 | struct rq *src_rq, struct rq *dst_rq) | 2281 | struct rq *src_rq, struct rq *dst_rq) |
| 2280 | { | 2282 | { |
| 2281 | lockdep_assert_rq_held(src_rq); | 2283 | lockdep_assert_rq_held(src_rq); |
| @@ -2291,15 +2293,19 @@ static void move_remote_task_to_local_dsq(struct task_struct *p, u64 enq_flags, · 9 unmodified lines |
| 2291 | switch_rq_lock(src_rq, dst_rq); | 2293 | switch_rq_lock(src_rq, dst_rq); |
| 2292 | | 2294 | |
| 2293 | /* | 2295 | /* |
| 2294 | * We want to pass scx-specific enq_flags but activate_task() will | 2296 | * activate_task() below truncates enq_flags to 32 bits and re-derives |
| 2295 | * truncate the upper 32 bit. As we own @rq, we can pass them through | 2297 | * @p's owner, dropping our scx flags and the placing @sch. We own @rq, |
| 2296 | * @rq->scx.remote_activate_enq_flags instead. | 2298 | * so stash both across the call. The enqueue reads them back, keeping |
| | 2299 | * the scx flags and checking caps against the placer, not the owner. |
| 2297 | */ | 2300 | */ |
| 2298 | WARN_ON_ONCE(!cpumask_test_cpu(cpu_of(dst_rq), p->cpus_ptr)); | 2301 | WARN_ON_ONCE(!cpumask_test_cpu(cpu_of(dst_rq), p->cpus_ptr)); |
| 2299 | WARN_ON_ONCE(dst_rq->scx.remote_activate_enq_flags); | 2302 | WARN_ON_ONCE(dst_rq->scx.remote_activate_enq_flags || |
| | 2303 | dst_rq->scx.remote_activate_sch); |
| 2300 | dst_rq->scx.remote_activate_enq_flags = enq_flags; | 2304 | dst_rq->scx.remote_activate_enq_flags = enq_flags; |
| | 2305 | dst_rq->scx.remote_activate_sch = sch; |
| 2301 | activate_task(dst_rq, p, 0); | 2306 | activate_task(dst_rq, p, 0); |
| 2302 | dst_rq->scx.remote_activate_enq_flags = 0; | 2307 | dst_rq->scx.remote_activate_enq_flags = 0; |
| | 2308 | dst_rq->scx.remote_activate_sch = NULL; |
| 2303 | } | 2309 | } |
| 2304 | | 2310 | |
| 2305 | /* | 2311 | /* |
| @@ -2431,12 +2437,12 @@ static bool unlink_dsq_and_switch_rq_lock(struct task_struct *p, · 125 unmodified lines |
| 2431 | !WARN_ON_ONCE(src_rq != task_rq(p)); | 2437 | !WARN_ON_ONCE(src_rq != task_rq(p)); |
| 2432 | } | 2438 | } |
| 2433 | | 2439 | |
| 2434 | static bool consume_remote_task(struct rq *this_rq, | 2440 | static bool consume_remote_task(struct scx_sched *sch, struct rq *this_rq, |
| 2435 | struct task_struct *p, u64 enq_flags, | 2441 | struct task_struct *p, u64 enq_flags, |
| 2436 | struct scx_dispatch_q *dsq, struct rq *src_rq) | 2442 | struct scx_dispatch_q *dsq, struct rq *src_rq) |
| 2437 | { | 2443 | { |
| 2438 | if (unlink_dsq_and_switch_rq_lock(p, dsq, this_rq, src_rq)) { | 2444 | if (unlink_dsq_and_switch_rq_lock(p, dsq, this_rq, src_rq)) { |
| 2439 | move_remote_task_to_local_dsq(p, enq_flags, src_rq, this_rq); | 2445 | move_remote_task_to_local_dsq(sch, p, enq_flags, src_rq, this_rq); |
| 2440 | return true; | 2446 | return true; |
| 2441 | } else { | 2447 | } else { |
| 2442 | switch_rq_lock(src_rq, this_rq); | 2448 | switch_rq_lock(src_rq, this_rq); |
| @@ -2497,8 +2503,7 @@ static struct rq *move_task_between_dsqs(struct scx_sched *sch, · 54 unmodified lines |
| 2497 | raw_spin_unlock(&src_dsq->lock); | 2503 | raw_spin_unlock(&src_dsq->lock); |
| 2498 | } else { | 2504 | } else { |
| 2499 | raw_spin_unlock(&src_dsq->lock); | 2505 | raw_spin_unlock(&src_dsq->lock); |
| 2500 | move_remote_task_to_local_dsq(p, enq_flags, | 2506 | move_remote_task_to_local_dsq(sch, p, enq_flags, src_rq, dst_rq); |
| 2501 | src_rq, dst_rq); | | |
| 2502 | } | 2507 | } |
| 2503 | } else { | 2508 | } else { |
| 2504 | /* | 2509 | /* |
| @@ -2551,7 +2556,7 @@ retry: · 46 unmodified lines |
| 2551 | } | 2556 | } |
| 2552 | | 2557 | |
| 2553 | if (task_can_run_on_remote_rq(sch, p, rq, false)) { | 2558 | if (task_can_run_on_remote_rq(sch, p, rq, false)) { |
| 2554 | if (likely(consume_remote_task(rq, p, enq_flags, dsq, task_rq))) | 2559 | if (likely(consume_remote_task(sch, rq, p, enq_flags, dsq, task_rq))) |
| 2555 | return true; | 2560 | return true; |
| 2556 | goto retry; | 2561 | goto retry; |
| 2557 | } | 2562 | } |
| @@ -2644,8 +2649,7 @@ static void dispatch_to_local_dsq(struct scx_sched *sch, struct rq *rq, · 86 unmodified lines |
| 2644 | scx_dispatch_enqueue(sch, src_rq, find_global_dsq(sch, task_cpu(p)), | 2649 | scx_dispatch_enqueue(sch, src_rq, find_global_dsq(sch, task_cpu(p)), |
| 2645 | p, enq_flags | SCX_ENQ_GDSQ_FALLBACK); | 2650 | p, enq_flags | SCX_ENQ_GDSQ_FALLBACK); |
| 2646 | } else { | 2651 | } else { |
| 2647 | move_remote_task_to_local_dsq(p, enq_flags, | 2652 | move_remote_task_to_local_dsq(sch, p, enq_flags, src_rq, dst_rq); |
| 2648 | src_rq, dst_rq); | | |
| 2649 | /* task has been moved to dst_rq, which is now locked */ | 2653 | /* task has been moved to dst_rq, which is now locked */ |
| 2650 | locked_rq = dst_rq; | 2654 | locked_rq = dst_rq; |
| 2651 | } | 2655 | } |