PCI: vmd: Use SRCU as a local RCU to prevent delaying global RCU

SRCU lets synchronize_srcu() depend on VMD-local RCU primitives, preventing
long delays from locking up RCU in other systems.  VMD performs a
synchronize when removing a device, but will hit all IRQ lists if the
device uses all VMD vectors.  This patch will not help VMD's RCU
synchronization, but will isolate the read side delays to the VMD
subsystem.  Additionally, the use of SRCU in VMD's ISR will keep it
isolated from any other RCU waiters in the rest of the system.

Tested using concurrent FIO and NVMe resets:

  [global]
  rw=read
  bs=4k
  direct=1
  ioengine=libaio
  iodepth=32
  norandommap
  timeout=300
  runtime=1000000000

  [nvme0]
  cpus_allowed=0-63
  numjobs=8
  filename=/dev/nvme0n1

  [nvme1]
  cpus_allowed=0-63
  numjobs=8
  filename=/dev/nvme1n1

  while (true) do
    for i in /sys/class/nvme/nvme*; do
      echo "Resetting ${i##*/}"
      echo 1 > $i/reset_controller;
      sleep 5
    done;
  done

Signed-off-by: Jon Derrick <jonathan.derrick@intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Keith Busch <keith.busch@intel.com>
2 files changed