diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-25 08:36:29 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-25 08:36:29 -0700 |
commit | a29a0a467e2c02fe4287c2d4eff86c9eb6beff0c (patch) | |
tree | 069e48d9d1520b54805861d54cbac6ac53b93021 /include | |
parent | bed38c3e2dca01b358a62b5e73b46e875742fd75 (diff) | |
parent | d7852fbd0f0423937fa287a598bfde188bb68c22 (diff) | |
download | linux-stable-a29a0a467e2c02fe4287c2d4eff86c9eb6beff0c.tar.gz linux-stable-a29a0a467e2c02fe4287c2d4eff86c9eb6beff0c.tar.bz2 linux-stable-a29a0a467e2c02fe4287c2d4eff86c9eb6beff0c.zip |
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 'include')
-rw-r--r-- | include/linux/cred.h | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/include/linux/cred.h b/include/linux/cred.h index 7eb43a038330..f7a30e0099be 100644 --- a/include/linux/cred.h +++ b/include/linux/cred.h @@ -145,7 +145,11 @@ struct cred { struct user_struct *user; /* real user ID subscription */ struct user_namespace *user_ns; /* user_ns the caps and keyrings are relative to. */ struct group_info *group_info; /* supplementary groups for euid/fsgid */ - struct rcu_head rcu; /* RCU deletion hook */ + /* RCU deletion */ + union { + int non_rcu; /* Can we skip RCU deletion? */ + struct rcu_head rcu; /* RCU deletion hook */ + }; } __randomize_layout; extern void __put_cred(struct cred *); @@ -246,6 +250,7 @@ static inline const struct cred *get_cred(const struct cred *cred) if (!cred) return cred; validate_creds(cred); + nonconst_cred->non_rcu = 0; return get_new_cred(nonconst_cred); } @@ -257,6 +262,7 @@ static inline const struct cred *get_cred_rcu(const struct cred *cred) if (!atomic_inc_not_zero(&nonconst_cred->usage)) return NULL; validate_creds(cred); + nonconst_cred->non_rcu = 0; return cred; } |