#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)
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;
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);
#include <drm/drm_managed.h>
#include "xe_assert.h"
+#include "xe_pci_sriov.h"
#include "xe_pm.h"
#include "xe_sriov.h"
#include "xe_sriov_pf.h"
* │ └── 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
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;
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
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");
+}