Commit e626ea2
committed
Merge patch series "kernfs: remove kernfs_rwsem from dentry revalidation"
Shakeel Butt <shakeel.butt@linux.dev> says:
kernfs: remove kernfs_rwsem from dentry revalidation
At Meta, we are seeing important system daemons that poll cgroupfs and
sysfs geth stuck in kernfs_dop_revalidate() for minutes. The two that
hurt most are the ones we can least afford to lose: oomd, which decides
what to kill when a machine runs out of memory, and below[1], which
records the telemetry used to understand what happened afterwards.
kernfs_dop_revalidate() takes kernfs_rwsem for read once per path component
of every walk into a kernfs mount. Linux rwsems do not permit reader lock
stealing once a writer is queued, so one writer -- a cgroup created or
destroyed, a device renamed -- parks the entire incoming reader stream in
uninterruptible sleep. Daemons polling cgroup files in a loop are exactly
the workload that turns this into a convoy, and cgroup churn is exactly
what a busy machine does.
Nothing the callback reads needs the semaphore. kn->active is an atomic_t
already tested lock-free elsewhere, kn->__parent and kn->name are RCU
pointers, kn->ns can be compared rather than dereferenced, and
parent->dir.rev is a plain counter.
1/4 uses the parent inode and name the VFS already passes to
->d_revalidate() rather than recovering them from mutable dentry
fields, comparing the name by explicit length
2/4 annotates the directory revision counter for lockless access
3/4 compares namespace tags by pointer
4/4 removes kernfs_rwsem from the callback
LOOKUP_RCU still returns -ECHILD. kernfs_iop_permission() forces every walk
out of RCU-walk before children are revalidated, so lifting it here would
have no effect until that path is fixed; left to a separate series.
Readers walking cgroupfs and sysfs while another thread churns cgroups,
renames netdevs and adds/removes devices, on an 8-CPU VM:
kernfs_rwsem read contentions revalidate among
acquisitions top call sites
before 48,593,360 1,744,517 #1 and #2
after 1,280,280 429,846 absent
Reader path-walk throughput improved 35-53% over the same workload.
Tested against an unpatched control of the same tree, built and booted with
KASAN, KCSAN (default and STRICT), PROVE_LOCKING, PROVE_RCU,
DEBUG_ATOMIC_SLEEP and LOCK_STAT. The deactivated, renamed and
namespace-moved reject paths and negative-dentry invalidation all behave as
before. KCSAN_STRICT over 180s reports no data race involving
kernfs_dop_revalidate() or any field it reads, and there are no KASAN,
lockdep or might-sleep reports across millions of concurrent path walks.
The only kernfs KCSAN reports are in kernfs_refresh_inode(), present
identically on the control and addressed separately.
Link: https://github.com/facebookincubator/below [1]
* patches from https://patch.msgid.link/20260821050507.2161607-1-shakeel.butt@linux.dev:
kernfs: Remove kernfs_rwsem from dentry revalidation
kernfs: Avoid namespace dereference in d_revalidate()
kernfs: Prepare directory revisions for lockless reads
kernfs: Use VFS lookup context in d_revalidate()
Link: https://patch.msgid.link/20260821050507.2161607-1-shakeel.butt@linux.dev
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>2 files changed
Lines changed: 35 additions & 50 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1171 | 1171 | | |
1172 | 1172 | | |
1173 | 1173 | | |
1174 | | - | |
1175 | | - | |
| 1174 | + | |
| 1175 | + | |
| 1176 | + | |
1176 | 1177 | | |
1177 | 1178 | | |
1178 | 1179 | | |
1179 | 1180 | | |
1180 | 1181 | | |
1181 | 1182 | | |
1182 | | - | |
1183 | | - | |
1184 | | - | |
1185 | | - | |
1186 | | - | |
1187 | | - | |
1188 | | - | |
1189 | | - | |
1190 | | - | |
| 1183 | + | |
| 1184 | + | |
| 1185 | + | |
1191 | 1186 | | |
1192 | 1187 | | |
1193 | 1188 | | |
1194 | 1189 | | |
1195 | 1190 | | |
1196 | 1191 | | |
1197 | 1192 | | |
1198 | | - | |
1199 | | - | |
1200 | | - | |
1201 | | - | |
1202 | | - | |
1203 | | - | |
1204 | | - | |
1205 | | - | |
1206 | | - | |
1207 | | - | |
1208 | | - | |
1209 | | - | |
1210 | | - | |
1211 | | - | |
1212 | | - | |
| 1193 | + | |
1213 | 1194 | | |
1214 | 1195 | | |
1215 | 1196 | | |
1216 | | - | |
1217 | | - | |
| 1197 | + | |
| 1198 | + | |
1218 | 1199 | | |
1219 | 1200 | | |
1220 | | - | |
1221 | | - | |
| 1201 | + | |
| 1202 | + | |
1222 | 1203 | | |
1223 | | - | |
1224 | 1204 | | |
1225 | | - | |
1226 | | - | |
| 1205 | + | |
| 1206 | + | |
1227 | 1207 | | |
1228 | 1208 | | |
1229 | | - | |
1230 | | - | |
| 1209 | + | |
| 1210 | + | |
| 1211 | + | |
| 1212 | + | |
1231 | 1213 | | |
1232 | | - | |
1233 | | - | |
1234 | | - | |
1235 | | - | |
| 1214 | + | |
| 1215 | + | |
| 1216 | + | |
| 1217 | + | |
| 1218 | + | |
| 1219 | + | |
| 1220 | + | |
| 1221 | + | |
| 1222 | + | |
| 1223 | + | |
| 1224 | + | |
| 1225 | + | |
1236 | 1226 | | |
1237 | | - | |
1238 | 1227 | | |
1239 | | - | |
1240 | | - | |
1241 | | - | |
1242 | 1228 | | |
1243 | 1229 | | |
1244 | 1230 | | |
| |||
1878 | 1864 | | |
1879 | 1865 | | |
1880 | 1866 | | |
1881 | | - | |
| 1867 | + | |
1882 | 1868 | | |
1883 | 1869 | | |
1884 | 1870 | | |
1885 | 1871 | | |
1886 | 1872 | | |
1887 | 1873 | | |
1888 | 1874 | | |
1889 | | - | |
| 1875 | + | |
1890 | 1876 | | |
1891 | 1877 | | |
1892 | 1878 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
147 | 147 | | |
148 | 148 | | |
149 | 149 | | |
150 | | - | |
| 150 | + | |
151 | 151 | | |
152 | 152 | | |
153 | 153 | | |
154 | 154 | | |
155 | | - | |
| 155 | + | |
| 156 | + | |
156 | 157 | | |
157 | 158 | | |
158 | 159 | | |
159 | 160 | | |
160 | 161 | | |
161 | | - | |
162 | | - | |
163 | | - | |
| 162 | + | |
164 | 163 | | |
165 | 164 | | |
166 | 165 | | |
| |||
0 commit comments