[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