* [PATCH i-g-t v2 0/3] tests/panthor: Add more tests
@ 2025-11-28 9:38 Boris Brezillon
2025-11-28 9:38 ` [PATCH i-g-t v2 1/3] drm-uapi/panthor: Sync panthor uapi Boris Brezillon
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Boris Brezillon @ 2025-11-28 9:38 UTC (permalink / raw)
To: igt-dev, Petri Latvala, Arkadiusz Hiler, Kamil Konieczny,
Juha-Pekka Heikkila, Bhanuprakash Modem
Cc: Boris Brezillon, Steven Price, Liviu Dudau, Adrián Larumbe,
Daniel Almeida, kernel
Hello,
Here's a bunch of tests that were developped while fixing different
bugs in panthor. I'm posting them before I forget.
v2:
- Add some docs
- Fix commit message
Regards,
Boris
Boris Brezillon (3):
drm-uapi/panthor: Sync panthor uapi
tests/panthor: Add a test to make sure the buffer is zeroed at alloc
time
tests/panthor: Add scheduler tests
include/drm-uapi/panthor_drm.h | 213 +++++++++++++++++----
lib/igt_panthor.c | 71 +++++++
lib/igt_panthor.h | 76 ++++++++
tests/panthor/meson.build | 1 +
tests/panthor/panthor_gem.c | 11 ++
tests/panthor/panthor_sched.c | 338 +++++++++++++++++++++++++++++++++
6 files changed, 668 insertions(+), 42 deletions(-)
create mode 100644 tests/panthor/panthor_sched.c
--
2.51.1
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH i-g-t v2 1/3] drm-uapi/panthor: Sync panthor uapi 2025-11-28 9:38 [PATCH i-g-t v2 0/3] tests/panthor: Add more tests Boris Brezillon @ 2025-11-28 9:38 ` Boris Brezillon 2025-11-28 9:38 ` [PATCH i-g-t v2 2/3] tests/panthor: Add a test to make sure the buffer is zeroed at alloc time Boris Brezillon 2025-11-28 9:38 ` [PATCH i-g-t v2 3/3] tests/panthor: Add scheduler tests Boris Brezillon 2 siblings, 0 replies; 10+ messages in thread From: Boris Brezillon @ 2025-11-28 9:38 UTC (permalink / raw) To: igt-dev, Petri Latvala, Arkadiusz Hiler, Kamil Konieczny, Juha-Pekka Heikkila, Bhanuprakash Modem Cc: Boris Brezillon, Steven Price, Liviu Dudau, Adrián Larumbe, Daniel Almeida, kernel Align with kernel commit 3b1dc21d6d80 ("drm/panthor: Add support for Mali-Gx15 family of GPUs"). Will be needed for the scheduler tests. Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Reviewed-by: Kamil Konieczny <kamil.konieczny@linux.intel.com> --- include/drm-uapi/panthor_drm.h | 213 ++++++++++++++++++++++++++------- 1 file changed, 171 insertions(+), 42 deletions(-) diff --git a/include/drm-uapi/panthor_drm.h b/include/drm-uapi/panthor_drm.h index e23a7f9b0eac..467d365ed7ba 100644 --- a/include/drm-uapi/panthor_drm.h +++ b/include/drm-uapi/panthor_drm.h @@ -127,50 +127,25 @@ enum drm_panthor_ioctl_id { /** @DRM_PANTHOR_TILER_HEAP_DESTROY: Destroy a tiler heap. */ DRM_PANTHOR_TILER_HEAP_DESTROY, + + /** @DRM_PANTHOR_BO_SET_LABEL: Label a BO. */ + DRM_PANTHOR_BO_SET_LABEL, + + /** + * @DRM_PANTHOR_SET_USER_MMIO_OFFSET: Set the offset to use as the user MMIO offset. + * + * The default behavior is to pick the MMIO offset based on the size of the pgoff_t + * type seen by the process that manipulates the FD, such that a 32-bit process can + * always map the user MMIO ranges. But this approach doesn't work well for emulators + * like FEX, where the emulator is an 64-bit binary which might be executing 32-bit + * code. In that case, the kernel thinks it's the 64-bit process and assumes + * DRM_PANTHOR_USER_MMIO_OFFSET_64BIT is in use, but the UMD library expects + * DRM_PANTHOR_USER_MMIO_OFFSET_32BIT, because it can't mmap() anything above the + * pgoff_t size. + */ + DRM_PANTHOR_SET_USER_MMIO_OFFSET, }; -/** - * DRM_IOCTL_PANTHOR() - Build a Panthor IOCTL number - * @__access: Access type. Must be R, W or RW. - * @__id: One of the DRM_PANTHOR_xxx id. - * @__type: Suffix of the type being passed to the IOCTL. - * - * Don't use this macro directly, use the DRM_IOCTL_PANTHOR_xxx - * values instead. - * - * Return: An IOCTL number to be passed to ioctl() from userspace. - */ -#define DRM_IOCTL_PANTHOR(__access, __id, __type) \ - DRM_IO ## __access(DRM_COMMAND_BASE + DRM_PANTHOR_ ## __id, \ - struct drm_panthor_ ## __type) - -#define DRM_IOCTL_PANTHOR_DEV_QUERY \ - DRM_IOCTL_PANTHOR(WR, DEV_QUERY, dev_query) -#define DRM_IOCTL_PANTHOR_VM_CREATE \ - DRM_IOCTL_PANTHOR(WR, VM_CREATE, vm_create) -#define DRM_IOCTL_PANTHOR_VM_DESTROY \ - DRM_IOCTL_PANTHOR(WR, VM_DESTROY, vm_destroy) -#define DRM_IOCTL_PANTHOR_VM_BIND \ - DRM_IOCTL_PANTHOR(WR, VM_BIND, vm_bind) -#define DRM_IOCTL_PANTHOR_VM_GET_STATE \ - DRM_IOCTL_PANTHOR(WR, VM_GET_STATE, vm_get_state) -#define DRM_IOCTL_PANTHOR_BO_CREATE \ - DRM_IOCTL_PANTHOR(WR, BO_CREATE, bo_create) -#define DRM_IOCTL_PANTHOR_BO_MMAP_OFFSET \ - DRM_IOCTL_PANTHOR(WR, BO_MMAP_OFFSET, bo_mmap_offset) -#define DRM_IOCTL_PANTHOR_GROUP_CREATE \ - DRM_IOCTL_PANTHOR(WR, GROUP_CREATE, group_create) -#define DRM_IOCTL_PANTHOR_GROUP_DESTROY \ - DRM_IOCTL_PANTHOR(WR, GROUP_DESTROY, group_destroy) -#define DRM_IOCTL_PANTHOR_GROUP_SUBMIT \ - DRM_IOCTL_PANTHOR(WR, GROUP_SUBMIT, group_submit) -#define DRM_IOCTL_PANTHOR_GROUP_GET_STATE \ - DRM_IOCTL_PANTHOR(WR, GROUP_GET_STATE, group_get_state) -#define DRM_IOCTL_PANTHOR_TILER_HEAP_CREATE \ - 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) - /** * DOC: IOCTL arguments */ @@ -260,6 +235,14 @@ enum drm_panthor_dev_query_type { /** @DRM_PANTHOR_DEV_QUERY_CSIF_INFO: Query command-stream interface information. */ DRM_PANTHOR_DEV_QUERY_CSIF_INFO, + + /** @DRM_PANTHOR_DEV_QUERY_TIMESTAMP_INFO: Query timestamp information. */ + DRM_PANTHOR_DEV_QUERY_TIMESTAMP_INFO, + + /** + * @DRM_PANTHOR_DEV_QUERY_GROUP_PRIORITIES_INFO: Query allowed group priorities information. + */ + DRM_PANTHOR_DEV_QUERY_GROUP_PRIORITIES_INFO, }; /** @@ -327,6 +310,9 @@ struct drm_panthor_gpu_info { /** @as_present: Bitmask encoding the number of address-space exposed by the MMU. */ __u32 as_present; + /** @pad0: MBZ. */ + __u32 pad0; + /** @shader_present: Bitmask encoding the shader cores exposed by the GPU. */ __u64 shader_present; @@ -341,6 +327,9 @@ struct drm_panthor_gpu_info { /** @pad: MBZ. */ __u32 pad; + + /** @gpu_features: Bitmask describing supported GPU-wide features */ + __u64 gpu_features; }; /** @@ -377,6 +366,42 @@ struct drm_panthor_csif_info { __u32 pad; }; +/** + * struct drm_panthor_timestamp_info - Timestamp information + * + * Structure grouping all queryable information relating to the GPU timestamp. + */ +struct drm_panthor_timestamp_info { + /** + * @timestamp_frequency: The frequency of the timestamp timer or 0 if + * unknown. + */ + __u64 timestamp_frequency; + + /** @current_timestamp: The current timestamp. */ + __u64 current_timestamp; + + /** @timestamp_offset: The offset of the timestamp timer. */ + __u64 timestamp_offset; +}; + +/** + * struct drm_panthor_group_priorities_info - Group priorities information + * + * Structure grouping all queryable information relating to the allowed group priorities. + */ +struct drm_panthor_group_priorities_info { + /** + * @allowed_mask: Bitmask of the allowed group priorities. + * + * Each bit represents a variant of the enum drm_panthor_group_priority. + */ + __u8 allowed_mask; + + /** @pad: Padding fields, MBZ. */ + __u8 pad[3]; +}; + /** * struct drm_panthor_dev_query - Arguments passed to DRM_PANTHOR_IOCTL_DEV_QUERY */ @@ -698,6 +723,13 @@ enum drm_panthor_group_priority { * Requires CAP_SYS_NICE or DRM_MASTER. */ PANTHOR_GROUP_PRIORITY_HIGH, + + /** + * @PANTHOR_GROUP_PRIORITY_REALTIME: Realtime priority group. + * + * Requires CAP_SYS_NICE or DRM_MASTER. + */ + PANTHOR_GROUP_PRIORITY_REALTIME, }; /** @@ -872,6 +904,15 @@ enum drm_panthor_group_state_flags { * When a group ends up with this flag set, no jobs can be submitted to its queues. */ DRM_PANTHOR_GROUP_STATE_FATAL_FAULT = 1 << 1, + + /** + * @DRM_PANTHOR_GROUP_STATE_INNOCENT: Group was killed during a reset caused by other + * groups. + * + * This flag can only be set if DRM_PANTHOR_GROUP_STATE_TIMEDOUT is set and + * DRM_PANTHOR_GROUP_STATE_FATAL_FAULT is not. + */ + DRM_PANTHOR_GROUP_STATE_INNOCENT = 1 << 2, }; /** @@ -959,6 +1000,94 @@ struct drm_panthor_tiler_heap_destroy { __u32 pad; }; +/** + * struct drm_panthor_bo_set_label - Arguments passed to DRM_IOCTL_PANTHOR_BO_SET_LABEL + */ +struct drm_panthor_bo_set_label { + /** @handle: Handle of the buffer object to label. */ + __u32 handle; + + /** @pad: MBZ. */ + __u32 pad; + + /** + * @label: User pointer to a NUL-terminated string + * + * Length cannot be greater than 4096 + */ + __u64 label; +}; + +/** + * struct drm_panthor_set_user_mmio_offset - Arguments passed to + * DRM_IOCTL_PANTHOR_SET_USER_MMIO_OFFSET + * + * This ioctl is only really useful if you want to support userspace + * CPU emulation environments where the size of an unsigned long differs + * between the host and the guest architectures. + */ +struct drm_panthor_set_user_mmio_offset { + /** + * @offset: User MMIO offset to use. + * + * Must be either DRM_PANTHOR_USER_MMIO_OFFSET_32BIT or + * DRM_PANTHOR_USER_MMIO_OFFSET_64BIT. + * + * Use DRM_PANTHOR_USER_MMIO_OFFSET (which selects OFFSET_32BIT or + * OFFSET_64BIT based on the size of an unsigned long) unless you + * have a very good reason to overrule this decision. + */ + __u64 offset; +}; + +/** + * DRM_IOCTL_PANTHOR() - Build a Panthor IOCTL number + * @__access: Access type. Must be R, W or RW. + * @__id: One of the DRM_PANTHOR_xxx id. + * @__type: Suffix of the type being passed to the IOCTL. + * + * Don't use this macro directly, use the DRM_IOCTL_PANTHOR_xxx + * values instead. + * + * Return: An IOCTL number to be passed to ioctl() from userspace. + */ +#define DRM_IOCTL_PANTHOR(__access, __id, __type) \ + DRM_IO ## __access(DRM_COMMAND_BASE + DRM_PANTHOR_ ## __id, \ + struct drm_panthor_ ## __type) + +enum { + DRM_IOCTL_PANTHOR_DEV_QUERY = + DRM_IOCTL_PANTHOR(WR, DEV_QUERY, dev_query), + DRM_IOCTL_PANTHOR_VM_CREATE = + DRM_IOCTL_PANTHOR(WR, VM_CREATE, vm_create), + DRM_IOCTL_PANTHOR_VM_DESTROY = + DRM_IOCTL_PANTHOR(WR, VM_DESTROY, vm_destroy), + DRM_IOCTL_PANTHOR_VM_BIND = + DRM_IOCTL_PANTHOR(WR, VM_BIND, vm_bind), + DRM_IOCTL_PANTHOR_VM_GET_STATE = + DRM_IOCTL_PANTHOR(WR, VM_GET_STATE, vm_get_state), + DRM_IOCTL_PANTHOR_BO_CREATE = + DRM_IOCTL_PANTHOR(WR, BO_CREATE, bo_create), + DRM_IOCTL_PANTHOR_BO_MMAP_OFFSET = + DRM_IOCTL_PANTHOR(WR, BO_MMAP_OFFSET, bo_mmap_offset), + DRM_IOCTL_PANTHOR_GROUP_CREATE = + DRM_IOCTL_PANTHOR(WR, GROUP_CREATE, group_create), + DRM_IOCTL_PANTHOR_GROUP_DESTROY = + DRM_IOCTL_PANTHOR(WR, GROUP_DESTROY, group_destroy), + DRM_IOCTL_PANTHOR_GROUP_SUBMIT = + DRM_IOCTL_PANTHOR(WR, GROUP_SUBMIT, group_submit), + DRM_IOCTL_PANTHOR_GROUP_GET_STATE = + DRM_IOCTL_PANTHOR(WR, GROUP_GET_STATE, group_get_state), + DRM_IOCTL_PANTHOR_TILER_HEAP_CREATE = + DRM_IOCTL_PANTHOR(WR, TILER_HEAP_CREATE, tiler_heap_create), + DRM_IOCTL_PANTHOR_TILER_HEAP_DESTROY = + DRM_IOCTL_PANTHOR(WR, TILER_HEAP_DESTROY, tiler_heap_destroy), + DRM_IOCTL_PANTHOR_BO_SET_LABEL = + DRM_IOCTL_PANTHOR(WR, BO_SET_LABEL, bo_set_label), + DRM_IOCTL_PANTHOR_SET_USER_MMIO_OFFSET = + DRM_IOCTL_PANTHOR(WR, SET_USER_MMIO_OFFSET, set_user_mmio_offset), +}; + #if defined(__cplusplus) } #endif -- 2.51.1 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH i-g-t v2 2/3] tests/panthor: Add a test to make sure the buffer is zeroed at alloc time 2025-11-28 9:38 [PATCH i-g-t v2 0/3] tests/panthor: Add more tests Boris Brezillon 2025-11-28 9:38 ` [PATCH i-g-t v2 1/3] drm-uapi/panthor: Sync panthor uapi Boris Brezillon @ 2025-11-28 9:38 ` Boris Brezillon 2025-12-01 11:14 ` Kamil Konieczny 2025-11-28 9:38 ` [PATCH i-g-t v2 3/3] tests/panthor: Add scheduler tests Boris Brezillon 2 siblings, 1 reply; 10+ messages in thread From: Boris Brezillon @ 2025-11-28 9:38 UTC (permalink / raw) To: igt-dev, Petri Latvala, Arkadiusz Hiler, Kamil Konieczny, Juha-Pekka Heikkila, Bhanuprakash Modem Cc: Boris Brezillon, Steven Price, Liviu Dudau, Adrián Larumbe, Daniel Almeida, kernel This covering for this bug [1]. Add an IGT test to make sure we don't hit that again. [1]https://lore.kernel.org/20251107171214.1186299-1-boris.brezillon@collabora.com Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Reviewed-by: Kamil Konieczny <kamil.konieczny@linux.intel.com> Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com> --- tests/panthor/panthor_gem.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/panthor/panthor_gem.c b/tests/panthor/panthor_gem.c index 57cd97e809fd..1566c713f876 100644 --- a/tests/panthor/panthor_gem.c +++ b/tests/panthor/panthor_gem.c @@ -66,6 +66,17 @@ igt_main { igt_panthor_free_bo(fd, &bo); } + igt_describe_f("Check zero-ing of buffer at creation time"); + igt_subtest("bo_zeroed") { + struct panthor_bo bo; + + igt_panthor_bo_create_mapped(fd, &bo, getpagesize(), 0, 0); + igt_assert(bo.map); + igt_assert_eq(*((uint32_t *)bo.map), 0); + + igt_panthor_free_bo(fd, &bo); + } + igt_fixture { drm_close_driver(fd); } -- 2.51.1 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH i-g-t v2 2/3] tests/panthor: Add a test to make sure the buffer is zeroed at alloc time 2025-11-28 9:38 ` [PATCH i-g-t v2 2/3] tests/panthor: Add a test to make sure the buffer is zeroed at alloc time Boris Brezillon @ 2025-12-01 11:14 ` Kamil Konieczny 2025-12-01 13:25 ` Daniel Almeida 0 siblings, 1 reply; 10+ messages in thread From: Kamil Konieczny @ 2025-12-01 11:14 UTC (permalink / raw) To: Boris Brezillon Cc: igt-dev, Petri Latvala, Arkadiusz Hiler, Juha-Pekka Heikkila, Bhanuprakash Modem, Steven Price, Liviu Dudau, Adrián Larumbe, Daniel Almeida, kernel Hi Boris, On 2025-11-28 at 10:38:57 +0100, Boris Brezillon wrote: > This covering for this bug [1]. Add an IGT test to make sure we don't > hit that again. > > [1]https://lore.kernel.org/20251107171214.1186299-1-boris.brezillon@collabora.com > > Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> > Reviewed-by: Kamil Konieczny <kamil.konieczny@linux.intel.com> > Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com> I merged 1/3 and this one, Regards, Kamil > --- > tests/panthor/panthor_gem.c | 11 +++++++++++ > 1 file changed, 11 insertions(+) > > diff --git a/tests/panthor/panthor_gem.c b/tests/panthor/panthor_gem.c > index 57cd97e809fd..1566c713f876 100644 > --- a/tests/panthor/panthor_gem.c > +++ b/tests/panthor/panthor_gem.c > @@ -66,6 +66,17 @@ igt_main { > igt_panthor_free_bo(fd, &bo); > } > > + igt_describe_f("Check zero-ing of buffer at creation time"); > + igt_subtest("bo_zeroed") { > + struct panthor_bo bo; > + > + igt_panthor_bo_create_mapped(fd, &bo, getpagesize(), 0, 0); > + igt_assert(bo.map); > + igt_assert_eq(*((uint32_t *)bo.map), 0); > + > + igt_panthor_free_bo(fd, &bo); > + } > + > igt_fixture { > drm_close_driver(fd); > } > -- > 2.51.1 > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH i-g-t v2 2/3] tests/panthor: Add a test to make sure the buffer is zeroed at alloc time 2025-12-01 11:14 ` Kamil Konieczny @ 2025-12-01 13:25 ` Daniel Almeida 2025-12-01 15:19 ` Kamil Konieczny 0 siblings, 1 reply; 10+ messages in thread From: Daniel Almeida @ 2025-12-01 13:25 UTC (permalink / raw) To: Kamil Konieczny Cc: Boris Brezillon, igt-dev, Petri Latvala, Arkadiusz Hiler, Juha-Pekka Heikkila, Bhanuprakash Modem, Steven Price, Liviu Dudau, Adrián Larumbe, kernel Hi Kamil, > On 1 Dec 2025, at 08:14, Kamil Konieczny <kamil.konieczny@linux.intel.com> wrote: > > Hi Boris, > On 2025-11-28 at 10:38:57 +0100, Boris Brezillon wrote: >> This covering for this bug [1]. Add an IGT test to make sure we don't >> hit that again. >> >> [1]https://lore.kernel.org/20251107171214.1186299-1-boris.brezillon@collabora.com >> >> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> >> Reviewed-by: Kamil Konieczny <kamil.konieczny@linux.intel.com> >> Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com> > > I merged 1/3 and this one, > > Regards, > Kamil > I’ll have a look on 2/3 today. — Daniel ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH i-g-t v2 2/3] tests/panthor: Add a test to make sure the buffer is zeroed at alloc time 2025-12-01 13:25 ` Daniel Almeida @ 2025-12-01 15:19 ` Kamil Konieczny 2025-12-01 15:21 ` Daniel Almeida 0 siblings, 1 reply; 10+ messages in thread From: Kamil Konieczny @ 2025-12-01 15:19 UTC (permalink / raw) To: Daniel Almeida Cc: Boris Brezillon, igt-dev, Petri Latvala, Arkadiusz Hiler, Juha-Pekka Heikkila, Bhanuprakash Modem, Steven Price, Liviu Dudau, Adrián Larumbe, kernel Hi Daniel, On 2025-12-01 at 10:25:06 -0300, Daniel Almeida wrote: > Hi Kamil, > > > On 1 Dec 2025, at 08:14, Kamil Konieczny <kamil.konieczny@linux.intel.com> wrote: > > > > Hi Boris, > > On 2025-11-28 at 10:38:57 +0100, Boris Brezillon wrote: > >> This covering for this bug [1]. Add an IGT test to make sure we don't > >> hit that again. > >> > >> [1]https://lore.kernel.org/20251107171214.1186299-1-boris.brezillon@collabora.com > >> > >> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> > >> Reviewed-by: Kamil Konieczny <kamil.konieczny@linux.intel.com> > >> Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com> > > > > I merged 1/3 and this one, > > > > Regards, > > Kamil > > > > I’ll have a look on 2/3 today. I merged 1/3 and 2/3, did you mean last one 3/3? Regards, Kamil > > — Daniel > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH i-g-t v2 2/3] tests/panthor: Add a test to make sure the buffer is zeroed at alloc time 2025-12-01 15:19 ` Kamil Konieczny @ 2025-12-01 15:21 ` Daniel Almeida 0 siblings, 0 replies; 10+ messages in thread From: Daniel Almeida @ 2025-12-01 15:21 UTC (permalink / raw) To: Kamil Konieczny Cc: Boris Brezillon, igt-dev, Petri Latvala, Arkadiusz Hiler, Juha-Pekka Heikkila, Bhanuprakash Modem, Steven Price, Liviu Dudau, Adrián Larumbe, kernel > On 1 Dec 2025, at 12:19, Kamil Konieczny <kamil.konieczny@linux.intel.com> wrote: > > Hi Daniel, > On 2025-12-01 at 10:25:06 -0300, Daniel Almeida wrote: >> Hi Kamil, >> >>> On 1 Dec 2025, at 08:14, Kamil Konieczny <kamil.konieczny@linux.intel.com> wrote: >>> >>> Hi Boris, >>> On 2025-11-28 at 10:38:57 +0100, Boris Brezillon wrote: >>>> This covering for this bug [1]. Add an IGT test to make sure we don't >>>> hit that again. >>>> >>>> [1]https://lore.kernel.org/20251107171214.1186299-1-boris.brezillon@collabora.com >>>> >>>> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> >>>> Reviewed-by: Kamil Konieczny <kamil.konieczny@linux.intel.com> >>>> Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com> >>> >>> I merged 1/3 and this one, >>> >>> Regards, >>> Kamil >>> >> >> I’ll have a look on 2/3 today. > > I merged 1/3 and 2/3, did you mean last one 3/3? > > Regards, > Kamil > >> >> — Daniel Yes, the last one, sorry. — Daniel ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH i-g-t v2 3/3] tests/panthor: Add scheduler tests 2025-11-28 9:38 [PATCH i-g-t v2 0/3] tests/panthor: Add more tests Boris Brezillon 2025-11-28 9:38 ` [PATCH i-g-t v2 1/3] drm-uapi/panthor: Sync panthor uapi Boris Brezillon 2025-11-28 9:38 ` [PATCH i-g-t v2 2/3] tests/panthor: Add a test to make sure the buffer is zeroed at alloc time Boris Brezillon @ 2025-11-28 9:38 ` Boris Brezillon 2025-12-03 19:31 ` Daniel Almeida 2 siblings, 1 reply; 10+ messages in thread From: Boris Brezillon @ 2025-11-28 9:38 UTC (permalink / raw) To: igt-dev, Petri Latvala, Arkadiusz Hiler, Kamil Konieczny, Juha-Pekka Heikkila, Bhanuprakash Modem Cc: Boris Brezillon, Steven Price, Liviu Dudau, Adrián Larumbe, Daniel Almeida, kernel Tests developed while working on this set of fixes [1]. [1]https://lore.kernel.org/all/20251112115142.1270931-1-boris.brezillon@collabora.com/ Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> --- lib/igt_panthor.c | 71 +++++++ lib/igt_panthor.h | 76 ++++++++ tests/panthor/meson.build | 1 + tests/panthor/panthor_sched.c | 338 ++++++++++++++++++++++++++++++++++ 4 files changed, 486 insertions(+) create mode 100644 tests/panthor/panthor_sched.c diff --git a/lib/igt_panthor.c b/lib/igt_panthor.c index 73ada9c59bfc..802cb182753c 100644 --- a/lib/igt_panthor.c +++ b/lib/igt_panthor.c @@ -2,6 +2,7 @@ // SPDX-FileCopyrightText: Copyright (C) 2025 Collabora Ltd. #include "drmtest.h" +#include "igt_aux.h" #include "igt_panthor.h" #include "ioctl_wrappers.h" #include "panthor_drm.h" @@ -370,3 +371,73 @@ void igt_panthor_free_bo(int fd, struct panthor_bo *bo) gem_close(fd, bo->handle); } + +/** + * igt_panthor_ctx_create: + * @fd: panthor device file descriptor + * @ctx: context to initialize + * + * Creates base resources (VM and GPU info) needed for GPU job submission + */ +void igt_panthor_ctx_create(int fd, struct panthor_ctx *ctx) +{ + memset(ctx, 0, sizeof(*ctx)); + igt_panthor_query(fd, DRM_PANTHOR_DEV_QUERY_GPU_INFO, + &ctx->gpu_info, sizeof(ctx->gpu_info), 0); + igt_panthor_vm_create(fd, &ctx->vm, 0); +} + +/** + * igt_panthor_ctx_destroy: + * @fd: panthor device file descriptor + * @ctx: context to cleanup + * + * Releases all the resources attached to a GPU context. + */ +void igt_panthor_ctx_destroy(int fd, struct panthor_ctx *ctx) +{ + for (uint32_t i = 0; i < ctx->group_count; i++) { + struct drm_panthor_group_destroy group_destroy = { + .group_handle = ctx->groups[i], + }; + + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_GROUP_DESTROY, &group_destroy), 0); + } + + igt_panthor_vm_destroy(fd, ctx->vm, 0); +} + +/** + * igt_panthor_ctx_add_group: + * @fd: panthor device file descriptor + * @ctx: context to add a group to + * @group_prio: group priority + * @queues: properties of queues attached to the group + * @queue_count: number of queues attached to the group + * + * Adds a group to a GPU context. Such groups will be released when + * the context is destroyed. + */ +void igt_panthor_ctx_add_group(int fd, struct panthor_ctx *ctx, + enum drm_panthor_group_priority group_prio, + const struct drm_panthor_queue_create *queues, + uint32_t queue_count) +{ + unsigned int shader_core_count = igt_hweight(ctx->gpu_info.shader_present); + struct drm_panthor_group_create group_create = { + .queues = DRM_PANTHOR_OBJ_ARRAY(queue_count, queues), + .max_compute_cores = shader_core_count, + .max_fragment_cores = shader_core_count, + .max_tiler_cores = 1, + .priority = group_prio, + .compute_core_mask = ctx->gpu_info.shader_present, + .fragment_core_mask = ctx->gpu_info.shader_present, + .tiler_core_mask = ctx->gpu_info.tiler_present, + .vm_id = ctx->vm, + }; + + igt_assert(ctx->group_count < ARRAY_SIZE(ctx->groups)); + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_GROUP_CREATE, &group_create), 0); + igt_assert(group_create.group_handle > 0); + ctx->groups[ctx->group_count++] = group_create.group_handle; +} diff --git a/lib/igt_panthor.h b/lib/igt_panthor.h index dc90033c0ad4..2a62eff37b2b 100644 --- a/lib/igt_panthor.h +++ b/lib/igt_panthor.h @@ -7,6 +7,7 @@ #include <stddef.h> #include <stdint.h> #include <stdbool.h> + #include "panthor_drm.h" struct panthor_bo { @@ -16,7 +17,17 @@ struct panthor_bo { void *map; }; +#define MAX_GROUPS_PER_CTX 128 + +struct panthor_ctx { + struct drm_panthor_gpu_info gpu_info; + uint32_t vm; + uint32_t group_count; + uint32_t groups[MAX_GROUPS_PER_CTX]; +}; + void igt_panthor_query(int fd, int32_t type, void *data, size_t size, int err); + void igt_panthor_vm_create(int fd, uint32_t *vm_id, int err); void igt_panthor_vm_destroy(int fd, uint32_t vm_id, int err); void igt_panthor_vm_bind(int fd, uint32_t vm_id, uint32_t bo_handle, uint64_t va, @@ -38,12 +49,21 @@ void igt_panthor_group_submit_simple(int fd, uint32_t group_handle, int err); uint64_t igt_panthor_get_first_core(uint64_t cores_present); +void igt_panthor_ctx_create(int fd, struct panthor_ctx *ctx); +void igt_panthor_ctx_destroy(int fd, struct panthor_ctx *ctx); +void igt_panthor_ctx_add_group(int fd, struct panthor_ctx *ctx, + enum drm_panthor_group_priority group_prio, + const struct drm_panthor_queue_create *queues, + uint32_t queue_count); + enum cs_opcode { CS_OPCODE_NOP = 0, CS_OPCODE_MOVE48 = 1, CS_OPCODE_MOVE32 = 2, CS_OPCODE_WAIT = 3, + CS_OPCODE_ADD64 = 17, CS_OPCODE_STM = 21, + CS_OPCODE_BRANCH = 22, CS_OPCODE_FLUSH_CACHE = 36, }; @@ -61,6 +81,16 @@ enum cs_flush_mode { #error "big endian not supported" #endif +enum cs_branch_cond { + CS_BRANCH_COND_LE = 0, + CS_BRANCH_COND_GT = 1, + CS_BRANCH_COND_EQ = 2, + CS_BRANCH_COND_NE = 3, + CS_BRANCH_COND_LT = 4, + CS_BRANCH_COND_GE = 5, + CS_BRANCH_COND_ALWAYS = 6, +}; + struct cs_instr { union { struct { @@ -89,6 +119,13 @@ struct cs_instr { uint64_t unused1: 23; uint64_t opcode: 8; } wait; + struct { + uint64_t immediate: 32; + uint64_t unused0: 8; + uint64_t src: 8; + uint64_t dst: 8; + uint64_t opcode: 8; + } add64; struct { uint64_t offset: 16; uint64_t mask: 16; @@ -97,6 +134,15 @@ struct cs_instr { uint64_t src: 8; uint64_t opcode: 8; } stm; + struct { + uint64_t offset: 16; + uint64_t unused0: 12; + uint64_t cond: 4; + uint64_t unused1: 8; + uint64_t src: 8; + uint64_t unused2: 8; + uint64_t opcode: 8; + } branch; struct { uint64_t l2_mode: 4; uint64_t lsc_mode: 4; @@ -167,6 +213,21 @@ cs_wait(uint16_t wait_mask, bool progress_inc) return instr.raw; } +static inline uint64_t +cs_add64(uint32_t imm, uint8_t src, uint8_t dst) +{ + struct cs_instr instr = { + .add64 = { + .immediate = imm, + .src = src, + .dst = dst, + .opcode = CS_OPCODE_ADD64, + }, + }; + + return instr.raw; +} + static inline uint64_t cs_stm(uint8_t address, uint8_t src, uint16_t mask, int16_t offset) { @@ -195,6 +256,21 @@ cs_stm64(uint8_t address, uint8_t src, int16_t offset) return cs_stm(address, src, 0x3, offset); } +static inline uint64_t +cs_branch(int16_t offset, enum cs_branch_cond cond, uint8_t src) +{ + struct cs_instr instr = { + .branch = { + .offset = (uint16_t)offset, + .cond = cond, + .src = src, + .opcode = CS_OPCODE_BRANCH, + }, + }; + + return instr.raw; +} + static inline uint64_t cs_flush(enum cs_flush_mode l2_mode, enum cs_flush_mode lsc_mode, diff --git a/tests/panthor/meson.build b/tests/panthor/meson.build index 42a46e9934a9..8bd391596a97 100644 --- a/tests/panthor/meson.build +++ b/tests/panthor/meson.build @@ -2,6 +2,7 @@ panthor_progs = [ 'panthor_gem', 'panthor_group', 'panthor_query', + 'panthor_sched', 'panthor_vm', ] diff --git a/tests/panthor/panthor_sched.c b/tests/panthor/panthor_sched.c new file mode 100644 index 000000000000..7cded16c0acd --- /dev/null +++ b/tests/panthor/panthor_sched.c @@ -0,0 +1,338 @@ +// SPDX-License-Identifier: MIT +// SPDX-FileCopyrightText: Copyright (C) 2025 Collabora Ltd. + +#include <stdint.h> +#include <sys/mman.h> +#include <unistd.h> + +#include "drm.h" +#include "igt.h" +#include "igt_core.h" +#include "igt_panthor.h" +#include "panthor_drm.h" + +static size_t +infinite_incr_loop(uint64_t *cs, uint64_t counter_va) +{ + const uint8_t counter_va_reg = 68; + const uint8_t val_reg = 70; + uint64_t instrs[] = { + /* Load the source register ([r68; r69]) with the kernel address */ + cs_mov48(counter_va_reg, counter_va), + /* Load a 0 into r70 */ + cs_mov48(val_reg, 1), + /* STORE_MULTIPLE: Store the first register to the address pointed to by + * [r68; r69] + */ + cs_stm64(counter_va_reg, val_reg, 0), + cs_wait(1, false), + cs_add64(1, val_reg, val_reg), + cs_branch(-4, CS_BRANCH_COND_ALWAYS, 0), + }; + + memcpy(cs, instrs, sizeof(instrs)); + return sizeof(instrs); +} + +struct panthor_sched_test_group_ctx { + uint32_t handle; + uint64_t *counter; + uint64_t cs_va; + uint32_t cs_size; +}; + +#define MAX_GROUPS 128 + +struct panthor_sched_test_ctx { + struct panthor_ctx ctx; + struct panthor_bo cs_bo; + uint32_t cs_bo_offset; + struct panthor_bo counter_bo; + uint32_t counter_bo_offset; + uint32_t group_count; + struct panthor_sched_test_group_ctx groups[MAX_GROUPS]; +}; + +#define CS_BO_VA 0x100000 +#define COUNTER_BO_VA 0x200000 + +static void +sched_test_ctx_create(int fd, struct panthor_sched_test_ctx *ctx) +{ + memset(ctx, 0, sizeof(*ctx)); + igt_panthor_ctx_create(fd, &ctx->ctx); + igt_panthor_bo_create_mapped(fd, &ctx->cs_bo, getpagesize(), 0, 0); + igt_panthor_vm_bind(fd, ctx->ctx.vm, ctx->cs_bo.handle, CS_BO_VA, ctx->cs_bo.size, + DRM_PANTHOR_VM_BIND_OP_MAP_READONLY | + DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, + 0); + igt_panthor_bo_create_mapped(fd, &ctx->counter_bo, getpagesize(), 0, 0); + igt_panthor_vm_bind(fd, ctx->ctx.vm, ctx->counter_bo.handle, COUNTER_BO_VA, + ctx->counter_bo.size, + DRM_PANTHOR_VM_BIND_OP_MAP_UNCACHED | + DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC | + DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, + 0); +} + +static void +sched_test_ctx_destroy(int fd, struct panthor_sched_test_ctx *ctx) +{ + igt_panthor_ctx_destroy(fd, &ctx->ctx); +} + +static void +sched_test_ctx_add_group(int fd, struct panthor_sched_test_ctx *ctx, + enum drm_panthor_group_priority group_prio) +{ + struct drm_panthor_queue_create queue_create = { + .priority = 0, + .ringbuf_size = getpagesize(), + }; + uint64_t *cs = (uint64_t *)((uint8_t *)ctx->cs_bo.map + ctx->cs_bo_offset); + uint64_t *counters = ctx->counter_bo.map; + unsigned int group_idx = ctx->group_count; + uint64_t counter_va = COUNTER_BO_VA + group_idx * sizeof(counters[0]); + unsigned int cs_size; + + igt_assert_lt(ctx->group_count, ARRAY_SIZE(ctx->groups)); + + igt_panthor_ctx_add_group(fd, &ctx->ctx, group_prio, &queue_create, 1); + cs_size = infinite_incr_loop(cs, counter_va); + cs_size = ALIGN(cs_size, 64); + ctx->groups[ctx->group_count++] = (struct panthor_sched_test_group_ctx){ + .handle = ctx->ctx.groups[group_idx], + .counter = &counters[group_idx], + .cs_va = CS_BO_VA + ctx->cs_bo_offset, + .cs_size = cs_size, + }; + + ctx->cs_bo_offset += cs_size; + igt_assert_lt(ctx->cs_bo_offset, ctx->cs_bo.size); +} + +static void +sched_test_ctx_submit_group(int fd, struct panthor_sched_test_ctx *ctx, + unsigned int group_idx) +{ + struct drm_panthor_queue_submit qsubmit = { + .queue_index = 0, + .stream_size = ctx->groups[group_idx].cs_size, + .stream_addr = ctx->groups[group_idx].cs_va, + .latest_flush = 0, + }; + struct drm_panthor_group_submit gsubmit = { + .group_handle = ctx->groups[group_idx].handle, + .queue_submits = DRM_PANTHOR_OBJ_ARRAY(1, &qsubmit), + }; + + igt_assert_lt(group_idx, ctx->group_count); + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_GROUP_SUBMIT, &gsubmit), 0); +} + +igt_main { + int fd; + + igt_fixture { + fd = drm_open_driver(DRIVER_PANTHOR); + } + + igt_describe("Schedule 8 groups with the same prio"); + igt_subtest("sched_8_groups_same_prio") { + uint64_t min_cnt = UINT64_MAX, max_cnt = 0; + struct panthor_sched_test_ctx ctx; + const unsigned int group_cnt = 8; + + sched_test_ctx_create(fd, &ctx); + + for (unsigned int i = 0; i < group_cnt; i++) + sched_test_ctx_add_group(fd, &ctx, PANTHOR_GROUP_PRIORITY_MEDIUM); + + for (unsigned int i = 0; i < group_cnt; i++) { + sched_test_ctx_submit_group(fd, &ctx, i); + + /* Add some delay, to make sure each group becomes + * active at a different time, and exercise the + * idle -> active transition that appeared to be + * broken at some point. + */ + usleep(100000); + } + + /* Jobs will timeout, because we've issued an infinte loop, + * but leave it some time before checking the counter + * values. + */ + sleep(6); + + for (unsigned int i = 0; i < group_cnt; i++) { + min_cnt = min(min_cnt, *ctx.groups[i].counter); + max_cnt = max(max_cnt, *ctx.groups[i].counter); + } + + igt_assert_lt(200000, min_cnt); + igt_assert_lte(min_cnt, max_cnt); + + /* Allow a 20% difference max? */ + igt_assert_lt((((max_cnt - min_cnt) * 100) / min_cnt), 20); + + sched_test_ctx_destroy(fd, &ctx); + } + + igt_describe("Schedule 16 groups with the same prio"); + igt_subtest("sched_16_groups_same_prio") { + uint64_t min_cnt = UINT64_MAX, max_cnt = 0; + struct panthor_sched_test_ctx ctx; + const unsigned int group_cnt = 16; + + sched_test_ctx_create(fd, &ctx); + + for (unsigned int i = 0; i < group_cnt; i++) + sched_test_ctx_add_group(fd, &ctx, PANTHOR_GROUP_PRIORITY_MEDIUM); + + for (unsigned int i = 0; i < group_cnt; i++) { + sched_test_ctx_submit_group(fd, &ctx, i); + + /* Add some delay, to make sure each group becomes + * active at a different time, and exercise the + * idle -> active transition that appeared to be + * broken at some point. + */ + usleep(100000); + } + + /* Jobs will timeout, because we've issued an infinte loop, + * but leave it some time before checking the counter + * values. + */ + sleep(15); + + for (unsigned int i = 0; i < group_cnt; i++) { + min_cnt = min(min_cnt, *ctx.groups[i].counter); + max_cnt = max(max_cnt, *ctx.groups[i].counter); + } + + igt_assert_lt(200000, min_cnt); + igt_assert_lte(min_cnt, max_cnt); + + /* Allow a 20% difference max? */ + igt_assert_lt((((max_cnt - min_cnt) * 100) / min_cnt), 20); + + sched_test_ctx_destroy(fd, &ctx); + } + + igt_describe("Schedule 15 groups with medium prio, one high"); + igt_subtest("sched_15_groups_med_1_high") { + uint64_t min_cnt = UINT64_MAX, max_cnt = 0; + struct panthor_sched_test_ctx ctx; + const unsigned int group_cnt = 16; + const unsigned int group_high = group_cnt - 1; + + sched_test_ctx_create(fd, &ctx); + + for (unsigned int i = 0; i < group_cnt; i++) { + sched_test_ctx_add_group(fd, &ctx, + i == group_high ? + PANTHOR_GROUP_PRIORITY_HIGH : + PANTHOR_GROUP_PRIORITY_MEDIUM); + } + + for (unsigned int i = 0; i < group_cnt; i++) { + sched_test_ctx_submit_group(fd, &ctx, i); + + /* Add some delay, to make sure each group becomes + * active at a different time, and exercise the + * idle -> active transition that appeared to be + * broken at some point. + */ + usleep(100000); + } + + /* Jobs will timeout, because we've issued an infinte loop, + * but leave it some time before checking the counter + * values. + */ + sleep(15); + + for (unsigned int i = 0; i < group_cnt; i++) { + if (i == group_high) + continue; + + min_cnt = min(min_cnt, *ctx.groups[i].counter); + max_cnt = max(max_cnt, *ctx.groups[i].counter); + } + + igt_assert_lt(200000, min_cnt); + igt_assert_lte(min_cnt, max_cnt); + + /* Allow a 30% difference max on all med groups? */ + igt_assert_lt((((max_cnt - min_cnt) * 100) / min_cnt), 30); + + /* High group's counter must be at least 1.5x the other groups. */ + igt_assert_lt((float)max_cnt * 1.5, (float)*ctx.groups[group_high].counter); + + sched_test_ctx_destroy(fd, &ctx); + } + + igt_describe("Schedule 4 groups with RT prio, one high"); + igt_subtest("sched_4_groups_rt_1_high") { + uint64_t min_cnt = UINT64_MAX, max_cnt = 0; + struct panthor_sched_test_ctx ctx; + const unsigned int group_cnt = 5; + const unsigned int group_high = group_cnt - 1; + uint64_t group_high_counter; + + sched_test_ctx_create(fd, &ctx); + + for (unsigned int i = 0; i < group_cnt; i++) { + sched_test_ctx_add_group(fd, &ctx, + i == group_high ? + PANTHOR_GROUP_PRIORITY_HIGH : + PANTHOR_GROUP_PRIORITY_REALTIME); + } + + for (unsigned int i = 0; i < group_cnt; i++) { + if (i == group_high) + continue; + sched_test_ctx_submit_group(fd, &ctx, i); + } + + /* Leave it some time so the SW scheduler can make all RT groups + * active, and the high one really doesn't get a chance to run. + * Ideally the dequeueing of jobs would also take the group + * priority into account, but that's not the case. + */ + usleep(200000); + sched_test_ctx_submit_group(fd, &ctx, group_high); + + /* Make sure we wait less than the timeout, otherwise the group with + * high priority will be left a chance to run as soon as one of the RT + * group dies. + */ + sleep(2); + + group_high_counter = *ctx.groups[group_high].counter; + for (unsigned int i = 0; i < group_cnt; i++) { + if (i == group_high) + continue; + + min_cnt = min(min_cnt, *ctx.groups[i].counter); + max_cnt = max(max_cnt, *ctx.groups[i].counter); + } + + igt_assert_lt(200000, min_cnt); + igt_assert_lte(min_cnt, max_cnt); + + /* Allow a 30% difference max on all med groups? */ + igt_assert_lt((((max_cnt - min_cnt) * 100) / min_cnt), 30); + + /* High group should never run. */ + igt_assert_eq(group_high_counter, 0); + + sched_test_ctx_destroy(fd, &ctx); + } + + igt_fixture { + drm_close_driver(fd); + } +} -- 2.51.1 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH i-g-t v2 3/3] tests/panthor: Add scheduler tests 2025-11-28 9:38 ` [PATCH i-g-t v2 3/3] tests/panthor: Add scheduler tests Boris Brezillon @ 2025-12-03 19:31 ` Daniel Almeida 2025-12-17 15:38 ` Boris Brezillon 0 siblings, 1 reply; 10+ messages in thread From: Daniel Almeida @ 2025-12-03 19:31 UTC (permalink / raw) To: Boris Brezillon Cc: igt-dev, Petri Latvala, Arkadiusz Hiler, Kamil Konieczny, Juha-Pekka Heikkila, Bhanuprakash Modem, Steven Price, Liviu Dudau, Adrián Larumbe, kernel Hi Boris, > On 28 Nov 2025, at 06:38, Boris Brezillon <boris.brezillon@collabora.com> wrote: > > Tests developed while working on this set of fixes [1]. > > [1]https://lore.kernel.org/all/20251112115142.1270931-1-boris.brezillon@collabora.com/ > > Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> > --- > lib/igt_panthor.c | 71 +++++++ > lib/igt_panthor.h | 76 ++++++++ > tests/panthor/meson.build | 1 + > tests/panthor/panthor_sched.c | 338 ++++++++++++++++++++++++++++++++++ > 4 files changed, 486 insertions(+) > create mode 100644 tests/panthor/panthor_sched.c > > diff --git a/lib/igt_panthor.c b/lib/igt_panthor.c > index 73ada9c59bfc..802cb182753c 100644 > --- a/lib/igt_panthor.c > +++ b/lib/igt_panthor.c > @@ -2,6 +2,7 @@ > // SPDX-FileCopyrightText: Copyright (C) 2025 Collabora Ltd. > > #include "drmtest.h" > +#include "igt_aux.h" > #include "igt_panthor.h" > #include "ioctl_wrappers.h" > #include "panthor_drm.h" > @@ -370,3 +371,73 @@ void igt_panthor_free_bo(int fd, struct panthor_bo *bo) > > gem_close(fd, bo->handle); > } > + > +/** > + * igt_panthor_ctx_create: > + * @fd: panthor device file descriptor > + * @ctx: context to initialize > + * > + * Creates base resources (VM and GPU info) needed for GPU job submission > + */ > +void igt_panthor_ctx_create(int fd, struct panthor_ctx *ctx) > +{ > + memset(ctx, 0, sizeof(*ctx)); > + igt_panthor_query(fd, DRM_PANTHOR_DEV_QUERY_GPU_INFO, > + &ctx->gpu_info, sizeof(ctx->gpu_info), 0); > + igt_panthor_vm_create(fd, &ctx->vm, 0); > +} > + > +/** > + * igt_panthor_ctx_destroy: > + * @fd: panthor device file descriptor > + * @ctx: context to cleanup > + * > + * Releases all the resources attached to a GPU context. > + */ > +void igt_panthor_ctx_destroy(int fd, struct panthor_ctx *ctx) > +{ > + for (uint32_t i = 0; i < ctx->group_count; i++) { > + struct drm_panthor_group_destroy group_destroy = { > + .group_handle = ctx->groups[i], > + }; > + > + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_GROUP_DESTROY, &group_destroy), 0); > + } > + > + igt_panthor_vm_destroy(fd, ctx->vm, 0); > +} > + > +/** > + * igt_panthor_ctx_add_group: > + * @fd: panthor device file descriptor > + * @ctx: context to add a group to > + * @group_prio: group priority > + * @queues: properties of queues attached to the group > + * @queue_count: number of queues attached to the group > + * > + * Adds a group to a GPU context. Such groups will be released when > + * the context is destroyed. > + */ > +void igt_panthor_ctx_add_group(int fd, struct panthor_ctx *ctx, > + enum drm_panthor_group_priority group_prio, > + const struct drm_panthor_queue_create *queues, > + uint32_t queue_count) > +{ > + unsigned int shader_core_count = igt_hweight(ctx->gpu_info.shader_present); > + struct drm_panthor_group_create group_create = { > + .queues = DRM_PANTHOR_OBJ_ARRAY(queue_count, queues), > + .max_compute_cores = shader_core_count, > + .max_fragment_cores = shader_core_count, > + .max_tiler_cores = 1, > + .priority = group_prio, > + .compute_core_mask = ctx->gpu_info.shader_present, > + .fragment_core_mask = ctx->gpu_info.shader_present, > + .tiler_core_mask = ctx->gpu_info.tiler_present, > + .vm_id = ctx->vm, > + }; > + > + igt_assert(ctx->group_count < ARRAY_SIZE(ctx->groups)); > + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_GROUP_CREATE, &group_create), 0); > + igt_assert(group_create.group_handle > 0); > + ctx->groups[ctx->group_count++] = group_create.group_handle; > +} > diff --git a/lib/igt_panthor.h b/lib/igt_panthor.h > index dc90033c0ad4..2a62eff37b2b 100644 > --- a/lib/igt_panthor.h > +++ b/lib/igt_panthor.h > @@ -7,6 +7,7 @@ > #include <stddef.h> > #include <stdint.h> > #include <stdbool.h> > + > #include "panthor_drm.h" > > struct panthor_bo { > @@ -16,7 +17,17 @@ struct panthor_bo { > void *map; > }; > > +#define MAX_GROUPS_PER_CTX 128 > + > +struct panthor_ctx { > + struct drm_panthor_gpu_info gpu_info; > + uint32_t vm; > + uint32_t group_count; > + uint32_t groups[MAX_GROUPS_PER_CTX]; > +}; > + > void igt_panthor_query(int fd, int32_t type, void *data, size_t size, int err); > + > void igt_panthor_vm_create(int fd, uint32_t *vm_id, int err); > void igt_panthor_vm_destroy(int fd, uint32_t vm_id, int err); > void igt_panthor_vm_bind(int fd, uint32_t vm_id, uint32_t bo_handle, uint64_t va, > @@ -38,12 +49,21 @@ void igt_panthor_group_submit_simple(int fd, uint32_t group_handle, > int err); > uint64_t igt_panthor_get_first_core(uint64_t cores_present); > > +void igt_panthor_ctx_create(int fd, struct panthor_ctx *ctx); > +void igt_panthor_ctx_destroy(int fd, struct panthor_ctx *ctx); > +void igt_panthor_ctx_add_group(int fd, struct panthor_ctx *ctx, > + enum drm_panthor_group_priority group_prio, > + const struct drm_panthor_queue_create *queues, > + uint32_t queue_count); > + > enum cs_opcode { > CS_OPCODE_NOP = 0, > CS_OPCODE_MOVE48 = 1, > CS_OPCODE_MOVE32 = 2, > CS_OPCODE_WAIT = 3, > + CS_OPCODE_ADD64 = 17, > CS_OPCODE_STM = 21, > + CS_OPCODE_BRANCH = 22, > CS_OPCODE_FLUSH_CACHE = 36, > }; > > @@ -61,6 +81,16 @@ enum cs_flush_mode { > #error "big endian not supported" > #endif > > +enum cs_branch_cond { > + CS_BRANCH_COND_LE = 0, > + CS_BRANCH_COND_GT = 1, > + CS_BRANCH_COND_EQ = 2, > + CS_BRANCH_COND_NE = 3, > + CS_BRANCH_COND_LT = 4, > + CS_BRANCH_COND_GE = 5, > + CS_BRANCH_COND_ALWAYS = 6, > +}; > + > struct cs_instr { > union { > struct { > @@ -89,6 +119,13 @@ struct cs_instr { > uint64_t unused1: 23; > uint64_t opcode: 8; > } wait; > + struct { > + uint64_t immediate: 32; > + uint64_t unused0: 8; > + uint64_t src: 8; > + uint64_t dst: 8; > + uint64_t opcode: 8; > + } add64; > struct { > uint64_t offset: 16; > uint64_t mask: 16; > @@ -97,6 +134,15 @@ struct cs_instr { > uint64_t src: 8; > uint64_t opcode: 8; > } stm; > + struct { > + uint64_t offset: 16; > + uint64_t unused0: 12; > + uint64_t cond: 4; > + uint64_t unused1: 8; > + uint64_t src: 8; > + uint64_t unused2: 8; > + uint64_t opcode: 8; > + } branch; > struct { > uint64_t l2_mode: 4; > uint64_t lsc_mode: 4; > @@ -167,6 +213,21 @@ cs_wait(uint16_t wait_mask, bool progress_inc) > return instr.raw; > } > > +static inline uint64_t > +cs_add64(uint32_t imm, uint8_t src, uint8_t dst) > +{ > + struct cs_instr instr = { > + .add64 = { > + .immediate = imm, > + .src = src, > + .dst = dst, > + .opcode = CS_OPCODE_ADD64, > + }, > + }; > + > + return instr.raw; > +} > + > static inline uint64_t > cs_stm(uint8_t address, uint8_t src, uint16_t mask, int16_t offset) > { > @@ -195,6 +256,21 @@ cs_stm64(uint8_t address, uint8_t src, int16_t offset) > return cs_stm(address, src, 0x3, offset); > } > > +static inline uint64_t > +cs_branch(int16_t offset, enum cs_branch_cond cond, uint8_t src) > +{ > + struct cs_instr instr = { > + .branch = { > + .offset = (uint16_t)offset, > + .cond = cond, > + .src = src, > + .opcode = CS_OPCODE_BRANCH, > + }, > + }; > + > + return instr.raw; > +} > + > static inline uint64_t > cs_flush(enum cs_flush_mode l2_mode, > enum cs_flush_mode lsc_mode, > diff --git a/tests/panthor/meson.build b/tests/panthor/meson.build > index 42a46e9934a9..8bd391596a97 100644 > --- a/tests/panthor/meson.build > +++ b/tests/panthor/meson.build > @@ -2,6 +2,7 @@ panthor_progs = [ > 'panthor_gem', > 'panthor_group', > 'panthor_query', > + 'panthor_sched', > 'panthor_vm', > ] > > diff --git a/tests/panthor/panthor_sched.c b/tests/panthor/panthor_sched.c > new file mode 100644 > index 000000000000..7cded16c0acd > --- /dev/null > +++ b/tests/panthor/panthor_sched.c > @@ -0,0 +1,338 @@ > +// SPDX-License-Identifier: MIT > +// SPDX-FileCopyrightText: Copyright (C) 2025 Collabora Ltd. > + > +#include <stdint.h> > +#include <sys/mman.h> > +#include <unistd.h> > + > +#include "drm.h" > +#include "igt.h" > +#include "igt_core.h" > +#include "igt_panthor.h" > +#include "panthor_drm.h" > + > +static size_t > +infinite_incr_loop(uint64_t *cs, uint64_t counter_va) > +{ > + const uint8_t counter_va_reg = 68; > + const uint8_t val_reg = 70; > + uint64_t instrs[] = { > + /* Load the source register ([r68; r69]) with the kernel address */ > + cs_mov48(counter_va_reg, counter_va), > + /* Load a 0 into r70 */ Load a 1 > + cs_mov48(val_reg, 1), > + /* STORE_MULTIPLE: Store the first register to the address pointed to by > + * [r68; r69] > + */ > + cs_stm64(counter_va_reg, val_reg, 0), > + cs_wait(1, false), Wait for what? All of these seem to be synchronous instructions? > + cs_add64(1, val_reg, val_reg), > + cs_branch(-4, CS_BRANCH_COND_ALWAYS, 0), > + }; > + > + memcpy(cs, instrs, sizeof(instrs)); > + return sizeof(instrs); > +} > + > +struct panthor_sched_test_group_ctx { > + uint32_t handle; > + uint64_t *counter; > + uint64_t cs_va; > + uint32_t cs_size; > +}; > + > +#define MAX_GROUPS 128 > + > +struct panthor_sched_test_ctx { > + struct panthor_ctx ctx; > + struct panthor_bo cs_bo; > + uint32_t cs_bo_offset; > + struct panthor_bo counter_bo; > + uint32_t counter_bo_offset; > + uint32_t group_count; > + struct panthor_sched_test_group_ctx groups[MAX_GROUPS]; > +}; > + > +#define CS_BO_VA 0x100000 > +#define COUNTER_BO_VA 0x200000 > + > +static void > +sched_test_ctx_create(int fd, struct panthor_sched_test_ctx *ctx) > +{ > + memset(ctx, 0, sizeof(*ctx)); > + igt_panthor_ctx_create(fd, &ctx->ctx); > + igt_panthor_bo_create_mapped(fd, &ctx->cs_bo, getpagesize(), 0, 0); > + igt_panthor_vm_bind(fd, ctx->ctx.vm, ctx->cs_bo.handle, CS_BO_VA, ctx->cs_bo.size, > + DRM_PANTHOR_VM_BIND_OP_MAP_READONLY | > + DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, > + 0); > + igt_panthor_bo_create_mapped(fd, &ctx->counter_bo, getpagesize(), 0, 0); > + igt_panthor_vm_bind(fd, ctx->ctx.vm, ctx->counter_bo.handle, COUNTER_BO_VA, > + ctx->counter_bo.size, > + DRM_PANTHOR_VM_BIND_OP_MAP_UNCACHED | > + DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC | > + DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, > + 0); > +} > + > +static void > +sched_test_ctx_destroy(int fd, struct panthor_sched_test_ctx *ctx) > +{ > + igt_panthor_ctx_destroy(fd, &ctx->ctx); > +} > + > +static void > +sched_test_ctx_add_group(int fd, struct panthor_sched_test_ctx *ctx, > + enum drm_panthor_group_priority group_prio) > +{ > + struct drm_panthor_queue_create queue_create = { > + .priority = 0, > + .ringbuf_size = getpagesize(), > + }; > + uint64_t *cs = (uint64_t *)((uint8_t *)ctx->cs_bo.map + ctx->cs_bo_offset); > + uint64_t *counters = ctx->counter_bo.map; > + unsigned int group_idx = ctx->group_count; > + uint64_t counter_va = COUNTER_BO_VA + group_idx * sizeof(counters[0]); > + unsigned int cs_size; > + > + igt_assert_lt(ctx->group_count, ARRAY_SIZE(ctx->groups)); > + > + igt_panthor_ctx_add_group(fd, &ctx->ctx, group_prio, &queue_create, 1); > + cs_size = infinite_incr_loop(cs, counter_va); > + cs_size = ALIGN(cs_size, 64); > + ctx->groups[ctx->group_count++] = (struct panthor_sched_test_group_ctx){ > + .handle = ctx->ctx.groups[group_idx], > + .counter = &counters[group_idx], > + .cs_va = CS_BO_VA + ctx->cs_bo_offset, > + .cs_size = cs_size, > + }; > + > + ctx->cs_bo_offset += cs_size; > + igt_assert_lt(ctx->cs_bo_offset, ctx->cs_bo.size); > +} > + > +static void > +sched_test_ctx_submit_group(int fd, struct panthor_sched_test_ctx *ctx, > + unsigned int group_idx) > +{ > + struct drm_panthor_queue_submit qsubmit = { > + .queue_index = 0, > + .stream_size = ctx->groups[group_idx].cs_size, > + .stream_addr = ctx->groups[group_idx].cs_va, > + .latest_flush = 0, > + }; > + struct drm_panthor_group_submit gsubmit = { > + .group_handle = ctx->groups[group_idx].handle, > + .queue_submits = DRM_PANTHOR_OBJ_ARRAY(1, &qsubmit), > + }; > + > + igt_assert_lt(group_idx, ctx->group_count); > + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_GROUP_SUBMIT, &gsubmit), 0); > +} > + > +igt_main { > + int fd; > + > + igt_fixture { > + fd = drm_open_driver(DRIVER_PANTHOR); > + } > + > + igt_describe("Schedule 8 groups with the same prio"); > + igt_subtest("sched_8_groups_same_prio") { > + uint64_t min_cnt = UINT64_MAX, max_cnt = 0; > + struct panthor_sched_test_ctx ctx; > + const unsigned int group_cnt = 8; > + > + sched_test_ctx_create(fd, &ctx); > + > + for (unsigned int i = 0; i < group_cnt; i++) > + sched_test_ctx_add_group(fd, &ctx, PANTHOR_GROUP_PRIORITY_MEDIUM); > + > + for (unsigned int i = 0; i < group_cnt; i++) { > + sched_test_ctx_submit_group(fd, &ctx, i); > + > + /* Add some delay, to make sure each group becomes > + * active at a different time, and exercise the > + * idle -> active transition that appeared to be > + * broken at some point. > + */ > + usleep(100000); > + } > + > + /* Jobs will timeout, because we've issued an infinte loop, > + * but leave it some time before checking the counter > + * values. > + */ > + sleep(6); > + > + for (unsigned int i = 0; i < group_cnt; i++) { > + min_cnt = min(min_cnt, *ctx.groups[i].counter); > + max_cnt = max(max_cnt, *ctx.groups[i].counter); > + } > + > + igt_assert_lt(200000, min_cnt); > + igt_assert_lte(min_cnt, max_cnt); > + > + /* Allow a 20% difference max? */ > + igt_assert_lt((((max_cnt - min_cnt) * 100) / min_cnt), 20); > + > + sched_test_ctx_destroy(fd, &ctx); > + } > + > + igt_describe("Schedule 16 groups with the same prio"); > + igt_subtest("sched_16_groups_same_prio") { > + uint64_t min_cnt = UINT64_MAX, max_cnt = 0; > + struct panthor_sched_test_ctx ctx; > + const unsigned int group_cnt = 16; > + > + sched_test_ctx_create(fd, &ctx); > + > + for (unsigned int i = 0; i < group_cnt; i++) > + sched_test_ctx_add_group(fd, &ctx, PANTHOR_GROUP_PRIORITY_MEDIUM); > + > + for (unsigned int i = 0; i < group_cnt; i++) { > + sched_test_ctx_submit_group(fd, &ctx, i); > + > + /* Add some delay, to make sure each group becomes > + * active at a different time, and exercise the > + * idle -> active transition that appeared to be > + * broken at some point. > + */ > + usleep(100000); > + } > + > + /* Jobs will timeout, because we've issued an infinte loop, > + * but leave it some time before checking the counter > + * values. > + */ > + sleep(15); > + > + for (unsigned int i = 0; i < group_cnt; i++) { > + min_cnt = min(min_cnt, *ctx.groups[i].counter); > + max_cnt = max(max_cnt, *ctx.groups[i].counter); > + } > + > + igt_assert_lt(200000, min_cnt); > + igt_assert_lte(min_cnt, max_cnt); > + > + /* Allow a 20% difference max? */ > + igt_assert_lt((((max_cnt - min_cnt) * 100) / min_cnt), 20); > + > + sched_test_ctx_destroy(fd, &ctx); > + } > + > + igt_describe("Schedule 15 groups with medium prio, one high"); > + igt_subtest("sched_15_groups_med_1_high") { > + uint64_t min_cnt = UINT64_MAX, max_cnt = 0; > + struct panthor_sched_test_ctx ctx; > + const unsigned int group_cnt = 16; > + const unsigned int group_high = group_cnt - 1; > + > + sched_test_ctx_create(fd, &ctx); > + > + for (unsigned int i = 0; i < group_cnt; i++) { > + sched_test_ctx_add_group(fd, &ctx, > + i == group_high ? > + PANTHOR_GROUP_PRIORITY_HIGH : > + PANTHOR_GROUP_PRIORITY_MEDIUM); > + } > + > + for (unsigned int i = 0; i < group_cnt; i++) { > + sched_test_ctx_submit_group(fd, &ctx, i); > + > + /* Add some delay, to make sure each group becomes > + * active at a different time, and exercise the > + * idle -> active transition that appeared to be > + * broken at some point. > + */ > + usleep(100000); > + } > + > + /* Jobs will timeout, because we've issued an infinte loop, > + * but leave it some time before checking the counter > + * values. > + */ > + sleep(15); > + > + for (unsigned int i = 0; i < group_cnt; i++) { > + if (i == group_high) > + continue; > + > + min_cnt = min(min_cnt, *ctx.groups[i].counter); > + max_cnt = max(max_cnt, *ctx.groups[i].counter); > + } > + > + igt_assert_lt(200000, min_cnt); > + igt_assert_lte(min_cnt, max_cnt); > + > + /* Allow a 30% difference max on all med groups? */ > + igt_assert_lt((((max_cnt - min_cnt) * 100) / min_cnt), 30); > + > + /* High group's counter must be at least 1.5x the other groups. */ > + igt_assert_lt((float)max_cnt * 1.5, (float)*ctx.groups[group_high].counter); > + > + sched_test_ctx_destroy(fd, &ctx); > + } > + > + igt_describe("Schedule 4 groups with RT prio, one high"); > + igt_subtest("sched_4_groups_rt_1_high") { > + uint64_t min_cnt = UINT64_MAX, max_cnt = 0; > + struct panthor_sched_test_ctx ctx; > + const unsigned int group_cnt = 5; > + const unsigned int group_high = group_cnt - 1; > + uint64_t group_high_counter; > + > + sched_test_ctx_create(fd, &ctx); > + > + for (unsigned int i = 0; i < group_cnt; i++) { > + sched_test_ctx_add_group(fd, &ctx, > + i == group_high ? > + PANTHOR_GROUP_PRIORITY_HIGH : > + PANTHOR_GROUP_PRIORITY_REALTIME); > + } > + > + for (unsigned int i = 0; i < group_cnt; i++) { > + if (i == group_high) > + continue; > + sched_test_ctx_submit_group(fd, &ctx, i); > + } > + > + /* Leave it some time so the SW scheduler can make all RT groups > + * active, and the high one really doesn't get a chance to run. > + * Ideally the dequeueing of jobs would also take the group > + * priority into account, but that's not the case. > + */ > + usleep(200000); > + sched_test_ctx_submit_group(fd, &ctx, group_high); > + > + /* Make sure we wait less than the timeout, otherwise the group with > + * high priority will be left a chance to run as soon as one of the RT > + * group dies. > + */ > + sleep(2); > + > + group_high_counter = *ctx.groups[group_high].counter; > + for (unsigned int i = 0; i < group_cnt; i++) { > + if (i == group_high) > + continue; > + > + min_cnt = min(min_cnt, *ctx.groups[i].counter); > + max_cnt = max(max_cnt, *ctx.groups[i].counter); > + } > + > + igt_assert_lt(200000, min_cnt); > + igt_assert_lte(min_cnt, max_cnt); > + > + /* Allow a 30% difference max on all med groups? */ > + igt_assert_lt((((max_cnt - min_cnt) * 100) / min_cnt), 30); > + > + /* High group should never run. */ > + igt_assert_eq(group_high_counter, 0); > + > + sched_test_ctx_destroy(fd, &ctx); > + } > + > + igt_fixture { > + drm_close_driver(fd); > + } > +} > -- > 2.51.1 > This looks good, but I tried it and this is the result: IGT-Version: 2.2-g6ba172359 (aarch64) (Linux: 6.18.0-rc4-hwe aarch64) Using IGT_SRANDOM=1764789962 for randomisation Opened device: /dev/dri/card0 Starting subtest: sched_8_groups_same_prio [ 956.405832] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 956.406839] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 956.661846] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 956.662752] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 956.917917] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 956.918794] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 956.919620] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 957.173858] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 (panthor_sched:8051) CRITICAL: Test assertion failure function __igt_unique____real_main133, file ../tests/panthor/panthor_sched.c:177: (panthor_sched:8051) CRITICAL: Failed assertion: (((max_cnt - min_cnt) * 100) / min_cnt) < 20 (panthor_sched:8051) CRITICAL: error: 1950 >= 20 Stack trace: #0 ../lib/igt_core.c:2296 __igt_fail_assert() #1 ../tests/panthor/panthor_sched.c:179 __igt_unique____real_main133() #2 ../tests/panthor/panthor_sched.c:133 main() #3 [<unknown>+0xb987229c] #4 [__libc_start_main+0x9c] Subtest sched_8_groups_same_prio failed. **** DEBUG **** (panthor_sched:8051) CRITICAL: Test assertion failure function __igt_unique____real_main133, file ../tests/panthor/panthor_sched.c:177: (panthor_sched:8051) CRITICAL: Failed assertion: (((max_cnt - min_cnt) * 100) / min_cnt) < 20 (panthor_sched:8051) CRITICAL: error: 1950 >= 20 (panthor_sched:8051) igt_core-INFO: Stack trace: (panthor_sched:8051) igt_core-INFO: #0 ../lib/igt_core.c:2296 __igt_fail_assert() (panthor_sched:8051) igt_core-INFO: #1 ../tests/panthor/panthor_sched.c:179 __igt_unique____real_main133() (panthor_sched:8051) igt_core-INFO: #2 ../tests/panthor/panthor_sched.c:133 main() (panthor_sched:8051) igt_core-INFO: #3 [<unknown>+0xb987229c] (panthor_sched:8051) igt_core-INFO: #4 [__libc_start_main+0x9c] **** END **** Subtest sched_8_groups_same_prio: FAIL (6.868s) Starting subtest: sched_16_groups_same_prio [ 966.658057] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 966.950047] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 967.286042] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 967.574037] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 967.862067] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 968.277970] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 968.342033] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 968.630049] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 968.694132] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 968.790115] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 968.886033] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 968.950019] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 968.982139] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 969.142087] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 972.278051] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 972.790126] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 (panthor_sched:8051) CRITICAL: Test assertion failure function __igt_unique____real_main133, file ../tests/panthor/panthor_sched.c:219: (panthor_sched:8051) CRITICAL: Failed assertion: (((max_cnt - min_cnt) * 100) / min_cnt) < 20 (panthor_sched:8051) CRITICAL: error: 1729 >= 20 Stack trace: #0 ../lib/igt_core.c:2296 __igt_fail_assert() #1 ../tests/panthor/panthor_sched.c:221 __igt_unique____real_main133() #2 ../tests/panthor/panthor_sched.c:133 main() #3 [<unknown>+0xb987229c] #4 [__libc_start_main+0x9c] Subtest sched_16_groups_same_prio failed. **** DEBUG **** (panthor_sched:8051) CRITICAL: Test assertion failure function __igt_unique____real_main133, file ../tests/panthor/panthor_sched.c:219: (panthor_sched:8051) CRITICAL: Failed assertion: (((max_cnt - min_cnt) * 100) / min_cnt) < 20 (panthor_sched:8051) CRITICAL: error: 1729 >= 20 (panthor_sched:8051) igt_core-INFO: Stack trace: (panthor_sched:8051) igt_core-INFO: #0 ../lib/igt_core.c:2296 __igt_fail_assert() (panthor_sched:8051) igt_core-INFO: #1 ../tests/panthor/panthor_sched.c:221 __igt_unique____real_main133() (panthor_sched:8051) igt_core-INFO: #2 ../tests/panthor/panthor_sched.c:133 main() (panthor_sched:8051) igt_core-INFO: #3 [<unknown>+0xb987229c] (panthor_sched:8051) igt_core-INFO: #4 [__libc_start_main+0x9c] **** END **** Subtest sched_16_groups_same_prio: FAIL (16.619s) Starting subtest: sched_15_groups_med_1_high [ 981.494175] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 982.774389] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 983.542380] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 983.706258] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 984.022303] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 984.534323] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 984.758239] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 984.886290] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 984.894132] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 985.046324] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 985.078218] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 985.238128] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 985.398222] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 985.462335] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 985.558313] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 [ 989.686323] panthor fb000000.gpu: [drm] job timeout: pid=8051, comm=panthor_sched, seqno=1 (panthor_sched:8051) CRITICAL: Test assertion failure function __igt_unique____real_main133, file ../tests/panthor/panthor_sched.c:269: (panthor_sched:8051) CRITICAL: Failed assertion: (((max_cnt - min_cnt) * 100) / min_cnt) < 30 (panthor_sched:8051) CRITICAL: error: 444 >= 30 Stack trace: #0 ../lib/igt_core.c:2296 __igt_fail_assert() #1 ../tests/panthor/panthor_sched.c:272 __igt_unique____real_main133() #2 ../tests/panthor/panthor_sched.c:133 main() #3 [<unknown>+0xb987229c] #4 [__libc_start_main+0x9c] Subtest sched_15_groups_med_1_high failed. **** DEBUG **** (panthor_sched:8051) CRITICAL: Test assertion failure function __igt_unique____real_main133, file ../tests/panthor/panthor_sched.c:269: (panthor_sched:8051) CRITICAL: Failed assertion: (((max_cnt - min_cnt) * 100) / min_cnt) < 30 (panthor_sched:8051) CRITICAL: error: 444 >= 30 (panthor_sched:8051) igt_core-INFO: Stack trace: (panthor_sched:8051) igt_core-INFO: #0 ../lib/igt_core.c:2296 __igt_fail_assert() (panthor_sched:8051) igt_core-INFO: #1 ../tests/panthor/panthor_sched.c:272 __igt_unique____real_main133() (panthor_sched:8051) igt_core-INFO: #2 ../tests/panthor/panthor_sched.c:133 main() (panthor_sched:8051) igt_core-INFO: #3 [<unknown>+0xb987229c] (panthor_sched:8051) igt_core-INFO: #4 [__libc_start_main+0x9c] **** END **** Subtest sched_15_groups_med_1_high: FAIL (16.617s) Starting subtest: sched_4_groups_rt_1_high Subtest sched_4_groups_rt_1_high: SUCCESS (2.205s) ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH i-g-t v2 3/3] tests/panthor: Add scheduler tests 2025-12-03 19:31 ` Daniel Almeida @ 2025-12-17 15:38 ` Boris Brezillon 0 siblings, 0 replies; 10+ messages in thread From: Boris Brezillon @ 2025-12-17 15:38 UTC (permalink / raw) To: Daniel Almeida Cc: igt-dev, Petri Latvala, Arkadiusz Hiler, Kamil Konieczny, Juha-Pekka Heikkila, Bhanuprakash Modem, Steven Price, Liviu Dudau, Adrián Larumbe, kernel On Wed, 3 Dec 2025 16:31:59 -0300 Daniel Almeida <daniel.almeida@collabora.com> wrote: [...] > > diff --git a/tests/panthor/panthor_sched.c b/tests/panthor/panthor_sched.c > > new file mode 100644 > > index 000000000000..7cded16c0acd > > --- /dev/null > > +++ b/tests/panthor/panthor_sched.c > > @@ -0,0 +1,338 @@ > > +// SPDX-License-Identifier: MIT > > +// SPDX-FileCopyrightText: Copyright (C) 2025 Collabora Ltd. > > + > > +#include <stdint.h> > > +#include <sys/mman.h> > > +#include <unistd.h> > > + > > +#include "drm.h" > > +#include "igt.h" > > +#include "igt_core.h" > > +#include "igt_panthor.h" > > +#include "panthor_drm.h" > > + > > +static size_t > > +infinite_incr_loop(uint64_t *cs, uint64_t counter_va) > > +{ > > + const uint8_t counter_va_reg = 68; > > + const uint8_t val_reg = 70; > > + uint64_t instrs[] = { > > + /* Load the source register ([r68; r69]) with the kernel address */ > > + cs_mov48(counter_va_reg, counter_va), > > + /* Load a 0 into r70 */ > > Load a 1 Oops, will fix the comment. > > > + cs_mov48(val_reg, 1), > > + /* STORE_MULTIPLE: Store the first register to the address pointed to by > > + * [r68; r69] > > + */ > > + cs_stm64(counter_va_reg, val_reg, 0), > > + cs_wait(1, false), > > Wait for what? All of these seem to be synchronous instructions? Nope, load/store instructions are asynchronous, you need to wait for the SB assigned to "other-asynchronous-ops" (defaults to zero) for the mem operation to be effective. > > > + cs_add64(1, val_reg, val_reg), > > + cs_branch(-4, CS_BRANCH_COND_ALWAYS, 0), > > + }; > > This looks good, but I tried it and this is the result: If you're not testing with drm-misc-next, that's normal. Those tests are added to make sure we don't regress those scheduling cases again. ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2025-12-17 15:38 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-11-28 9:38 [PATCH i-g-t v2 0/3] tests/panthor: Add more tests Boris Brezillon 2025-11-28 9:38 ` [PATCH i-g-t v2 1/3] drm-uapi/panthor: Sync panthor uapi Boris Brezillon 2025-11-28 9:38 ` [PATCH i-g-t v2 2/3] tests/panthor: Add a test to make sure the buffer is zeroed at alloc time Boris Brezillon 2025-12-01 11:14 ` Kamil Konieczny 2025-12-01 13:25 ` Daniel Almeida 2025-12-01 15:19 ` Kamil Konieczny 2025-12-01 15:21 ` Daniel Almeida 2025-11-28 9:38 ` [PATCH i-g-t v2 3/3] tests/panthor: Add scheduler tests Boris Brezillon 2025-12-03 19:31 ` Daniel Almeida 2025-12-17 15:38 ` Boris Brezillon
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox