tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Deferred freeing of kauth_cred_ts
Hi,
See diff attached...
(I'm running it locally plus the socket credentials changes.)
Thanks,
-e.
Index: kern/kern_auth.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_auth.c,v
retrieving revision 1.64
diff -u -p -r1.64 kern_auth.c
--- kern/kern_auth.c 3 Sep 2009 04:45:27 -0000 1.64
+++ kern/kern_auth.c 25 Dec 2009 04:58:00 -0000
@@ -69,6 +69,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_auth.c,
#include <sys/atomic.h>
#include <sys/specificdata.h>
#include <sys/vnode.h>
+#include <sys/kthread.h>
/*
* Secmodel-specific credentials.
@@ -106,6 +107,7 @@ struct kauth_cred {
u_int cr_ngroups; /* number of groups */
gid_t cr_groups[NGROUPS]; /* group memberships */
specificdata_reference cr_sd; /* specific data */
+ SLIST_ENTRY(kauth_cred) cr_list;/* deferred free */
};
/*
@@ -149,6 +151,10 @@ static unsigned int nsecmodels = 0;
static specificdata_domain_t kauth_domain;
static pool_cache_t kauth_cred_cache;
+
+static SLIST_HEAD(,kauth_cred) kauth_thread_discard;
+static lwp_t *kauth_thread_lwp;
+
krwlock_t kauth_lock;
/* Allocate new, empty kauth credentials. */
@@ -184,6 +190,15 @@ kauth_cred_hold(kauth_cred_t cred)
atomic_inc_uint(&cred->cr_refcnt);
}
+static void
+kauth_cred_free_now(kauth_cred_t cred)
+{
+
+ kauth_cred_hook(cred, KAUTH_CRED_FREE, NULL, NULL);
+ specificdata_fini(kauth_domain, &cred->cr_sd);
+ pool_cache_put(kauth_cred_cache, cred);
+}
+
/* Decrease reference count to cred. If reached zero, free it. */
void
kauth_cred_free(kauth_cred_t cred)
@@ -196,9 +211,7 @@ kauth_cred_free(kauth_cred_t cred)
if (atomic_dec_uint_nv(&cred->cr_refcnt) > 0)
return;
- kauth_cred_hook(cred, KAUTH_CRED_FREE, NULL, NULL);
- specificdata_fini(kauth_domain, &cred->cr_sd);
- pool_cache_put(kauth_cred_cache, cred);
+ SLIST_INSERT_HEAD(&kauth_thread_discard, cred, cr_list);
}
static void
@@ -786,6 +799,25 @@ kauth_register_scope(const char *id, kau
return (scope);
}
+static void
+kauth_thread(void *cookie)
+{
+ kauth_cred_t cred;
+ extern int hz;
+
+ KASSERT(curlwp == kauth_thread_lwp);
+
+ for (;;) {
+ while (!SLIST_EMPTY(&kauth_thread_discard)) {
+ cred = SLIST_FIRST(&kauth_thread_discard);
+ SLIST_REMOVE_HEAD(&kauth_thread_discard, cr_list);
+ kauth_cred_free_now(cred);
+ }
+
+ kpause("kauthgc", false, mstohz(1000), NULL);
+ }
+}
+
/*
* Initialize the kernel authorization subsystem.
*
@@ -839,6 +871,18 @@ kauth_init(void)
NULL, NULL);
}
+
+void
+kauth_start_gc_thread(void)
+{
+ int error;
+
+ error = kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL, kauth_thread,
+ NULL, &kauth_thread_lwp, "kauthgc");
+ if (error)
+ panic("kauth_start_gc_thread: can't create gc thread: error
%d", error);
+}
+
/*
* Deregister a scope.
* Requires scope list lock to be held by the caller.
Index: kern/init_main.c
===================================================================
RCS file: /cvsroot/src/sys/kern/init_main.c,v
retrieving revision 1.413
diff -u -p -r1.413 init_main.c
--- kern/init_main.c 23 Dec 2009 00:21:38 -0000 1.413
+++ kern/init_main.c 25 Dec 2009 04:58:03 -0000
@@ -678,6 +678,9 @@ main(void)
uvm_aiodone_worker, NULL, PRI_VM, IPL_NONE, WQ_MPSAFE))
panic("fork aiodoned");
+ /* Start the kauth(9) garbage collector. */
+ kauth_start_gc_thread();
+
vmem_rehash_start();
/* Initialize exec structures */
Index: sys/kauth.h
===================================================================
RCS file: /cvsroot/src/sys/sys/kauth.h,v
retrieving revision 1.64
diff -u -p -r1.64 kauth.h
--- sys/kauth.h 24 Dec 2009 19:02:07 -0000 1.64
+++ sys/kauth.h 25 Dec 2009 04:58:06 -0000
@@ -341,6 +341,7 @@ enum {
* Prototypes.
*/
void kauth_init(void);
+void kauth_start_gc_thread(void);
kauth_scope_t kauth_register_scope(const char *, kauth_scope_callback_t, void
*);
void kauth_deregister_scope(kauth_scope_t);
kauth_listener_t kauth_listen_scope(const char *, kauth_scope_callback_t, void
*);
Home |
Main Index |
Thread Index |
Old Index