mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 04:33:26 +02:00
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
This commit is contained in:
@@ -144,7 +144,10 @@ void __put_cred(struct cred *cred)
|
||||
BUG_ON(cred == current->cred);
|
||||
BUG_ON(cred == current->real_cred);
|
||||
|
||||
call_rcu(&cred->rcu, put_cred_rcu);
|
||||
if (cred->non_rcu)
|
||||
put_cred_rcu(&cred->rcu);
|
||||
else
|
||||
call_rcu(&cred->rcu, put_cred_rcu);
|
||||
}
|
||||
EXPORT_SYMBOL(__put_cred);
|
||||
|
||||
@@ -261,6 +264,7 @@ struct cred *prepare_creds(void)
|
||||
old = task->cred;
|
||||
memcpy(new, old, sizeof(struct cred));
|
||||
|
||||
new->non_rcu = 0;
|
||||
atomic_set(&new->usage, 1);
|
||||
set_cred_subscribers(new, 0);
|
||||
get_group_info(new->group_info);
|
||||
@@ -544,7 +548,19 @@ const struct cred *override_creds(const struct cred *new)
|
||||
|
||||
validate_creds(old);
|
||||
validate_creds(new);
|
||||
get_cred(new);
|
||||
|
||||
/*
|
||||
* NOTE! This uses 'get_new_cred()' rather than 'get_cred()'.
|
||||
*
|
||||
* That means that we do not clear the 'non_rcu' flag, since
|
||||
* we are only installing the cred into the thread-synchronous
|
||||
* '->cred' pointer, not the '->real_cred' pointer that is
|
||||
* visible to other threads under RCU.
|
||||
*
|
||||
* Also note that we did validate_creds() manually, not depending
|
||||
* on the validation in 'get_cred()'.
|
||||
*/
|
||||
get_new_cred((struct cred *)new);
|
||||
alter_cred_subscribers(new, 1);
|
||||
rcu_assign_pointer(current->cred, new);
|
||||
alter_cred_subscribers(old, -1);
|
||||
@@ -681,6 +697,7 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon)
|
||||
validate_creds(old);
|
||||
|
||||
*new = *old;
|
||||
new->non_rcu = 0;
|
||||
atomic_set(&new->usage, 1);
|
||||
set_cred_subscribers(new, 0);
|
||||
get_uid(new->user);
|
||||
|
Reference in New Issue
Block a user