Make the sched_process_csg_irq_locked() call part of group_unbind_locked() so we don't have to manually call it in tick_ctx_apply()/panthor_sched_suspend().
This implies moving group_[un]bind_locked() around to avoid a forward declaration. Signed-off-by: Boris Brezillon <[email protected]> --- drivers/gpu/drm/panthor/panthor_sched.c | 176 +++++++++++++++----------------- 1 file changed, 82 insertions(+), 94 deletions(-) diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c index fbf76b59b7ef..6c5ba747ae45 100644 --- a/drivers/gpu/drm/panthor/panthor_sched.c +++ b/drivers/gpu/drm/panthor/panthor_sched.c @@ -982,86 +982,6 @@ group_get(struct panthor_group *group) return group; } -/** - * group_bind_locked() - Bind a group to a group slot - * @group: Group. - * @csg_id: Slot. - * - * Return: 0 on success, a negative error code otherwise. - */ -static int -group_bind_locked(struct panthor_group *group, u32 csg_id) -{ - struct panthor_device *ptdev = group->ptdev; - int ret; - - lockdep_assert_held(&ptdev->scheduler->lock); - - if (drm_WARN_ON(&ptdev->base, group->csg_id != -1 || csg_id >= MAX_CSGS || - ptdev->scheduler->csg_slots[csg_id].group)) - return -EINVAL; - - ret = panthor_vm_active(group->vm); - if (ret) - return ret; - - group_get(group); - - /* Dummy doorbell allocation: doorbell is assigned to the group and - * all queues use the same doorbell. - * - * TODO: Implement LRU-based doorbell assignment, so the most often - * updated queues get their own doorbell, thus avoiding useless checks - * on queues belonging to the same group that are rarely updated. - */ - for (u32 i = 0; i < group->queue_count; i++) - group->queues[i]->doorbell_id = csg_id + 1; - - scoped_guard(spinlock_irqsave, &ptdev->scheduler->events_lock) { - ptdev->scheduler->csg_slots[csg_id].group = group; - group->csg_id = csg_id; - } - - return 0; -} - -/** - * group_unbind_locked() - Unbind a group from a slot. - * @group: Group to unbind. - * - * Return: 0 on success, a negative error code otherwise. - */ -static int -group_unbind_locked(struct panthor_group *group) -{ - struct panthor_device *ptdev = group->ptdev; - - lockdep_assert_held(&ptdev->scheduler->lock); - - if (drm_WARN_ON(&ptdev->base, group->csg_id < 0 || group->csg_id >= MAX_CSGS)) - return -EINVAL; - - if (drm_WARN_ON(&ptdev->base, group->state == PANTHOR_CS_GROUP_ACTIVE)) - return -EINVAL; - - scoped_guard(spinlock_irqsave, &ptdev->scheduler->events_lock) { - ptdev->scheduler->csg_slots[group->csg_id].group = NULL; - group->csg_id = -1; - } - - panthor_vm_idle(group->vm); - - /* Tiler OOM events will be re-issued next time the group is scheduled. */ - atomic_set(&group->tiler_oom, 0); - cancel_work(&group->tiler_oom_work); - - for (u32 i = 0; i < group->queue_count; i++) - group->queues[i]->doorbell_id = -1; - - group_put(group); - return 0; -} - static bool group_is_idle(struct panthor_group *group) { @@ -1968,6 +1888,88 @@ void panthor_sched_report_fw_events(struct panthor_device *ptdev, u32 events) } } +/** + * group_bind_locked() - Bind a group to a group slot + * @group: Group. + * @csg_id: Slot. + * + * Return: 0 on success, a negative error code otherwise. + */ +static int +group_bind_locked(struct panthor_group *group, u32 csg_id) +{ + struct panthor_device *ptdev = group->ptdev; + int ret; + + lockdep_assert_held(&ptdev->scheduler->lock); + + if (drm_WARN_ON(&ptdev->base, group->csg_id != -1 || csg_id >= MAX_CSGS || + ptdev->scheduler->csg_slots[csg_id].group)) + return -EINVAL; + + ret = panthor_vm_active(group->vm); + if (ret) + return ret; + + group_get(group); + + /* Dummy doorbell allocation: doorbell is assigned to the group and + * all queues use the same doorbell. + * + * TODO: Implement LRU-based doorbell assignment, so the most often + * updated queues get their own doorbell, thus avoiding useless checks + * on queues belonging to the same group that are rarely updated. + */ + for (u32 i = 0; i < group->queue_count; i++) + group->queues[i]->doorbell_id = csg_id + 1; + + scoped_guard(spinlock_irqsave, &ptdev->scheduler->events_lock) { + ptdev->scheduler->csg_slots[csg_id].group = group; + group->csg_id = csg_id; + } + + return 0; +} + +/** + * group_unbind_locked() - Unbind a group from a slot. + * @group: Group to unbind. + * + * Return: 0 on success, a negative error code otherwise. + */ +static int +group_unbind_locked(struct panthor_group *group) +{ + struct panthor_device *ptdev = group->ptdev; + + lockdep_assert_held(&ptdev->scheduler->lock); + + if (drm_WARN_ON(&ptdev->base, group->csg_id < 0 || group->csg_id >= MAX_CSGS)) + return -EINVAL; + + if (drm_WARN_ON(&ptdev->base, group->state == PANTHOR_CS_GROUP_ACTIVE)) + return -EINVAL; + + scoped_guard(spinlock_irqsave, &ptdev->scheduler->events_lock) { + /* Process all pending IRQs before returning the slot. */ + sched_process_csg_irq_locked(ptdev, group->csg_id); + ptdev->scheduler->csg_slots[group->csg_id].group = NULL; + group->csg_id = -1; + } + + panthor_vm_idle(group->vm); + + /* Tiler OOM events will be re-issued next time the group is scheduled. */ + atomic_set(&group->tiler_oom, 0); + cancel_work(&group->tiler_oom_work); + + for (u32 i = 0; i < group->queue_count; i++) + group->queues[i]->doorbell_id = -1; + + group_put(group); + return 0; +} + static const char *fence_get_driver_name(struct dma_fence *fence) { return "panthor"; @@ -2396,15 +2398,6 @@ tick_ctx_apply(struct panthor_scheduler *sched, struct panthor_sched_tick_ctx *c /* Unbind evicted groups. */ for (prio = PANTHOR_CSG_PRIORITY_COUNT - 1; prio >= 0; prio--) { list_for_each_entry(group, &ctx->old_groups[prio], run_node) { - /* This group is gone. Process interrupts to clear - * any pending interrupts before we start the new - * group. - */ - if (group->csg_id >= 0) { - guard(spinlock_irqsave)(&sched->events_lock); - sched_process_csg_irq_locked(ptdev, group->csg_id); - } - group_unbind_locked(group); } } @@ -2988,11 +2981,6 @@ void panthor_sched_suspend(struct panthor_device *ptdev) group_get(group); - if (group->csg_id >= 0) { - guard(spinlock_irqsave)(&sched->events_lock); - sched_process_csg_irq_locked(ptdev, group->csg_id); - } - group_unbind_locked(group); drm_WARN_ON(&group->ptdev->base, !list_empty(&group->run_node)); -- 2.54.0
