Date: Sat, 25 Nov 2000 04:17:47 -0800 From: Alfred Perlstein <bright@wintelcom.net> To: smp@freebsd.org Subject: uidinfo patches, review please. Message-ID: <20001125041747.I8051@fw.wintelcom.net>
next in thread | raw e-mail | index | archive | help
Protect the uidinfo structures. My only concern is that I must now include sys/mutex.h in sys/resourcevar.h, I didn't notice any userland utils using this file, I'm going to try to do a buildworld. A kernel with this patch boots and seems to run multiuser fine. Index: kern/kern_resource.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_resource.c,v retrieving revision 1.65 diff -u -r1.65 kern_resource.c --- kern/kern_resource.c 2000/11/22 07:41:58 1.65 +++ kern/kern_resource.c 2000/11/25 12:16:02 @@ -64,6 +64,7 @@ static MALLOC_DEFINE(M_UIDINFO, "uidinfo", "uidinfo structures"); #define UIHASH(uid) (&uihashtbl[(uid) & uihash]) +static struct mtx uidhash_mtx; static LIST_HEAD(uihashhead, uidinfo) *uihashtbl; static u_long uihash; /* size of hash table - 1 */ @@ -663,9 +664,15 @@ void uihashinit() { + uihashtbl = hashinit(maxproc / 16, M_UIDINFO, &uihash); + mtx_init(&uidhash_mtx, "uidinfo hash", MTX_DEF); } +/* + * lookup a uidinfo struct for the parameter uid. + * uidhash_mtx must be locked. + */ static struct uidinfo * uilookup(uid) uid_t uid; @@ -673,6 +680,7 @@ struct uihashhead *uipp; struct uidinfo *uip; + mtx_assert(&uidhash_mtx, MA_OWNED); uipp = UIHASH(uid); LIST_FOREACH(uip, uipp, ui_hash) if (uip->ui_uid == uid) @@ -681,43 +689,42 @@ return (uip); } +/* + * Create a uidinfo struct for the parameter uid. + * uidhash_mtx must be locked. + */ static struct uidinfo * uicreate(uid) uid_t uid; { - struct uidinfo *uip, *norace; + struct uidinfo *uip; - MALLOC(uip, struct uidinfo *, sizeof(*uip), M_UIDINFO, M_NOWAIT); - if (uip == NULL) { - MALLOC(uip, struct uidinfo *, sizeof(*uip), M_UIDINFO, M_WAITOK); - /* - * if we M_WAITOK we must look afterwards or risk - * redundant entries - */ - norace = uilookup(uid); - if (norace != NULL) { - FREE(uip, M_UIDINFO); - return (norace); - } - } + mtx_assert(&uidhash_mtx, MA_OWNED); + MALLOC(uip, struct uidinfo *, sizeof(*uip), M_UIDINFO, M_WAITOK); LIST_INSERT_HEAD(UIHASH(uid), uip, ui_hash); uip->ui_uid = uid; uip->ui_proccnt = 0; uip->ui_sbsize = 0; uip->ui_ref = 0; + mtx_init(&uip->ui_mtx, "uidinfo struct", MTX_DEF); return (uip); } +/* + * find or allocate a struct uidinfo for a particular uid + */ struct uidinfo * uifind(uid) uid_t uid; { struct uidinfo *uip; + mtx_enter(&uidhash_mtx, MTX_DEF); uip = uilookup(uid); if (uip == NULL) uip = uicreate(uid); - uip->ui_ref++; + uihold(uip); + mtx_exit(&uidhash_mtx, MTX_DEF); return (uip); } @@ -726,6 +733,8 @@ struct uidinfo *uip; { + mtx_enter(&uidhash_mtx, MTX_DEF); + mtx_enter(&uip->ui_mtx, MTX_DEF); if (--uip->ui_ref == 0) { if (uip->ui_sbsize != 0) /* XXX no %qd in kernel. Truncate. */ @@ -735,9 +744,13 @@ printf("freeing uidinfo: uid = %d, proccnt = %ld\n", uip->ui_uid, uip->ui_proccnt); LIST_REMOVE(uip, ui_hash); + mtx_destroy(&uip->ui_mtx); + mtx_exit(&uidhash_mtx, MTX_DEF); FREE(uip, M_UIDINFO); return (1); } + mtx_exit(&uip->ui_mtx, MTX_DEF); + mtx_exit(&uidhash_mtx, MTX_DEF); return (0); } @@ -751,12 +764,17 @@ int diff; int max; { + + mtx_enter(&uip->ui_mtx, MTX_DEF); /* don't allow them to exceed max, but allow subtraction */ - if (diff > 0 && uip->ui_proccnt + diff > max && max != 0) + if (diff > 0 && uip->ui_proccnt + diff > max && max != 0) { + mtx_exit(&uip->ui_mtx, MTX_DEF); return (0); + } uip->ui_proccnt += diff; if (uip->ui_proccnt < 0) printf("negative proccnt for uid = %d\n", uip->ui_uid); + mtx_exit(&uip->ui_mtx, MTX_DEF); return (1); } @@ -773,11 +791,14 @@ rlim_t new; int s; + mtx_enter(&uip->ui_mtx, MTX_DEF); + s = splnet(); new = uip->ui_sbsize + to - *hiwat; /* don't allow them to exceed max, but allow subtraction */ if (to > *hiwat && new > max) { splx(s); + mtx_exit(&uip->ui_mtx, MTX_DEF); return (0); } uip->ui_sbsize = new; @@ -785,5 +806,6 @@ if (uip->ui_sbsize < 0) printf("negative sbsize for uid = %d\n", uip->ui_uid); splx(s); + mtx_exit(&uip->ui_mtx, MTX_DEF); return (1); } Index: sys/resourcevar.h =================================================================== RCS file: /home/ncvs/src/sys/sys/resourcevar.h,v retrieving revision 1.17 diff -u -r1.17 resourcevar.h --- sys/resourcevar.h 2000/09/05 22:11:12 1.17 +++ sys/resourcevar.h 2000/11/25 12:16:03 @@ -40,6 +40,9 @@ #include <sys/resource.h> #include <sys/queue.h> +#include <sys/mutex.h> /* XXX */ + + /* * Kernel per-process accounting / statistics * (not necessarily resident except when running). @@ -90,10 +93,17 @@ long ui_proccnt; /* number of processes */ uid_t ui_uid; /* uid */ u_short ui_ref; /* reference count */ + struct mtx ui_mtx; /* protect counts */ }; #ifdef _KERNEL -#define uihold(uip) (uip)->ui_ref++ +#define uihold(uip) \ + do { \ + mtx_enter(&(uip)->ui_mtx, MTX_DEF); \ + (uip)->ui_ref++; \ + mtx_exit(&(uip)->ui_mtx, MTX_DEF); \ + } while(0) + struct proc; void addupc_intr __P((struct proc *p, u_long pc, u_int ticks)); -- -Alfred Perlstein - [bright@wintelcom.net|alfred@freebsd.org] "I have the heart of a child; I keep it in a jar on my desk." To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-smp" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20001125041747.I8051>