mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-27 06:20:50 +07:00
Merge branch 'pci/yijing-mps-v8' into next
* pci/yijing-mps-v8: PCI: Warn if unsafe MPS settings detected PCI: Fix MPS peer-to-peer DMA comment syntax PCI: Don't restrict MPS for slots below Root Ports PCI: Simplify MPS test for Downstream Port PCI: Remove unnecessary check for pcie_get_mps() failure PCI: Simplify pcie_bus_configure_settings() interface PCI: Drop "PCI-E" prefix from Max Payload Size message
This commit is contained in:
commit
07f2daad09
@ -1672,12 +1672,8 @@ void pcibios_scan_phb(struct pci_controller *hose)
|
||||
/* Configure PCI Express settings */
|
||||
if (bus && !pci_has_flag(PCI_PROBE_ONLY)) {
|
||||
struct pci_bus *child;
|
||||
list_for_each_entry(child, &bus->children, node) {
|
||||
struct pci_dev *self = child->self;
|
||||
if (!self)
|
||||
continue;
|
||||
pcie_bus_configure_settings(child, self->pcie_mpss);
|
||||
}
|
||||
list_for_each_entry(child, &bus->children, node)
|
||||
pcie_bus_configure_settings(child);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -508,13 +508,8 @@ static void fixup_read_and_payload_sizes(struct pci_controller *controller)
|
||||
rc_dev_cap.word);
|
||||
|
||||
/* Configure PCI Express MPS setting. */
|
||||
list_for_each_entry(child, &root_bus->children, node) {
|
||||
struct pci_dev *self = child->self;
|
||||
if (!self)
|
||||
continue;
|
||||
|
||||
pcie_bus_configure_settings(child, self->pcie_mpss);
|
||||
}
|
||||
list_for_each_entry(child, &root_bus->children, node)
|
||||
pcie_bus_configure_settings(child);
|
||||
|
||||
/*
|
||||
* Set the mac_config register in trio based on the MPS/MRS of the link.
|
||||
|
@ -568,13 +568,8 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
|
||||
*/
|
||||
if (bus) {
|
||||
struct pci_bus *child;
|
||||
list_for_each_entry(child, &bus->children, node) {
|
||||
struct pci_dev *self = child->self;
|
||||
if (!self)
|
||||
continue;
|
||||
|
||||
pcie_bus_configure_settings(child, self->pcie_mpss);
|
||||
}
|
||||
list_for_each_entry(child, &bus->children, node)
|
||||
pcie_bus_configure_settings(child);
|
||||
}
|
||||
|
||||
if (bus && node != -1) {
|
||||
|
@ -160,9 +160,8 @@ void pci_configure_slot(struct pci_dev *dev)
|
||||
(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
|
||||
return;
|
||||
|
||||
if (dev->bus && dev->bus->self)
|
||||
pcie_bus_configure_settings(dev->bus,
|
||||
dev->bus->self->pcie_mpss);
|
||||
if (dev->bus)
|
||||
pcie_bus_configure_settings(dev->bus);
|
||||
|
||||
memset(&hpp, 0, sizeof(hpp));
|
||||
ret = pci_get_hp_params(dev, &hpp);
|
||||
|
@ -3939,8 +3939,6 @@ int pcie_set_readrq(struct pci_dev *dev, int rq)
|
||||
if (pcie_bus_config == PCIE_BUS_PERFORMANCE) {
|
||||
int mps = pcie_get_mps(dev);
|
||||
|
||||
if (mps < 0)
|
||||
return mps;
|
||||
if (mps < rq)
|
||||
rq = mps;
|
||||
}
|
||||
@ -3957,7 +3955,6 @@ EXPORT_SYMBOL(pcie_set_readrq);
|
||||
* @dev: PCI device to query
|
||||
*
|
||||
* Returns maximum payload size in bytes
|
||||
* or appropriate error value.
|
||||
*/
|
||||
int pcie_get_mps(struct pci_dev *dev)
|
||||
{
|
||||
|
@ -1491,24 +1491,23 @@ static int pcie_find_smpss(struct pci_dev *dev, void *data)
|
||||
if (!pci_is_pcie(dev))
|
||||
return 0;
|
||||
|
||||
/* For PCIE hotplug enabled slots not connected directly to a
|
||||
* PCI-E root port, there can be problems when hotplugging
|
||||
* devices. This is due to the possibility of hotplugging a
|
||||
* device into the fabric with a smaller MPS that the devices
|
||||
* currently running have configured. Modifying the MPS on the
|
||||
* running devices could cause a fatal bus error due to an
|
||||
* incoming frame being larger than the newly configured MPS.
|
||||
* To work around this, the MPS for the entire fabric must be
|
||||
* set to the minimum size. Any devices hotplugged into this
|
||||
* fabric will have the minimum MPS set. If the PCI hotplug
|
||||
* slot is directly connected to the root port and there are not
|
||||
* other devices on the fabric (which seems to be the most
|
||||
* common case), then this is not an issue and MPS discovery
|
||||
* will occur as normal.
|
||||
/*
|
||||
* We don't have a way to change MPS settings on devices that have
|
||||
* drivers attached. A hot-added device might support only the minimum
|
||||
* MPS setting (MPS=128). Therefore, if the fabric contains a bridge
|
||||
* where devices may be hot-added, we limit the fabric MPS to 128 so
|
||||
* hot-added devices will work correctly.
|
||||
*
|
||||
* However, if we hot-add a device to a slot directly below a Root
|
||||
* Port, it's impossible for there to be other existing devices below
|
||||
* the port. We don't limit the MPS in this case because we can
|
||||
* reconfigure MPS on both the Root Port and the hot-added device,
|
||||
* and there are no other devices involved.
|
||||
*
|
||||
* Note that this PCIE_BUS_SAFE path assumes no peer-to-peer DMA.
|
||||
*/
|
||||
if (dev->is_hotplug_bridge && (!list_is_singular(&dev->bus->devices) ||
|
||||
(dev->bus->self &&
|
||||
pci_pcie_type(dev->bus->self) != PCI_EXP_TYPE_ROOT_PORT)))
|
||||
if (dev->is_hotplug_bridge &&
|
||||
pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT)
|
||||
*smpss = 0;
|
||||
|
||||
if (*smpss > dev->pcie_mpss)
|
||||
@ -1583,6 +1582,22 @@ static void pcie_write_mrrs(struct pci_dev *dev)
|
||||
"with pci=pcie_bus_safe.\n");
|
||||
}
|
||||
|
||||
static void pcie_bus_detect_mps(struct pci_dev *dev)
|
||||
{
|
||||
struct pci_dev *bridge = dev->bus->self;
|
||||
int mps, p_mps;
|
||||
|
||||
if (!bridge)
|
||||
return;
|
||||
|
||||
mps = pcie_get_mps(dev);
|
||||
p_mps = pcie_get_mps(bridge);
|
||||
|
||||
if (mps != p_mps)
|
||||
dev_warn(&dev->dev, "Max Payload Size %d, but upstream %s set to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n",
|
||||
mps, pci_name(bridge), p_mps);
|
||||
}
|
||||
|
||||
static int pcie_bus_configure_set(struct pci_dev *dev, void *data)
|
||||
{
|
||||
int mps, orig_mps;
|
||||
@ -1590,13 +1605,18 @@ static int pcie_bus_configure_set(struct pci_dev *dev, void *data)
|
||||
if (!pci_is_pcie(dev))
|
||||
return 0;
|
||||
|
||||
if (pcie_bus_config == PCIE_BUS_TUNE_OFF) {
|
||||
pcie_bus_detect_mps(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
mps = 128 << *(u8 *)data;
|
||||
orig_mps = pcie_get_mps(dev);
|
||||
|
||||
pcie_write_mps(dev, mps);
|
||||
pcie_write_mrrs(dev);
|
||||
|
||||
dev_info(&dev->dev, "PCI-E Max Payload Size set to %4d/%4d (was %4d), "
|
||||
dev_info(&dev->dev, "Max Payload Size set to %4d/%4d (was %4d), "
|
||||
"Max Read Rq %4d\n", pcie_get_mps(dev), 128 << dev->pcie_mpss,
|
||||
orig_mps, pcie_get_readrq(dev));
|
||||
|
||||
@ -1607,25 +1627,25 @@ static int pcie_bus_configure_set(struct pci_dev *dev, void *data)
|
||||
* parents then children fashion. If this changes, then this code will not
|
||||
* work as designed.
|
||||
*/
|
||||
void pcie_bus_configure_settings(struct pci_bus *bus, u8 mpss)
|
||||
void pcie_bus_configure_settings(struct pci_bus *bus)
|
||||
{
|
||||
u8 smpss;
|
||||
|
||||
if (!bus->self)
|
||||
return;
|
||||
|
||||
if (!pci_is_pcie(bus->self))
|
||||
return;
|
||||
|
||||
if (pcie_bus_config == PCIE_BUS_TUNE_OFF)
|
||||
return;
|
||||
|
||||
/* FIXME - Peer to peer DMA is possible, though the endpoint would need
|
||||
* to be aware to the MPS of the destination. To work around this,
|
||||
* to be aware of the MPS of the destination. To work around this,
|
||||
* simply force the MPS of the entire system to the smallest possible.
|
||||
*/
|
||||
if (pcie_bus_config == PCIE_BUS_PEER2PEER)
|
||||
smpss = 0;
|
||||
|
||||
if (pcie_bus_config == PCIE_BUS_SAFE) {
|
||||
smpss = mpss;
|
||||
smpss = bus->self->pcie_mpss;
|
||||
|
||||
pcie_find_smpss(bus->self, &smpss);
|
||||
pci_walk_bus(bus, pcie_find_smpss, &smpss);
|
||||
|
@ -675,7 +675,7 @@ struct pci_driver {
|
||||
/* these external functions are only available when PCI support is enabled */
|
||||
#ifdef CONFIG_PCI
|
||||
|
||||
void pcie_bus_configure_settings(struct pci_bus *bus, u8 smpss);
|
||||
void pcie_bus_configure_settings(struct pci_bus *bus);
|
||||
|
||||
enum pcie_bus_config_types {
|
||||
PCIE_BUS_TUNE_OFF,
|
||||
|
Loading…
Reference in New Issue
Block a user