From: Ketil Johnsen <ketil.johnsen@xxxxxxx> * Extend GROUP_CREATE to allow the kernel to expose the ringbuf, user I/O and doorbell pages for each queue, and add eventfds to signal sync updates and group state changes * Add a KICK ioctl to re-evaluate queues within a group * Add cross-group sync (XGS) queues as a mechanism to synchronise between groups' queues across a VM * Add a SYNC_UPDATE ioctl for user to notify kernel that it needs to re-evaluate groups and XGS queues; use eventfds for kernel-to-user notifications Signed-off-by: Ketil Johnsen <ketil.johnsen@xxxxxxx> Co-developed-by: Mihail Atanassov <mihail.atanassov@xxxxxxx> Signed-off-by: Mihail Atanassov <mihail.atanassov@xxxxxxx> --- This is going to conflict with [1] due to the driver version bump. [1] https://lore.kernel.org/dri-devel/20240819112508.67988-2-mary.guillemard@xxxxxxxxxxxxx/ drivers/gpu/drm/panthor/panthor_drv.c | 3 +- drivers/gpu/drm/panthor/panthor_sched.c | 2 +- include/uapi/drm/panthor_drm.h | 243 +++++++++++++++++++++++- 3 files changed, 244 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c index b5e7b919f241..4f1efe616698 100644 --- a/drivers/gpu/drm/panthor/panthor_drv.c +++ b/drivers/gpu/drm/panthor/panthor_drv.c @@ -1372,6 +1372,7 @@ static void panthor_debugfs_init(struct drm_minor *minor) /* * PanCSF driver version: * - 1.0 - initial interface + * - 1.1 - add user submission path */ static const struct drm_driver panthor_drm_driver = { .driver_features = DRIVER_RENDER | DRIVER_GEM | DRIVER_SYNCOBJ | @@ -1385,7 +1386,7 @@ static const struct drm_driver panthor_drm_driver = { .desc = "Panthor DRM driver", .date = "20230801", .major = 1, - .minor = 0, + .minor = 1, .gem_create_object = panthor_gem_create_object, .gem_prime_import_sg_table = drm_gem_shmem_prime_import_sg_table, diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c index 463bcd3cf00f..b2cf053b3601 100644 --- a/drivers/gpu/drm/panthor/panthor_sched.c +++ b/drivers/gpu/drm/panthor/panthor_sched.c @@ -3089,7 +3089,7 @@ int panthor_group_create(struct panthor_file *pfile, u32 gid, i, suspend_size; int ret; - if (group_args->pad) + if (group_args->flags & ~DRM_PANTHOR_GROUP_CREATE_USER_SUBMIT) return -EINVAL; if (group_args->priority > PANTHOR_CSG_PRIORITY_HIGH) diff --git a/include/uapi/drm/panthor_drm.h b/include/uapi/drm/panthor_drm.h index 926b1deb1116..1a6a3877e5b3 100644 --- a/include/uapi/drm/panthor_drm.h +++ b/include/uapi/drm/panthor_drm.h @@ -127,6 +127,21 @@ enum drm_panthor_ioctl_id { /** @DRM_PANTHOR_TILER_HEAP_DESTROY: Destroy a tiler heap. */ DRM_PANTHOR_TILER_HEAP_DESTROY, + + /** @DRM_PANTHOR_GROUP_KICK: Re-evaluate group for scheduling. */ + DRM_PANTHOR_GROUP_KICK, + + /** @DRM_PANTHOR_XGS_QUEUE_CREATE: Create a cross-group sync queue. */ + DRM_PANTHOR_XGS_QUEUE_CREATE, + + /** @DRM_PANTHOR_XGS_QUEUE_DESTROY: Destroy a cross-group sync queue. */ + DRM_PANTHOR_XGS_QUEUE_DESTROY, + + /** @DRM_PANTHOR_XGS_QUEUE_SUBMIT: Submit a cross-group sync op to an XGS queue. */ + DRM_PANTHOR_XGS_QUEUE_SUBMIT, + + /** @DRM_PANTHOR_SYNC_UPDATE: Notify kernel that a HW syncobj has been updated. */ + DRM_PANTHOR_SYNC_UPDATE, }; /** @@ -170,6 +185,16 @@ enum drm_panthor_ioctl_id { DRM_IOCTL_PANTHOR(WR, TILER_HEAP_CREATE, tiler_heap_create) #define DRM_IOCTL_PANTHOR_TILER_HEAP_DESTROY \ DRM_IOCTL_PANTHOR(WR, TILER_HEAP_DESTROY, tiler_heap_destroy) +#define DRM_IOCTL_PANTHOR_GROUP_KICK \ + DRM_IOCTL_PANTHOR(WR, GROUP_KICK, group_kick) +#define DRM_IOCTL_PANTHOR_XGS_QUEUE_CREATE \ + DRM_IOCTL_PANTHOR(WR, XGS_QUEUE_CREATE, xgs_queue_create) +#define DRM_IOCTL_PANTHOR_XGS_QUEUE_DESTROY \ + DRM_IOCTL_PANTHOR(WR, XGS_QUEUE_DESTROY, xgs_queue_destroy) +#define DRM_IOCTL_PANTHOR_XGS_QUEUE_SUBMIT \ + DRM_IOCTL_PANTHOR(WR, XGS_QUEUE_SUBMIT, xgs_queue_submit) +#define DRM_IOCTL_PANTHOR_SYNC_UPDATE \ + DRM_IOCTL_PANTHOR(WR, SYNC_UPDATE, sync_update) /** * DOC: IOCTL arguments @@ -680,6 +705,40 @@ struct drm_panthor_queue_create { /** @ringbuf_size: Size of the ring buffer to allocate to this queue. */ __u32 ringbuf_size; + + /** + * @ringbuf_offset: file offset to map the ring buffer + * + * Returns a file offset which can be used to map the queues ring buffer. + * The size of this buffer is as requested with @ringbuf_size + * + * Only valid if DRM_PANTHOR_GROUP_CREATE_USER_SUBMIT is set in + * the respective drm_panthor_group_create::flags, 0 otherwise. + */ + __u64 ringbuf_offset; + + /** + * @user_io_offset: file offset to map user input/output pages. + * + * Returns a file offset which can be used to map the user input page + * and the user output page (two consecutive pages). + * + * Only valid if DRM_PANTHOR_GROUP_CREATE_USER_SUBMIT is set in + * the respective drm_panthor_group_create::flags, 0 otherwise. + */ + __u64 user_io_offset; + + /** + * @doorbell_offset: file offset to map doorbell page + * + * Returns a file offset which can be used to map the queues HW doorbell page. + * Note: multiple queues can share same HW doorbell page, and this offset + * will be the same in this case. + * + * Only valid if DRM_PANTHOR_GROUP_CREATE_USER_SUBMIT is set in + * the respective drm_panthor_group_create::flags, 0 otherwise. + */ + __u64 doorbell_offset; }; /** @@ -696,6 +755,16 @@ enum drm_panthor_group_priority { PANTHOR_GROUP_PRIORITY_HIGH, }; +/** + * enum drm_panthor_group_create_flags - Flags for group creation + */ +enum drm_panthor_group_create_flags { + /** + * @DRM_PANTHOR_GROUP_CREATE_USER_SUBMIT: Enable user submission + */ + DRM_PANTHOR_GROUP_CREATE_USER_SUBMIT = 1 << 0, +}; + /** * struct drm_panthor_group_create - Arguments passed to DRM_IOCTL_PANTHOR_GROUP_CREATE */ @@ -730,8 +799,8 @@ struct drm_panthor_group_create { /** @priority: Group priority (see enum drm_panthor_group_priority). */ __u8 priority; - /** @pad: Padding field, MBZ. */ - __u32 pad; + /** @flags: Combination of drm_panthor_group_create_flags flags */ + __u32 flags; /** * @compute_core_mask: Mask encoding cores that can be used for compute jobs. @@ -772,6 +841,23 @@ struct drm_panthor_group_create { * destroying a group. */ __u32 group_handle; + + /** + * @eventfd_sync_update: eventfd to increment for group SYNC_UPDATE events + * + * Only valid when DRM_PANTHOR_GROUP_CREATE_USER_SUBMIT is set. + * Can be set to -1 if UMD don't want to receive these events. + */ + __s32 eventfd_sync_update; + + /** + * @eventfd_group_state: eventfd to increment when group state has been changed + * + * Only valid when DRM_PANTHOR_GROUP_CREATE_USER_SUBMIT is set. + * Can be set to -1 if UMD don't want to receive these events. + * DRM_IOCTL_PANTHOR_GROUP_GET_STATE should be used to retrieve the new group state. + */ + __s32 eventfd_group_state; }; /** @@ -955,6 +1041,159 @@ struct drm_panthor_tiler_heap_destroy { __u32 pad; }; +/** + * @struct drm_panthor_group_kick - arguments to DRM_IOCTL_PANTHOR_GROUP_KICK + */ +struct drm_panthor_group_kick { + /** @handle: handle to group */ + __u32 handle; + + /** @queue_mask: mask with queues to kick */ + __u32 queue_mask; +}; + +/** + * struct drm_panthor_xgs_queue_create - Arguments passed to DRM_IOCTL_PANTHOR_XGS_QUEUE_CREATE + */ +struct drm_panthor_xgs_queue_create { + /** @vm_id: VM id to associate this XGS queue with */ + __u32 vm_id; + + /** + * @eventfd_sync_update: eventfd to increment when a XGS object has been set + * + * Can be set to -1 if UMD don't want to receive these events. + */ + __s32 eventfd_sync_update; + + /** @handle: Returned handle to the XGS queue created */ + __u32 handle; + + /** @pad: MBZ */ + __u32 pad; +}; + +/** + * struct drm_panthor_xgs_queue_destroy - Arguments passed to DRM_IOCTL_PANTHOR_XGS_QUEUE_DESTROY + */ +struct drm_panthor_xgs_queue_destroy { + /** @handle: handle to XGS queue to destroy */ + __u32 handle; + + /** @pad: MBZ */ + __u32 pad; +}; + +/** + * enum drm_panthor_xgs_ops - Types of XGS operations + */ +enum drm_panthor_xgs_ops { + /** @DRM_PANTHOR_XGS_OP_WAIT_LE: Wait for condition to be less-or-equal specified value */ + DRM_PANTHOR_XGS_OP_WAIT_LE = 0, + + /** @DRM_PANTHOR_XGS_OP_WAIT_GT: Wait for condition to be greater than specified value */ + DRM_PANTHOR_XGS_OP_WAIT_GT, + + /** @DRM_PANTHOR_XGS_OP_SIGNAL_SET: Set XGS object to specified value */ + DRM_PANTHOR_XGS_OP_SIGNAL_SET, + + /** @DRM_PANTHOR_XGS_OP_SIGNAL_ADD: Add specified value to XGS object */ + DRM_PANTHOR_XGS_OP_SIGNAL_ADD +}; + +/** + * enum drm_panthor_xgs_op_formnat - Format of XGS object + */ +enum drm_panthor_xgs_op_format { + /** @DRM_PANTHOR_XGS_OP_FORMAT_U32: XGS object is of 32-bit format */ + DRM_PANTHOR_XGS_OP_FORMAT_U32 = 0, + + /** @DRM_PANTHOR_XGS_OP_FORMAT_U64: XGS object is of 64-bit format */ + DRM_PANTHOR_XGS_OP_FORMAT_U64 +}; + +/** + * enum drm_panthor_xgs_op_flags - Flags for a XGS operation + */ +enum drm_panthor_xgs_op_flags { + /** + * @DRM_PANTHOR_XGS_OP_INHERIT_ERROR_WAIT: Propagate XGS wait errors to XGS queue + * + * WAIT operations for a XGS which is signaled with error will set this XGS queue + * in an error state. This error state is cleared on next XGS submit with either the + * @DRM_PANTHOR_XGS_QUEUE_SUBMIT_ERROR_BARRIER_PRE or + * DRM_PANTHOR_XGS_QUEUE_SUBMIT_ERROR_BARRIER_POST flag set. + * + * Note: Errors during SIGNAL operations will always set the XGS queue in an error state + */ + DRM_PANTHOR_XGS_OP_INHERIT_ERROR_WAIT = 1 << 0 +}; + +/** + * struct drm_panthor_xgs_op - XGS operation + */ +struct drm_panthor_xgs_op { + /** @addr: GPU address of XGS object */ + __u64 addr; + + /** @value: value to WAIT for or SET/ADD */ + __u64 value; + + /** @op: operation from enum drm_panthor_xgs_ops */ + __u8 op; + + /** @format: format from enum drm_panthor_xgs_op_format */ + __u8 format; + + /** @flags: flags from enum drm_panthor_xgs_op_flags */ + __u16 flags; + + /** @pad: MBZ */ + __u32 pad; +}; + +/** + * enum drm_panthor_xgs_queue_submit_flags - Flags for XGS queue submission + */ +enum drm_panthor_xgs_queue_submit_flags { + /** @DRM_PANTHOR_XGS_QUEUE_SUBMIT_ERROR_BARRIER_PRE: Error barrier pre operation + * + * Clear queue error state before processing the XGS operations + */ + DRM_PANTHOR_XGS_QUEUE_SUBMIT_ERROR_BARRIER_PRE = 1 << 0, + + /** @DRM_PANTHOR_XGS_QUEUE_SUBMIT_ERROR_BARRIER_POST: Error barrier post operation + * + * Clear queue error state after processing the XGS operations + */ + DRM_PANTHOR_XGS_QUEUE_SUBMIT_ERROR_BARRIER_POST = 1 << 1 +}; + +/** + * struct drm_panthor_xgs_queue_submit - Arguments passed to DRM_IOCTL_PANTHOR_XGS_QUEUE_SUBMIT + */ +struct drm_panthor_xgs_queue_submit { + /** @handle: XGS queue handle to submit work to */ + __u32 handle; + + /** @flags: flags from enum drm_panthor_xgs_queue_submit_flags */ + __u32 flags; + + /** @ops: Array of struct drm_panthor_xgs_op sync operations */ + struct drm_panthor_obj_array ops; + + /** @syncs: Array of struct drm_panthor_sync_op sync operations */ + struct drm_panthor_obj_array syncs; +}; + +/** + * struct drm_panthor_sync_update - Arguments passed to DRM_IOCTL_PANTHOR_SYNC_UPDATE + */ +struct drm_panthor_sync_update { + /** @pad: MBZ */ + __u64 pad; +}; + #if defined(__cplusplus) } #endif -- 2.45.0