xref: /linux/drivers/gpu/drm/xe/xe_sriov_pf.c (revision face6a3615a649456eb4549f6d474221d877d604)
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_configfs.h"
12 #include "xe_device.h"
13 #include "xe_gt_sriov_pf.h"
14 #include "xe_module.h"
15 #include "xe_sriov.h"
16 #include "xe_sriov_pf.h"
17 #include "xe_sriov_pf_helpers.h"
18 #include "xe_sriov_pf_service.h"
19 #include "xe_sriov_printk.h"
20 
21 static unsigned int wanted_max_vfs(struct xe_device *xe)
22 {
23 	if (IS_ENABLED(CONFIG_CONFIGFS_FS))
24 		return xe_configfs_get_max_vfs(to_pci_dev(xe->drm.dev));
25 	return xe_modparam.max_vfs;
26 }
27 
28 static int pf_reduce_totalvfs(struct xe_device *xe, int limit)
29 {
30 	struct device *dev = xe->drm.dev;
31 	struct pci_dev *pdev = to_pci_dev(dev);
32 	int err;
33 
34 	err = pci_sriov_set_totalvfs(pdev, limit);
35 	if (err)
36 		xe_sriov_notice(xe, "Failed to set number of VFs to %d (%pe)\n",
37 				limit, ERR_PTR(err));
38 	return err;
39 }
40 
41 static bool pf_continue_as_native(struct xe_device *xe, const char *why)
42 {
43 	xe_sriov_dbg(xe, "%s, continuing as native\n", why);
44 	pf_reduce_totalvfs(xe, 0);
45 	return false;
46 }
47 
48 /**
49  * xe_sriov_pf_readiness - Check if PF functionality can be enabled.
50  * @xe: the &xe_device to check
51  *
52  * This function is called as part of the SR-IOV probe to validate if all
53  * PF prerequisites are satisfied and we can continue with enabling PF mode.
54  *
55  * Return: true if the PF mode can be turned on.
56  */
57 bool xe_sriov_pf_readiness(struct xe_device *xe)
58 {
59 	struct device *dev = xe->drm.dev;
60 	struct pci_dev *pdev = to_pci_dev(dev);
61 	int totalvfs = pci_sriov_get_totalvfs(pdev);
62 	int newlimit = min_t(u16, wanted_max_vfs(xe), totalvfs);
63 
64 	xe_assert(xe, totalvfs <= U16_MAX);
65 
66 	if (!dev_is_pf(dev))
67 		return false;
68 
69 	if (!xe_device_uc_enabled(xe))
70 		return pf_continue_as_native(xe, "Guc submission disabled");
71 
72 	if (!newlimit)
73 		return pf_continue_as_native(xe, "all VFs disabled");
74 
75 	pf_reduce_totalvfs(xe, newlimit);
76 
77 	xe->sriov.pf.device_total_vfs = totalvfs;
78 	xe->sriov.pf.driver_max_vfs = newlimit;
79 
80 	return true;
81 }
82 
83 /**
84  * xe_sriov_pf_init_early - Initialize SR-IOV PF specific data.
85  * @xe: the &xe_device to initialize
86  *
87  * Return: 0 on success or a negative error code on failure.
88  */
89 int xe_sriov_pf_init_early(struct xe_device *xe)
90 {
91 	int err;
92 
93 	xe_assert(xe, IS_SRIOV_PF(xe));
94 
95 	xe->sriov.pf.vfs = drmm_kcalloc(&xe->drm, 1 + xe_sriov_pf_get_totalvfs(xe),
96 					sizeof(*xe->sriov.pf.vfs), GFP_KERNEL);
97 	if (!xe->sriov.pf.vfs)
98 		return -ENOMEM;
99 
100 	err = drmm_mutex_init(&xe->drm, &xe->sriov.pf.master_lock);
101 	if (err)
102 		return err;
103 
104 	xe_sriov_pf_service_init(xe);
105 
106 	return 0;
107 }
108 
109 /**
110  * xe_sriov_pf_init_late() - Late initialization of the SR-IOV PF.
111  * @xe: the &xe_device to initialize
112  *
113  * This function can only be called on PF.
114  *
115  * Return: 0 on success or a negative error code on failure.
116  */
117 int xe_sriov_pf_init_late(struct xe_device *xe)
118 {
119 	struct xe_gt *gt;
120 	unsigned int id;
121 	int err;
122 
123 	xe_assert(xe, IS_SRIOV_PF(xe));
124 
125 	for_each_gt(gt, xe, id) {
126 		err = xe_gt_sriov_pf_init(gt);
127 		if (err)
128 			return err;
129 	}
130 
131 	return 0;
132 }
133 
134 /**
135  * xe_sriov_pf_wait_ready() - Wait until PF is ready to operate.
136  * @xe: the &xe_device to test
137  *
138  * This function can only be called on PF.
139  *
140  * Return: 0 on success or a negative error code on failure.
141  */
142 int xe_sriov_pf_wait_ready(struct xe_device *xe)
143 {
144 	struct xe_gt *gt;
145 	unsigned int id;
146 	int err;
147 
148 	if (xe_device_wedged(xe))
149 		return -ECANCELED;
150 
151 	for_each_gt(gt, xe, id) {
152 		err = xe_gt_sriov_pf_wait_ready(gt);
153 		if (err)
154 			return err;
155 	}
156 
157 	return 0;
158 }
159 
160 /**
161  * xe_sriov_pf_print_vfs_summary - Print SR-IOV PF information.
162  * @xe: the &xe_device to print info from
163  * @p: the &drm_printer
164  *
165  * Print SR-IOV PF related information into provided DRM printer.
166  */
167 void xe_sriov_pf_print_vfs_summary(struct xe_device *xe, struct drm_printer *p)
168 {
169 	struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
170 
171 	xe_assert(xe, IS_SRIOV_PF(xe));
172 
173 	drm_printf(p, "total: %u\n", xe->sriov.pf.device_total_vfs);
174 	drm_printf(p, "supported: %u\n", xe->sriov.pf.driver_max_vfs);
175 	drm_printf(p, "enabled: %u\n", pci_num_vf(pdev));
176 }
177