* [PATCH] accel/ivpu: Add support for getting and setting command queue priority
@ 2026-08-31 12:16 Andrzej Kacprowski
2026-08-31 12:33 ` sashiko-bot
2026-09-09 10:13 ` Wachowski, Karol
0 siblings, 2 replies; 5+ messages in thread
From: Andrzej Kacprowski @ 2026-08-31 12:16 UTC (permalink / raw)
To: dri-devel
Cc: oded.gabbay, jeff.hugo, karol.wachowski, lizhi.hou,
andrzej.kacprowski, dawid.osuchowski
Add a new DRM_IVPU_PARAM_CMDQ_PRIORITY parameter to query and update
the scheduling priority of an existing command queue, identified by
its ID via drm_ivpu_param.index.
The priority can be changed on a queue that already has pending jobs;
if the queue's doorbell is registered, the new priority is propagated
to the firmware immediately, otherwise it is applied when the queue is
next registered. The firmware picks up the change at the first
opportunity.
The feature requires HW scheduling mode and is advertised through the
new DRM_IVPU_CAP_CMDQ_SET_PRIORITY capability. Legacy command queues
are not supported.
Signed-off-by: Andrzej Kacprowski <andrzej.kacprowski@linux.intel.com>
---
drivers/accel/ivpu/ivpu_drv.c | 13 ++++++
drivers/accel/ivpu/ivpu_job.c | 85 +++++++++++++++++++++++++++++++++++
drivers/accel/ivpu/ivpu_job.h | 5 ++-
include/uapi/drm/ivpu_accel.h | 17 ++++++-
4 files changed, 118 insertions(+), 2 deletions(-)
diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c
index 95120957f42a..0f215392d42d 100644
--- a/drivers/accel/ivpu/ivpu_drv.c
+++ b/drivers/accel/ivpu/ivpu_drv.c
@@ -205,6 +205,7 @@ bool ivpu_is_capable(struct ivpu_device *vdev, u32 capability)
case DRM_IVPU_CAP_BO_CREATE_FROM_USERPTR:
return true;
case DRM_IVPU_CAP_MANAGE_CMDQ:
+ case DRM_IVPU_CAP_CMDQ_SET_PRIORITY:
return vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW;
default:
return false;
@@ -273,6 +274,9 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f
case DRM_IVPU_PARAM_PREEMPT_BUFFER_SIZE:
args->value = ivpu_fw_preempt_buf_size(vdev);
break;
+ case DRM_IVPU_PARAM_CMDQ_PRIORITY:
+ ret = ivpu_cmdq_get_priority(file_priv, args->index, &args->value);
+ break;
default:
ret = -EINVAL;
break;
@@ -284,14 +288,23 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f
static int ivpu_set_param_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
{
+ struct ivpu_file_priv *file_priv = file->driver_priv;
struct drm_ivpu_param *args = data;
int ret = 0;
+ int idx;
+
+ if (!drm_dev_enter(dev, &idx))
+ return -ENODEV;
switch (args->param) {
+ case DRM_IVPU_PARAM_CMDQ_PRIORITY:
+ ret = ivpu_cmdq_set_priority(file_priv, args->index, args->value);
+ break;
default:
ret = -EINVAL;
}
+ drm_dev_exit(idx);
return ret;
}
diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c
index ebb2c865b09a..b3de5dd29d1e 100644
--- a/drivers/accel/ivpu/ivpu_job.c
+++ b/drivers/accel/ivpu/ivpu_job.c
@@ -323,6 +323,11 @@ static inline u8 ivpu_job_to_jsm_priority(u8 priority)
return priority - 1;
}
+static inline u8 ivpu_jsm_to_job_priority(u8 priority)
+{
+ return priority + 1;
+}
+
static void ivpu_cmdq_destroy(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq)
{
lockdep_assert_held(&file_priv->lock);
@@ -1127,6 +1132,86 @@ int ivpu_cmdq_destroy_ioctl(struct drm_device *dev, void *data, struct drm_file
return ret;
}
+static int ivpu_cmdq_priority_args_check(struct ivpu_device *vdev, u32 cmdq_id, u64 priority)
+{
+ if (!ivpu_is_capable(vdev, DRM_IVPU_CAP_CMDQ_SET_PRIORITY)) {
+ ivpu_dbg(vdev, IOCTL, "Command queue priority not supported\n");
+ return -ENODEV;
+ }
+
+ if (cmdq_id < IVPU_CMDQ_MIN_ID || cmdq_id > IVPU_CMDQ_MAX_ID) {
+ ivpu_dbg(vdev, IOCTL, "Invalid command queue ID %u\n", cmdq_id);
+ return -EINVAL;
+ }
+
+ if (priority > DRM_IVPU_JOB_PRIORITY_REALTIME)
+ return -EINVAL;
+
+ return 0;
+}
+
+int ivpu_cmdq_get_priority(struct ivpu_file_priv *file_priv, u32 cmdq_id, u64 *priority)
+{
+ struct ivpu_device *vdev = file_priv->vdev;
+ struct ivpu_cmdq *cmdq;
+ int ret;
+
+ ret = ivpu_cmdq_priority_args_check(vdev, cmdq_id, DRM_IVPU_JOB_PRIORITY_NORMAL);
+ if (ret)
+ return ret;
+
+ guard(mutex)(&file_priv->lock);
+
+ cmdq = ivpu_cmdq_acquire(file_priv, cmdq_id);
+ if (!cmdq || cmdq->is_legacy)
+ return -EINVAL;
+
+ *priority = ivpu_jsm_to_job_priority(cmdq->priority);
+ return 0;
+}
+
+int ivpu_cmdq_set_priority(struct ivpu_file_priv *file_priv, u32 cmdq_id, u64 priority)
+{
+ struct ivpu_device *vdev = file_priv->vdev;
+ struct ivpu_cmdq *cmdq;
+ u8 jsm_priority;
+ int ret = 0;
+
+ ret = ivpu_cmdq_priority_args_check(vdev, cmdq_id, priority);
+ if (ret)
+ return ret;
+
+ ret = ivpu_rpm_get(vdev);
+ if (ret < 0)
+ return ret;
+
+ mutex_lock(&file_priv->lock);
+
+ cmdq = ivpu_cmdq_acquire(file_priv, cmdq_id);
+ if (!cmdq || cmdq->is_legacy) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ jsm_priority = ivpu_job_to_jsm_priority(priority);
+ if (cmdq->priority == jsm_priority)
+ goto out;
+
+ if (cmdq->db_id) {
+ ret = ivpu_jsm_hws_set_context_sched_properties(vdev, file_priv->ctx.id, cmdq_id,
+ jsm_priority);
+ if (ret)
+ goto out;
+ }
+
+ cmdq->priority = jsm_priority;
+
+out:
+ mutex_unlock(&file_priv->lock);
+ ivpu_rpm_put(vdev);
+ return ret;
+}
+
static void
ivpu_job_done_callback(struct ivpu_device *vdev, struct ivpu_ipc_hdr *ipc_hdr,
struct vpu_jsm_msg *jsm_msg)
diff --git a/drivers/accel/ivpu/ivpu_job.h b/drivers/accel/ivpu/ivpu_job.h
index d8dbce82447a..6e32fea1eb62 100644
--- a/drivers/accel/ivpu/ivpu_job.h
+++ b/drivers/accel/ivpu/ivpu_job.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (C) 2020-2025 Intel Corporation
+ * Copyright (C) 2020-2026 Intel Corporation
*/
#ifndef __IVPU_JOB_H__
@@ -81,6 +81,9 @@ int ivpu_cmdq_create_ioctl(struct drm_device *dev, void *data, struct drm_file *
int ivpu_cmdq_destroy_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
int ivpu_cmdq_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
+int ivpu_cmdq_get_priority(struct ivpu_file_priv *file_priv, u32 cmdq_id, u64 *priority);
+int ivpu_cmdq_set_priority(struct ivpu_file_priv *file_priv, u32 cmdq_id, u64 priority);
+
void ivpu_context_abort_locked(struct ivpu_file_priv *file_priv);
void ivpu_cmdq_release_all_locked(struct ivpu_file_priv *file_priv);
diff --git a/include/uapi/drm/ivpu_accel.h b/include/uapi/drm/ivpu_accel.h
index 264505d54f93..9ce19d9c3131 100644
--- a/include/uapi/drm/ivpu_accel.h
+++ b/include/uapi/drm/ivpu_accel.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
/*
- * Copyright (C) 2020-2025 Intel Corporation
+ * Copyright (C) 2020-2026 Intel Corporation
*/
#ifndef __UAPI_IVPU_DRM_H__
@@ -96,6 +96,7 @@ extern "C" {
#define DRM_IVPU_PARAM_SKU 12
#define DRM_IVPU_PARAM_CAPABILITIES 13
#define DRM_IVPU_PARAM_PREEMPT_BUFFER_SIZE 14
+#define DRM_IVPU_PARAM_CMDQ_PRIORITY 15
#define DRM_IVPU_PLATFORM_TYPE_SILICON 0
@@ -140,6 +141,15 @@ extern "C" {
*/
#define DRM_IVPU_CAP_BO_CREATE_FROM_USERPTR 4
+/**
+ * DRM_IVPU_CAP_CMDQ_SET_PRIORITY
+ *
+ * Driver supports DRM_IVPU_PARAM_CMDQ_PRIORITY parameter to get/set command
+ * queue priority.
+ * This allows changing command queue priority after creation.
+ */
+#define DRM_IVPU_CAP_CMDQ_SET_PRIORITY 5
+
/**
* struct drm_ivpu_param - Get/Set VPU parameters
*/
@@ -192,6 +202,11 @@ struct drm_ivpu_param {
*
* %DRM_IVPU_PARAM_PREEMPT_BUFFER_SIZE:
* Size of the preemption buffer (read-only)
+ *
+ * %DRM_IVPU_PARAM_CMDQ_PRIORITY:
+ * Get/Set command queue priority (see DRM_IVPU_JOB_PRIORITY_*).
+ * DRM_IVPU_JOB_PRIORITY_DEFAULT is treated as DRM_IVPU_JOB_PRIORITY_NORMAL.
+ * Command queue ID is given via drm_ivpu_param.index.
*/
__u32 param;
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] accel/ivpu: Add support for getting and setting command queue priority
2026-08-31 12:16 [PATCH] accel/ivpu: Add support for getting and setting command queue priority Andrzej Kacprowski
@ 2026-08-31 12:33 ` sashiko-bot
2026-09-09 10:06 ` Andrzej Kacprowski
2026-09-09 10:13 ` Wachowski, Karol
1 sibling, 1 reply; 5+ messages in thread
From: sashiko-bot @ 2026-08-31 12:33 UTC (permalink / raw)
To: Andrzej Kacprowski; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Missing CAP_SYS_NICE or DRM_MASTER check for elevated job priorities (REALTIME / FOCUS), allowing unprivileged users to monopolize the NPU.
--
commit 57cf0d7005a7761ad6193ea568802164b7fac6db
Author: Andrzej Kacprowski <andrzej.kacprowski@linux.intel.com>
accel/ivpu: Add support for getting and setting command queue priority
This commit adds a new DRM_IVPU_PARAM_CMDQ_PRIORITY parameter to query and
update the scheduling priority of an existing command queue. The priority
can be changed on a queue that already has pending jobs, propagating the
change to firmware in hardware scheduling mode.
> diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c
> index ebb2c865b09a0..b3de5dd29d1e8 100644
> --- a/drivers/accel/ivpu/ivpu_job.c
> +++ b/drivers/accel/ivpu/ivpu_job.c
[ ... ]
> @@ -1127,6 +1132,86 @@ int ivpu_cmdq_destroy_ioctl(struct drm_device *dev, void *data, struct drm_file
> return ret;
> }
>
> +static int ivpu_cmdq_priority_args_check(struct ivpu_device *vdev, u32 cmdq_id, u64 priority)
> +{
> + if (!ivpu_is_capable(vdev, DRM_IVPU_CAP_CMDQ_SET_PRIORITY)) {
> + ivpu_dbg(vdev, IOCTL, "Command queue priority not supported\n");
> + return -ENODEV;
> + }
> +
> + if (cmdq_id < IVPU_CMDQ_MIN_ID || cmdq_id > IVPU_CMDQ_MAX_ID) {
> + ivpu_dbg(vdev, IOCTL, "Invalid command queue ID %u\n", cmdq_id);
> + return -EINVAL;
> + }
> +
> + if (priority > DRM_IVPU_JOB_PRIORITY_REALTIME)
> + return -EINVAL;
[Severity: High]
This is a pre-existing issue, but is there a missing capability check for
elevated priorities here?
An unprivileged user who opens the NPU device can call the IVPU_SET_PARAM
ioctl with DRM_IVPU_PARAM_CMDQ_PRIORITY and set the priority to
DRM_IVPU_JOB_PRIORITY_REALTIME. Without a CAP_SYS_NICE or DRM_MASTER check,
could a malicious or buggy application elevate its command queue priority to
monopolize the hardware and starve other processes?
I notice this same behavior appears to be pre-existing in
ivpu_cmdq_create_ioctl() as well, where queues can be created with realtime
priority by any user. Should these priority levels be restricted?
> +
> + return 0;
> +}
> +
> +int ivpu_cmdq_get_priority(struct ivpu_file_priv *file_priv, u32 cmdq_id, u64 *priority)
> +{
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260831121617.395523-1-andrzej.kacprowski@linux.intel.com?part=1
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] accel/ivpu: Add support for getting and setting command queue priority
2026-08-31 12:33 ` sashiko-bot
@ 2026-09-09 10:06 ` Andrzej Kacprowski
0 siblings, 0 replies; 5+ messages in thread
From: Andrzej Kacprowski @ 2026-09-09 10:06 UTC (permalink / raw)
To: sashiko-reviews; +Cc: dri-devel
On 31-Aug-26 2:33 PM, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
>
> Pre-existing issues:
> - [High] Missing CAP_SYS_NICE or DRM_MASTER check for elevated job priorities (REALTIME / FOCUS), allowing unprivileged users to monopolize the NPU.
> --
>
> commit 57cf0d7005a7761ad6193ea568802164b7fac6db
> Author: Andrzej Kacprowski <andrzej.kacprowski@linux.intel.com>
>
> accel/ivpu: Add support for getting and setting command queue priority
>
> This commit adds a new DRM_IVPU_PARAM_CMDQ_PRIORITY parameter to query and
> update the scheduling priority of an existing command queue. The priority
> can be changed on a queue that already has pending jobs, propagating the
> change to firmware in hardware scheduling mode.
>
>> diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c
>> index ebb2c865b09a0..b3de5dd29d1e8 100644
>> --- a/drivers/accel/ivpu/ivpu_job.c
>> +++ b/drivers/accel/ivpu/ivpu_job.c
>
> [ ... ]
>
>> @@ -1127,6 +1132,86 @@ int ivpu_cmdq_destroy_ioctl(struct drm_device *dev, void *data, struct drm_file
>> return ret;
>> }
>>
>> +static int ivpu_cmdq_priority_args_check(struct ivpu_device *vdev, u32 cmdq_id, u64 priority)
>> +{
>> + if (!ivpu_is_capable(vdev, DRM_IVPU_CAP_CMDQ_SET_PRIORITY)) {
>> + ivpu_dbg(vdev, IOCTL, "Command queue priority not supported\n");
>> + return -ENODEV;
>> + }
>> +
>> + if (cmdq_id < IVPU_CMDQ_MIN_ID || cmdq_id > IVPU_CMDQ_MAX_ID) {
>> + ivpu_dbg(vdev, IOCTL, "Invalid command queue ID %u\n", cmdq_id);
>> + return -EINVAL;
>> + }
>> +
>> + if (priority > DRM_IVPU_JOB_PRIORITY_REALTIME)
>> + return -EINVAL;
>
> [Severity: High]
> This is a pre-existing issue, but is there a missing capability check for
> elevated priorities here?
>
> An unprivileged user who opens the NPU device can call the IVPU_SET_PARAM
> ioctl with DRM_IVPU_PARAM_CMDQ_PRIORITY and set the priority to
> DRM_IVPU_JOB_PRIORITY_REALTIME. Without a CAP_SYS_NICE or DRM_MASTER check,
> could a malicious or buggy application elevate its command queue priority to
> monopolize the hardware and starve other processes?
>
> I notice this same behavior appears to be pre-existing in
> ivpu_cmdq_create_ioctl() as well, where queues can be created with realtime
> priority by any user. Should these priority levels be restricted?
>
The Intel NPU is not a display/graphics device and has no notion of
DRM_MASTER which is typically the display server process.
Using CAP_SYS_NICE has a bit more merit however:
- strict CAP_SYS_NICE check in KMD will break existing use cases
- no other accel drivers use CAP_SYS_NICE
Current strategy is to allow OS level AI runtime to control NPU workload
priority - dynamic priority change was added to
support that use case.
I will take it into consideration for future driver updates, but it
cannot be immediately solved in this patch.
- Andrzej
>> +
>> + return 0;
>> +}
>> +
>> +int ivpu_cmdq_get_priority(struct ivpu_file_priv *file_priv, u32 cmdq_id, u64 *priority)
>> +{
>
> [ ... ]
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] accel/ivpu: Add support for getting and setting command queue priority
2026-08-31 12:16 [PATCH] accel/ivpu: Add support for getting and setting command queue priority Andrzej Kacprowski
2026-08-31 12:33 ` sashiko-bot
@ 2026-09-09 10:13 ` Wachowski, Karol
2026-09-11 5:30 ` Wachowski, Karol
1 sibling, 1 reply; 5+ messages in thread
From: Wachowski, Karol @ 2026-09-09 10:13 UTC (permalink / raw)
To: Andrzej Kacprowski, dri-devel
Cc: oded.gabbay, jeff.hugo, lizhi.hou, dawid.osuchowski
On 31-Aug-26 14:16, Andrzej Kacprowski wrote:
> Add a new DRM_IVPU_PARAM_CMDQ_PRIORITY parameter to query and update
> the scheduling priority of an existing command queue, identified by
> its ID via drm_ivpu_param.index.
>
> The priority can be changed on a queue that already has pending jobs;
> if the queue's doorbell is registered, the new priority is propagated
> to the firmware immediately, otherwise it is applied when the queue is
> next registered. The firmware picks up the change at the first
> opportunity.
>
> The feature requires HW scheduling mode and is advertised through the
> new DRM_IVPU_CAP_CMDQ_SET_PRIORITY capability. Legacy command queues
> are not supported.
>
> Signed-off-by: Andrzej Kacprowski <andrzej.kacprowski@linux.intel.com>
> ---
> drivers/accel/ivpu/ivpu_drv.c | 13 ++++++
> drivers/accel/ivpu/ivpu_job.c | 85 +++++++++++++++++++++++++++++++++++
> drivers/accel/ivpu/ivpu_job.h | 5 ++-
> include/uapi/drm/ivpu_accel.h | 17 ++++++-
> 4 files changed, 118 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c
> index 95120957f42a..0f215392d42d 100644
> --- a/drivers/accel/ivpu/ivpu_drv.c
> +++ b/drivers/accel/ivpu/ivpu_drv.c
> @@ -205,6 +205,7 @@ bool ivpu_is_capable(struct ivpu_device *vdev, u32 capability)
> case DRM_IVPU_CAP_BO_CREATE_FROM_USERPTR:
> return true;
> case DRM_IVPU_CAP_MANAGE_CMDQ:
> + case DRM_IVPU_CAP_CMDQ_SET_PRIORITY:
> return vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW;
> default:
> return false;
> @@ -273,6 +274,9 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f
> case DRM_IVPU_PARAM_PREEMPT_BUFFER_SIZE:
> args->value = ivpu_fw_preempt_buf_size(vdev);
> break;
> + case DRM_IVPU_PARAM_CMDQ_PRIORITY:
> + ret = ivpu_cmdq_get_priority(file_priv, args->index, &args->value);
> + break;
> default:
> ret = -EINVAL;
> break;
> @@ -284,14 +288,23 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f
>
> static int ivpu_set_param_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
> {
> + struct ivpu_file_priv *file_priv = file->driver_priv;
> struct drm_ivpu_param *args = data;
> int ret = 0;
> + int idx;
> +
> + if (!drm_dev_enter(dev, &idx))
> + return -ENODEV;
>
> switch (args->param) {
> + case DRM_IVPU_PARAM_CMDQ_PRIORITY:
> + ret = ivpu_cmdq_set_priority(file_priv, args->index, args->value);
> + break;
> default:
> ret = -EINVAL;
> }
>
> + drm_dev_exit(idx);
> return ret;
> }
>
> diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c
> index ebb2c865b09a..b3de5dd29d1e 100644
> --- a/drivers/accel/ivpu/ivpu_job.c
> +++ b/drivers/accel/ivpu/ivpu_job.c
> @@ -323,6 +323,11 @@ static inline u8 ivpu_job_to_jsm_priority(u8 priority)
> return priority - 1;
> }
>
> +static inline u8 ivpu_jsm_to_job_priority(u8 priority)
> +{
> + return priority + 1;
> +}
> +
> static void ivpu_cmdq_destroy(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq)
> {
> lockdep_assert_held(&file_priv->lock);
> @@ -1127,6 +1132,86 @@ int ivpu_cmdq_destroy_ioctl(struct drm_device *dev, void *data, struct drm_file
> return ret;
> }
>
> +static int ivpu_cmdq_priority_args_check(struct ivpu_device *vdev, u32 cmdq_id, u64 priority)
> +{
> + if (!ivpu_is_capable(vdev, DRM_IVPU_CAP_CMDQ_SET_PRIORITY)) {
> + ivpu_dbg(vdev, IOCTL, "Command queue priority not supported\n");
> + return -ENODEV;
> + }
> +
> + if (cmdq_id < IVPU_CMDQ_MIN_ID || cmdq_id > IVPU_CMDQ_MAX_ID) {
> + ivpu_dbg(vdev, IOCTL, "Invalid command queue ID %u\n", cmdq_id);
> + return -EINVAL;
> + }
> +
> + if (priority > DRM_IVPU_JOB_PRIORITY_REALTIME)
> + return -EINVAL;
> +
> + return 0;
> +}
> +
> +int ivpu_cmdq_get_priority(struct ivpu_file_priv *file_priv, u32 cmdq_id, u64 *priority)
> +{
> + struct ivpu_device *vdev = file_priv->vdev;
> + struct ivpu_cmdq *cmdq;
> + int ret;
> +
> + ret = ivpu_cmdq_priority_args_check(vdev, cmdq_id, DRM_IVPU_JOB_PRIORITY_NORMAL);
> + if (ret)
> + return ret;
> +
> + guard(mutex)(&file_priv->lock);
> +
> + cmdq = ivpu_cmdq_acquire(file_priv, cmdq_id);
> + if (!cmdq || cmdq->is_legacy)
> + return -EINVAL;
> +
> + *priority = ivpu_jsm_to_job_priority(cmdq->priority);
> + return 0;
> +}
> +
> +int ivpu_cmdq_set_priority(struct ivpu_file_priv *file_priv, u32 cmdq_id, u64 priority)
> +{
> + struct ivpu_device *vdev = file_priv->vdev;
> + struct ivpu_cmdq *cmdq;
> + u8 jsm_priority;
> + int ret = 0;
> +
> + ret = ivpu_cmdq_priority_args_check(vdev, cmdq_id, priority);
> + if (ret)
> + return ret;
> +
> + ret = ivpu_rpm_get(vdev);
> + if (ret < 0)
> + return ret;
> +
> + mutex_lock(&file_priv->lock);
> +
> + cmdq = ivpu_cmdq_acquire(file_priv, cmdq_id);
> + if (!cmdq || cmdq->is_legacy) {
> + ret = -EINVAL;
> + goto out;
> + }
> +
> + jsm_priority = ivpu_job_to_jsm_priority(priority);
> + if (cmdq->priority == jsm_priority)
> + goto out;
> +
> + if (cmdq->db_id) {
> + ret = ivpu_jsm_hws_set_context_sched_properties(vdev, file_priv->ctx.id, cmdq_id,
> + jsm_priority);
> + if (ret)
> + goto out;
> + }
> +
> + cmdq->priority = jsm_priority;
> +
> +out:
> + mutex_unlock(&file_priv->lock);
> + ivpu_rpm_put(vdev);
> + return ret;
> +}
> +
> static void
> ivpu_job_done_callback(struct ivpu_device *vdev, struct ivpu_ipc_hdr *ipc_hdr,
> struct vpu_jsm_msg *jsm_msg)
> diff --git a/drivers/accel/ivpu/ivpu_job.h b/drivers/accel/ivpu/ivpu_job.h
> index d8dbce82447a..6e32fea1eb62 100644
> --- a/drivers/accel/ivpu/ivpu_job.h
> +++ b/drivers/accel/ivpu/ivpu_job.h
> @@ -1,6 +1,6 @@
> /* SPDX-License-Identifier: GPL-2.0-only */
> /*
> - * Copyright (C) 2020-2025 Intel Corporation
> + * Copyright (C) 2020-2026 Intel Corporation
> */
>
> #ifndef __IVPU_JOB_H__
> @@ -81,6 +81,9 @@ int ivpu_cmdq_create_ioctl(struct drm_device *dev, void *data, struct drm_file *
> int ivpu_cmdq_destroy_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
> int ivpu_cmdq_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
>
> +int ivpu_cmdq_get_priority(struct ivpu_file_priv *file_priv, u32 cmdq_id, u64 *priority);
> +int ivpu_cmdq_set_priority(struct ivpu_file_priv *file_priv, u32 cmdq_id, u64 priority);
> +
> void ivpu_context_abort_locked(struct ivpu_file_priv *file_priv);
>
> void ivpu_cmdq_release_all_locked(struct ivpu_file_priv *file_priv);
> diff --git a/include/uapi/drm/ivpu_accel.h b/include/uapi/drm/ivpu_accel.h
> index 264505d54f93..9ce19d9c3131 100644
> --- a/include/uapi/drm/ivpu_accel.h
> +++ b/include/uapi/drm/ivpu_accel.h
> @@ -1,6 +1,6 @@
> /* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
> /*
> - * Copyright (C) 2020-2025 Intel Corporation
> + * Copyright (C) 2020-2026 Intel Corporation
> */
>
> #ifndef __UAPI_IVPU_DRM_H__
> @@ -96,6 +96,7 @@ extern "C" {
> #define DRM_IVPU_PARAM_SKU 12
> #define DRM_IVPU_PARAM_CAPABILITIES 13
> #define DRM_IVPU_PARAM_PREEMPT_BUFFER_SIZE 14
> +#define DRM_IVPU_PARAM_CMDQ_PRIORITY 15
>
> #define DRM_IVPU_PLATFORM_TYPE_SILICON 0
>
> @@ -140,6 +141,15 @@ extern "C" {
> */
> #define DRM_IVPU_CAP_BO_CREATE_FROM_USERPTR 4
>
> +/**
> + * DRM_IVPU_CAP_CMDQ_SET_PRIORITY
> + *
> + * Driver supports DRM_IVPU_PARAM_CMDQ_PRIORITY parameter to get/set command
> + * queue priority.
> + * This allows changing command queue priority after creation.
> + */
> +#define DRM_IVPU_CAP_CMDQ_SET_PRIORITY 5
> +
> /**
> * struct drm_ivpu_param - Get/Set VPU parameters
> */
> @@ -192,6 +202,11 @@ struct drm_ivpu_param {
> *
> * %DRM_IVPU_PARAM_PREEMPT_BUFFER_SIZE:
> * Size of the preemption buffer (read-only)
> + *
> + * %DRM_IVPU_PARAM_CMDQ_PRIORITY:
> + * Get/Set command queue priority (see DRM_IVPU_JOB_PRIORITY_*).
> + * DRM_IVPU_JOB_PRIORITY_DEFAULT is treated as DRM_IVPU_JOB_PRIORITY_NORMAL.
> + * Command queue ID is given via drm_ivpu_param.index.
> */
> __u32 param;
>
Reviewed-by: Karol Wachowski <karol.wachowski@linux.intel.com>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] accel/ivpu: Add support for getting and setting command queue priority
2026-09-09 10:13 ` Wachowski, Karol
@ 2026-09-11 5:30 ` Wachowski, Karol
0 siblings, 0 replies; 5+ messages in thread
From: Wachowski, Karol @ 2026-09-11 5:30 UTC (permalink / raw)
To: Andrzej Kacprowski, dri-devel
Cc: oded.gabbay, jeff.hugo, lizhi.hou, dawid.osuchowski
On 09-Sep-26 12:13, Wachowski, Karol wrote:
> On 31-Aug-26 14:16, Andrzej Kacprowski wrote:
>> Add a new DRM_IVPU_PARAM_CMDQ_PRIORITY parameter to query and update
>> the scheduling priority of an existing command queue, identified by
>> its ID via drm_ivpu_param.index.
>>
>> The priority can be changed on a queue that already has pending jobs;
>> if the queue's doorbell is registered, the new priority is propagated
>> to the firmware immediately, otherwise it is applied when the queue is
>> next registered. The firmware picks up the change at the first
>> opportunity.
>>
>> The feature requires HW scheduling mode and is advertised through the
>> new DRM_IVPU_CAP_CMDQ_SET_PRIORITY capability. Legacy command queues
>> are not supported.
>>
>> Signed-off-by: Andrzej Kacprowski <andrzej.kacprowski@linux.intel.com>
>> ---
>> drivers/accel/ivpu/ivpu_drv.c | 13 ++++++
>> drivers/accel/ivpu/ivpu_job.c | 85 +++++++++++++++++++++++++++++++++++
>> drivers/accel/ivpu/ivpu_job.h | 5 ++-
>> include/uapi/drm/ivpu_accel.h | 17 ++++++-
>> 4 files changed, 118 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/
>> ivpu_drv.c
>> index 95120957f42a..0f215392d42d 100644
>> --- a/drivers/accel/ivpu/ivpu_drv.c
>> +++ b/drivers/accel/ivpu/ivpu_drv.c
>> @@ -205,6 +205,7 @@ bool ivpu_is_capable(struct ivpu_device *vdev, u32
>> capability)
>> case DRM_IVPU_CAP_BO_CREATE_FROM_USERPTR:
>> return true;
>> case DRM_IVPU_CAP_MANAGE_CMDQ:
>> + case DRM_IVPU_CAP_CMDQ_SET_PRIORITY:
>> return vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW;
>> default:
>> return false;
>> @@ -273,6 +274,9 @@ static int ivpu_get_param_ioctl(struct drm_device
>> *dev, void *data, struct drm_f
>> case DRM_IVPU_PARAM_PREEMPT_BUFFER_SIZE:
>> args->value = ivpu_fw_preempt_buf_size(vdev);
>> break;
>> + case DRM_IVPU_PARAM_CMDQ_PRIORITY:
>> + ret = ivpu_cmdq_get_priority(file_priv, args->index, &args-
>> >value);
>> + break;
>> default:
>> ret = -EINVAL;
>> break;
>> @@ -284,14 +288,23 @@ static int ivpu_get_param_ioctl(struct
>> drm_device *dev, void *data, struct drm_f
>> static int ivpu_set_param_ioctl(struct drm_device *dev, void *data,
>> struct drm_file *file)
>> {
>> + struct ivpu_file_priv *file_priv = file->driver_priv;
>> struct drm_ivpu_param *args = data;
>> int ret = 0;
>> + int idx;
>> +
>> + if (!drm_dev_enter(dev, &idx))
>> + return -ENODEV;
>> switch (args->param) {
>> + case DRM_IVPU_PARAM_CMDQ_PRIORITY:
>> + ret = ivpu_cmdq_set_priority(file_priv, args->index, args-
>> >value);
>> + break;
>> default:
>> ret = -EINVAL;
>> }
>> + drm_dev_exit(idx);
>> return ret;
>> }
>> diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/
>> ivpu_job.c
>> index ebb2c865b09a..b3de5dd29d1e 100644
>> --- a/drivers/accel/ivpu/ivpu_job.c
>> +++ b/drivers/accel/ivpu/ivpu_job.c
>> @@ -323,6 +323,11 @@ static inline u8 ivpu_job_to_jsm_priority(u8
>> priority)
>> return priority - 1;
>> }
>> +static inline u8 ivpu_jsm_to_job_priority(u8 priority)
>> +{
>> + return priority + 1;
>> +}
>> +
>> static void ivpu_cmdq_destroy(struct ivpu_file_priv *file_priv,
>> struct ivpu_cmdq *cmdq)
>> {
>> lockdep_assert_held(&file_priv->lock);
>> @@ -1127,6 +1132,86 @@ int ivpu_cmdq_destroy_ioctl(struct drm_device
>> *dev, void *data, struct drm_file
>> return ret;
>> }
>> +static int ivpu_cmdq_priority_args_check(struct ivpu_device *vdev,
>> u32 cmdq_id, u64 priority)
>> +{
>> + if (!ivpu_is_capable(vdev, DRM_IVPU_CAP_CMDQ_SET_PRIORITY)) {
>> + ivpu_dbg(vdev, IOCTL, "Command queue priority not supported\n");
>> + return -ENODEV;
>> + }
>> +
>> + if (cmdq_id < IVPU_CMDQ_MIN_ID || cmdq_id > IVPU_CMDQ_MAX_ID) {
>> + ivpu_dbg(vdev, IOCTL, "Invalid command queue ID %u\n", cmdq_id);
>> + return -EINVAL;
>> + }
>> +
>> + if (priority > DRM_IVPU_JOB_PRIORITY_REALTIME)
>> + return -EINVAL;
>> +
>> + return 0;
>> +}
>> +
>> +int ivpu_cmdq_get_priority(struct ivpu_file_priv *file_priv, u32
>> cmdq_id, u64 *priority)
>> +{
>> + struct ivpu_device *vdev = file_priv->vdev;
>> + struct ivpu_cmdq *cmdq;
>> + int ret;
>> +
>> + ret = ivpu_cmdq_priority_args_check(vdev, cmdq_id,
>> DRM_IVPU_JOB_PRIORITY_NORMAL);
>> + if (ret)
>> + return ret;
>> +
>> + guard(mutex)(&file_priv->lock);
>> +
>> + cmdq = ivpu_cmdq_acquire(file_priv, cmdq_id);
>> + if (!cmdq || cmdq->is_legacy)
>> + return -EINVAL;
>> +
>> + *priority = ivpu_jsm_to_job_priority(cmdq->priority);
>> + return 0;
>> +}
>> +
>> +int ivpu_cmdq_set_priority(struct ivpu_file_priv *file_priv, u32
>> cmdq_id, u64 priority)
>> +{
>> + struct ivpu_device *vdev = file_priv->vdev;
>> + struct ivpu_cmdq *cmdq;
>> + u8 jsm_priority;
>> + int ret = 0;
>> +
>> + ret = ivpu_cmdq_priority_args_check(vdev, cmdq_id, priority);
>> + if (ret)
>> + return ret;
>> +
>> + ret = ivpu_rpm_get(vdev);
>> + if (ret < 0)
>> + return ret;
>> +
>> + mutex_lock(&file_priv->lock);
>> +
>> + cmdq = ivpu_cmdq_acquire(file_priv, cmdq_id);
>> + if (!cmdq || cmdq->is_legacy) {
>> + ret = -EINVAL;
>> + goto out;
>> + }
>> +
>> + jsm_priority = ivpu_job_to_jsm_priority(priority);
>> + if (cmdq->priority == jsm_priority)
>> + goto out;
>> +
>> + if (cmdq->db_id) {
>> + ret = ivpu_jsm_hws_set_context_sched_properties(vdev,
>> file_priv->ctx.id, cmdq_id,
>> + jsm_priority);
>> + if (ret)
>> + goto out;
>> + }
>> +
>> + cmdq->priority = jsm_priority;
>> +
>> +out:
>> + mutex_unlock(&file_priv->lock);
>> + ivpu_rpm_put(vdev);
>> + return ret;
>> +}
>> +
>> static void
>> ivpu_job_done_callback(struct ivpu_device *vdev, struct ivpu_ipc_hdr
>> *ipc_hdr,
>> struct vpu_jsm_msg *jsm_msg)
>> diff --git a/drivers/accel/ivpu/ivpu_job.h b/drivers/accel/ivpu/
>> ivpu_job.h
>> index d8dbce82447a..6e32fea1eb62 100644
>> --- a/drivers/accel/ivpu/ivpu_job.h
>> +++ b/drivers/accel/ivpu/ivpu_job.h
>> @@ -1,6 +1,6 @@
>> /* SPDX-License-Identifier: GPL-2.0-only */
>> /*
>> - * Copyright (C) 2020-2025 Intel Corporation
>> + * Copyright (C) 2020-2026 Intel Corporation
>> */
>> #ifndef __IVPU_JOB_H__
>> @@ -81,6 +81,9 @@ int ivpu_cmdq_create_ioctl(struct drm_device *dev,
>> void *data, struct drm_file *
>> int ivpu_cmdq_destroy_ioctl(struct drm_device *dev, void *data,
>> struct drm_file *file);
>> int ivpu_cmdq_submit_ioctl(struct drm_device *dev, void *data,
>> struct drm_file *file);
>> +int ivpu_cmdq_get_priority(struct ivpu_file_priv *file_priv, u32
>> cmdq_id, u64 *priority);
>> +int ivpu_cmdq_set_priority(struct ivpu_file_priv *file_priv, u32
>> cmdq_id, u64 priority);
>> +
>> void ivpu_context_abort_locked(struct ivpu_file_priv *file_priv);
>> void ivpu_cmdq_release_all_locked(struct ivpu_file_priv *file_priv);
>> diff --git a/include/uapi/drm/ivpu_accel.h b/include/uapi/drm/
>> ivpu_accel.h
>> index 264505d54f93..9ce19d9c3131 100644
>> --- a/include/uapi/drm/ivpu_accel.h
>> +++ b/include/uapi/drm/ivpu_accel.h
>> @@ -1,6 +1,6 @@
>> /* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
>> /*
>> - * Copyright (C) 2020-2025 Intel Corporation
>> + * Copyright (C) 2020-2026 Intel Corporation
>> */
>> #ifndef __UAPI_IVPU_DRM_H__
>> @@ -96,6 +96,7 @@ extern "C" {
>> #define DRM_IVPU_PARAM_SKU 12
>> #define DRM_IVPU_PARAM_CAPABILITIES 13
>> #define DRM_IVPU_PARAM_PREEMPT_BUFFER_SIZE 14
>> +#define DRM_IVPU_PARAM_CMDQ_PRIORITY 15
>> #define DRM_IVPU_PLATFORM_TYPE_SILICON 0
>> @@ -140,6 +141,15 @@ extern "C" {
>> */
>> #define DRM_IVPU_CAP_BO_CREATE_FROM_USERPTR 4
>> +/**
>> + * DRM_IVPU_CAP_CMDQ_SET_PRIORITY
>> + *
>> + * Driver supports DRM_IVPU_PARAM_CMDQ_PRIORITY parameter to get/set
>> command
>> + * queue priority.
>> + * This allows changing command queue priority after creation.
>> + */
>> +#define DRM_IVPU_CAP_CMDQ_SET_PRIORITY 5
>> +
>> /**
>> * struct drm_ivpu_param - Get/Set VPU parameters
>> */
>> @@ -192,6 +202,11 @@ struct drm_ivpu_param {
>> *
>> * %DRM_IVPU_PARAM_PREEMPT_BUFFER_SIZE:
>> * Size of the preemption buffer (read-only)
>> + *
>> + * %DRM_IVPU_PARAM_CMDQ_PRIORITY:
>> + * Get/Set command queue priority (see DRM_IVPU_JOB_PRIORITY_*).
>> + * DRM_IVPU_JOB_PRIORITY_DEFAULT is treated as
>> DRM_IVPU_JOB_PRIORITY_NORMAL.
>> + * Command queue ID is given via drm_ivpu_param.index.
>> */
>> __u32 param;
>
> Reviewed-by: Karol Wachowski <karol.wachowski@linux.intel.com>
Applied to drm-misc-next.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-09-11 5:30 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-31 12:16 [PATCH] accel/ivpu: Add support for getting and setting command queue priority Andrzej Kacprowski
2026-08-31 12:33 ` sashiko-bot
2026-09-09 10:06 ` Andrzej Kacprowski
2026-09-09 10:13 ` Wachowski, Karol
2026-09-11 5:30 ` Wachowski, Karol
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox