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.

drm/panthor: Fix the group priority rotation logic

When rotating group priorities, we want the group with the
highest priority to go back to the end of the queue, and all
other active groups to get their priority bumped, otherwise
some groups will never get a chance to run with the highest
priority. This implies moving the rotation itself to
tick_work(), and only dealing with old group ordering in
tick_ctx_insert_old_group().

v2:
- Add R-b
- Fix the commit message

v3:
- Drop the full_tick argument in tick_ctx_init()
- Collect R-b

Fixes: de8548813824 ("drm/panthor: Add the scheduler logical block")
Reviewed-by: Steven Price <steven.price@arm.com>
Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
Link: https://patch.msgid.link/20251128094839.3856402-5-boris.brezillon@collabora.com
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>

+31 -21
+31 -21
drivers/gpu/drm/panthor/panthor_sched.c
··· 2050 2050 static void 2051 2051 tick_ctx_insert_old_group(struct panthor_scheduler *sched, 2052 2052 struct panthor_sched_tick_ctx *ctx, 2053 - struct panthor_group *group, 2054 - bool full_tick) 2053 + struct panthor_group *group) 2055 2054 { 2056 2055 struct panthor_csg_slot *csg_slot = &sched->csg_slots[group->csg_id]; 2057 2056 struct panthor_group *other_group; 2058 2057 2059 - if (!full_tick) { 2060 - list_add_tail(&group->run_node, &ctx->old_groups[group->priority]); 2061 - return; 2062 - } 2063 - 2064 - /* Rotate to make sure groups with lower CSG slot 2065 - * priorities have a chance to get a higher CSG slot 2066 - * priority next time they get picked. This priority 2067 - * has an impact on resource request ordering, so it's 2068 - * important to make sure we don't let one group starve 2069 - * all other groups with the same group priority. 2070 - */ 2058 + /* Class groups in descending priority order so we can easily rotate. */ 2071 2059 list_for_each_entry(other_group, 2072 2060 &ctx->old_groups[csg_slot->group->priority], 2073 2061 run_node) { 2074 2062 struct panthor_csg_slot *other_csg_slot = &sched->csg_slots[other_group->csg_id]; 2075 2063 2076 - if (other_csg_slot->priority > csg_slot->priority) { 2077 - list_add_tail(&csg_slot->group->run_node, &other_group->run_node); 2064 + /* Our group has a higher prio than the one we're testing against, 2065 + * place it just before. 2066 + */ 2067 + if (csg_slot->priority > other_csg_slot->priority) { 2068 + list_add_tail(&group->run_node, &other_group->run_node); 2078 2069 return; 2079 2070 } 2080 2071 } ··· 2075 2084 2076 2085 static void 2077 2086 tick_ctx_init(struct panthor_scheduler *sched, 2078 - struct panthor_sched_tick_ctx *ctx, 2079 - bool full_tick) 2087 + struct panthor_sched_tick_ctx *ctx) 2080 2088 { 2081 2089 struct panthor_device *ptdev = sched->ptdev; 2082 2090 struct panthor_csg_slots_upd_ctx upd_ctx; ··· 2113 2123 group->fatal_queues |= GENMASK(group->queue_count - 1, 0); 2114 2124 } 2115 2125 2116 - tick_ctx_insert_old_group(sched, ctx, group, full_tick); 2126 + tick_ctx_insert_old_group(sched, ctx, group); 2117 2127 csgs_upd_ctx_queue_reqs(ptdev, &upd_ctx, i, 2118 2128 csg_iface->output->ack ^ CSG_STATUS_UPDATE, 2119 2129 CSG_STATUS_UPDATE); ··· 2456 2466 if (panthor_device_reset_is_pending(sched->ptdev)) 2457 2467 goto out_unlock; 2458 2468 2459 - tick_ctx_init(sched, &ctx, full_tick); 2469 + tick_ctx_init(sched, &ctx); 2460 2470 if (ctx.csg_upd_failed_mask) 2461 2471 goto out_cleanup_ctx; 2462 2472 ··· 2482 2492 for (prio = PANTHOR_CSG_PRIORITY_COUNT - 1; 2483 2493 prio >= 0 && !tick_ctx_is_full(sched, &ctx); 2484 2494 prio--) { 2495 + struct panthor_group *old_highest_prio_group = 2496 + list_first_entry_or_null(&ctx.old_groups[prio], 2497 + struct panthor_group, run_node); 2498 + 2499 + /* Pull out the group with the highest prio for rotation. */ 2500 + if (old_highest_prio_group) 2501 + list_del(&old_highest_prio_group->run_node); 2502 + 2503 + /* Re-insert old active groups so they get a chance to run with higher prio. */ 2504 + tick_ctx_pick_groups_from_list(sched, &ctx, &ctx.old_groups[prio], true, true); 2505 + 2506 + /* Fill the remaining slots with runnable groups. */ 2485 2507 tick_ctx_pick_groups_from_list(sched, &ctx, &sched->groups.runnable[prio], 2486 2508 true, false); 2487 - tick_ctx_pick_groups_from_list(sched, &ctx, &ctx.old_groups[prio], true, true); 2509 + 2510 + /* Re-insert the old group with the highest prio, and give it a chance to be 2511 + * scheduled again (but with a lower prio) if there's room left. 2512 + */ 2513 + if (old_highest_prio_group) { 2514 + list_add_tail(&old_highest_prio_group->run_node, &ctx.old_groups[prio]); 2515 + tick_ctx_pick_groups_from_list(sched, &ctx, &ctx.old_groups[prio], 2516 + true, true); 2517 + } 2488 2518 } 2489 2519 2490 2520 /* If we have free CSG slots left, pick idle groups */