Linux driver-core infrastructure
 help / color / mirror / Atom feed
* [PATCH 0/3] kernfs, driver core: Cut per-node lock traffic in bulk registration
@ 2026-09-11 17:16 Pavol Sakac
  2026-09-11 17:16 ` [PATCH 1/3] kernfs: activate nodes while linking them Pavol Sakac
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Pavol Sakac @ 2026-09-11 17:16 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Tejun Heo, Rafael J . Wysocki,
	Danilo Krummrich
  Cc: driver-core, linux-kernel, Andy Shevchenko, Xu Yang,
	Bartosz Golaszewski, nh-open-source

Registering VFs in parallel, introduced in [1], runs into three lock
costs in kernfs and the driver core. Two scale with the number of
sysfs nodes created: the kernfs root rwsem is write-taken twice per
node, and every inode ID is allocated under kernfs_idr_lock. The third
scales with the number of devices: get_device_parent()'s glue
directory lookup walks a flat list under the global gdp_mutex.

The glue directory is how the driver core groups class devices under a
parent that is not itself a class device: when vfio-pci binds, each VF
gets a "vfio-dev" glue directory holding its vfio-dev class device.
get_device_parent() finds or creates it by walking the class's flat
glue_dirs list under gdp_mutex, so with thousands of VFs each
registration walks thousands of entries - quadratic work, serialized
on one global mutex.

Patch 1 (kernfs) activates a new node inside the same kernfs_rwsem
write hold that links it: one write acquisition per node instead of
two. Patch 2 (driver core) indexes glue directories by parent kobject
in an rbtree, replacing the linear walk; gdp_mutex still serializes as
before. Patch 3 (kernfs) pre-allocates inode IDs in batches of 16,
caches them per CPU, and installs the node pointer with an RCU store
via idr_replace(), cutting kernfs_idr_lock acquisitions 16x.

Lock statistics and SR-IOV init time for 4x PF (NVMe, 255 VFs each), on
the reproducer from the parallel VF initialization cover letter [1]:

  lock_stat:
  Lock                     wait: Before     After   contentions: Before   After
  iommu_probe_device_lock      10471 ms   9154 ms                   841     783
  &vfio.group_lock              3614 ms   3823 ms                   736     730
  &root->kernfs_rwsem           1834 ms   1285 ms                116316   55459
  &root->kernfs_idr_lock           5 ms      0 ms                  4580      77

  iommu_probe_device_lock and vfio.group_lock are shown for scale;
  neither is touched by this series - they are addressed by the
  IOMMU [2] and VFIO [3] series posted separately.

  kernfs_rwsem write acquisitions  168302 (2/node) -> 84661 (1/node)
  kernfs_idr_lock acquisitions     83641 -> 5229 (batch 16)
  gdp_mutex avg hold               18 -> 7 us (2040 acq. both arms)

  Stage                 SR-IOV init time:
  S0 (baseline)         3027 ms
  S1                     999 ms
  S2                     995 ms
  S3 (this series)       991 ms

Reproducer disclaimer:
I lean primarily on lock_stat numbers to defend the improvements. In
the reproducer, the residual iommu_probe_device_lock dominates the
window and masks the later series' wall-time gains; reducing that lock
further is out of scope for this set. On real hardware the five series
together cut SR-IOV initialization by 65%, more in [1].

The staged sysfs RFC [4] builds on top of these changes (mainly the
IDR batching).

This series adds a KUnit suite. The lock_stat and timing figures come
from the public reproducer. The full series has also been tested on
current datacenter server hardware with thousands of VFs.


[1] https://lore.kernel.org/r/20260911-vfopt-s1-v1-0-693271dc0226@amazon.de
[2] https://lore.kernel.org/r/20260911-vfopt-s2-v1-0-fff3db7e01c2@amazon.de
[3] https://lore.kernel.org/r/20260911-vfopt-s4-v1-0-98ba1d2ef7ab@amazon.de
[4] https://lore.kernel.org/r/20260911-vfopt-s5-v1-0-fa4cacdb6ca8@amazon.de

Pavol Sakac (3):
  kernfs: activate nodes while linking them
  driver core: Index class glue directories by parent kobject
  kernfs: batch inode ID allocation per CPU

 drivers/base/base.h                  |   4 +
 drivers/base/core.c                  | 112 +++++--
 drivers/base/test/.kunitconfig       |   1 +
 drivers/base/test/Kconfig            |  12 +
 drivers/base/test/Makefile           |   2 +
 drivers/base/test/glue-dir-test.c    | 466 +++++++++++++++++++++++++++
 drivers/base/test/root-device-test.c | 215 ++++++++++++
 fs/kernfs/dir.c                      | 139 +++++++-
 fs/kernfs/kernfs-internal.h          |   3 +
 fs/sysfs/mount.c                     |   3 +-
 include/linux/kernfs.h               |  13 +
 11 files changed, 930 insertions(+), 40 deletions(-)
 create mode 100644 drivers/base/test/glue-dir-test.c


base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
-- 
2.47.3


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-09-11 18:12 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-11 17:16 [PATCH 0/3] kernfs, driver core: Cut per-node lock traffic in bulk registration Pavol Sakac
2026-09-11 17:16 ` [PATCH 1/3] kernfs: activate nodes while linking them Pavol Sakac
2026-09-11 18:12   ` Andy Shevchenko
2026-09-11 17:16 ` [PATCH 2/3] driver core: Index class glue directories by parent kobject Pavol Sakac
2026-09-11 18:11   ` Andy Shevchenko
2026-09-11 17:16 ` [PATCH 3/3] kernfs: batch inode ID allocation per CPU Pavol Sakac

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox