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