PERFORCE change 107407 for review
Roman Divacky
rdivacky at FreeBSD.org
Sat Oct 7 03:27:10 PDT 2006
http://perforce.freebsd.org/chv.cgi?CH=107407
Change 107407 by rdivacky at rdivacky_witten on 2006/10/07 10:26:15
Make sem_undo's process referenced structures instead of preallocated
from an array. This means that we can have arbitrary number of
sem_undo structures (as memory permits) and we can share these structures.
This is a pre-requisite for CLONE_SYSVSEM.
This is UNTESTED and this commit is only for me to be able to generate diffs
from p4.
Affected files ...
.. //depot/projects/linuxolator/src/sys/kern/kern_fork.c#2 edit
.. //depot/projects/linuxolator/src/sys/kern/sysv_sem.c#3 edit
.. //depot/projects/linuxolator/src/sys/sys/proc.h#2 edit
.. //depot/projects/linuxolator/src/sys/sys/sem.h#2 edit
Differences ...
==== //depot/projects/linuxolator/src/sys/kern/kern_fork.c#2 (text+ko) ====
@@ -418,6 +418,7 @@
p2->p_state = PRS_NEW; /* protect against others */
p2->p_pid = trypid;
AUDIT_ARG(pid, p2->p_pid);
+ p2->p_semundo = NULL;
LIST_INSERT_HEAD(&allproc, p2, p_list);
LIST_INSERT_HEAD(PIDHASH(p2->p_pid), p2, p_hash);
sx_xunlock(&allproc_lock);
==== //depot/projects/linuxolator/src/sys/kern/sysv_sem.c#3 (text+ko) ====
@@ -51,6 +51,7 @@
#include <sys/lock.h>
#include <sys/module.h>
#include <sys/mutex.h>
+#include <sys/refcount.h>
#include <sys/sem.h>
#include <sys/syscall.h>
#include <sys/syscallsubr.h>
@@ -101,8 +102,7 @@
static struct semid_kernel *sema; /* semaphore id pool */
static struct mtx *sema_mtx; /* semaphore id pool mutexes*/
static struct sem *sem; /* semaphore pool */
-SLIST_HEAD(, sem_undo) semu_list; /* list of active undo structures */
-static int *semu; /* undo structure pool */
+SLIST_HEAD(, sem_undo) semu_list; /* list of active undo structures */
static eventhandler_tag semexit_tag;
#define SEMUNDO_MTX sem_mtx
@@ -118,20 +118,6 @@
};
/*
- * Undo structure (one per process)
- */
-struct sem_undo {
- SLIST_ENTRY(sem_undo) un_next; /* ptr to next active undo structure */
- struct proc *un_proc; /* owner of this structure */
- short un_cnt; /* # of active entries */
- struct undo {
- short un_adjval; /* adjust on exit values */
- short un_num; /* semaphore # */
- int un_id; /* semid */
- } un_ent[1]; /* undo entries */
-};
-
-/*
* Configuration parameters
*/
#ifndef SEMMNI
@@ -143,9 +129,6 @@
#ifndef SEMUME
#define SEMUME 10 /* max # of undo entries per process */
#endif
-#ifndef SEMMNU
-#define SEMMNU 30 /* # of undo structures in system */
-#endif
/* shouldn't need tuning */
#ifndef SEMMAP
@@ -184,7 +167,6 @@
SEMMAP, /* # of entries in semaphore map */
SEMMNI, /* # of semaphore identifiers */
SEMMNS, /* # of semaphores in system */
- SEMMNU, /* # of undo structures in system */
SEMMSL, /* max # of semaphores per id */
SEMOPM, /* max # of operations per semop call */
SEMUME, /* max # of undo entries per process */
@@ -199,8 +181,6 @@
"Number of semaphore identifiers");
SYSCTL_INT(_kern_ipc, OID_AUTO, semmns, CTLFLAG_RDTUN, &seminfo.semmns, 0,
"Maximum number of semaphores in the system");
-SYSCTL_INT(_kern_ipc, OID_AUTO, semmnu, CTLFLAG_RDTUN, &seminfo.semmnu, 0,
- "Maximum number of undo structures in the system");
SYSCTL_INT(_kern_ipc, OID_AUTO, semmsl, CTLFLAG_RW, &seminfo.semmsl, 0,
"Max semaphores per id");
SYSCTL_INT(_kern_ipc, OID_AUTO, semopm, CTLFLAG_RDTUN, &seminfo.semopm, 0,
@@ -224,7 +204,6 @@
TUNABLE_INT_FETCH("kern.ipc.semmap", &seminfo.semmap);
TUNABLE_INT_FETCH("kern.ipc.semmni", &seminfo.semmni);
TUNABLE_INT_FETCH("kern.ipc.semmns", &seminfo.semmns);
- TUNABLE_INT_FETCH("kern.ipc.semmnu", &seminfo.semmnu);
TUNABLE_INT_FETCH("kern.ipc.semmsl", &seminfo.semmsl);
TUNABLE_INT_FETCH("kern.ipc.semopm", &seminfo.semopm);
TUNABLE_INT_FETCH("kern.ipc.semume", &seminfo.semume);
@@ -237,7 +216,6 @@
M_WAITOK);
sema_mtx = malloc(sizeof(struct mtx) * seminfo.semmni, M_SEM,
M_WAITOK | M_ZERO);
- semu = malloc(seminfo.semmnu * seminfo.semusz, M_SEM, M_WAITOK);
for (i = 0; i < seminfo.semmni; i++) {
sema[i].u.sem_base = 0;
@@ -249,11 +227,6 @@
}
for (i = 0; i < seminfo.semmni; i++)
mtx_init(&sema_mtx[i], "semid", NULL, MTX_DEF);
- for (i = 0; i < seminfo.semmnu; i++) {
- struct sem_undo *suptr = SEMU(i);
- suptr->un_proc = NULL;
- }
- SLIST_INIT(&semu_list);
mtx_init(&sem_mtx, "sem", NULL, MTX_DEF);
semexit_tag = EVENTHANDLER_REGISTER(process_exit, semexit_myhook, NULL,
EVENTHANDLER_PRI_ANY);
@@ -274,7 +247,6 @@
#endif
free(sem, M_SEM);
free(sema, M_SEM);
- free(semu, M_SEM);
for (i = 0; i < seminfo.semmni; i++)
mtx_destroy(&sema_mtx[i]);
mtx_destroy(&sem_mtx);
@@ -354,66 +326,16 @@
semu_alloc(td)
struct thread *td;
{
- int i;
struct sem_undo *suptr;
- struct sem_undo **supptr;
- int attempt;
- SEMUNDO_LOCKASSERT(MA_OWNED);
- /*
- * Try twice to allocate something.
- * (we'll purge an empty structure after the first pass so
- * two passes are always enough)
- */
+ suptr = malloc(seminfo.semusz, M_SEM, M_WAITOK);
+ refcount_init(&suptr->refcount, 1);
- for (attempt = 0; attempt < 2; attempt++) {
- /*
- * Look for a free structure.
- * Fill it in and return it if we find one.
- */
+ PROC_LOCK(td->td_proc);
+ td->td_proc->p_semundo = suptr;
+ PROC_UNLOCK(td->td_proc);
- for (i = 0; i < seminfo.semmnu; i++) {
- suptr = SEMU(i);
- if (suptr->un_proc == NULL) {
- SLIST_INSERT_HEAD(&semu_list, suptr, un_next);
- suptr->un_cnt = 0;
- suptr->un_proc = td->td_proc;
- return(suptr);
- }
- }
-
- /*
- * We didn't find a free one, if this is the first attempt
- * then try to free a structure.
- */
-
- if (attempt == 0) {
- /* All the structures are in use - try to free one */
- int did_something = 0;
-
- SLIST_FOREACH_PREVPTR(suptr, supptr, &semu_list,
- un_next) {
- if (suptr->un_cnt == 0) {
- suptr->un_proc = NULL;
- did_something = 1;
- *supptr = SLIST_NEXT(suptr, un_next);
- break;
- }
- }
-
- /* If we didn't free anything then just give-up */
- if (!did_something)
- return(NULL);
- } else {
- /*
- * The second pass failed even though we freed
- * something after the first pass!
- * This is IMPOSSIBLE!
- */
- panic("semu_alloc - second attempt failed");
- }
- }
- return (NULL);
+ return (suptr);
}
/*
@@ -427,7 +349,6 @@
int semid, semnum;
int adjval;
{
- struct proc *p = td->td_proc;
struct sem_undo *suptr;
struct undo *sunptr;
int i;
@@ -438,18 +359,12 @@
suptr = *supptr;
if (suptr == NULL) {
- SLIST_FOREACH(suptr, &semu_list, un_next) {
- if (suptr->un_proc == p) {
- *supptr = suptr;
- break;
- }
- }
+ suptr = td->td_proc->p_semundo;
+
if (suptr == NULL) {
if (adjval == 0)
return(0);
suptr = semu_alloc(td);
- if (suptr == NULL)
- return(ENOSPC);
*supptr = suptr;
}
}
@@ -1292,18 +1207,8 @@
struct proc *p;
{
struct sem_undo *suptr;
- struct sem_undo **supptr;
- /*
- * Go through the chain of undo vectors looking for one
- * associated with this process.
- */
- SEMUNDO_LOCK();
- SLIST_FOREACH_PREVPTR(suptr, supptr, &semu_list, un_next) {
- if (suptr->un_proc == p)
- break;
- }
- SEMUNDO_UNLOCK();
+ suptr = p->p_semundo;
if (suptr == NULL)
return;
@@ -1335,7 +1240,7 @@
DPRINTF((
"semexit: %p id=%d num=%d(adj=%d) ; sem=%d\n",
- suptr->un_proc, suptr->un_ent[ix].un_id,
+ td->td_proc, suptr->un_ent[ix].un_id,
suptr->un_ent[ix].un_num,
suptr->un_ent[ix].un_adjval,
semakptr->u.sem_base[semnum].semval));
@@ -1361,8 +1266,13 @@
* Deallocate the undo vector.
*/
DPRINTF(("removing vector\n"));
- suptr->un_proc = NULL;
- *supptr = SLIST_NEXT(suptr, un_next);
+ refcount_release(&p->p_semundo->refcount);
+ if (p->p_semundo->refcount == 0)
+ free(p->p_semundo, M_SEM);
+ refcount_acquire(&p->p_semundo->refcount);
+ PROC_LOCK(p);
+ p->p_semundo = SLIST_NEXT(suptr, un_next);
+ PROC_UNLOCK(p);
}
static int
==== //depot/projects/linuxolator/src/sys/sys/proc.h#2 (text+ko) ====
@@ -49,6 +49,7 @@
#include <sys/priority.h>
#include <sys/rtprio.h> /* XXX. */
#include <sys/runq.h>
+#include <sys/sem.h>
#include <sys/sigio.h>
#include <sys/signal.h>
#include <sys/signalvar.h>
@@ -622,6 +623,7 @@
STAILQ_HEAD(, ktr_request) p_ktr; /* (o) KTR event queue. */
LIST_HEAD(, mqueue_notifier) p_mqnotifier; /* (c) mqueue notifiers.*/
struct auditinfo *p_au; /* (c) Process audit properties. */
+ struct sem_undo *p_semundo; /* (c) Process sysv semundo struct. */
};
#define p_session p_pgrp->pg_session
==== //depot/projects/linuxolator/src/sys/sys/sem.h#2 (text+ko) ====
@@ -74,7 +74,6 @@
int semmap, /* # of entries in semaphore map */
semmni, /* # of semaphore identifiers */
semmns, /* # of semaphores in system */
- semmnu, /* # of undo structures in system */
semmsl, /* max # of semaphores per id */
semopm, /* max # of operations per semop call */
semume, /* max # of undo entries per process */
@@ -100,6 +99,21 @@
* Process sem_undo vectors at proc exit.
*/
void semexit(struct proc *p);
+
+/*
+ * Undo structure (one per process)
+ */
+struct sem_undo {
+ SLIST_ENTRY(sem_undo) un_next; /* ptr to next active undo structure */
+ short un_cnt; /* # of active entries */
+ u_int refcount; /* reference counting */
+ struct undo {
+ short un_adjval; /* adjust on exit values */
+ short un_num; /* semaphore # */
+ int un_id; /* semid */
+ } un_ent[1]; /* undo entries */
+};
+
#endif /* _KERNEL */
#ifndef _KERNEL
@@ -122,6 +136,7 @@
int semget(key_t, int, int);
int semop(int, struct sembuf *, size_t);
__END_DECLS
+
#endif /* !_KERNEL */
#endif /* !_SYS_SEM_H_ */
More information about the p4-projects
mailing list