File Index
Files and directories
Sign in
FILE

xe_tile_sriov_pf_debugfs.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/xe/xe_tile_sriov_pf_debugfs.c C
  1// SPDX-License-Identifier: MIT
  2/*
  3 * Copyright © 2025 Intel Corporation
  4 */
  5
  6#include <linux/debugfs.h>
  7#include <drm/drm_debugfs.h>
  8
  9#include "xe_device.h"
 10#include "xe_device_types.h"
 11#include "xe_gt_sriov_pf_config.h"
 12#include "xe_gt_sriov_pf_debugfs.h"
 13#include "xe_pm.h"
 14#include "xe_tile_debugfs.h"
 15#include "xe_tile_sriov_pf_debugfs.h"
 16#include "xe_sriov.h"
 17#include "xe_sriov_pf.h"
 18#include "xe_sriov_pf_provision.h"
 19
 20/*
 21 *      /sys/kernel/debug/dri/BDF/
 22 *      ├── sriov		# d_inode->i_private = (xe_device*)
 23 *      │   ├── pf		# d_inode->i_private = (xe_device*)
 24 *      │   │   ├── tile0	# d_inode->i_private = (xe_tile*)
 25 *      │   │   ├── tile1
 26 *      │   │   :   :
 27 *      │   ├── vf1		# d_inode->i_private = VFID(1)
 28 *      │   │   ├── tile0	# d_inode->i_private = (xe_tile*)
 29 *      │   │   ├── tile1
 30 *      │   │   :   :
 31 *      │   ├── vfN		# d_inode->i_private = VFID(N)
 32 *      │   │   ├── tile0	# d_inode->i_private = (xe_tile*)
 33 *      │   │   ├── tile1
 34 *      :   :   :   :
 35 */
 36
 37static void *extract_priv(struct dentry *d)
 38{
 39	return d->d_inode->i_private;
 40}
 41
 42__maybe_unused
 43static struct xe_tile *extract_tile(struct dentry *d)
 44{
 45	return extract_priv(d);
 46}
 47
 48static struct xe_device *extract_xe(struct dentry *d)
 49{
 50	return extract_priv(d->d_parent->d_parent);
 51}
 52
 53__maybe_unused
 54static unsigned int extract_vfid(struct dentry *d)
 55{
 56	void *pp = extract_priv(d->d_parent);
 57
 58	return pp == extract_xe(d) ? PFID : (uintptr_t)pp;
 59}
 60
 61/*
 62 *      /sys/kernel/debug/dri/BDF/
 63 *      ├── sriov
 64 *      :   ├── pf
 65 *          :   ├── tile0
 66 *              :   ├── ggtt_available
 67 *                  ├── ggtt_provisioned
 68 */
 69
 70static int pf_config_print_available_ggtt(struct xe_tile *tile, struct drm_printer *p)
 71{
 72	return xe_gt_sriov_pf_config_print_available_ggtt(tile->primary_gt, p);
 73}
 74
 75static int pf_config_print_ggtt(struct xe_tile *tile, struct drm_printer *p)
 76{
 77	return xe_gt_sriov_pf_config_print_ggtt(tile->primary_gt, p);
 78}
 79
 80static const struct drm_info_list pf_ggtt_info[] = {
 81	{
 82		"ggtt_available",
 83		.show = xe_tile_debugfs_simple_show,
 84		.data = pf_config_print_available_ggtt,
 85	},
 86	{
 87		"ggtt_provisioned",
 88		.show = xe_tile_debugfs_simple_show,
 89		.data = pf_config_print_ggtt,
 90	},
 91};
 92
 93/*
 94 *      /sys/kernel/debug/dri/BDF/
 95 *      ├── sriov
 96 *      :   ├── pf
 97 *          :   ├── tile0
 98 *              :   ├── vram_provisioned
 99 */
100
101static int pf_config_print_vram(struct xe_tile *tile, struct drm_printer *p)
102{
103	return xe_gt_sriov_pf_config_print_lmem(tile->primary_gt, p);
104}
105
106static const struct drm_info_list pf_vram_info[] = {
107	{
108		"vram_provisioned",
109		.show = xe_tile_debugfs_simple_show,
110		.data = pf_config_print_vram,
111	},
112};
113
114/*
115 *      /sys/kernel/debug/dri/BDF/
116 *      ├── sriov
117 *      │   ├── pf
118 *      │   │   ├── tile0
119 *      │   │   │   ├── ggtt_spare
120 *      │   │   │   ├── vram_spare
121 *      │   │   ├── tile1
122 *      │   │   :   :
123 *      │   ├── vf1
124 *      │   :   ├── tile0
125 *      │       │   ├── ggtt_quota
126 *      │       │   ├── vram_quota
127 *      │       ├── tile1
128 *      │       :   :
129 */
130
131#define DEFINE_SRIOV_TILE_CONFIG_DEBUGFS_ATTRIBUTE(NAME, CONFIG, TYPE, FORMAT)	\
132										\
133static int NAME##_set(void *data, u64 val)					\
134{										\
135	struct xe_tile *tile = extract_tile(data);				\
136	unsigned int vfid = extract_vfid(data);					\
137	struct xe_gt *gt = tile->primary_gt;					\
138	struct xe_device *xe = tile->xe;					\
139	int err;								\
140										\
141	if (val > (TYPE)~0ull)							\
142		return -EOVERFLOW;						\
143										\
144	xe_pm_runtime_get(xe);							\
145	err = xe_sriov_pf_wait_ready(xe) ?:					\
146	      xe_gt_sriov_pf_config_set_##CONFIG(gt, vfid, val);		\
147	if (!err)								\
148		xe_sriov_pf_provision_set_custom_mode(xe);			\
149	xe_pm_runtime_put(xe);							\
150										\
151	return err;								\
152}										\
153										\
154static int NAME##_get(void *data, u64 *val)					\
155{										\
156	struct xe_tile *tile = extract_tile(data);				\
157	unsigned int vfid = extract_vfid(data);					\
158	struct xe_gt *gt = tile->primary_gt;					\
159										\
160	*val = xe_gt_sriov_pf_config_get_##CONFIG(gt, vfid);			\
161	return 0;								\
162}										\
163										\
164DEFINE_DEBUGFS_ATTRIBUTE(NAME##_fops, NAME##_get, NAME##_set, FORMAT)
165
166DEFINE_SRIOV_TILE_CONFIG_DEBUGFS_ATTRIBUTE(ggtt, ggtt, u64, "%llu\n");
167DEFINE_SRIOV_TILE_CONFIG_DEBUGFS_ATTRIBUTE(vram, lmem, u64, "%llu\n");
168
169static void pf_add_config_attrs(struct xe_tile *tile, struct dentry *dent, unsigned int vfid)
170{
171	struct xe_device *xe = tile->xe;
172
173	xe_tile_assert(tile, tile == extract_tile(dent));
174	xe_tile_assert(tile, vfid == extract_vfid(dent));
175
176	debugfs_create_file_unsafe(vfid ? "ggtt_quota" : "ggtt_spare",
177				   0644, dent, dent, &ggtt_fops);
178	if (IS_DGFX(xe))
179		debugfs_create_file_unsafe(vfid ? "vram_quota" : "vram_spare",
180					   xe_device_has_lmtt(xe) ? 0644 : 0444,
181					   dent, dent, &vram_fops);
182}
183
184static void pf_populate_tile(struct xe_tile *tile, struct dentry *dent, unsigned int vfid)
185{
186	struct xe_device *xe = tile->xe;
187	struct drm_minor *minor = xe->drm.primary;
188	struct xe_gt *gt;
189	unsigned int id;
190
191	pf_add_config_attrs(tile, dent, vfid);
192
193	if (!vfid) {
194		drm_debugfs_create_files(pf_ggtt_info,
195					 ARRAY_SIZE(pf_ggtt_info),
196					 dent, minor);
197		if (IS_DGFX(xe))
198			drm_debugfs_create_files(pf_vram_info,
199						 ARRAY_SIZE(pf_vram_info),
200						 dent, minor);
201	}
202
203	for_each_gt_on_tile(gt, tile, id)
204		xe_gt_sriov_pf_debugfs_populate(gt, dent, vfid);
205}
206
207/**
208 * xe_tile_sriov_pf_debugfs_populate() - Populate SR-IOV debugfs tree with tile files.
209 * @tile: the &xe_tile to register
210 * @parent: the parent &dentry that represents the SR-IOV @vfid function
211 * @vfid: the VF identifier
212 *
213 * Add to the @parent directory new debugfs directory that will represent a @tile and
214 * populate it with files that are related to the SR-IOV @vfid function.
215 *
216 * This function can only be called on PF.
217 */
218void xe_tile_sriov_pf_debugfs_populate(struct xe_tile *tile, struct dentry *parent,
219				       unsigned int vfid)
220{
221	struct xe_device *xe = tile->xe;
222	struct dentry *dent;
223	char name[10]; /* should be enough up to "tile%u\0" for 2^16 - 1 */
224
225	xe_tile_assert(tile, IS_SRIOV_PF(xe));
226	xe_tile_assert(tile, extract_priv(parent->d_parent) == xe);
227	xe_tile_assert(tile, extract_priv(parent) == tile->xe ||
228		       (uintptr_t)extract_priv(parent) == vfid);
229
230	/*
231	 *      /sys/kernel/debug/dri/BDF/
232	 *      ├── sriov
233	 *      │   ├── pf		# parent, d_inode->i_private = (xe_device*)
234	 *      │   │   ├── tile0	# d_inode->i_private = (xe_tile*)
235	 *      │   │   ├── tile1
236	 *      │   │   :   :
237	 *      │   ├── vf1		# parent, d_inode->i_private = VFID(1)
238	 *      │   │   ├── tile0	# d_inode->i_private = (xe_tile*)
239	 *      │   │   ├── tile1
240	 *      :   :   :   :
241	 */
242	snprintf(name, sizeof(name), "tile%u", tile->id);
243	dent = debugfs_create_dir(name, parent);
244	if (IS_ERR(dent))
245		return;
246	dent->d_inode->i_private = tile;
247
248	xe_tile_assert(tile, extract_tile(dent) == tile);
249	xe_tile_assert(tile, extract_vfid(dent) == vfid);
250	xe_tile_assert(tile, extract_xe(dent) == xe);
251
252	pf_populate_tile(tile, dent, vfid);
253}
~/ Read-only file preview.