Skip to content

Commit 7102172

Browse files
Abdiel Janulguematt-auld
authored andcommitted
drm/i915/query: Expose memory regions through the query uAPI
Returns the available memory region areas supported by the HW. v2(Daniel & Jason): - Add some kernel-doc, including example usage. - Drop all the extra rsvd v3(Jason & Tvrtko) - add back rsvd Signed-off-by: Abdiel Janulgue <[email protected]> Signed-off-by: Matthew Auld <[email protected]> Cc: Joonas Lahtinen <[email protected]> Cc: Thomas Hellström <[email protected]> Cc: Daniele Ceraolo Spurio <[email protected]> Cc: Lionel Landwerlin <[email protected]> Cc: Jon Bloomfield <[email protected]> Cc: Jordan Justen <[email protected]> Cc: Daniel Vetter <[email protected]> Cc: Kenneth Graunke <[email protected]> Cc: Jason Ekstrand <[email protected]> Cc: Dave Airlie <[email protected]> Cc: [email protected] Cc: [email protected] Reviewed-by: Kenneth Graunke <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 36150bb commit 7102172

File tree

3 files changed

+196
-5
lines changed

3 files changed

+196
-5
lines changed

drivers/gpu/drm/i915/i915_query.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,11 +419,70 @@ static int query_perf_config(struct drm_i915_private *i915,
419419
}
420420
}
421421

422+
static int query_memregion_info(struct drm_i915_private *i915,
423+
struct drm_i915_query_item *query_item)
424+
{
425+
struct drm_i915_query_memory_regions __user *query_ptr =
426+
u64_to_user_ptr(query_item->data_ptr);
427+
struct drm_i915_memory_region_info __user *info_ptr =
428+
&query_ptr->regions[0];
429+
struct drm_i915_memory_region_info info = { };
430+
struct drm_i915_query_memory_regions query;
431+
struct intel_memory_region *mr;
432+
u32 total_length;
433+
int ret, id, i;
434+
435+
if (query_item->flags != 0)
436+
return -EINVAL;
437+
438+
total_length = sizeof(query);
439+
for_each_memory_region(mr, i915, id) {
440+
if (mr->private)
441+
continue;
442+
443+
total_length += sizeof(info);
444+
}
445+
446+
ret = copy_query_item(&query, sizeof(query), total_length, query_item);
447+
if (ret != 0)
448+
return ret;
449+
450+
if (query.num_regions)
451+
return -EINVAL;
452+
453+
for (i = 0; i < ARRAY_SIZE(query.rsvd); i++) {
454+
if (query.rsvd[i])
455+
return -EINVAL;
456+
}
457+
458+
for_each_memory_region(mr, i915, id) {
459+
if (mr->private)
460+
continue;
461+
462+
info.region.memory_class = mr->type;
463+
info.region.memory_instance = mr->instance;
464+
info.probed_size = mr->total;
465+
info.unallocated_size = mr->avail;
466+
467+
if (__copy_to_user(info_ptr, &info, sizeof(info)))
468+
return -EFAULT;
469+
470+
query.num_regions++;
471+
info_ptr++;
472+
}
473+
474+
if (__copy_to_user(query_ptr, &query, sizeof(query)))
475+
return -EFAULT;
476+
477+
return total_length;
478+
}
479+
422480
static int (* const i915_query_funcs[])(struct drm_i915_private *dev_priv,
423481
struct drm_i915_query_item *query_item) = {
424482
query_topology_info,
425483
query_engine_info,
426484
query_perf_config,
485+
query_memregion_info,
427486
};
428487

429488
int i915_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file)

drivers/gpu/drm/i915/intel_memory_region.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <linux/mutex.h>
1212
#include <linux/io-mapping.h>
1313
#include <drm/drm_mm.h>
14+
#include <drm/i915_drm.h>
1415

1516
#include "i915_buddy.h"
1617

@@ -19,12 +20,9 @@ struct drm_i915_gem_object;
1920
struct intel_memory_region;
2021
struct sg_table;
2122

22-
/**
23-
* Base memory type
24-
*/
2523
enum intel_memory_type {
26-
INTEL_MEMORY_SYSTEM = 0,
27-
INTEL_MEMORY_LOCAL,
24+
INTEL_MEMORY_SYSTEM = I915_MEMORY_CLASS_SYSTEM,
25+
INTEL_MEMORY_LOCAL = I915_MEMORY_CLASS_DEVICE,
2826
INTEL_MEMORY_STOLEN_SYSTEM,
2927
INTEL_MEMORY_STOLEN_LOCAL,
3028
};

include/uapi/drm/i915_drm.h

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2230,6 +2230,7 @@ struct drm_i915_query_item {
22302230
#define DRM_I915_QUERY_TOPOLOGY_INFO 1
22312231
#define DRM_I915_QUERY_ENGINE_INFO 2
22322232
#define DRM_I915_QUERY_PERF_CONFIG 3
2233+
#define DRM_I915_QUERY_MEMORY_REGIONS 4
22332234
/* Must be kept compact -- no holes and well documented */
22342235

22352236
/**
@@ -2464,6 +2465,139 @@ struct drm_i915_query_perf_config {
24642465
__u8 data[];
24652466
};
24662467

2468+
/**
2469+
* enum drm_i915_gem_memory_class - Supported memory classes
2470+
*/
2471+
enum drm_i915_gem_memory_class {
2472+
/** @I915_MEMORY_CLASS_SYSTEM: System memory */
2473+
I915_MEMORY_CLASS_SYSTEM = 0,
2474+
/** @I915_MEMORY_CLASS_DEVICE: Device local-memory */
2475+
I915_MEMORY_CLASS_DEVICE,
2476+
};
2477+
2478+
/**
2479+
* struct drm_i915_gem_memory_class_instance - Identify particular memory region
2480+
*/
2481+
struct drm_i915_gem_memory_class_instance {
2482+
/** @memory_class: See enum drm_i915_gem_memory_class */
2483+
__u16 memory_class;
2484+
2485+
/** @memory_instance: Which instance */
2486+
__u16 memory_instance;
2487+
};
2488+
2489+
/**
2490+
* struct drm_i915_memory_region_info - Describes one region as known to the
2491+
* driver.
2492+
*
2493+
* Note that we reserve some stuff here for potential future work. As an example
2494+
* we might want expose the capabilities for a given region, which could include
2495+
* things like if the region is CPU mappable/accessible, what are the supported
2496+
* mapping types etc.
2497+
*
2498+
* Note that to extend struct drm_i915_memory_region_info and struct
2499+
* drm_i915_query_memory_regions in the future the plan is to do the following:
2500+
*
2501+
* .. code-block:: C
2502+
*
2503+
* struct drm_i915_memory_region_info {
2504+
* struct drm_i915_gem_memory_class_instance region;
2505+
* union {
2506+
* __u32 rsvd0;
2507+
* __u32 new_thing1;
2508+
* };
2509+
* ...
2510+
* union {
2511+
* __u64 rsvd1[8];
2512+
* struct {
2513+
* __u64 new_thing2;
2514+
* __u64 new_thing3;
2515+
* ...
2516+
* };
2517+
* };
2518+
* };
2519+
*
2520+
* With this things should remain source compatible between versions for
2521+
* userspace, even as we add new fields.
2522+
*
2523+
* Note this is using both struct drm_i915_query_item and struct drm_i915_query.
2524+
* For this new query we are adding the new query id DRM_I915_QUERY_MEMORY_REGIONS
2525+
* at &drm_i915_query_item.query_id.
2526+
*/
2527+
struct drm_i915_memory_region_info {
2528+
/** @region: The class:instance pair encoding */
2529+
struct drm_i915_gem_memory_class_instance region;
2530+
2531+
/** @rsvd0: MBZ */
2532+
__u32 rsvd0;
2533+
2534+
/** @probed_size: Memory probed by the driver (-1 = unknown) */
2535+
__u64 probed_size;
2536+
2537+
/** @unallocated_size: Estimate of memory remaining (-1 = unknown) */
2538+
__u64 unallocated_size;
2539+
2540+
/** @rsvd1: MBZ */
2541+
__u64 rsvd1[8];
2542+
};
2543+
2544+
/**
2545+
* struct drm_i915_query_memory_regions
2546+
*
2547+
* The region info query enumerates all regions known to the driver by filling
2548+
* in an array of struct drm_i915_memory_region_info structures.
2549+
*
2550+
* Example for getting the list of supported regions:
2551+
*
2552+
* .. code-block:: C
2553+
*
2554+
* struct drm_i915_query_memory_regions *info;
2555+
* struct drm_i915_query_item item = {
2556+
* .query_id = DRM_I915_QUERY_MEMORY_REGIONS;
2557+
* };
2558+
* struct drm_i915_query query = {
2559+
* .num_items = 1,
2560+
* .items_ptr = (uintptr_t)&item,
2561+
* };
2562+
* int err, i;
2563+
*
2564+
* // First query the size of the blob we need, this needs to be large
2565+
* // enough to hold our array of regions. The kernel will fill out the
2566+
* // item.length for us, which is the number of bytes we need.
2567+
* err = ioctl(fd, DRM_IOCTL_I915_QUERY, &query);
2568+
* if (err) ...
2569+
*
2570+
* info = calloc(1, item.length);
2571+
* // Now that we allocated the required number of bytes, we call the ioctl
2572+
* // again, this time with the data_ptr pointing to our newly allocated
2573+
* // blob, which the kernel can then populate with the all the region info.
2574+
* item.data_ptr = (uintptr_t)&info,
2575+
*
2576+
* err = ioctl(fd, DRM_IOCTL_I915_QUERY, &query);
2577+
* if (err) ...
2578+
*
2579+
* // We can now access each region in the array
2580+
* for (i = 0; i < info->num_regions; i++) {
2581+
* struct drm_i915_memory_region_info mr = info->regions[i];
2582+
* u16 class = mr.region.class;
2583+
* u16 instance = mr.region.instance;
2584+
*
2585+
* ....
2586+
* }
2587+
*
2588+
* free(info);
2589+
*/
2590+
struct drm_i915_query_memory_regions {
2591+
/** @num_regions: Number of supported regions */
2592+
__u32 num_regions;
2593+
2594+
/** @rsvd: MBZ */
2595+
__u32 rsvd[3];
2596+
2597+
/** @regions: Info about each supported region */
2598+
struct drm_i915_memory_region_info regions[];
2599+
};
2600+
24672601
#if defined(__cplusplus)
24682602
}
24692603
#endif

0 commit comments

Comments
 (0)