summaryrefslogtreecommitdiffstats
path: root/fs/open.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-07-25 11:36:29 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-07-25 11:36:29 -0400
commita29a0a467e2c02fe4287c2d4eff86c9eb6beff0c (patch)
tree069e48d9d1520b54805861d54cbac6ac53b93021 /fs/open.c
parentbed38c3e2dca01b358a62b5e73b46e875742fd75 (diff)
parentd7852fbd0f0423937fa287a598bfde188bb68c22 (diff)
Merge branch 'access-creds'
The access() (and faccessat()) credentials change can cause an unnecessary load on the RCU machinery because every access() call ends up freeing the temporary access credential using RCU. This isn't really noticeable on small machines, but if you have hundreds of cores you can cause huge slowdowns due to RCU storms. It's easy to avoid: the temporary access crededntials aren't actually normally accessed using RCU at all, so we can avoid the whole issue by just marking them as such. * access-creds: access: avoid the RCU grace period for the temporary subjective credentials
Diffstat (limited to 'fs/open.c')
-rw-r--r--fs/open.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/fs/open.c b/fs/open.c
index b5b80469b93d..a59abe3c669a 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -374,6 +374,25 @@ long do_faccessat(int dfd, const char __user *filename, int mode)
374 override_cred->cap_permitted; 374 override_cred->cap_permitted;
375 } 375 }
376 376
377 /*
378 * The new set of credentials can *only* be used in
379 * task-synchronous circumstances, and does not need
380 * RCU freeing, unless somebody then takes a separate
381 * reference to it.
382 *
383 * NOTE! This is _only_ true because this credential
384 * is used purely for override_creds() that installs
385 * it as the subjective cred. Other threads will be
386 * accessing ->real_cred, not the subjective cred.
387 *
388 * If somebody _does_ make a copy of this (using the
389 * 'get_current_cred()' function), that will clear the
390 * non_rcu field, because now that other user may be
391 * expecting RCU freeing. But normal thread-synchronous
392 * cred accesses will keep things non-RCY.
393 */
394 override_cred->non_rcu = 1;
395
377 old_cred = override_creds(override_cred); 396 old_cred = override_creds(override_cred);
378retry: 397retry:
379 res = user_path_at(dfd, filename, lookup_flags, &path); 398 res = user_path_at(dfd, filename, lookup_flags, &path);