From: Michal Wajdeczko Date: Thu, 30 Oct 2025 22:23:46 +0000 (+0100) Subject: drm/xe/pf: Add sysfs device symlinks to enabled VFs X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=17899358f66df9d3910ebb479b666a05c4c4040e;p=thirdparty%2Fkernel%2Flinux.git drm/xe/pf: Add sysfs device symlinks to enabled VFs For convenience, for every enabled VF add 'device' symlink from our SR-IOV admin VF folder to enabled sysfs PCI VF device entry. Remove all those links when disabling PCI VFs. For completeness, add static 'device' symlink for the PF itself. /sys/bus/pci/drivers/xe/BDF/sriov_admin/ ├── pf │   └── device -> ../../../BDF # PF BDF ├── vf1 │   └── device -> ../../../BDF' # VF1 BDF ├── vf2 │   └── device -> ../../../BDF" # VF2 BDF Signed-off-by: Michal Wajdeczko Cc: Lucas De Marchi Cc: Rodrigo Vivi Acked-by: Rodrigo Vivi Reviewed-by: Lucas De Marchi Link: https://patch.msgid.link/20251030222348.186658-16-michal.wajdeczko@intel.com --- diff --git a/drivers/gpu/drm/xe/xe_pci_sriov.c b/drivers/gpu/drm/xe/xe_pci_sriov.c index 4d5da6686e923..d0fcde66a7749 100644 --- a/drivers/gpu/drm/xe/xe_pci_sriov.c +++ b/drivers/gpu/drm/xe/xe_pci_sriov.c @@ -20,6 +20,7 @@ #include "xe_sriov_pf_control.h" #include "xe_sriov_pf_helpers.h" #include "xe_sriov_pf_provision.h" +#include "xe_sriov_pf_sysfs.h" #include "xe_sriov_printk.h" static void pf_reset_vfs(struct xe_device *xe, unsigned int num_vfs) @@ -138,6 +139,8 @@ static int pf_enable_vfs(struct xe_device *xe, int num_vfs) xe_sriov_info(xe, "Enabled %u of %u VF%s\n", num_vfs, total_vfs, str_plural(total_vfs)); + xe_sriov_pf_sysfs_link_vfs(xe, num_vfs); + pf_engine_activity_stats(xe, num_vfs, true); return num_vfs; @@ -165,6 +168,8 @@ static int pf_disable_vfs(struct xe_device *xe) pf_engine_activity_stats(xe, num_vfs, false); + xe_sriov_pf_sysfs_unlink_vfs(xe, num_vfs); + pci_disable_sriov(pdev); pf_reset_vfs(xe, num_vfs); diff --git a/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c b/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c index 0b1b4606ac76e..a3205bd1c21f0 100644 --- a/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c +++ b/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c @@ -9,6 +9,7 @@ #include #include "xe_assert.h" +#include "xe_pci_sriov.h" #include "xe_pm.h" #include "xe_sriov.h" #include "xe_sriov_pf.h" @@ -45,12 +46,14 @@ static int emit_choice(char *buf, int choice, const char * const *array, size_t * │ └── sched_priority * ├── pf/ * │ ├── ... + * │ ├── device -> ../../../BDF * │ └── profile * │ ├── exec_quantum_ms * │ ├── preempt_timeout_us * │ └── sched_priority * ├── vf1/ * │ ├── ... + * │ ├── device -> ../../../BDF.1 * │ └── profile * │ ├── exec_quantum_ms * │ ├── preempt_timeout_us @@ -414,6 +417,11 @@ static int pf_sysfs_error(struct xe_device *xe, int err, const char *what) return err; } +static void pf_sysfs_note(struct xe_device *xe, int err, const char *what) +{ + xe_sriov_dbg(xe, "Failed to setup sysfs %s (%pe)\n", what, ERR_PTR(err)); +} + static void action_put_kobject(void *arg) { struct kobject *kobj = arg; @@ -480,6 +488,29 @@ static int pf_setup_tree(struct xe_device *xe) return 0; } +static void action_rm_device_link(void *arg) +{ + struct kobject *kobj = arg; + + sysfs_remove_link(kobj, "device"); +} + +static int pf_link_pf_device(struct xe_device *xe) +{ + struct kobject *kobj = xe->sriov.pf.vfs[PFID].kobj; + int err; + + err = sysfs_create_link(kobj, &xe->drm.dev->kobj, "device"); + if (err) + return pf_sysfs_error(xe, err, "PF device link"); + + err = devm_add_action_or_reset(xe->drm.dev, action_rm_device_link, kobj); + if (err) + return pf_sysfs_error(xe, err, "PF unlink action"); + + return 0; +} + /** * xe_sriov_pf_sysfs_init() - Setup PF's SR-IOV sysfs tree. * @xe: the PF &xe_device to setup sysfs @@ -501,5 +532,67 @@ int xe_sriov_pf_sysfs_init(struct xe_device *xe) if (err) return err; + err = pf_link_pf_device(xe); + if (err) + return err; + return 0; } + +/** + * xe_sriov_pf_sysfs_link_vfs() - Add VF's links in SR-IOV sysfs tree. + * @xe: the &xe_device where to update sysfs + * @num_vfs: number of enabled VFs to link + * + * This function is specific for the PF driver. + * + * This function will add symbolic links between VFs represented in the SR-IOV + * sysfs tree maintained by the PF and enabled VF PCI devices. + * + * The @xe_sriov_pf_sysfs_unlink_vfs() shall be used to remove those links. + */ +void xe_sriov_pf_sysfs_link_vfs(struct xe_device *xe, unsigned int num_vfs) +{ + unsigned int totalvfs = xe_sriov_pf_get_totalvfs(xe); + struct pci_dev *pf_pdev = to_pci_dev(xe->drm.dev); + struct pci_dev *vf_pdev = NULL; + unsigned int n; + int err; + + xe_assert(xe, IS_SRIOV_PF(xe)); + xe_assert(xe, num_vfs <= totalvfs); + + for (n = 1; n <= num_vfs; n++) { + vf_pdev = xe_pci_sriov_get_vf_pdev(pf_pdev, VFID(n)); + if (!vf_pdev) + return pf_sysfs_note(xe, -ENOENT, "VF link"); + + err = sysfs_create_link(xe->sriov.pf.vfs[VFID(n)].kobj, + &vf_pdev->dev.kobj, "device"); + + /* must balance xe_pci_sriov_get_vf_pdev() */ + pci_dev_put(vf_pdev); + + if (err) + return pf_sysfs_note(xe, err, "VF link"); + } +} + +/** + * xe_sriov_pf_sysfs_unlink_vfs() - Remove VF's links from SR-IOV sysfs tree. + * @xe: the &xe_device where to update sysfs + * @num_vfs: number of VFs to unlink + * + * This function shall be called only on the PF. + * This function will remove "device" links added by @xe_sriov_sysfs_link_vfs(). + */ +void xe_sriov_pf_sysfs_unlink_vfs(struct xe_device *xe, unsigned int num_vfs) +{ + unsigned int n; + + xe_assert(xe, IS_SRIOV_PF(xe)); + xe_assert(xe, num_vfs <= xe_sriov_pf_get_totalvfs(xe)); + + for (n = 1; n <= num_vfs; n++) + sysfs_remove_link(xe->sriov.pf.vfs[VFID(n)].kobj, "device"); +} diff --git a/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.h b/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.h index 1e6698cc29d38..ae92ed1766e70 100644 --- a/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.h +++ b/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.h @@ -10,4 +10,7 @@ struct xe_device; int xe_sriov_pf_sysfs_init(struct xe_device *xe); +void xe_sriov_pf_sysfs_link_vfs(struct xe_device *xe, unsigned int num_vfs); +void xe_sriov_pf_sysfs_unlink_vfs(struct xe_device *xe, unsigned int num_vfs); + #endif