Skip to content

Commit 146e438

Browse files
committed
drm/xe: Add proper detection of the SR-IOV PF mode
SR-IOV PF mode detection is based on PCI capability as reported by the PCI dev_is_pf() function and additionally on 'max_vfs' module parameter which could be also used to disable PF capability even if SR-IOV PF capability is reported by the hardware. Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240404154431.583-3-michal.wajdeczko@intel.com
1 parent e806fac commit 146e438

File tree

6 files changed

+137
-1
lines changed

6 files changed

+137
-1
lines changed

drivers/gpu/drm/xe/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,8 @@ xe-$(CONFIG_PCI_IOV) += \
159159
xe_gt_sriov_pf_control.o \
160160
xe_lmtt.o \
161161
xe_lmtt_2l.o \
162-
xe_lmtt_ml.o
162+
xe_lmtt_ml.o \
163+
xe_sriov_pf.o
163164

164165
# include helpers for tests even when XE is built-in
165166
ifdef CONFIG_DRM_XE_KUNIT_TEST

drivers/gpu/drm/xe/xe_device_types.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,10 @@ struct xe_device {
321321
struct {
322322
/** @sriov.__mode: SR-IOV mode (Don't access directly!) */
323323
enum xe_sriov_mode __mode;
324+
325+
/** @sriov.pf: PF specific data */
326+
struct xe_device_pf pf;
327+
324328
/** @sriov.wq: workqueue used by the virtualization workers */
325329
struct workqueue_struct *wq;
326330
} sriov;

drivers/gpu/drm/xe/xe_sriov.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "xe_device.h"
1212
#include "xe_mmio.h"
1313
#include "xe_sriov.h"
14+
#include "xe_sriov_pf.h"
1415

1516
/**
1617
* xe_sriov_mode_to_string - Convert enum value to string.
@@ -58,6 +59,8 @@ void xe_sriov_probe_early(struct xe_device *xe)
5859
if (has_sriov) {
5960
if (test_is_vf(xe))
6061
mode = XE_SRIOV_MODE_VF;
62+
else if (xe_sriov_pf_readiness(xe))
63+
mode = XE_SRIOV_MODE_PF;
6164
}
6265

6366
xe_assert(xe, !xe->sriov.__mode);

drivers/gpu/drm/xe/xe_sriov_pf.c

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// SPDX-License-Identifier: MIT
2+
/*
3+
* Copyright © 2023-2024 Intel Corporation
4+
*/
5+
6+
#include "xe_assert.h"
7+
#include "xe_device.h"
8+
#include "xe_module.h"
9+
#include "xe_sriov.h"
10+
#include "xe_sriov_pf.h"
11+
#include "xe_sriov_printk.h"
12+
13+
static unsigned int wanted_max_vfs(struct xe_device *xe)
14+
{
15+
return xe_modparam.max_vfs;
16+
}
17+
18+
static int pf_reduce_totalvfs(struct xe_device *xe, int limit)
19+
{
20+
struct device *dev = xe->drm.dev;
21+
struct pci_dev *pdev = to_pci_dev(dev);
22+
int err;
23+
24+
err = pci_sriov_set_totalvfs(pdev, limit);
25+
if (err)
26+
xe_sriov_notice(xe, "Failed to set number of VFs to %d (%pe)\n",
27+
limit, ERR_PTR(err));
28+
return err;
29+
}
30+
31+
static bool pf_continue_as_native(struct xe_device *xe, const char *why)
32+
{
33+
xe_sriov_dbg(xe, "%s, continuing as native\n", why);
34+
pf_reduce_totalvfs(xe, 0);
35+
return false;
36+
}
37+
38+
/**
39+
* xe_sriov_pf_readiness - Check if PF functionality can be enabled.
40+
* @xe: the &xe_device to check
41+
*
42+
* This function is called as part of the SR-IOV probe to validate if all
43+
* PF prerequisites are satisfied and we can continue with enabling PF mode.
44+
*
45+
* Return: true if the PF mode can be turned on.
46+
*/
47+
bool xe_sriov_pf_readiness(struct xe_device *xe)
48+
{
49+
struct device *dev = xe->drm.dev;
50+
struct pci_dev *pdev = to_pci_dev(dev);
51+
int totalvfs = pci_sriov_get_totalvfs(pdev);
52+
int newlimit = min_t(u16, wanted_max_vfs(xe), totalvfs);
53+
54+
xe_assert(xe, totalvfs <= U16_MAX);
55+
56+
if (!dev_is_pf(dev))
57+
return false;
58+
59+
if (!xe_device_uc_enabled(xe))
60+
return pf_continue_as_native(xe, "Guc submission disabled");
61+
62+
if (!newlimit)
63+
return pf_continue_as_native(xe, "all VFs disabled");
64+
65+
pf_reduce_totalvfs(xe, newlimit);
66+
67+
xe->sriov.pf.device_total_vfs = totalvfs;
68+
xe->sriov.pf.driver_max_vfs = newlimit;
69+
70+
return true;
71+
}
72+
73+
/**
74+
* xe_sriov_pf_print_vfs_summary - Print SR-IOV PF information.
75+
* @xe: the &xe_device to print info from
76+
* @p: the &drm_printer
77+
*
78+
* Print SR-IOV PF related information into provided DRM printer.
79+
*/
80+
void xe_sriov_pf_print_vfs_summary(struct xe_device *xe, struct drm_printer *p)
81+
{
82+
struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
83+
84+
xe_assert(xe, IS_SRIOV_PF(xe));
85+
86+
drm_printf(p, "total: %u\n", xe->sriov.pf.device_total_vfs);
87+
drm_printf(p, "supported: %u\n", xe->sriov.pf.driver_max_vfs);
88+
drm_printf(p, "enabled: %u\n", pci_num_vf(pdev));
89+
}

drivers/gpu/drm/xe/xe_sriov_pf.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/* SPDX-License-Identifier: MIT */
2+
/*
3+
* Copyright © 2023-2024 Intel Corporation
4+
*/
5+
6+
#ifndef _XE_SRIOV_PF_H_
7+
#define _XE_SRIOV_PF_H_
8+
9+
#include <linux/types.h>
10+
11+
struct drm_printer;
12+
struct xe_device;
13+
14+
#ifdef CONFIG_PCI_IOV
15+
bool xe_sriov_pf_readiness(struct xe_device *xe);
16+
void xe_sriov_pf_print_vfs_summary(struct xe_device *xe, struct drm_printer *p);
17+
#else
18+
static inline bool xe_sriov_pf_readiness(struct xe_device *xe)
19+
{
20+
return false;
21+
}
22+
#endif
23+
24+
#endif

drivers/gpu/drm/xe/xe_sriov_types.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#define _XE_SRIOV_TYPES_H_
88

99
#include <linux/build_bug.h>
10+
#include <linux/types.h>
1011

1112
/**
1213
* VFID - Virtual Function Identifier
@@ -37,4 +38,18 @@ enum xe_sriov_mode {
3738
};
3839
static_assert(XE_SRIOV_MODE_NONE);
3940

41+
/**
42+
* struct xe_device_pf - Xe PF related data
43+
*
44+
* The data in this structure is valid only if driver is running in the
45+
* @XE_SRIOV_MODE_PF mode.
46+
*/
47+
struct xe_device_pf {
48+
/** @device_total_vfs: Maximum number of VFs supported by the device. */
49+
u16 device_total_vfs;
50+
51+
/** @driver_max_vfs: Maximum number of VFs supported by the driver. */
52+
u16 driver_max_vfs;
53+
};
54+
4055
#endif

0 commit comments

Comments
 (0)