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 20 static unsigned int wanted_max_vfs(struct xe_device *xe) 21 { 22 return xe_modparam.max_vfs; 23 } 24 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 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 */ 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 */ 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 */ 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 */ 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 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 */ 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