Skip to content

Commit 31e04a4

Browse files
committed
Merge branch 'pci/enumeration'
- Use PCI_HEADER_TYPE_* defines, not hard-coded values (Ilpo Järvinen) - Clean up early_dump_pci_device() to avoid hard-coded values (Ilpo Järvinen) - Clean up pci_scan_child_bus_extend() loop to avoid hard-coded values (Ilpo Järvinen) - Add a Xeon 6 quirk to disable Extended Tags and limit Max Read Request Size to 128B to avoid a performance issue (Ilpo Järvinen) * pci/enumeration: PCI: Add Extended Tag + MRRS quirk for Xeon 6 PCI: Clean up pci_scan_child_bus_extend() loop PCI: Clean up early_dump_pci_device() PCI: Use header type defines in pci_setup_device()
2 parents 7cc5e1e + a22250f commit 31e04a4

3 files changed

Lines changed: 51 additions & 9 deletions

File tree

arch/x86/pci/fixup.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,46 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PB1, pcie_r
294294
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PC, pcie_rootport_aspm_quirk);
295295
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PC1, pcie_rootport_aspm_quirk);
296296

297+
/*
298+
* PCIe devices underneath Xeon 6 PCIe Root Port bifurcated to x2 have lower
299+
* performance with Extended Tags and MRRS > 128B. Work around the performance
300+
* problems by disabling Extended Tags and limiting MRRS to 128B.
301+
*
302+
* https://cdrdv2.intel.com/v1/dl/getContent/837176
303+
*/
304+
static int limit_mrrs_to_128(struct pci_host_bridge *b, struct pci_dev *pdev)
305+
{
306+
int readrq = pcie_get_readrq(pdev);
307+
308+
if (readrq > 128)
309+
pcie_set_readrq(pdev, 128);
310+
311+
return 0;
312+
}
313+
314+
static void pci_xeon_x2_bifurc_quirk(struct pci_dev *pdev)
315+
{
316+
struct pci_host_bridge *bridge = pci_find_host_bridge(pdev->bus);
317+
u32 linkcap;
318+
319+
pcie_capability_read_dword(pdev, PCI_EXP_LNKCAP, &linkcap);
320+
if (FIELD_GET(PCI_EXP_LNKCAP_MLW, linkcap) != 0x2)
321+
return;
322+
323+
bridge->no_ext_tags = 1;
324+
bridge->enable_device = limit_mrrs_to_128;
325+
pci_info(pdev, "Disabling Extended Tags and limiting MRRS to 128B (performance reasons due to x2 PCIe link)\n");
326+
}
327+
328+
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x0db0, pci_xeon_x2_bifurc_quirk);
329+
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x0db1, pci_xeon_x2_bifurc_quirk);
330+
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x0db2, pci_xeon_x2_bifurc_quirk);
331+
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x0db3, pci_xeon_x2_bifurc_quirk);
332+
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x0db6, pci_xeon_x2_bifurc_quirk);
333+
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x0db7, pci_xeon_x2_bifurc_quirk);
334+
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x0db8, pci_xeon_x2_bifurc_quirk);
335+
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x0db9, pci_xeon_x2_bifurc_quirk);
336+
297337
/*
298338
* Fixup to mark boot BIOS video selected by BIOS before it changes
299339
*

drivers/pci/pci.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ struct pcie_tlp_log;
88

99
/* Number of possible devfns: 0.0 to 1f.7 inclusive */
1010
#define MAX_NR_DEVFNS 256
11+
#define PCI_MAX_NR_DEVS 32
1112

1213
#define MAX_NR_LANES 16
1314

drivers/pci/probe.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* PCI detection and setup code
44
*/
55

6+
#include <linux/array_size.h>
67
#include <linux/kernel.h>
78
#include <linux/delay.h>
89
#include <linux/init.h>
@@ -1912,16 +1913,16 @@ static int pci_intx_mask_broken(struct pci_dev *dev)
19121913

19131914
static void early_dump_pci_device(struct pci_dev *pdev)
19141915
{
1915-
u32 value[256 / 4];
1916+
u32 value[PCI_CFG_SPACE_SIZE / sizeof(u32)];
19161917
int i;
19171918

19181919
pci_info(pdev, "config space:\n");
19191920

1920-
for (i = 0; i < 256; i += 4)
1921-
pci_read_config_dword(pdev, i, &value[i / 4]);
1921+
for (i = 0; i < ARRAY_SIZE(value); i++)
1922+
pci_read_config_dword(pdev, i * sizeof(u32), &value[i]);
19221923

19231924
print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1,
1924-
value, 256, false);
1925+
value, ARRAY_SIZE(value) * sizeof(u32), false);
19251926
}
19261927

19271928
static const char *pci_type_str(struct pci_dev *dev)
@@ -1985,8 +1986,8 @@ int pci_setup_device(struct pci_dev *dev)
19851986
dev->sysdata = dev->bus->sysdata;
19861987
dev->dev.parent = dev->bus->bridge;
19871988
dev->dev.bus = &pci_bus_type;
1988-
dev->hdr_type = hdr_type & 0x7f;
1989-
dev->multifunction = !!(hdr_type & 0x80);
1989+
dev->hdr_type = FIELD_GET(PCI_HEADER_TYPE_MASK, hdr_type);
1990+
dev->multifunction = FIELD_GET(PCI_HEADER_TYPE_MFD, hdr_type);
19901991
dev->error_state = pci_channel_io_normal;
19911992
set_pcie_port_type(dev);
19921993

@@ -3045,14 +3046,14 @@ static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus,
30453046
{
30463047
unsigned int used_buses, normal_bridges = 0, hotplug_bridges = 0;
30473048
unsigned int start = bus->busn_res.start;
3048-
unsigned int devfn, cmax, max = start;
3049+
unsigned int devnr, cmax, max = start;
30493050
struct pci_dev *dev;
30503051

30513052
dev_dbg(&bus->dev, "scanning bus\n");
30523053

30533054
/* Go find them, Rover! */
3054-
for (devfn = 0; devfn < 256; devfn += 8)
3055-
pci_scan_slot(bus, devfn);
3055+
for (devnr = 0; devnr < PCI_MAX_NR_DEVS; devnr++)
3056+
pci_scan_slot(bus, PCI_DEVFN(devnr, 0));
30563057

30573058
/* Reserve buses for SR-IOV capability */
30583059
used_buses = pci_iov_bus_range(bus);

0 commit comments

Comments
 (0)