From owner-p4-projects@FreeBSD.ORG Sat Oct 7 10:27:10 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 8DDF116A412; Sat, 7 Oct 2006 10:27:10 +0000 (UTC) X-Original-To: perforce@FreeBSD.org Delivered-To: perforce@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 4D33816A403 for ; Sat, 7 Oct 2006 10:27:10 +0000 (UTC) (envelope-from rdivacky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id BE71943D67 for ; Sat, 7 Oct 2006 10:27:02 +0000 (GMT) (envelope-from rdivacky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k97AR210058690 for ; Sat, 7 Oct 2006 10:27:02 GMT (envelope-from rdivacky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k97AR2vt058686 for perforce@freebsd.org; Sat, 7 Oct 2006 10:27:02 GMT (envelope-from rdivacky@FreeBSD.org) Date: Sat, 7 Oct 2006 10:27:02 GMT Message-Id: <200610071027.k97AR2vt058686@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to rdivacky@FreeBSD.org using -f From: Roman Divacky To: Perforce Change Reviews Cc: Subject: PERFORCE change 107407 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 07 Oct 2006 10:27:10 -0000 http://perforce.freebsd.org/chv.cgi?CH=107407 Change 107407 by rdivacky@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 #include #include +#include #include #include #include @@ -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 #include /* XXX. */ #include +#include #include #include #include @@ -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_ */