Date: Sun, 11 Jul 2010 16:26:56 GMT From: Gabor Kovesdan <gabor@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 180763 for review Message-ID: <201007111626.o6BGQuXm061552@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@180763?ac=10 Change 180763 by gabor@gabor_aspire on 2010/07/11 16:26:06 - Simplify two-level locking. First, I added a lock for the linked list holding the job entries and a lock for each entry to minimize the sleeping on locks but probably the locking overhead is more than the benefit, especially because the operations we do on the list and the entries are quite short. - Add irix_jobs_free() as a counterpart for irix_jobs_alloc() to free up resources. - Whitespace. Affected files ... .. //depot/projects/soc2010/gabor_jobs/irix_jobs/sys/kern/kern_exit.c#3 edit .. //depot/projects/soc2010/gabor_jobs/irix_jobs/sys/kern/kern_jobs.c#3 edit .. //depot/projects/soc2010/gabor_jobs/irix_jobs/sys/sys/_types.h#3 edit .. //depot/projects/soc2010/gabor_jobs/irix_jobs/sys/sys/errno.h#3 edit .. //depot/projects/soc2010/gabor_jobs/irix_jobs/sys/sys/jobs.h#2 edit Differences ... ==== //depot/projects/soc2010/gabor_jobs/irix_jobs/sys/kern/kern_exit.c#3 (text+ko) ==== @@ -772,8 +772,10 @@ /* * Release IRIX jobs resources */ - if (p->p_ucred->cr_jid != (jid_t)0) + if (p->p_ucred->cr_jid != (jid_t)0) { + irix_jobs_free(p, JLIMIT_NUMPROC, 1); irix_jobs_remove_proc(p->p_ucred->cr_jid, p->p_pid); + } /* * Free credentials, arguments, and sigacts. ==== //depot/projects/soc2010/gabor_jobs/irix_jobs/sys/kern/kern_jobs.c#3 (text+ko) ==== @@ -48,25 +48,6 @@ #define JOBLIST_WLOCK rw_wlock(&joblist_lock); #define JOBLIST_WUNLOCK rw_wunlock(&joblist_lock); -/* -#define JOBLIST_RLOCK -#define JOBLIST_RUNLOCK -#define JOBLIST_WLOCK -#define JOBLIST_WUNLOCK -*/ - -/* XXX: fix locking -#define JOB_RLOCK(j) rw_rlock(&j->lock); -#define JOB_RUNLOCK(j) rw_runlock(&j->lock); -#define JOB_WLOCK(j) rw_wlock(&j->lock); -#define JOB_WUNLOCK(j) rw_wunlock(&j->lock); -*/ - -#define JOB_RLOCK(j) -#define JOB_RUNLOCK(j) -#define JOB_WLOCK(j) -#define JOB_WUNLOCK(j) - static struct rwlock joblist_lock; static jid_t min_free_jid = 1; @@ -84,7 +65,6 @@ rlim_t usage[JLIMIT_NLIMITS]; struct procentry_head proclist; struct rlimit limits[JLIMIT_NLIMITS]; -// struct rwlock lock; LIST_ENTRY(jobentry) entries; }; @@ -93,7 +73,7 @@ static struct jobentry *jobentry_alloc(jid_t); static void jobentry_free(struct jobentry *); -static LIST_HEAD(, jobentry) irix_joblist = LIST_HEAD_INITIALIZER(irix_joblist); +static LIST_HEAD(, jobentry) irix_joblist; static MALLOC_DEFINE(M_IRIX_JOBS, "irix_jobs", "IRIX Jobs"); SYSINIT(jobs, SI_SUB_CPU, SI_ORDER_FIRST, jobs_init, NULL); @@ -125,15 +105,12 @@ if (uap->rjid != (jid_t)0) { JOBLIST_RLOCK; LIST_FOREACH(jp, &irix_joblist, entries) { - JOB_RLOCK(jp); if (jp->jid == uap->rjid) { /* jid already in use */ td->td_retval[0] = (jid_t)-1; - JOB_RUNLOCK(jp); JOBLIST_RUNLOCK; return (EBUSY); } - JOB_RUNLOCK(jp); } JOBLIST_RUNLOCK; } else @@ -182,8 +159,7 @@ JOBLIST_WLOCK; LIST_FOREACH_SAFE(jp, &irix_joblist, entries, jtmp) { - if (jp->jid == uap->jid) { - JOB_WLOCK(jp); + if (jp->jid == (jid_t)uap->jid) { LIST_FOREACH_SAFE(pp, &jp->proclist, entries, ptmp) { struct kill_args args; @@ -191,13 +167,11 @@ args.signum = uap->signal; if (kill((struct thread *)0, &args) == -1) { td->td_retval[0] = -1; - JOB_WUNLOCK(jp); JOBLIST_WUNLOCK; return (EPERM); } LIST_REMOVE(pp, entries); } - JOB_WUNLOCK(jp); td->td_retval[0] = 0; LIST_REMOVE(jp, entries); JOBLIST_WUNLOCK; @@ -247,17 +221,14 @@ JOBLIST_RLOCK; LIST_FOREACH(jp, &irix_joblist, entries) { - JOB_RLOCK(jp); if (jp->jid == uap->jid) { /* copy limits to job's entry */ uap->rlp->rlim_cur = jp->limits[uap->resource].rlim_cur; uap->rlp->rlim_max = jp->limits[uap->resource].rlim_max; td->td_retval[0] = 0; - JOB_RUNLOCK(jp); JOBLIST_RUNLOCK; return (0); } - JOB_RUNLOCK(jp); } JOBLIST_RUNLOCK; @@ -283,21 +254,18 @@ return (EFAULT); } - JOBLIST_RLOCK; + JOBLIST_WLOCK; LIST_FOREACH(jp, &irix_joblist, entries) { - JOB_WLOCK(jp); if (jp->jid == uap->jid) { /* get struct rlim from job's entry */ jp->limits[uap->resource].rlim_cur = uap->rlp->rlim_cur; jp->limits[uap->resource].rlim_max = uap->rlp->rlim_max; td->td_retval[0] = 0; - JOB_WUNLOCK(jp); - JOBLIST_RUNLOCK; + JOBLIST_WUNLOCK; return (0); } - JOB_WUNLOCK(jp); } - JOBLIST_RUNLOCK; + JOBLIST_WUNLOCK; /* no such job */ td->td_retval[0] = -1; @@ -314,28 +282,24 @@ /* not in a job */ return (0); - JOBLIST_RLOCK; + JOBLIST_WLOCK; LIST_FOREACH(jp, &irix_joblist, entries) { - JOB_WLOCK(jp); if (jp->jid == jid) { if (jp->limits[resource].rlim_max != RLIM_INFINITY && (jp->usage[resource] + amount > jp->limits[resource].rlim_max)) { /* limit exceeded */ - JOB_WUNLOCK(jp); - JOBLIST_RUNLOCK; + JOBLIST_WUNLOCK; goto exceeded; } else { /* bump counter, allow allocation */ jp->usage[resource] += amount; - JOB_WUNLOCK(jp); - JOBLIST_RUNLOCK; + JOBLIST_WUNLOCK; return (0); } } - JOB_WUNLOCK(jp); } - JOBLIST_RUNLOCK; + JOBLIST_WUNLOCK; return (0); exceeded: @@ -354,7 +318,27 @@ } +void +irix_jobs_free(struct proc *p, int resource, rlim_t amount) +{ + struct jobentry *jp; + jid_t jid; + + if ((jid = p->p_ucred->cr_jid) == 0) + /* not in a job */ + return; + JOBLIST_WLOCK; + LIST_FOREACH(jp, &irix_joblist, entries) { + if (jp->jid == jid) { + jp->usage[resource] -= amount; + JOBLIST_WUNLOCK; + return; + } + } + JOBLIST_WUNLOCK; +} + jid_t getjid_by_pid(pid_t pid) { @@ -364,7 +348,7 @@ // if (p->p_pid == pid) // return (p->p_ucred->cr_jid); // } -// return (0); + return (0); } void @@ -378,14 +362,14 @@ if (jp->jid == jid) { LIST_FOREACH_SAFE(pp, &jp->proclist, entries, ptmp) { if (pp->pid == pid) { - JOB_WLOCK(jp); LIST_REMOVE(pp, entries); free(pp, M_IRIX_JOBS); - JOB_WUNLOCK(jp); } if (LIST_EMPTY(&jp->proclist)) { LIST_REMOVE(jp, entries); + JOBLIST_WUNLOCK; jobentry_free(jp); + return; } } } @@ -401,13 +385,11 @@ JOBLIST_WLOCK; LIST_FOREACH_SAFE(jp, &irix_joblist, entries, jtmp) { - JOB_WLOCK(jp); if (jp->jid == jid) { pp = malloc(sizeof(struct procentry), M_IRIX_JOBS, M_NOWAIT); pp->pid = pid; LIST_INSERT_HEAD(&jp->proclist, pp, entries); } - JOB_WUNLOCK(jp); } JOBLIST_WUNLOCK; } @@ -420,14 +402,6 @@ jp = malloc(sizeof(struct jobentry), M_IRIX_JOBS, M_NOWAIT | M_ZERO); for (int i = 0; i < JLIMIT_NLIMITS; i++) { - char *lockstr; - - lockstr = malloc(29, M_IRIX_JOBS, M_NOWAIT | M_ZERO); - sprintf(lockstr, "jobentry_%lld", jid); -// if (rw_initialized(&jp->lock) == 0) -// rw_init(&jp->lock, lockstr); -// else -// free(lockstr, M_IRIX_JOBS); jp->jid = jid; jp->limits[i].rlim_cur = RLIM_INFINITY; jp->limits[i].rlim_max = RLIM_INFINITY; @@ -442,6 +416,5 @@ jobentry_free(struct jobentry *jp) { -// rw_destroy(&jp->lock); free(jp, M_IRIX_JOBS); } ==== //depot/projects/soc2010/gabor_jobs/irix_jobs/sys/sys/_types.h#3 (text+ko) ==== @@ -45,7 +45,7 @@ typedef __int64_t __id_t; /* can hold a gid_t, pid_t, uid_t or jid_t */ typedef __uint32_t __ino_t; /* inode number */ -typedef __int64_t __jid_t; /* job id (for IRIX jobs) */ +typedef __int64_t __jid_t; /* job id (for IRIX jobs) */ typedef long __key_t; /* IPC key (for Sys V IPC) */ typedef __int32_t __lwpid_t; /* Thread ID (a.k.a. LWP) */ typedef __uint16_t __mode_t; /* permissions */ ==== //depot/projects/soc2010/gabor_jobs/irix_jobs/sys/sys/errno.h#3 (text+ko) ==== @@ -178,7 +178,7 @@ #endif /* _POSIX_SOURCE */ #define ENOJOB 94 /* No such job */ -#define ENOPKG 95 /* Required software not installed */ +#define ENOPKG 95 /* Required software not installed */ #ifndef _POSIX_SOURCE #define ELAST 95 /* Must be equal largest errno */ ==== //depot/projects/soc2010/gabor_jobs/irix_jobs/sys/sys/jobs.h#2 (text+ko) ==== @@ -37,6 +37,7 @@ void irix_jobs_add_proc(jid_t jid, pid_t pid); void irix_jobs_remove_proc(jid_t jid, pid_t pid); int irix_jobs_alloc(struct proc *p, int resource, rlim_t amount); +void irix_jobs_free(struct proc *p, int resource, rlim_t amount); __END_DECLS #endif /* _KERNEL */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201007111626.o6BGQuXm061552>