xref: /linux/drivers/gpu/drm/xe/xe_sriov_pf.c (revision ffe8ac927d935d7d4a0bd9ac94afd705df79982b)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2023-2024 Intel Corporation
4  */
5 
6 #include <linux/debugfs.h>
7 #include <drm/drm_debugfs.h>
8 #include <drm/drm_managed.h>
9 
10 #include "xe_assert.h"
11 #include "xe_device.h"
12 #include "xe_gt_sriov_pf.h"
13 #include "xe_module.h"
14 #include "xe_sriov.h"
15 #include "xe_sriov_pf.h"
16 #include "xe_sriov_pf_helpers.h"
17 #include "xe_sriov_pf_service.h"
18 #include "xe_sriov_printk.h"
19 
wanted_max_vfs(struct xe_device * xe)20 static unsigned int wanted_max_vfs(struct xe_device *xe)
21 {
22 	return xe_modparam.max_vfs;
23 }
24 
pf_reduce_totalvfs(struct xe_device * xe,int limit)25 static int pf_reduce_totalvfs(struct xe_device *xe, int limit)
26 {
27 	struct device *dev = xe->drm.dev;
28 	struct pci_dev *pdev = to_pci_dev(dev);
29 	int err;
30 
31 	err = pci_sriov_set_totalvfs(pdev, limit);
32 	if (err)
33 		xe_sriov_notice(xe, "Failed to set number of VFs to %d (%pe)\n",
34 				limit, ERR_PTR(err));
35 	return err;
36 }
37 
pf_continue_as_native(struct xe_device * xe,const char * why)38 static bool pf_continue_as_native(struct xe_device *xe, const char *why)
39 {
40 	xe_sriov_dbg(xe, "%s, continuing as native\n", why);
41 	pf_reduce_totalvfs(xe, 0);
42 	return false;
43 }
44 
45 /**
46  * xe_sriov_pf_readiness - Check if PF functionality can be enabled.
47  * @xe: the &xe_device to check
48  *
49  * This function is called as part of the SR-IOV probe to validate if all
50  * PF prerequisites are satisfied and we can continue with enabling PF mode.
51  *
52  * Return: true if the PF mode can be turned on.
53  */
xe_sriov_pf_readiness(struct xe_device * xe)54 bool xe_sriov_pf_readiness(struct xe_device *xe)
55 {
56 	struct device *dev = xe->drm.dev;
57 	struct pci_dev *pdev = to_pci_dev(dev);
58 	int totalvfs = pci_sriov_get_totalvfs(pdev);
59 	int newlimit = min_t(u16, wanted_max_vfs(xe), totalvfs);
60 
61 	xe_assert(xe, totalvfs <= U16_MAX);
62 
63 	if (!dev_is_pf(dev))
64 		return false;
65 
66 	if (!xe_device_uc_enabled(xe))
67 		return pf_continue_as_native(xe, "Guc submission disabled");
68 
69 	if (!newlimit)
70 		return pf_continue_as_native(xe, "all VFs disabled");
71 
72 	pf_reduce_totalvfs(xe, newlimit);
73 
74 	xe->sriov.pf.device_total_vfs = totalvfs;
75 	xe->sriov.pf.driver_max_vfs = newlimit;
76 
77 	return true;
78 }
79 
80 /**
81  * xe_sriov_pf_init_early - Initialize SR-IOV PF specific data.
82  * @xe: the &xe_device to initialize
83  *
84  * Return: 0 on success or a negative error code on failure.
85  */
xe_sriov_pf_init_early(struct xe_device * xe)86 int xe_sriov_pf_init_early(struct xe_device *xe)
87 {
88 	int err;
89 
90 	xe_assert(xe, IS_SRIOV_PF(xe));
91 
92 	xe->sriov.pf.vfs = drmm_kcalloc(&xe->drm, 1 + xe_sriov_pf_get_totalvfs(xe),
93 					sizeof(*xe->sriov.pf.vfs), GFP_KERNEL);
94 	if (!xe->sriov.pf.vfs)
95 		return -ENOMEM;
96 
97 	err = drmm_mutex_init(&xe->drm, &xe->sriov.pf.master_lock);
98 	if (err)
99 		return err;
100 
101 	xe_sriov_pf_service_init(xe);
102 
103 	return 0;
104 }
105 
106 /**
107  * xe_sriov_pf_wait_ready() - Wait until PF is ready to operate.
108  * @xe: the &xe_device to test
109  *
110  * This function can only be called on PF.
111  *
112  * Return: 0 on success or a negative error code on failure.
113  */
xe_sriov_pf_wait_ready(struct xe_device * xe)114 int xe_sriov_pf_wait_ready(struct xe_device *xe)
115 {
116 	struct xe_gt *gt;
117 	unsigned int id;
118 	int err;
119 
120 	if (xe_device_wedged(xe))
121 		return -ECANCELED;
122 
123 	for_each_gt(gt, xe, id) {
124 		err = xe_gt_sriov_pf_wait_ready(gt);
125 		if (err)
126 			return err;
127 	}
128 
129 	return 0;
130 }
131 
132 /**
133  * xe_sriov_pf_print_vfs_summary - Print SR-IOV PF information.
134  * @xe: the &xe_device to print info from
135  * @p: the &drm_printer
136  *
137  * Print SR-IOV PF related information into provided DRM printer.
138  */
xe_sriov_pf_print_vfs_summary(struct xe_device * xe,struct drm_printer * p)139 void xe_sriov_pf_print_vfs_summary(struct xe_device *xe, struct drm_printer *p)
140 {
141 	struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
142 
143 	xe_assert(xe, IS_SRIOV_PF(xe));
144 
145 	drm_printf(p, "total: %u\n", xe->sriov.pf.device_total_vfs);
146 	drm_printf(p, "supported: %u\n", xe->sriov.pf.driver_max_vfs);
147 	drm_printf(p, "enabled: %u\n", pci_num_vf(pdev));
148 }
149 
simple_show(struct seq_file * m,void * data)150 static int simple_show(struct seq_file *m, void *data)
151 {
152 	struct drm_printer p = drm_seq_file_printer(m);
153 	struct drm_info_node *node = m->private;
154 	struct dentry *parent = node->dent->d_parent;
155 	struct xe_device *xe = parent->d_inode->i_private;
156 	void (*print)(struct xe_device *, struct drm_printer *) = node->info_ent->data;
157 
158 	print(xe, &p);
159 	return 0;
160 }
161 
162 static const struct drm_info_list debugfs_list[] = {
163 	{ .name = "vfs", .show = simple_show, .data = xe_sriov_pf_print_vfs_summary },
164 	{ .name = "versions", .show = simple_show, .data = xe_sriov_pf_service_print_versions },
165 };
166 
167 /**
168  * xe_sriov_pf_debugfs_register - Register PF debugfs attributes.
169  * @xe: the &xe_device
170  * @root: the root &dentry
171  *
172  * Prepare debugfs attributes exposed by the PF.
173  */
xe_sriov_pf_debugfs_register(struct xe_device * xe,struct dentry * root)174 void xe_sriov_pf_debugfs_register(struct xe_device *xe, struct dentry *root)
175 {
176 	struct drm_minor *minor = xe->drm.primary;
177 	struct dentry *parent;
178 
179 	/*
180 	 *      /sys/kernel/debug/dri/0/
181 	 *      ├── pf
182 	 *      │   ├── ...
183 	 */
184 	parent = debugfs_create_dir("pf", root);
185 	if (IS_ERR(parent))
186 		return;
187 	parent->d_inode->i_private = xe;
188 
189 	drm_debugfs_create_files(debugfs_list, ARRAY_SIZE(debugfs_list), parent, minor);
190 }
191