Skip to content

Commit a446ae2

Browse files
drm/i915: add query uAPI
There are a number of information that are readable from hardware registers and that we would like to make accessible to userspace. One particular example is the topology of the execution units (how are execution units grouped in subslices and slices and also which ones have been fused off for die recovery). At the moment the GET_PARAM ioctl covers some basic needs, but generally is only able to return a single value for each defined parameter. This is a bit problematic with topology descriptions which are array/maps of available units. This change introduces a new ioctl that can deal with requests to fill structures of potentially variable lengths. The user is expected fill a query with length fields set at 0 on the first call, the kernel then sets the length fields to the their expected values. A second call to the kernel with length fields at their expected values will trigger a copy of the data to the pointed memory locations. The scope of this uAPI is only to provide information to userspace, not to allow configuration of the device. v2: Simplify dispatcher code iteration (Tvrtko) Tweak uapi drm_i915_query_item structure (Tvrtko) v3: Rename pad fields into flags (Chris) Return error on flags field != 0 (Chris) Only copy length back to userspace in drm_i915_query_item (Chris) v4: Use array of functions instead of switch (Chris) v5: More comments in uapi (Tvrtko) Return query item errors in length field (All) v6: Tweak uapi comments style to match the coding style (Lionel) v7: Add i915_query.h (Joonas) v8: (Lionel) Change the behavior of the item iterator to report invalid queries into the query item rather than stopping the iteration. This enables userspace applications to query newer items on older kernels and only have failure on the items that are not supported. v9: Edit copyright headers (Joonas) v10: Typos & comments in uapi (Joonas) Signed-off-by: Lionel Landwerlin <[email protected]> Reviewed-by: Tvrtko Ursulin <[email protected]> Acked-by: Chris Wilson <[email protected]> Reviewed-by: Joonas Lahtinen <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent cac6cfa commit a446ae2

File tree

5 files changed

+111
-3
lines changed

5 files changed

+111
-3
lines changed

drivers/gpu/drm/i915/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ i915-y += i915_cmd_parser.o \
6969
i915_gem_timeline.o \
7070
i915_gem_userptr.o \
7171
i915_gemfs.o \
72+
i915_query.o \
7273
i915_request.o \
7374
i915_trace_points.o \
7475
i915_vma.o \

drivers/gpu/drm/i915/i915_drv.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#include "i915_drv.h"
5050
#include "i915_trace.h"
5151
#include "i915_pmu.h"
52+
#include "i915_query.h"
5253
#include "i915_vgpu.h"
5354
#include "intel_drv.h"
5455
#include "intel_uc.h"
@@ -2832,6 +2833,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
28322833
DRM_IOCTL_DEF_DRV(I915_PERF_OPEN, i915_perf_open_ioctl, DRM_RENDER_ALLOW),
28332834
DRM_IOCTL_DEF_DRV(I915_PERF_ADD_CONFIG, i915_perf_add_config_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
28342835
DRM_IOCTL_DEF_DRV(I915_PERF_REMOVE_CONFIG, i915_perf_remove_config_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
2836+
DRM_IOCTL_DEF_DRV(I915_QUERY, i915_query_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
28352837
};
28362838

28372839
static struct drm_driver driver = {

drivers/gpu/drm/i915/i915_query.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* SPDX-License-Identifier: MIT
3+
*
4+
* Copyright © 2018 Intel Corporation
5+
*/
6+
7+
#include "i915_drv.h"
8+
#include "i915_query.h"
9+
#include <uapi/drm/i915_drm.h>
10+
11+
static int (* const i915_query_funcs[])(struct drm_i915_private *dev_priv,
12+
struct drm_i915_query_item *query_item) = {
13+
};
14+
15+
int i915_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
16+
{
17+
struct drm_i915_private *dev_priv = to_i915(dev);
18+
struct drm_i915_query *args = data;
19+
struct drm_i915_query_item __user *user_item_ptr =
20+
u64_to_user_ptr(args->items_ptr);
21+
u32 i;
22+
23+
if (args->flags != 0)
24+
return -EINVAL;
25+
26+
for (i = 0; i < args->num_items; i++, user_item_ptr++) {
27+
struct drm_i915_query_item item;
28+
u64 func_idx;
29+
int ret;
30+
31+
if (copy_from_user(&item, user_item_ptr, sizeof(item)))
32+
return -EFAULT;
33+
34+
if (item.query_id == 0)
35+
return -EINVAL;
36+
37+
func_idx = item.query_id - 1;
38+
39+
if (func_idx < ARRAY_SIZE(i915_query_funcs))
40+
ret = i915_query_funcs[func_idx](dev_priv, &item);
41+
else
42+
ret = -EINVAL;
43+
44+
/* Only write the length back to userspace if they differ. */
45+
if (ret != item.length && put_user(ret, &user_item_ptr->length))
46+
return -EFAULT;
47+
}
48+
49+
return 0;
50+
}

drivers/gpu/drm/i915/i915_query.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
* SPDX-License-Identifier: MIT
3+
*
4+
* Copyright © 2018 Intel Corporation
5+
*/
6+
7+
#ifndef _I915_QUERY_H_
8+
#define _I915_QUERY_H_
9+
10+
struct drm_device;
11+
struct drm_file;
12+
13+
int i915_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
14+
15+
#endif

include/uapi/drm/i915_drm.h

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ typedef struct _drm_i915_sarea {
318318
#define DRM_I915_PERF_OPEN 0x36
319319
#define DRM_I915_PERF_ADD_CONFIG 0x37
320320
#define DRM_I915_PERF_REMOVE_CONFIG 0x38
321+
#define DRM_I915_QUERY 0x39
321322

322323
#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
323324
#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
@@ -375,6 +376,7 @@ typedef struct _drm_i915_sarea {
375376
#define DRM_IOCTL_I915_PERF_OPEN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_OPEN, struct drm_i915_perf_open_param)
376377
#define DRM_IOCTL_I915_PERF_ADD_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_ADD_CONFIG, struct drm_i915_perf_oa_config)
377378
#define DRM_IOCTL_I915_PERF_REMOVE_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_REMOVE_CONFIG, __u64)
379+
#define DRM_IOCTL_I915_QUERY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_QUERY, struct drm_i915_query)
378380

379381
/* Allow drivers to submit batchbuffers directly to hardware, relying
380382
* on the security mechanisms provided by hardware.
@@ -1606,15 +1608,53 @@ struct drm_i915_perf_oa_config {
16061608
__u32 n_flex_regs;
16071609

16081610
/*
1609-
* These fields are pointers to tuples of u32 values (register
1610-
* address, value). For example the expected length of the buffer
1611-
* pointed by mux_regs_ptr is (2 * sizeof(u32) * n_mux_regs).
1611+
* These fields are pointers to tuples of u32 values (register address,
1612+
* value). For example the expected length of the buffer pointed by
1613+
* mux_regs_ptr is (2 * sizeof(u32) * n_mux_regs).
16121614
*/
16131615
__u64 mux_regs_ptr;
16141616
__u64 boolean_regs_ptr;
16151617
__u64 flex_regs_ptr;
16161618
};
16171619

1620+
struct drm_i915_query_item {
1621+
__u64 query_id;
1622+
1623+
/*
1624+
* When set to zero by userspace, this is filled with the size of the
1625+
* data to be written at the data_ptr pointer. The kernel sets this
1626+
* value to a negative value to signal an error on a particular query
1627+
* item.
1628+
*/
1629+
__s32 length;
1630+
1631+
/*
1632+
* Unused for now. Must be cleared to zero.
1633+
*/
1634+
__u32 flags;
1635+
1636+
/*
1637+
* Data will be written at the location pointed by data_ptr when the
1638+
* value of length matches the length of the data to be written by the
1639+
* kernel.
1640+
*/
1641+
__u64 data_ptr;
1642+
};
1643+
1644+
struct drm_i915_query {
1645+
__u32 num_items;
1646+
1647+
/*
1648+
* Unused for now. Must be cleared to zero.
1649+
*/
1650+
__u32 flags;
1651+
1652+
/*
1653+
* This points to an array of num_items drm_i915_query_item structures.
1654+
*/
1655+
__u64 items_ptr;
1656+
};
1657+
16181658
#if defined(__cplusplus)
16191659
}
16201660
#endif

0 commit comments

Comments
 (0)