Re: [RFC v6 3/3] drm/panthor: Create per queue priority workqueues

From: Tejun Heo

Date: Fri Oct 02 2026 - 15:34:03 EST


Hello,

The following is a Claude-generated review.

On Thu, Oct 01, 2026 at 05:07:11PM +0100, Tvrtko Ursulin wrote:
> Low and medium GPU priority are served by a normal workqueue,
> high is server by a WQ_HIGHPRI instance, while realtime GPU priority is
> using the newly added WQ_RTPRI flag for lowest possible latency.

s/server/served/ and the flag is WQ_RT now.

> + if (group->priority >= ARRAY_SIZE(group->ptdev->scheduler->submit_wq) ||
> + !group->ptdev->scheduler->submit_wq[group->priority]) {
> + ret = -EINVAL;
> + goto err_free_queue;
> + }

panthor_group_create() already rejects priorities >=
PANTHOR_CSG_PRIORITY_COUNT and all slots are populated once
panthor_sched_init() succeeded, so this can't fire.

> + sched_args.submit_wq = group->ptdev->scheduler->submit_wq[group->priority];

The .submit_wq = sched->wq initializer at the top of the function is still
there and gets overwritten here.

> + if (sched->submit_wq[PANTHOR_CSG_PRIORITY_RT])
> + destroy_workqueue(sched->submit_wq[PANTHOR_CSG_PRIORITY_RT]);
> +
> if (sched->wq)
> destroy_workqueue(sched->wq);

Work on sched->wq signals job fences whose callbacks queue onto the submit
wqs, so destroying sched->wq first would be the safer order.

> + sched->submit_wq[PANTHOR_CSG_PRIORITY_MEDIUM] = alloc_workqueue("panthor-drm", WQ_MEM_RECLAIM | WQ_UNBOUND, 2);
> + sched->submit_wq[PANTHOR_CSG_PRIORITY_LOW] = sched->submit_wq[PANTHOR_CSG_PRIORITY_MEDIUM];
> + sched->submit_wq[PANTHOR_CSG_PRIORITY_HIGH] = alloc_workqueue("panthor-drm-high", WQ_HIGHPRI | WQ_MEM_RECLAIM | WQ_UNBOUND, 2);
> + sched->submit_wq[PANTHOR_CSG_PRIORITY_RT] = alloc_workqueue("panthor-drm-rt", WQ_RT | WQ_MEM_RECLAIM | WQ_UNBOUND, 2);

For an unbound wq max_active applies to the whole wq, so this is two
in-flight items per priority level across all the queues on the device,
where the shared wq before had no effective limit. queue_run_job() blocks
on sched->lock which tick_work() holds across FW round trips, so two
blocked run_jobs would stall every other queue's run and free work at that
level. What's the reason for 2? Also, these lines are over 100 columns.

Thanks.

--
tejun