thread: batch credential freeing
This commit is contained in:
parent
fb8ab68084
commit
f34a2f56c3
@ -86,6 +86,7 @@ static MALLOC_DEFINE(M_CRED, "cred", "credentials");
|
||||
SYSCTL_NODE(_security, OID_AUTO, bsd, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
|
||||
"BSD security policy");
|
||||
|
||||
static void crfree_final(struct ucred *cr);
|
||||
static void crsetgroups_locked(struct ucred *cr, int ngrp,
|
||||
gid_t *groups);
|
||||
|
||||
@ -1902,6 +1903,31 @@ crunuse(struct thread *td)
|
||||
return (crold);
|
||||
}
|
||||
|
||||
static void
|
||||
crunusebatch(struct ucred *cr, int users, int ref)
|
||||
{
|
||||
|
||||
KASSERT(users > 0, ("%s: passed users %d not > 0 ; cred %p",
|
||||
__func__, users, cr));
|
||||
mtx_lock(&cr->cr_mtx);
|
||||
KASSERT(cr->cr_users >= users, ("%s: users %d not > %d on cred %p",
|
||||
__func__, cr->cr_users, users, cr));
|
||||
cr->cr_users -= users;
|
||||
cr->cr_ref += ref;
|
||||
cr->cr_ref -= users;
|
||||
if (cr->cr_users > 0) {
|
||||
mtx_unlock(&cr->cr_mtx);
|
||||
return;
|
||||
}
|
||||
KASSERT(cr->cr_ref >= 0, ("%s: ref %d not >= 0 on cred %p",
|
||||
__func__, cr->cr_ref, cr));
|
||||
if (cr->cr_ref > 0) {
|
||||
mtx_unlock(&cr->cr_mtx);
|
||||
return;
|
||||
}
|
||||
crfree_final(cr);
|
||||
}
|
||||
|
||||
void
|
||||
crcowfree(struct thread *td)
|
||||
{
|
||||
@ -1934,6 +1960,44 @@ crcowsync(void)
|
||||
return (crold);
|
||||
}
|
||||
|
||||
/*
|
||||
* Batching.
|
||||
*/
|
||||
void
|
||||
credbatch_add(struct credbatch *crb, struct thread *td)
|
||||
{
|
||||
struct ucred *cr;
|
||||
|
||||
MPASS(td->td_realucred != NULL);
|
||||
MPASS(td->td_realucred == td->td_ucred);
|
||||
MPASS(td->td_state == TDS_INACTIVE);
|
||||
cr = td->td_realucred;
|
||||
KASSERT(cr->cr_users > 0, ("%s: users %d not > 0 on cred %p",
|
||||
__func__, cr->cr_users, cr));
|
||||
if (crb->cred != cr) {
|
||||
if (crb->users > 0) {
|
||||
MPASS(crb->cred != NULL);
|
||||
crunusebatch(crb->cred, crb->users, crb->ref);
|
||||
crb->users = 0;
|
||||
crb->ref = 0;
|
||||
}
|
||||
}
|
||||
crb->cred = cr;
|
||||
crb->users++;
|
||||
crb->ref += td->td_ucredref;
|
||||
td->td_ucredref = 0;
|
||||
td->td_realucred = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
credbatch_final(struct credbatch *crb)
|
||||
{
|
||||
|
||||
MPASS(crb->cred != NULL);
|
||||
MPASS(crb->users > 0);
|
||||
crunusebatch(crb->cred, crb->users, crb->ref);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a zeroed cred structure.
|
||||
*/
|
||||
@ -2007,6 +2071,17 @@ crfree(struct ucred *cr)
|
||||
mtx_unlock(&cr->cr_mtx);
|
||||
return;
|
||||
}
|
||||
crfree_final(cr);
|
||||
}
|
||||
|
||||
static void
|
||||
crfree_final(struct ucred *cr)
|
||||
{
|
||||
|
||||
KASSERT(cr->cr_users == 0, ("%s: users %d not == 0 on cred %p",
|
||||
__func__, cr->cr_users, cr));
|
||||
KASSERT(cr->cr_ref == 0, ("%s: ref %d not == 0 on cred %p",
|
||||
__func__, cr->cr_ref, cr));
|
||||
/*
|
||||
* Some callers of crget(), such as nfs_statfs(), allocate a temporary
|
||||
* credential, but don't allocate a uidinfo structure.
|
||||
|
@ -536,6 +536,7 @@ thread_reap(void)
|
||||
{
|
||||
struct thread *itd, *ntd;
|
||||
struct tidbatch tidbatch;
|
||||
struct credbatch credbatch;
|
||||
int tdcount;
|
||||
struct plimit *lim;
|
||||
int limcount;
|
||||
@ -553,6 +554,7 @@ thread_reap(void)
|
||||
return;
|
||||
|
||||
tidbatch_prep(&tidbatch);
|
||||
credbatch_prep(&credbatch);
|
||||
tdcount = 0;
|
||||
lim = NULL;
|
||||
limcount = 0;
|
||||
@ -560,8 +562,7 @@ thread_reap(void)
|
||||
ntd = itd->td_zombie;
|
||||
EVENTHANDLER_DIRECT_INVOKE(thread_dtor, itd);
|
||||
tidbatch_add(&tidbatch, itd);
|
||||
MPASS(itd->td_realucred != NULL);
|
||||
crcowfree(itd);
|
||||
credbatch_add(&credbatch, itd);
|
||||
MPASS(itd->td_limit != NULL);
|
||||
if (lim != itd->td_limit) {
|
||||
if (limcount != 0) {
|
||||
@ -573,6 +574,7 @@ thread_reap(void)
|
||||
limcount++;
|
||||
thread_free_batched(itd);
|
||||
tidbatch_process(&tidbatch);
|
||||
credbatch_process(&credbatch);
|
||||
tdcount++;
|
||||
if (tdcount == 32) {
|
||||
thread_count_sub(tdcount);
|
||||
@ -582,6 +584,7 @@ thread_reap(void)
|
||||
}
|
||||
|
||||
tidbatch_final(&tidbatch);
|
||||
credbatch_final(&credbatch);
|
||||
if (tdcount != 0) {
|
||||
thread_count_sub(tdcount);
|
||||
}
|
||||
|
@ -114,6 +114,28 @@ struct xucred {
|
||||
struct proc;
|
||||
struct thread;
|
||||
|
||||
struct credbatch {
|
||||
struct ucred *cred;
|
||||
int users;
|
||||
int ref;
|
||||
};
|
||||
|
||||
static inline void
|
||||
credbatch_prep(struct credbatch *crb)
|
||||
{
|
||||
crb->cred = NULL;
|
||||
crb->users = 0;
|
||||
crb->ref = 0;
|
||||
}
|
||||
void credbatch_add(struct credbatch *crb, struct thread *td);
|
||||
static inline void
|
||||
credbatch_process(struct credbatch *crb)
|
||||
{
|
||||
|
||||
}
|
||||
void credbatch_add(struct credbatch *crb, struct thread *td);
|
||||
void credbatch_final(struct credbatch *crb);
|
||||
|
||||
void change_egid(struct ucred *newcred, gid_t egid);
|
||||
void change_euid(struct ucred *newcred, struct uidinfo *euip);
|
||||
void change_rgid(struct ucred *newcred, gid_t rgid);
|
||||
|
Loading…
Reference in New Issue
Block a user