Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 7 Oct 2006 10:27:02 GMT
From:      Roman Divacky <rdivacky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 107407 for review
Message-ID:  <200610071027.k97AR2vt058686@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <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_ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200610071027.k97AR2vt058686>