[RFC 1/2] drm/i915: Expose local memory information via sysfs
Jani Nikula
jani.nikula at linux.intel.com
Mon May 19 15:57:20 UTC 2025
On Mon, 19 May 2025, Krzysztof Niemiec <krzysztof.niemiec at intel.com> wrote:
> Introduce sysfs entries regarding basic local memory information
> (unallocated memory and total memory, for both the entire region and the
> CPU visible part). This simplifies how external tools might read this
> information, which at the point of writing this patch is only accessible
> via the i915_query() ioctl.
>
> This change exposes that information to users without CAP_PERFMON.
>
> This change was requested in [1] by a developer of one such external
> tool, with the sysfs idea surfacing in a corresponding request for xe [2].
>
> [1] https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/14153
> [2] https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/4861
>
> Signed-off-by: Krzysztof Niemiec <krzysztof.niemiec at intel.com>
> ---
> drivers/gpu/drm/i915/i915_sysfs.c | 6 ++
> drivers/gpu/drm/i915/intel_memory_region.c | 106 +++++++++++++++++++++
> drivers/gpu/drm/i915/intel_memory_region.h | 3 +
> 3 files changed, 115 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
> index f936e8f1f129..048d6da2f6db 100644
> --- a/drivers/gpu/drm/i915/i915_sysfs.c
> +++ b/drivers/gpu/drm/i915/i915_sysfs.c
> @@ -35,6 +35,8 @@
> #include "gt/intel_rps.h"
> #include "gt/sysfs_engines.h"
>
> +#include "intel_memory_region.h"
> +
> #include "i915_drv.h"
> #include "i915_sysfs.h"
>
> @@ -182,6 +184,8 @@ void i915_setup_sysfs(struct drm_i915_private *dev_priv)
>
> i915_gpu_error_sysfs_setup(dev_priv);
>
> + intel_memory_region_setup_sysfs(dev_priv);
> +
> intel_engines_add_sysfs(dev_priv);
> }
>
> @@ -189,6 +193,8 @@ void i915_teardown_sysfs(struct drm_i915_private *dev_priv)
> {
> struct device *kdev = dev_priv->drm.primary->kdev;
>
> + intel_memory_region_teardown_sysfs();
> +
> i915_gpu_error_sysfs_teardown(dev_priv);
>
> device_remove_bin_file(kdev, &dpf_attrs_1);
> diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c
> index 59bd603e6deb..9558e300209b 100644
> --- a/drivers/gpu/drm/i915/intel_memory_region.c
> +++ b/drivers/gpu/drm/i915/intel_memory_region.c
> @@ -3,14 +3,19 @@
> * Copyright © 2019 Intel Corporation
> */
>
> +#include <linux/kobject.h>
> #include <linux/prandom.h>
> +#include <linux/sysfs.h>
>
> #include <uapi/drm/i915_drm.h>
>
> #include "intel_memory_region.h"
> #include "i915_drv.h"
> +#include "i915_sysfs.h"
> #include "i915_ttm_buddy_manager.h"
>
> +static struct kobject *memory_info_dir;
This can't be per module.
BR,
Jani.
> +
> static const struct {
> u16 class;
> u16 instance;
> @@ -423,6 +428,107 @@ void intel_memory_regions_driver_release(struct drm_i915_private *i915)
> }
> }
>
> +static ssize_t
> +vram_total_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
> +{
> + struct device *dev = kobj_to_dev(kobj->parent);
> + struct intel_memory_region *mr;
> +
> + mr = intel_memory_region_by_type(kdev_minor_to_i915(dev), INTEL_MEMORY_LOCAL);
> +
> + return sysfs_emit(buf, "%llu\n", mr->total);
> +}
> +
> +static const struct kobj_attribute vram_total_attr =
> +__ATTR(vram_total, 0444, vram_total_show, NULL);
> +
> +static ssize_t
> +vram_avail_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
> +{
> + struct device *dev = kobj_to_dev(kobj->parent);
> + struct intel_memory_region *mr;
> + u64 unallocated_size;
> + u64 dummy;
> +
> + mr = intel_memory_region_by_type(kdev_minor_to_i915(dev), INTEL_MEMORY_LOCAL);
> + intel_memory_region_avail(mr, &unallocated_size, &dummy);
> +
> + return sysfs_emit(buf, "%llu\n", unallocated_size);
> +}
> +
> +static const struct kobj_attribute vram_avail_attr =
> +__ATTR(vram_available, 0444, vram_avail_show, NULL);
> +
> +
> +static ssize_t
> +vram_total_visible_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
> +{
> + struct device *dev = kobj_to_dev(kobj->parent);
> + struct intel_memory_region *mr;
> +
> + mr = intel_memory_region_by_type(kdev_minor_to_i915(dev), INTEL_MEMORY_LOCAL);
> +
> + return sysfs_emit(buf, "%llu\n", resource_size(&mr->io));
> +}
> +
> +static const struct kobj_attribute vram_total_visible_attr =
> +__ATTR(vram_total_cpu_visible, 0444, vram_total_visible_show, NULL);
> +
> +static ssize_t
> +vram_avail_visible_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
> +{
> + struct device *dev = kobj_to_dev(kobj->parent);
> + struct intel_memory_region *mr;
> + u64 unallocated_cpu_visible_size;
> + u64 dummy;
> +
> + mr = intel_memory_region_by_type(kdev_minor_to_i915(dev), INTEL_MEMORY_LOCAL);
> + intel_memory_region_avail(mr, &dummy, &unallocated_cpu_visible_size);
> +
> + return sysfs_emit(buf, "%llu\n", unallocated_cpu_visible_size);
> +}
> +
> +static const struct kobj_attribute vram_avail_visible_attr =
> +__ATTR(vram_available_cpu_visible, 0444, vram_avail_visible_show, NULL);
> +
> +int intel_memory_region_setup_sysfs(struct drm_i915_private *i915)
> +{
> + static const struct attribute *const files[] = {
> + &vram_total_attr.attr,
> + &vram_avail_attr.attr,
> + &vram_total_visible_attr.attr,
> + &vram_avail_visible_attr.attr,
> + NULL
> + };
> + struct device *kdev = i915->drm.primary->kdev;
> + int err;
> +
> + /* Skip this function completely if the system does not support lmem */
> + if(!intel_memory_region_by_type(i915, INTEL_MEMORY_LOCAL))
> + return 0;
> +
> + memory_info_dir = kobject_create_and_add("memory_info", &kdev->kobj);
> + if (!memory_info_dir) {
> + drm_warn(&i915->drm, "Failed to create memory_info sysfs directory\n");
> + return -EAGAIN;
> + }
> +
> + err = sysfs_create_files(memory_info_dir, files);
> + if (err) {
> + drm_warn(&i915->drm, "Failed to create memory info sysfs files: %d\n", err);
> + kobject_put(memory_info_dir);
> + return err;
> + }
> +
> + return 0;
> +}
> +
> +int intel_memory_region_teardown_sysfs(void)
> +{
> + kobject_put(memory_info_dir);
> + return 0;
> +}
> +
> #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
> #include "selftests/intel_memory_region.c"
> #include "selftests/mock_region.c"
> diff --git a/drivers/gpu/drm/i915/intel_memory_region.h b/drivers/gpu/drm/i915/intel_memory_region.h
> index b3b75be9ced5..9838eca9344c 100644
> --- a/drivers/gpu/drm/i915/intel_memory_region.h
> +++ b/drivers/gpu/drm/i915/intel_memory_region.h
> @@ -132,4 +132,7 @@ struct intel_memory_region *
> i915_gem_shmem_setup(struct drm_i915_private *i915,
> u16 type, u16 instance);
>
> +int intel_memory_region_setup_sysfs(struct drm_i915_private *i915);
> +int intel_memory_region_teardown_sysfs(void);
> +
> #endif
--
Jani Nikula, Intel
More information about the Intel-gfx
mailing list