* [PATCH v3 1/8] drm/panthor: Simplify group idleness tracking
2025-11-28 9:48 [PATCH v3 0/8] drm/panthor: Misc scheduler fixes Boris Brezillon
@ 2025-11-28 9:48 ` Boris Brezillon
2025-11-28 9:48 ` [PATCH v3 2/8] drm/panthor: Don't try to enable extract events Boris Brezillon
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Boris Brezillon @ 2025-11-28 9:48 UTC (permalink / raw)
To: Boris Brezillon, Steven Price, Liviu Dudau, Adrián Larumbe
Cc: dri-devel, Florent Tomasin, Heinrich Fink, Chia-I Wu, kernel
csg_slot_sync_queues_state_locked() queries the queues state which can
then be used to determine if a group is idle or not. Let's base our
idleness detection logic solely on the {idle,blocked}_queues masks to
avoid inconsistencies between the group state and the state of its
subqueues.
v2:
- Add R-b
v3:
- Collect R-b
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Steven Price <steven.price@arm.com>
Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
---
drivers/gpu/drm/panthor/panthor_sched.c | 31 ++-----------------------
1 file changed, 2 insertions(+), 29 deletions(-)
diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c
index 1beddc175722..5b2ab963ac99 100644
--- a/drivers/gpu/drm/panthor/panthor_sched.c
+++ b/drivers/gpu/drm/panthor/panthor_sched.c
@@ -108,15 +108,6 @@ struct panthor_csg_slot {
/** @priority: Group priority. */
u8 priority;
-
- /**
- * @idle: True if the group bound to this slot is idle.
- *
- * A group is idle when it has nothing waiting for execution on
- * all its queues, or when queues are blocked waiting for something
- * to happen (synchronization object).
- */
- bool idle;
};
/**
@@ -1056,13 +1047,8 @@ group_unbind_locked(struct panthor_group *group)
static bool
group_is_idle(struct panthor_group *group)
{
- struct panthor_device *ptdev = group->ptdev;
- u32 inactive_queues;
+ u32 inactive_queues = group->idle_queues | group->blocked_queues;
- if (group->csg_id >= 0)
- return ptdev->scheduler->csg_slots[group->csg_id].idle;
-
- inactive_queues = group->idle_queues | group->blocked_queues;
return hweight32(inactive_queues) == group->queue_count;
}
@@ -1719,17 +1705,6 @@ static bool cs_slot_process_irq_locked(struct panthor_device *ptdev,
return (events & (CS_FAULT | CS_TILER_OOM)) != 0;
}
-static void csg_slot_sync_idle_state_locked(struct panthor_device *ptdev, u32 csg_id)
-{
- struct panthor_csg_slot *csg_slot = &ptdev->scheduler->csg_slots[csg_id];
- struct panthor_fw_csg_iface *csg_iface;
-
- lockdep_assert_held(&ptdev->scheduler->lock);
-
- csg_iface = panthor_fw_get_csg_iface(ptdev, csg_id);
- csg_slot->idle = csg_iface->output->status_state & CSG_STATUS_STATE_IS_IDLE;
-}
-
static void csg_slot_process_idle_event_locked(struct panthor_device *ptdev, u32 csg_id)
{
struct panthor_scheduler *sched = ptdev->scheduler;
@@ -1991,10 +1966,8 @@ static int csgs_upd_ctx_apply_locked(struct panthor_device *ptdev,
if (acked & CSG_STATE_MASK)
csg_slot_sync_state_locked(ptdev, csg_id);
- if (acked & CSG_STATUS_UPDATE) {
+ if (acked & CSG_STATUS_UPDATE)
csg_slot_sync_queues_state_locked(ptdev, csg_id);
- csg_slot_sync_idle_state_locked(ptdev, csg_id);
- }
if (ret && acked != req_mask &&
((csg_iface->input->req ^ csg_iface->output->ack) & req_mask) != 0) {
--
2.51.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v3 2/8] drm/panthor: Don't try to enable extract events
2025-11-28 9:48 [PATCH v3 0/8] drm/panthor: Misc scheduler fixes Boris Brezillon
2025-11-28 9:48 ` [PATCH v3 1/8] drm/panthor: Simplify group idleness tracking Boris Brezillon
@ 2025-11-28 9:48 ` Boris Brezillon
2025-11-28 9:48 ` [PATCH v3 3/8] drm/panthor: Fix the full_tick check Boris Brezillon
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Boris Brezillon @ 2025-11-28 9:48 UTC (permalink / raw)
To: Boris Brezillon, Steven Price, Liviu Dudau, Adrián Larumbe
Cc: dri-devel, Florent Tomasin, Heinrich Fink, Chia-I Wu, kernel
Not only this only works once, because of how extract events work
(event is enabled if the req and ack bit differ, and it's signalled
by the FW by setting identical req and ack, to re-enable the event,
we need to toggle the bit, which we never do). But more importantly,
we never do anything with this event, so we're better off dropping it
when programming the CS slot.
v2:
- Add R-b
v3:
- Collect R-b
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Steven Price <steven.price@arm.com>
Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
---
drivers/gpu/drm/panthor/panthor_sched.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c
index 5b2ab963ac99..5ec553818c28 100644
--- a/drivers/gpu/drm/panthor/panthor_sched.c
+++ b/drivers/gpu/drm/panthor/panthor_sched.c
@@ -1180,12 +1180,10 @@ cs_slot_prog_locked(struct panthor_device *ptdev, u32 csg_id, u32 cs_id)
panthor_fw_update_reqs(cs_iface, req,
CS_IDLE_SYNC_WAIT |
CS_IDLE_EMPTY |
- CS_STATE_START |
- CS_EXTRACT_EVENT,
+ CS_STATE_START,
CS_IDLE_SYNC_WAIT |
CS_IDLE_EMPTY |
- CS_STATE_MASK |
- CS_EXTRACT_EVENT);
+ CS_STATE_MASK);
if (queue->iface.input->insert != queue->iface.input->extract)
queue_resume_timeout(queue);
}
--
2.51.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v3 3/8] drm/panthor: Fix the full_tick check
2025-11-28 9:48 [PATCH v3 0/8] drm/panthor: Misc scheduler fixes Boris Brezillon
2025-11-28 9:48 ` [PATCH v3 1/8] drm/panthor: Simplify group idleness tracking Boris Brezillon
2025-11-28 9:48 ` [PATCH v3 2/8] drm/panthor: Don't try to enable extract events Boris Brezillon
@ 2025-11-28 9:48 ` Boris Brezillon
2025-11-28 9:48 ` [PATCH v3 4/8] drm/panthor: Fix the group priority rotation logic Boris Brezillon
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Boris Brezillon @ 2025-11-28 9:48 UTC (permalink / raw)
To: Boris Brezillon, Steven Price, Liviu Dudau, Adrián Larumbe
Cc: dri-devel, Florent Tomasin, Heinrich Fink, Chia-I Wu, kernel
We have a full tick when the remaining time to the next tick is zero,
not the other way around. Declare a full_tick variable so we don't get
that test wrong in other places.
v2:
- Add R-b
v3:
- Collect R-b
Fixes: de8548813824 ("drm/panthor: Add the scheduler logical block")
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Steven Price <steven.price@arm.com>
Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
---
drivers/gpu/drm/panthor/panthor_sched.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c
index 5ec553818c28..5d280d9c8225 100644
--- a/drivers/gpu/drm/panthor/panthor_sched.c
+++ b/drivers/gpu/drm/panthor/panthor_sched.c
@@ -2448,6 +2448,7 @@ static void tick_work(struct work_struct *work)
u64 remaining_jiffies = 0, resched_delay;
u64 now = get_jiffies_64();
int prio, ret, cookie;
+ bool full_tick;
if (!drm_dev_enter(&ptdev->base, &cookie))
return;
@@ -2459,15 +2460,17 @@ static void tick_work(struct work_struct *work)
if (time_before64(now, sched->resched_target))
remaining_jiffies = sched->resched_target - now;
+ full_tick = remaining_jiffies == 0;
+
mutex_lock(&sched->lock);
if (panthor_device_reset_is_pending(sched->ptdev))
goto out_unlock;
- tick_ctx_init(sched, &ctx, remaining_jiffies != 0);
+ tick_ctx_init(sched, &ctx, full_tick);
if (ctx.csg_upd_failed_mask)
goto out_cleanup_ctx;
- if (remaining_jiffies) {
+ if (!full_tick) {
/* Scheduling forced in the middle of a tick. Only RT groups
* can preempt non-RT ones. Currently running RT groups can't be
* preempted.
--
2.51.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v3 4/8] drm/panthor: Fix the group priority rotation logic
2025-11-28 9:48 [PATCH v3 0/8] drm/panthor: Misc scheduler fixes Boris Brezillon
` (2 preceding siblings ...)
2025-11-28 9:48 ` [PATCH v3 3/8] drm/panthor: Fix the full_tick check Boris Brezillon
@ 2025-11-28 9:48 ` Boris Brezillon
2025-11-28 9:48 ` [PATCH v3 5/8] drm/panthor: Fix immediate ticking on a disabled tick Boris Brezillon
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Boris Brezillon @ 2025-11-28 9:48 UTC (permalink / raw)
To: Boris Brezillon, Steven Price, Liviu Dudau, Adrián Larumbe
Cc: dri-devel, Florent Tomasin, Heinrich Fink, Chia-I Wu, kernel
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")
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Steven Price <steven.price@arm.com>
Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
---
drivers/gpu/drm/panthor/panthor_sched.c | 52 +++++++++++++++----------
1 file changed, 31 insertions(+), 21 deletions(-)
diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c
index 5d280d9c8225..531b52ee3a92 100644
--- a/drivers/gpu/drm/panthor/panthor_sched.c
+++ b/drivers/gpu/drm/panthor/panthor_sched.c
@@ -2050,31 +2050,22 @@ tick_ctx_pick_groups_from_list(const struct panthor_scheduler *sched,
static void
tick_ctx_insert_old_group(struct panthor_scheduler *sched,
struct panthor_sched_tick_ctx *ctx,
- struct panthor_group *group,
- bool full_tick)
+ struct panthor_group *group)
{
struct panthor_csg_slot *csg_slot = &sched->csg_slots[group->csg_id];
struct panthor_group *other_group;
- if (!full_tick) {
- list_add_tail(&group->run_node, &ctx->old_groups[group->priority]);
- return;
- }
-
- /* Rotate to make sure groups with lower CSG slot
- * priorities have a chance to get a higher CSG slot
- * priority next time they get picked. This priority
- * has an impact on resource request ordering, so it's
- * important to make sure we don't let one group starve
- * all other groups with the same group priority.
- */
+ /* Class groups in descending priority order so we can easily rotate. */
list_for_each_entry(other_group,
&ctx->old_groups[csg_slot->group->priority],
run_node) {
struct panthor_csg_slot *other_csg_slot = &sched->csg_slots[other_group->csg_id];
- if (other_csg_slot->priority > csg_slot->priority) {
- list_add_tail(&csg_slot->group->run_node, &other_group->run_node);
+ /* Our group has a higher prio than the one we're testing against,
+ * place it just before.
+ */
+ if (csg_slot->priority > other_csg_slot->priority) {
+ list_add_tail(&group->run_node, &other_group->run_node);
return;
}
}
@@ -2084,8 +2075,7 @@ tick_ctx_insert_old_group(struct panthor_scheduler *sched,
static void
tick_ctx_init(struct panthor_scheduler *sched,
- struct panthor_sched_tick_ctx *ctx,
- bool full_tick)
+ struct panthor_sched_tick_ctx *ctx)
{
struct panthor_device *ptdev = sched->ptdev;
struct panthor_csg_slots_upd_ctx upd_ctx;
@@ -2123,7 +2113,7 @@ tick_ctx_init(struct panthor_scheduler *sched,
group->fatal_queues |= GENMASK(group->queue_count - 1, 0);
}
- tick_ctx_insert_old_group(sched, ctx, group, full_tick);
+ tick_ctx_insert_old_group(sched, ctx, group);
csgs_upd_ctx_queue_reqs(ptdev, &upd_ctx, i,
csg_iface->output->ack ^ CSG_STATUS_UPDATE,
CSG_STATUS_UPDATE);
@@ -2466,7 +2456,7 @@ static void tick_work(struct work_struct *work)
if (panthor_device_reset_is_pending(sched->ptdev))
goto out_unlock;
- tick_ctx_init(sched, &ctx, full_tick);
+ tick_ctx_init(sched, &ctx);
if (ctx.csg_upd_failed_mask)
goto out_cleanup_ctx;
@@ -2492,9 +2482,29 @@ static void tick_work(struct work_struct *work)
for (prio = PANTHOR_CSG_PRIORITY_COUNT - 1;
prio >= 0 && !tick_ctx_is_full(sched, &ctx);
prio--) {
+ struct panthor_group *old_highest_prio_group =
+ list_first_entry_or_null(&ctx.old_groups[prio],
+ struct panthor_group, run_node);
+
+ /* Pull out the group with the highest prio for rotation. */
+ if (old_highest_prio_group)
+ list_del(&old_highest_prio_group->run_node);
+
+ /* Re-insert old active groups so they get a chance to run with higher prio. */
+ tick_ctx_pick_groups_from_list(sched, &ctx, &ctx.old_groups[prio], true, true);
+
+ /* Fill the remaining slots with runnable groups. */
tick_ctx_pick_groups_from_list(sched, &ctx, &sched->groups.runnable[prio],
true, false);
- tick_ctx_pick_groups_from_list(sched, &ctx, &ctx.old_groups[prio], true, true);
+
+ /* Re-insert the old group with the highest prio, and give it a chance to be
+ * scheduled again (but with a lower prio) if there's room left.
+ */
+ if (old_highest_prio_group) {
+ list_add_tail(&old_highest_prio_group->run_node, &ctx.old_groups[prio]);
+ tick_ctx_pick_groups_from_list(sched, &ctx, &ctx.old_groups[prio],
+ true, true);
+ }
}
/* If we have free CSG slots left, pick idle groups */
--
2.51.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v3 5/8] drm/panthor: Fix immediate ticking on a disabled tick
2025-11-28 9:48 [PATCH v3 0/8] drm/panthor: Misc scheduler fixes Boris Brezillon
` (3 preceding siblings ...)
2025-11-28 9:48 ` [PATCH v3 4/8] drm/panthor: Fix the group priority rotation logic Boris Brezillon
@ 2025-11-28 9:48 ` Boris Brezillon
2025-11-28 9:48 ` [PATCH v3 6/8] drm/panthor: Fix the logic that decides when to stop ticking Boris Brezillon
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Boris Brezillon @ 2025-11-28 9:48 UTC (permalink / raw)
To: Boris Brezillon, Steven Price, Liviu Dudau, Adrián Larumbe
Cc: dri-devel, Florent Tomasin, Heinrich Fink, Chia-I Wu, kernel
We have a few paths where we schedule the tick work immediately without
changing the resched_target. If the tick was stopped, this would lead
to a remaining_jiffies that's always > 0, and it wouldn't force a full
tick in that case. Add extra checks to cover that case properly.
v2:
- Fix typo
- Simplify the code as suggested by Steve
v3:
- Collect R-b
Fixes: de8548813824 ("drm/panthor: Add the scheduler logical block")
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Steven Price <steven.price@arm.com>
Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
---
drivers/gpu/drm/panthor/panthor_sched.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c
index 531b52ee3a92..1efeabc4b0ac 100644
--- a/drivers/gpu/drm/panthor/panthor_sched.c
+++ b/drivers/gpu/drm/panthor/panthor_sched.c
@@ -2435,6 +2435,7 @@ static void tick_work(struct work_struct *work)
tick_work.work);
struct panthor_device *ptdev = sched->ptdev;
struct panthor_sched_tick_ctx ctx;
+ u64 resched_target = sched->resched_target;
u64 remaining_jiffies = 0, resched_delay;
u64 now = get_jiffies_64();
int prio, ret, cookie;
@@ -2447,8 +2448,12 @@ static void tick_work(struct work_struct *work)
if (drm_WARN_ON(&ptdev->base, ret))
goto out_dev_exit;
- if (time_before64(now, sched->resched_target))
- remaining_jiffies = sched->resched_target - now;
+ /* If the tick is stopped, calculate when the next tick would be */
+ if (resched_target == U64_MAX)
+ resched_target = sched->last_tick + sched->tick_period;
+
+ if (time_before64(now, resched_target))
+ remaining_jiffies = resched_target - now;
full_tick = remaining_jiffies == 0;
--
2.51.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v3 6/8] drm/panthor: Fix the logic that decides when to stop ticking
2025-11-28 9:48 [PATCH v3 0/8] drm/panthor: Misc scheduler fixes Boris Brezillon
` (4 preceding siblings ...)
2025-11-28 9:48 ` [PATCH v3 5/8] drm/panthor: Fix immediate ticking on a disabled tick Boris Brezillon
@ 2025-11-28 9:48 ` Boris Brezillon
2025-11-28 9:48 ` [PATCH v3 7/8] drm/panthor: Make sure we resume the tick when new jobs are submitted Boris Brezillon
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Boris Brezillon @ 2025-11-28 9:48 UTC (permalink / raw)
To: Boris Brezillon, Steven Price, Liviu Dudau, Adrián Larumbe
Cc: dri-devel, Florent Tomasin, Heinrich Fink, Chia-I Wu, kernel
When we have multiple active groups with the same priority, we need to
keep ticking for the priority rotation to take place. If we don't do
that, we might starve slots with lower priorities.
It's annoying to deal with that in tick_ctx_update_resched_target(),
so let's add a ::stop_tick field to the tick context which is
initialized to true, and downgraded to false as soon as we detect
something that requires to tick to happen. This way we can complement
the current logic with extra conditions if needed.
v2:
- Add R-b
v3:
- Drop panthor_sched_tick_ctx::min_priority (no longer relevant)
- Collect R-b
Fixes: de8548813824 ("drm/panthor: Add the scheduler logical block")
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Steven Price <steven.price@arm.com>
Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
---
drivers/gpu/drm/panthor/panthor_sched.c | 46 ++++++++++---------------
1 file changed, 18 insertions(+), 28 deletions(-)
diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c
index 1efeabc4b0ac..8846608dd127 100644
--- a/drivers/gpu/drm/panthor/panthor_sched.c
+++ b/drivers/gpu/drm/panthor/panthor_sched.c
@@ -1985,10 +1985,10 @@ struct panthor_sched_tick_ctx {
struct list_head groups[PANTHOR_CSG_PRIORITY_COUNT];
u32 idle_group_count;
u32 group_count;
- enum panthor_csg_priority min_priority;
struct panthor_vm *vms[MAX_CS_PER_CSG];
u32 as_count;
bool immediate_tick;
+ bool stop_tick;
u32 csg_upd_failed_mask;
};
@@ -2031,17 +2031,21 @@ tick_ctx_pick_groups_from_list(const struct panthor_scheduler *sched,
if (!owned_by_tick_ctx)
group_get(group);
- list_move_tail(&group->run_node, &ctx->groups[group->priority]);
ctx->group_count++;
+
+ /* If we have more than one active group with the same priority,
+ * we need to keep ticking to rotate the CSG priority.
+ */
if (group_is_idle(group))
ctx->idle_group_count++;
+ else if (!list_empty(&ctx->groups[group->priority]))
+ ctx->stop_tick = false;
+
+ list_move_tail(&group->run_node, &ctx->groups[group->priority]);
if (i == ctx->as_count)
ctx->vms[ctx->as_count++] = group->vm;
- if (ctx->min_priority > group->priority)
- ctx->min_priority = group->priority;
-
if (tick_ctx_is_full(sched, ctx))
return;
}
@@ -2085,7 +2089,7 @@ tick_ctx_init(struct panthor_scheduler *sched,
memset(ctx, 0, sizeof(*ctx));
csgs_upd_ctx_init(&upd_ctx);
- ctx->min_priority = PANTHOR_CSG_PRIORITY_COUNT;
+ ctx->stop_tick = true;
for (i = 0; i < ARRAY_SIZE(ctx->groups); i++) {
INIT_LIST_HEAD(&ctx->groups[i]);
INIT_LIST_HEAD(&ctx->old_groups[i]);
@@ -2397,32 +2401,18 @@ static u64
tick_ctx_update_resched_target(struct panthor_scheduler *sched,
const struct panthor_sched_tick_ctx *ctx)
{
- /* We had space left, no need to reschedule until some external event happens. */
- if (!tick_ctx_is_full(sched, ctx))
+ u64 resched_target;
+
+ if (ctx->stop_tick)
goto no_tick;
- /* If idle groups were scheduled, no need to wake up until some external
- * event happens (group unblocked, new job submitted, ...).
- */
- if (ctx->idle_group_count)
- goto no_tick;
+ resched_target = sched->last_tick + sched->tick_period;
- if (drm_WARN_ON(&sched->ptdev->base, ctx->min_priority >= PANTHOR_CSG_PRIORITY_COUNT))
- goto no_tick;
+ if (time_before64(sched->resched_target, sched->last_tick) ||
+ time_before64(resched_target, sched->resched_target))
+ sched->resched_target = resched_target;
- /* If there are groups of the same priority waiting, we need to
- * keep the scheduler ticking, otherwise, we'll just wait for
- * new groups with higher priority to be queued.
- */
- if (!list_empty(&sched->groups.runnable[ctx->min_priority])) {
- u64 resched_target = sched->last_tick + sched->tick_period;
-
- if (time_before64(sched->resched_target, sched->last_tick) ||
- time_before64(resched_target, sched->resched_target))
- sched->resched_target = resched_target;
-
- return sched->resched_target - sched->last_tick;
- }
+ return sched->resched_target - sched->last_tick;
no_tick:
sched->resched_target = U64_MAX;
--
2.51.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v3 7/8] drm/panthor: Make sure we resume the tick when new jobs are submitted
2025-11-28 9:48 [PATCH v3 0/8] drm/panthor: Misc scheduler fixes Boris Brezillon
` (5 preceding siblings ...)
2025-11-28 9:48 ` [PATCH v3 6/8] drm/panthor: Fix the logic that decides when to stop ticking Boris Brezillon
@ 2025-11-28 9:48 ` Boris Brezillon
2025-11-28 9:48 ` [PATCH v3 8/8] drm/panthor: Kill panthor_sched_immediate_tick() Boris Brezillon
2025-11-28 9:58 ` [PATCH v3 0/8] drm/panthor: Misc scheduler fixes Boris Brezillon
8 siblings, 0 replies; 10+ messages in thread
From: Boris Brezillon @ 2025-11-28 9:48 UTC (permalink / raw)
To: Boris Brezillon, Steven Price, Liviu Dudau, Adrián Larumbe
Cc: dri-devel, Florent Tomasin, Heinrich Fink, Chia-I Wu, kernel
If the group is already assigned a slot but was idle before this job
submission, we need to make sure the priority rotation happens in the
future. Extract the existing logic living in group_schedule_locked()
and call this new sched_resume_tick() helper from the "group is
assigned a slot" path.
v2:
- Add R-b
v3:
- Re-use queue_mask to clear the bit
- Collect R-b
Fixes: de8548813824 ("drm/panthor: Add the scheduler logical block")
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Steven Price <steven.price@arm.com>
Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
---
drivers/gpu/drm/panthor/panthor_sched.c | 43 +++++++++++++++++++------
1 file changed, 34 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c
index 8846608dd127..7759a8a8565e 100644
--- a/drivers/gpu/drm/panthor/panthor_sched.c
+++ b/drivers/gpu/drm/panthor/panthor_sched.c
@@ -2624,14 +2624,33 @@ static void sync_upd_work(struct work_struct *work)
sched_queue_delayed_work(sched, tick, 0);
}
+static void sched_resume_tick(struct panthor_device *ptdev)
+{
+ struct panthor_scheduler *sched = ptdev->scheduler;
+ u64 delay_jiffies, now;
+
+ drm_WARN_ON(&ptdev->base, sched->resched_target != U64_MAX);
+
+ /* Scheduler tick was off, recalculate the resched_target based on the
+ * last tick event, and queue the scheduler work.
+ */
+ now = get_jiffies_64();
+ sched->resched_target = sched->last_tick + sched->tick_period;
+ if (sched->used_csg_slot_count == sched->csg_slot_count &&
+ time_before64(now, sched->resched_target))
+ delay_jiffies = min_t(unsigned long, sched->resched_target - now, ULONG_MAX);
+ else
+ delay_jiffies = 0;
+
+ sched_queue_delayed_work(sched, tick, delay_jiffies);
+}
+
static void group_schedule_locked(struct panthor_group *group, u32 queue_mask)
{
struct panthor_device *ptdev = group->ptdev;
struct panthor_scheduler *sched = ptdev->scheduler;
struct list_head *queue = &sched->groups.runnable[group->priority];
- u64 delay_jiffies = 0;
bool was_idle;
- u64 now;
if (!group_can_run(group))
return;
@@ -2676,13 +2695,7 @@ static void group_schedule_locked(struct panthor_group *group, u32 queue_mask)
/* Scheduler tick was off, recalculate the resched_target based on the
* last tick event, and queue the scheduler work.
*/
- now = get_jiffies_64();
- sched->resched_target = sched->last_tick + sched->tick_period;
- if (sched->used_csg_slot_count == sched->csg_slot_count &&
- time_before64(now, sched->resched_target))
- delay_jiffies = min_t(unsigned long, sched->resched_target - now, ULONG_MAX);
-
- sched_queue_delayed_work(sched, tick, delay_jiffies);
+ sched_resume_tick(ptdev);
}
static void queue_stop(struct panthor_queue *queue,
@@ -3314,6 +3327,18 @@ queue_run_job(struct drm_sched_job *sched_job)
if (group->csg_id < 0) {
group_schedule_locked(group, BIT(job->queue_idx));
} else {
+ u32 queue_mask = BIT(job->queue_idx);
+ bool resume_tick = group_is_idle(group) &&
+ (group->idle_queues & queue_mask) &&
+ !(group->blocked_queues & queue_mask) &&
+ sched->resched_target == U64_MAX;
+
+ /* We just added something to the queue, so it's no longer idle. */
+ group->idle_queues &= ~queue_mask;
+
+ if (resume_tick)
+ sched_resume_tick(ptdev);
+
gpu_write(ptdev, CSF_DOORBELL(queue->doorbell_id), 1);
if (!sched->pm.has_ref &&
!(group->blocked_queues & BIT(job->queue_idx))) {
--
2.51.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v3 8/8] drm/panthor: Kill panthor_sched_immediate_tick()
2025-11-28 9:48 [PATCH v3 0/8] drm/panthor: Misc scheduler fixes Boris Brezillon
` (6 preceding siblings ...)
2025-11-28 9:48 ` [PATCH v3 7/8] drm/panthor: Make sure we resume the tick when new jobs are submitted Boris Brezillon
@ 2025-11-28 9:48 ` Boris Brezillon
2025-11-28 9:58 ` [PATCH v3 0/8] drm/panthor: Misc scheduler fixes Boris Brezillon
8 siblings, 0 replies; 10+ messages in thread
From: Boris Brezillon @ 2025-11-28 9:48 UTC (permalink / raw)
To: Boris Brezillon, Steven Price, Liviu Dudau, Adrián Larumbe
Cc: dri-devel, Florent Tomasin, Heinrich Fink, Chia-I Wu, kernel
It's only used in a couple places and everyone else is just using
sched_queue_delayed_work(sched, tick, 0) directly, so let's make
this consistent.
v2:
- Add R-b
v3:
- Collect R-b
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Steven Price <steven.price@arm.com>
Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
---
drivers/gpu/drm/panthor/panthor_sched.c | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c
index 7759a8a8565e..389d508b3848 100644
--- a/drivers/gpu/drm/panthor/panthor_sched.c
+++ b/drivers/gpu/drm/panthor/panthor_sched.c
@@ -2753,13 +2753,6 @@ static void panthor_group_start(struct panthor_group *group)
group_put(group);
}
-static void panthor_sched_immediate_tick(struct panthor_device *ptdev)
-{
- struct panthor_scheduler *sched = ptdev->scheduler;
-
- sched_queue_delayed_work(sched, tick, 0);
-}
-
/**
* panthor_sched_report_mmu_fault() - Report MMU faults to the scheduler.
*/
@@ -2767,13 +2760,13 @@ void panthor_sched_report_mmu_fault(struct panthor_device *ptdev)
{
/* Force a tick to immediately kill faulty groups. */
if (ptdev->scheduler)
- panthor_sched_immediate_tick(ptdev);
+ sched_queue_delayed_work(ptdev->scheduler, tick, 0);
}
void panthor_sched_resume(struct panthor_device *ptdev)
{
/* Force a tick to re-evaluate after a resume. */
- panthor_sched_immediate_tick(ptdev);
+ sched_queue_delayed_work(ptdev->scheduler, tick, 0);
}
void panthor_sched_suspend(struct panthor_device *ptdev)
--
2.51.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH v3 0/8] drm/panthor: Misc scheduler fixes
2025-11-28 9:48 [PATCH v3 0/8] drm/panthor: Misc scheduler fixes Boris Brezillon
` (7 preceding siblings ...)
2025-11-28 9:48 ` [PATCH v3 8/8] drm/panthor: Kill panthor_sched_immediate_tick() Boris Brezillon
@ 2025-11-28 9:58 ` Boris Brezillon
8 siblings, 0 replies; 10+ messages in thread
From: Boris Brezillon @ 2025-11-28 9:58 UTC (permalink / raw)
To: Boris Brezillon, Steven Price, Liviu Dudau, Adrián Larumbe
Cc: dri-devel, Florent Tomasin, Heinrich Fink, Chia-I Wu, kernel
On Fri, 28 Nov 2025 10:48:31 +0100
Boris Brezillon <boris.brezillon@collabora.com> wrote:
> Hello,
>
> This series is a collection of fixes that seem to address the problem
> reported here [1]. In order to validate those changes, I added a few
> IGT tests [2], but I'd like to extend the test coverage before claiming
> this is working properly. Until I get to it, I thought I'd post what
> I have for preliminary review/testing.
>
> No major changes in this version, for more details, check the changelog
> in each patch.
>
> Regards,
>
> Boris
>
> [1]https://gitlab.freedesktop.org/panfrost/linux/-/issues/48
> [2]https://gitlab.freedesktop.org/bbrezillon/igt-gpu-tools/-/tree/panthor-sched?ref_type=heads
>
> Boris Brezillon (8):
> drm/panthor: Simplify group idleness tracking
> drm/panthor: Don't try to enable extract events
> drm/panthor: Fix the full_tick check
> drm/panthor: Fix the group priority rotation logic
> drm/panthor: Fix immediate ticking on a disabled tick
> drm/panthor: Fix the logic that decides when to stop ticking
> drm/panthor: Make sure we resume the tick when new jobs are submitted
> drm/panthor: Kill panthor_sched_immediate_tick()
Queued to drm-misc-next
>
> drivers/gpu/drm/panthor/panthor_sched.c | 203 ++++++++++++------------
> 1 file changed, 100 insertions(+), 103 deletions(-)
>
^ permalink raw reply [flat|nested] 10+ messages in thread