Determine PCIe device NUMA node

9

2

Assuming fairly recent Linux OS, is there an easy way to determine to which NUMA node the PCIe slot, where a device is plugged in, belongs?

user49531

Posted 2014-01-13T15:59:37.497

Reputation:

Answers

10

You must go to the directory of the PCIe slot in question, for instance eth0:

 cd /sys/class/net/eth0/device

where you will find numa_node, local_cpus, and local_cpulist, the three files of interest to you. You can just cat them, and see the desired data.

MariusMatutiae

Posted 2014-01-13T15:59:37.497

Reputation: 41 321

Huh, I got numa_node = -1 and local_cpulist = 0-15. That can't be right, I have 2 numa nodes as confirmed by hwloc. – Navin – 2016-04-15T22:14:50.523

3

You can also use hwloc (http://www.open-mpi.de/projects/hwloc/) if you know the device id. However, if you have 2 of the same device (for instance, GPUs), the only way to know the NUMA node where the physical slot is associated to is to have a look at the motherboard manual.

For the Asus Z9PE-D8 (http://dlcdnet.asus.com/pub/ASUS/mb/LGA2011/Z9PE-D8-WS/Manual/e8726_z9pe-d8_ws.pdf) it's in page 223.

GuillermoMA

Posted 2014-01-13T15:59:37.497

Reputation: 31

If true, it is probably architecture dependent. For example, the the past several generations of Intel Xeon processors, the PCIe root bridge is on the CPU chip itself. Thus, knowing the CPU socket where a device's PCIe bus resides is a core requirement for operation. This is evidenced by the "/sys/class..." answer above in this case. On these same systems, two identical CPUs on different sockets would show different NUMA devices. Alternatively, on most systems, devices on different busses would have significantly different PCIe addresses, e.g. 1a:00.0 on socket 1, and 89:00.0 on socket 2. – Paul – 2017-10-16T22:04:33.747

2

The accepted answer only works for network cards, as far as I've found. Per GuillermoMA's answer, hwloc will give you the real deal even if it's not as legible. lstopo is found in the hwloc package (at least on RHEL 7):

# lstopo
Machine (256GB)
  NUMANode L#0 (P#0 128GB)
    Socket L#0 + L3 L#0 (20MB)
      L2 L#0 (256KB) + L1d L#0 (32KB) + L1i L#0 (32KB) + Core L#0 + PU L#0 (P#0)
      L2 L#1 (256KB) + L1d L#1 (32KB) + L1i L#1 (32KB) + Core L#1 + PU L#1 (P#2)
      L2 L#2 (256KB) + L1d L#2 (32KB) + L1i L#2 (32KB) + Core L#2 + PU L#2 (P#4)
      L2 L#3 (256KB) + L1d L#3 (32KB) + L1i L#3 (32KB) + Core L#3 + PU L#3 (P#6)
      L2 L#4 (256KB) + L1d L#4 (32KB) + L1i L#4 (32KB) + Core L#4 + PU L#4 (P#8)
      L2 L#5 (256KB) + L1d L#5 (32KB) + L1i L#5 (32KB) + Core L#5 + PU L#5 (P#10)
      L2 L#6 (256KB) + L1d L#6 (32KB) + L1i L#6 (32KB) + Core L#6 + PU L#6 (P#12)
      L2 L#7 (256KB) + L1d L#7 (32KB) + L1i L#7 (32KB) + Core L#7 + PU L#7 (P#14)
    HostBridge L#0
      PCIBridge
        PCI 1000:005d
          Block L#0 "sda"
      PCIBridge
        PCI 14e4:16a1
          Net L#1 "eth0"
        PCI 14e4:16a1
          Net L#2 "eth1"
        PCI 14e4:16a1
          Net L#3 "eth2"
        PCI 14e4:16a1
          Net L#4 "eth3"
      PCI 8086:8d62
      PCIBridge
        PCIBridge
          PCIBridge
            PCIBridge
              PCI 102b:0534
      PCI 8086:8d02
        Block L#5 "sr0"
  NUMANode L#1 (P#1 128GB)
    Socket L#1 + L3 L#1 (20MB)
      L2 L#8 (256KB) + L1d L#8 (32KB) + L1i L#8 (32KB) + Core L#8 + PU L#8 (P#1)
      L2 L#9 (256KB) + L1d L#9 (32KB) + L1i L#9 (32KB) + Core L#9 + PU L#9 (P#3)
      L2 L#10 (256KB) + L1d L#10 (32KB) + L1i L#10 (32KB) + Core L#10 + PU L#10 (P#5)
      L2 L#11 (256KB) + L1d L#11 (32KB) + L1i L#11 (32KB) + Core L#11 + PU L#11 (P#7)
      L2 L#12 (256KB) + L1d L#12 (32KB) + L1i L#12 (32KB) + Core L#12 + PU L#12 (P#9)
      L2 L#13 (256KB) + L1d L#13 (32KB) + L1i L#13 (32KB) + Core L#13 + PU L#13 (P#11)
      L2 L#14 (256KB) + L1d L#14 (32KB) + L1i L#14 (32KB) + Core L#14 + PU L#14 (P#13)
      L2 L#15 (256KB) + L1d L#15 (32KB) + L1i L#15 (32KB) + Core L#15 + PU L#15 (P#15)
    HostBridge L#7
      PCIBridge
        PCI 15b3:1003
          Net L#6 "eth4"
          Net L#7 "eth5"

NUMANode L#0 is, of course, CPU0 and NUMANode L#1 is CPU1. You can then take your favorite PCI number from the above, eg 14e4:16a1, and discover what it is, and its PCI address for further analysis from lspci:

# lspci -nn | grep 14e4:16a1
01:00.0 Ethernet controller [0200]: Broadcom Corporation BCM57840 NetXtreme II 10 Gigabit Ethernet [14e4:16a1] (rev 11)
01:00.1 Ethernet controller [0200]: Broadcom Corporation BCM57840 NetXtreme II 10 Gigabit Ethernet [14e4:16a1] (rev 11)
01:00.2 Ethernet controller [0200]: Broadcom Corporation BCM57840 NetXtreme II 10 Gigabit Ethernet [14e4:16a1] (rev 11)
01:00.3 Ethernet controller [0200]: Broadcom Corporation BCM57840 NetXtreme II 10 Gigabit Ethernet [14e4:16a1] (rev 11)

On one of my machines, an Emulex Fibre Channel card did not show up in the lstopo output. I found it using lstopo --whole-io, by performing the reverse lookup process (scroll to the right if you have to, to see the 10df hex number that I grep for):

# lspci -nn | grep -i emulex
03:00.0 Fibre Channel [0c04]: Emulex Corporation Saturn-X: LightPulse Fibre Channel Host Adapter [10df:f100] (rev 03)
03:00.1 Fibre Channel [0c04]: Emulex Corporation Saturn-X: LightPulse Fibre Channel Host Adapter [10df:f100] (rev 03)
# lstopo --whole-io | grep 10df   
        PCI 10df:f100
        PCI 10df:f100

Remove the piped grep command, above, and rummage through the output semi-manually to find the device in the full lstopo --whole-io display (left as an exercise for the reader).

Mike S

Posted 2014-01-13T15:59:37.497

Reputation: 166

lspci -nn | grep PCINUMBER made my day. I have two Samsung 970 Pro and that command helped me to identify them from the ltopo output. Thank you. – pietrop – 2018-08-10T07:03:08.393

0

One can get using: # cat /sys/bus/pci/devices/<PCI device>/numa_node

Get PCI device address using # lspci -nn

Hem

Posted 2014-01-13T15:59:37.497

Reputation: 3