Re: [PATCH 05/17] media: v4l2-mem2mem: support running multiple jobs in parallel

Detlev Casanova <[email protected]>
Newsgroups org.kernel.vger.linux-media,org.infradead.lists.linux-arm-kernel,org.infradead.lists.linux-rockchip,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
Hi,

On Wednesday, 15 July 2026 05:44:01 EDT Sven Püschel wrote:
> Hi,
> 
> On 7/10/26 11:18 PM, Nicolas Dufresne wrote:
> > Hi,
> > 
> > Le samedi 06 juin 2026 à 00:06 +0200, Sven Püschel a écrit :
> >> Add support for running multiple jobs in parallel for SoCs containing
> >> multiple identical devices. An example is the Rockchip RK3588 SoC,
> >> which contains two identical RGA3 devices. Therefore it is desirable to
> >> have the kernel schedule the work across all available devices and only
> >> expose one video device to the userspace.
> >> 
> >> Previously the curr_ctx member of a v4l2_m2m_dev was used to track the
> >> currently running context. But the currently running context will always
> >> be at the top of the job_queue. As the TRANS_RUNNING flag can be used to
> >> check if the queue head is already running, the curr_ctx member can be
> >> completely dropped
> >> 
> >> To avoid queueing too many parallel jobs, the
> >> v4l2_m2m_set_max_parallel_jobs method is added. It allows a driver
> >> to set the number of parallel jobs and avoids calling device_run when
> >> the given number of jobs is already running. This is set to 1 by default
> >> to prevent parallel job runs. Drivers with the need and support for
> >> scheduling jobs can adjust this value accordingly.
> >> 
> >> Note that this change doesn't allow a context to be used multiple times
> >> in parallel. So a single stream won't be able to utilize multiple devices
> >> at once, but N streams can utilize up to N devices. This is caused by the
> >> fact that a context is not added multiple times to the job_list and also
> >> holds the job_flags to distinguish if it's currently running.
> > 
> > I do prefer this over Detlev proposal, so let's move toward this. Would be
> > it cleaner though to first remove curr_ctx and then add
> > max_parallel_jobs ?
> 
> Nice idea. I could move the max_parallel_jobs variable and the new
> function to a new small commit.
> 
> I could also move the whole looping and counting of running jobs over
> the jobs to the new commit. But this would cause replacing the curr_ctx
> variable with a `list_first_entry(...)->job_flags & TRANS_RUNNING` and
> drop it in the commit afterwards to replace it with loops.
> 
> While the commits would look a bit nicer in the latter example (as the
> removal of curr_ctx wouldn't also prepare for parallel jobs), I think
> the addition and direct removal style is frowned upon and therefore I
> tend towards the first option. On the other side I'm unsure if a 10 line
> patch to just add max_parallel_jobs variable and function with
> everything done in a (removal) patch provides benefit or harms to get to
> the related changes.

I rebased the rkvdec multicore support on this, and also used the same 
components approcah for cores probing ([1]).

All works well, I'll make sure to rebase on these changes when they happen.

Thanks for your work !

[1]: https://lore.kernel.org/all/[email protected]/

> >> @@ -252,13 +266,11 @@ EXPORT_SYMBOL(v4l2_m2m_get_curr_priv);
> >> 
> >>   static void v4l2_m2m_try_run(struct v4l2_m2m_dev *m2m_dev)
> >>   {
> >>   	unsigned long flags;
> >> 
> >> +	struct v4l2_m2m_ctx *ctx;
> >> +	struct v4l2_m2m_ctx *chosen_ctx = NULL;
> >> +	u32 running_jobs = 0;
> >> 
> >>   	spin_lock_irqsave(&m2m_dev->job_spinlock, flags);
> >> 
> >> -	if (NULL != m2m_dev->curr_ctx) {
> >> -		spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
> >> -		dprintk("Another instance is running, won't run 
now\n");
> >> -		return;
> >> -	}
> >> 
> >>   	if (list_empty(&m2m_dev->job_queue)) {
> >>   		spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
> >> 
> >> @@ -272,13 +284,30 @@ static void v4l2_m2m_try_run(struct v4l2_m2m_dev
> >> *m2m_dev)
> >> 
> >>   		return;
> >>   	}
> >> 
> >> -	m2m_dev->curr_ctx = list_first_entry(&m2m_dev->job_queue,
> >> -				   struct v4l2_m2m_ctx, queue);
> >> -	m2m_dev->curr_ctx->job_flags |= TRANS_RUNNING;
> >> +	list_for_each_entry(ctx, &m2m_dev->job_queue, queue) {
> >> +		if (!(ctx->job_flags & TRANS_RUNNING)) {
> >> +			chosen_ctx = ctx;
> >> +			break;
> >> +		}
> >> +
> >> +		running_jobs++;
> >> +	}
> >> +	if (running_jobs >= m2m_dev->max_parallel_jobs) {
> >> +		spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
> >> +		dprintk("Maximum number of parallel jobs reached\n");
> >> +		return;
> >> +	}
> >> +	if (!chosen_ctx) {
> >> +		spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
> >> +		dprintk("All jobs already running\n");
> >> +		return;
> >> +	}
> >> +
> >> +	chosen_ctx->job_flags |= TRANS_RUNNING;
> >> 
> >>   	spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
> 
> This is the most prominent example on how to split it up. E.g. either
> keep everything in the curr_ctx removal commit (and just use 1 for
> max_parallel_jobs) or use list_first_head to check if we have a curr_ctx
> and drop it afterwards for the counting logic.
> 
> 
> Sincerely
>      Sven
> 
> 
> _______________________________________________
> Linux-rockchip mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-rockchip
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.