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
This commit is contained in:
parent
e806fac0bd
commit
146e438495
@ -159,7 +159,8 @@ xe-$(CONFIG_PCI_IOV) += \
|
||||
xe_gt_sriov_pf_control.o \
|
||||
xe_lmtt.o \
|
||||
xe_lmtt_2l.o \
|
||||
xe_lmtt_ml.o
|
||||
xe_lmtt_ml.o \
|
||||
xe_sriov_pf.o
|
||||
|
||||
# include helpers for tests even when XE is built-in
|
||||
ifdef CONFIG_DRM_XE_KUNIT_TEST
|
||||
|
@ -321,6 +321,10 @@ struct xe_device {
|
||||
struct {
|
||||
/** @sriov.__mode: SR-IOV mode (Don't access directly!) */
|
||||
enum xe_sriov_mode __mode;
|
||||
|
||||
/** @sriov.pf: PF specific data */
|
||||
struct xe_device_pf pf;
|
||||
|
||||
/** @sriov.wq: workqueue used by the virtualization workers */
|
||||
struct workqueue_struct *wq;
|
||||
} sriov;
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "xe_device.h"
|
||||
#include "xe_mmio.h"
|
||||
#include "xe_sriov.h"
|
||||
#include "xe_sriov_pf.h"
|
||||
|
||||
/**
|
||||
* xe_sriov_mode_to_string - Convert enum value to string.
|
||||
@ -58,6 +59,8 @@ void xe_sriov_probe_early(struct xe_device *xe)
|
||||
if (has_sriov) {
|
||||
if (test_is_vf(xe))
|
||||
mode = XE_SRIOV_MODE_VF;
|
||||
else if (xe_sriov_pf_readiness(xe))
|
||||
mode = XE_SRIOV_MODE_PF;
|
||||
}
|
||||
|
||||
xe_assert(xe, !xe->sriov.__mode);
|
||||
|
89
drivers/gpu/drm/xe/xe_sriov_pf.c
Normal file
89
drivers/gpu/drm/xe/xe_sriov_pf.c
Normal file
@ -0,0 +1,89 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* Copyright © 2023-2024 Intel Corporation
|
||||
*/
|
||||
|
||||
#include "xe_assert.h"
|
||||
#include "xe_device.h"
|
||||
#include "xe_module.h"
|
||||
#include "xe_sriov.h"
|
||||
#include "xe_sriov_pf.h"
|
||||
#include "xe_sriov_printk.h"
|
||||
|
||||
static unsigned int wanted_max_vfs(struct xe_device *xe)
|
||||
{
|
||||
return xe_modparam.max_vfs;
|
||||
}
|
||||
|
||||
static int pf_reduce_totalvfs(struct xe_device *xe, int limit)
|
||||
{
|
||||
struct device *dev = xe->drm.dev;
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
int err;
|
||||
|
||||
err = pci_sriov_set_totalvfs(pdev, limit);
|
||||
if (err)
|
||||
xe_sriov_notice(xe, "Failed to set number of VFs to %d (%pe)\n",
|
||||
limit, ERR_PTR(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
static bool pf_continue_as_native(struct xe_device *xe, const char *why)
|
||||
{
|
||||
xe_sriov_dbg(xe, "%s, continuing as native\n", why);
|
||||
pf_reduce_totalvfs(xe, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* xe_sriov_pf_readiness - Check if PF functionality can be enabled.
|
||||
* @xe: the &xe_device to check
|
||||
*
|
||||
* This function is called as part of the SR-IOV probe to validate if all
|
||||
* PF prerequisites are satisfied and we can continue with enabling PF mode.
|
||||
*
|
||||
* Return: true if the PF mode can be turned on.
|
||||
*/
|
||||
bool xe_sriov_pf_readiness(struct xe_device *xe)
|
||||
{
|
||||
struct device *dev = xe->drm.dev;
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
int totalvfs = pci_sriov_get_totalvfs(pdev);
|
||||
int newlimit = min_t(u16, wanted_max_vfs(xe), totalvfs);
|
||||
|
||||
xe_assert(xe, totalvfs <= U16_MAX);
|
||||
|
||||
if (!dev_is_pf(dev))
|
||||
return false;
|
||||
|
||||
if (!xe_device_uc_enabled(xe))
|
||||
return pf_continue_as_native(xe, "Guc submission disabled");
|
||||
|
||||
if (!newlimit)
|
||||
return pf_continue_as_native(xe, "all VFs disabled");
|
||||
|
||||
pf_reduce_totalvfs(xe, newlimit);
|
||||
|
||||
xe->sriov.pf.device_total_vfs = totalvfs;
|
||||
xe->sriov.pf.driver_max_vfs = newlimit;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* xe_sriov_pf_print_vfs_summary - Print SR-IOV PF information.
|
||||
* @xe: the &xe_device to print info from
|
||||
* @p: the &drm_printer
|
||||
*
|
||||
* Print SR-IOV PF related information into provided DRM printer.
|
||||
*/
|
||||
void xe_sriov_pf_print_vfs_summary(struct xe_device *xe, struct drm_printer *p)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
|
||||
|
||||
xe_assert(xe, IS_SRIOV_PF(xe));
|
||||
|
||||
drm_printf(p, "total: %u\n", xe->sriov.pf.device_total_vfs);
|
||||
drm_printf(p, "supported: %u\n", xe->sriov.pf.driver_max_vfs);
|
||||
drm_printf(p, "enabled: %u\n", pci_num_vf(pdev));
|
||||
}
|
24
drivers/gpu/drm/xe/xe_sriov_pf.h
Normal file
24
drivers/gpu/drm/xe/xe_sriov_pf.h
Normal file
@ -0,0 +1,24 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Copyright © 2023-2024 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef _XE_SRIOV_PF_H_
|
||||
#define _XE_SRIOV_PF_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct drm_printer;
|
||||
struct xe_device;
|
||||
|
||||
#ifdef CONFIG_PCI_IOV
|
||||
bool xe_sriov_pf_readiness(struct xe_device *xe);
|
||||
void xe_sriov_pf_print_vfs_summary(struct xe_device *xe, struct drm_printer *p);
|
||||
#else
|
||||
static inline bool xe_sriov_pf_readiness(struct xe_device *xe)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -7,6 +7,7 @@
|
||||
#define _XE_SRIOV_TYPES_H_
|
||||
|
||||
#include <linux/build_bug.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
/**
|
||||
* VFID - Virtual Function Identifier
|
||||
@ -37,4 +38,18 @@ enum xe_sriov_mode {
|
||||
};
|
||||
static_assert(XE_SRIOV_MODE_NONE);
|
||||
|
||||
/**
|
||||
* struct xe_device_pf - Xe PF related data
|
||||
*
|
||||
* The data in this structure is valid only if driver is running in the
|
||||
* @XE_SRIOV_MODE_PF mode.
|
||||
*/
|
||||
struct xe_device_pf {
|
||||
/** @device_total_vfs: Maximum number of VFs supported by the device. */
|
||||
u16 device_total_vfs;
|
||||
|
||||
/** @driver_max_vfs: Maximum number of VFs supported by the driver. */
|
||||
u16 driver_max_vfs;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user