Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/i915/gt: create per-tile sysfs interface

Now that we have tiles we want each of them to have its own
interface. A directory "gt/" is created under "cardN/" that will
contain as many diroctories as the tiles.

In the coming patches tile related interfaces will be added. For
now the sysfs gt structure simply has an id interface related
to the current tile count.

The directory structure will follow this scheme:

/sys/.../card0
└── gt
   ├── gt0
   │   └── id
:
:
└─- gtN
      └── id

This new set of interfaces will be a basic tool for system
managers and administrators when using i915.

Signed-off-by: Andi Shyti <andi.shyti@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Sujaritha Sundaresan <sujaritha.sundaresan@intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Reviewed-by: Sujaritha Sundaresan <sujaritha.sundaresan@intel.com>
Reviewed-by: Andrzej Hajda <andrzej.hajda@intel.com>
Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220318233938.149744-5-andi.shyti@linux.intel.com

authored by

Andi Shyti and committed by
Matthew Auld
b770bcfa bec68cc9

+151 -1
+1
drivers/gpu/drm/i915/Makefile
··· 105 105 gt/intel_gt_pm_debugfs.o \ 106 106 gt/intel_gt_pm_irq.o \ 107 107 gt/intel_gt_requests.o \ 108 + gt/intel_gt_sysfs.o \ 108 109 gt/intel_gtt.o \ 109 110 gt/intel_llc.o \ 110 111 gt/intel_lrc.o \
+2
drivers/gpu/drm/i915/gt/intel_gt.c
··· 26 26 #include "intel_rc6.h" 27 27 #include "intel_renderstate.h" 28 28 #include "intel_rps.h" 29 + #include "intel_gt_sysfs.h" 29 30 #include "intel_uncore.h" 30 31 #include "shmem_utils.h" 31 32 ··· 459 458 intel_rps_driver_register(&gt->rps); 460 459 461 460 intel_gt_debugfs_register(gt); 461 + intel_gt_sysfs_register(gt); 462 462 } 463 463 464 464 static int intel_gt_init_scratch(struct intel_gt *gt, unsigned int size)
+103
drivers/gpu/drm/i915/gt/intel_gt_sysfs.c
··· 1 + // SPDX-License-Identifier: MIT 2 + /* 3 + * Copyright © 2022 Intel Corporation 4 + */ 5 + 6 + #include <drm/drm_device.h> 7 + #include <linux/device.h> 8 + #include <linux/kobject.h> 9 + #include <linux/printk.h> 10 + #include <linux/sysfs.h> 11 + 12 + #include "i915_drv.h" 13 + #include "i915_sysfs.h" 14 + #include "intel_gt.h" 15 + #include "intel_gt_sysfs.h" 16 + #include "intel_gt_types.h" 17 + #include "intel_rc6.h" 18 + 19 + bool is_object_gt(struct kobject *kobj) 20 + { 21 + return !strncmp(kobj->name, "gt", 2); 22 + } 23 + 24 + static struct intel_gt *kobj_to_gt(struct kobject *kobj) 25 + { 26 + return container_of(kobj, struct kobj_gt, base)->gt; 27 + } 28 + 29 + struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev, 30 + const char *name) 31 + { 32 + struct kobject *kobj = &dev->kobj; 33 + 34 + /* 35 + * We are interested at knowing from where the interface 36 + * has been called, whether it's called from gt/ or from 37 + * the parent directory. 38 + * From the interface position it depends also the value of 39 + * the private data. 40 + * If the interface is called from gt/ then private data is 41 + * of the "struct intel_gt *" type, otherwise it's * a 42 + * "struct drm_i915_private *" type. 43 + */ 44 + if (!is_object_gt(kobj)) { 45 + struct drm_i915_private *i915 = kdev_minor_to_i915(dev); 46 + 47 + return to_gt(i915); 48 + } 49 + 50 + return kobj_to_gt(kobj); 51 + } 52 + 53 + static ssize_t id_show(struct device *dev, 54 + struct device_attribute *attr, 55 + char *buf) 56 + { 57 + struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev, attr->attr.name); 58 + 59 + return sysfs_emit(buf, "%u\n", gt->info.id); 60 + } 61 + static DEVICE_ATTR_RO(id); 62 + 63 + static struct attribute *id_attrs[] = { 64 + &dev_attr_id.attr, 65 + NULL, 66 + }; 67 + ATTRIBUTE_GROUPS(id); 68 + 69 + static void kobj_gt_release(struct kobject *kobj) 70 + { 71 + kfree(kobj); 72 + } 73 + 74 + static struct kobj_type kobj_gt_type = { 75 + .release = kobj_gt_release, 76 + .sysfs_ops = &kobj_sysfs_ops, 77 + .default_groups = id_groups, 78 + }; 79 + 80 + void intel_gt_sysfs_register(struct intel_gt *gt) 81 + { 82 + struct kobj_gt *kg; 83 + 84 + kg = kzalloc(sizeof(*kg), GFP_KERNEL); 85 + if (!kg) 86 + goto exit_fail; 87 + 88 + kobject_init(&kg->base, &kobj_gt_type); 89 + kg->gt = gt; 90 + 91 + /* xfer ownership to sysfs tree */ 92 + if (kobject_add(&kg->base, gt->i915->sysfs_gt, "gt%d", gt->info.id)) 93 + goto exit_kobj_put; 94 + 95 + return; 96 + 97 + exit_kobj_put: 98 + kobject_put(&kg->base); 99 + 100 + exit_fail: 101 + drm_warn(&gt->i915->drm, 102 + "failed to initialize gt%d sysfs root\n", gt->info.id); 103 + }
+34
drivers/gpu/drm/i915/gt/intel_gt_sysfs.h
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 + * Copyright © 2022 Intel Corporation 4 + */ 5 + 6 + #ifndef __SYSFS_GT_H__ 7 + #define __SYSFS_GT_H__ 8 + 9 + #include <linux/ctype.h> 10 + #include <linux/kobject.h> 11 + 12 + #include "i915_gem.h" /* GEM_BUG_ON() */ 13 + 14 + struct intel_gt; 15 + 16 + struct kobj_gt { 17 + struct kobject base; 18 + struct intel_gt *gt; 19 + }; 20 + 21 + bool is_object_gt(struct kobject *kobj); 22 + 23 + struct drm_i915_private *kobj_to_i915(struct kobject *kobj); 24 + 25 + struct kobject * 26 + intel_gt_create_kobj(struct intel_gt *gt, 27 + struct kobject *dir, 28 + const char *name); 29 + 30 + void intel_gt_sysfs_register(struct intel_gt *gt); 31 + struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev, 32 + const char *name); 33 + 34 + #endif /* SYSFS_GT_H */
+2
drivers/gpu/drm/i915/i915_drv.h
··· 814 814 #define I915_MAX_GT 4 815 815 struct intel_gt *gt[I915_MAX_GT]; 816 816 817 + struct kobject *sysfs_gt; 818 + 817 819 struct { 818 820 struct i915_gem_contexts { 819 821 spinlock_t lock; /* locks list */
+6 -1
drivers/gpu/drm/i915/i915_sysfs.c
··· 39 39 #include "i915_sysfs.h" 40 40 #include "intel_pm.h" 41 41 42 - static inline struct drm_i915_private *kdev_minor_to_i915(struct device *kdev) 42 + struct drm_i915_private *kdev_minor_to_i915(struct device *kdev) 43 43 { 44 44 struct drm_minor *minor = dev_get_drvdata(kdev); 45 45 return to_i915(minor->dev); ··· 537 537 ret = sysfs_create_files(&kdev->kobj, gen6_attrs); 538 538 if (ret) 539 539 drm_err(&dev_priv->drm, "RPS sysfs setup failed\n"); 540 + 541 + dev_priv->sysfs_gt = kobject_create_and_add("gt", &kdev->kobj); 542 + if (!dev_priv->sysfs_gt) 543 + drm_warn(&dev_priv->drm, 544 + "failed to register GT sysfs directory\n"); 540 545 541 546 i915_setup_error_capture(kdev); 542 547
+3
drivers/gpu/drm/i915/i915_sysfs.h
··· 6 6 #ifndef __I915_SYSFS_H__ 7 7 #define __I915_SYSFS_H__ 8 8 9 + struct device; 9 10 struct drm_i915_private; 11 + 12 + struct drm_i915_private *kdev_minor_to_i915(struct device *kdev); 10 13 11 14 void i915_setup_sysfs(struct drm_i915_private *i915); 12 15 void i915_teardown_sysfs(struct drm_i915_private *i915);