PERFORCE change 114932 for review

Alexander Leidinger netchild at FreeBSD.org
Fri Feb 23 23:44:45 UTC 2007


http://perforce.freebsd.org/chv.cgi?CH=114932

Change 114932 by netchild at netchild_magellan on 2007/02/23 23:43:57

	Backout the sysv sem stuff. It never worked. This makes it more
	easy to provide diffs from p4 (no nedd to handedit the diff
	anymore).
	Discussed with:	rdivacky

Affected files ...

.. //depot/projects/linuxolator/src/sys/kern/kern_fork.c#11 edit
.. //depot/projects/linuxolator/src/sys/kern/sysv_sem.c#7 edit
.. //depot/projects/linuxolator/src/sys/sys/proc.h#12 edit
.. //depot/projects/linuxolator/src/sys/sys/sem.h#5 edit

Differences ...

==== //depot/projects/linuxolator/src/sys/kern/kern_fork.c#11 (text+ko) ====

@@ -421,7 +421,6 @@
 	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#7 (text+ko) ====

@@ -51,7 +51,6 @@
 #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>
@@ -103,7 +102,8 @@
 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 */
+SLIST_HEAD(, sem_undo) semu_list;	/* list of active undo structures */
+static int	*semu;		/* undo structure pool */
 static eventhandler_tag semexit_tag;
 
 #define SEMUNDO_MTX		sem_mtx
@@ -119,6 +119,20 @@
 };
 
 /*
+ * 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
@@ -130,6 +144,9 @@
 #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
@@ -168,6 +185,7 @@
                 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 */
@@ -182,6 +200,8 @@
     "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,
@@ -205,6 +225,7 @@
 	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);
@@ -217,6 +238,7 @@
 	    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;
@@ -228,6 +250,10 @@
 	}
 	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,
@@ -249,6 +275,7 @@
 #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);
@@ -328,18 +355,66 @@
 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)
+	 */
+
+	for (attempt = 0; attempt < 2; attempt++) {
+		/*
+		 * Look for a free structure.
+		 * Fill it in and return it if we find one.
+		 */
+
+		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);
+			}
+		}
 
-	suptr = malloc(seminfo.semusz, M_SEM, M_WAITOK);
-	refcount_init(&suptr->refcount, 1);
+		/*
+		 * We didn't find a free one, if this is the first attempt
+		 * then try to free a structure.
+		 */
 
-	SLIST_INSERT_HEAD(&semu_list, suptr, un_next);
+		if (attempt == 0) {
+			/* All the structures are in use - try to free one */
+			int did_something = 0;
 
-	PROC_LOCK(td->td_proc);
-	td->td_proc->p_semundo = suptr;
-	PROC_UNLOCK(td->td_proc);
+			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;
+				}
+			}
 
-	return (suptr);
+			/* 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);
 }
 
 /*
@@ -353,6 +428,7 @@
 	int semid, semnum;
 	int adjval;
 {
+	struct proc *p = td->td_proc;
 	struct sem_undo *suptr;
 	struct undo *sunptr;
 	int i;
@@ -363,12 +439,18 @@
 
 	suptr = *supptr;
 	if (suptr == NULL) {
-	   	suptr = td->td_proc->p_semundo;
-
+		SLIST_FOREACH(suptr, &semu_list, un_next) {
+			if (suptr->un_proc == p) {
+				*supptr = suptr;
+				break;
+			}
+		}
 		if (suptr == NULL) {
 			if (adjval == 0)
 				return(0);
 			suptr = semu_alloc(td);
+			if (suptr == NULL)
+				return(ENOSPC);
 			*supptr = suptr;
 		}
 	}
@@ -1211,8 +1293,18 @@
 	struct proc *p;
 {
 	struct sem_undo *suptr;
+	struct sem_undo **supptr;
 
-	suptr = p->p_semundo;
+	/*
+	 * 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();
 
 	if (suptr == NULL)
 		return;
@@ -1244,7 +1336,7 @@
 
 			DPRINTF((
 			    "semexit:  %p id=%d num=%d(adj=%d) ; sem=%d\n",
-			    td->td_proc, suptr->un_ent[ix].un_id,
+			    suptr->un_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));
@@ -1270,13 +1362,8 @@
 	 * Deallocate the undo vector.
 	 */
 	DPRINTF(("removing vector\n"));
-	refcount_release(&p->p_semundo->refcount);
-	if (p->p_semundo->refcount == 0)
-   	   	free(p->p_semundo, M_SEM);
-	PROC_LOCK(p);
-	p->p_semundo = SLIST_NEXT(suptr, un_next);
-	PROC_UNLOCK(p);
-	refcount_acquire(&p->p_semundo->refcount);
+	suptr->un_proc = NULL;
+	*supptr = SLIST_NEXT(suptr, un_next);
 }
 
 static int

==== //depot/projects/linuxolator/src/sys/sys/proc.h#12 (text+ko) ====

@@ -49,7 +49,6 @@
 #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>
@@ -574,7 +573,6 @@
 	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#5 (text+ko) ====

@@ -87,6 +87,7 @@
 	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 */
@@ -113,20 +114,6 @@
  */
 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 */
-};
-
 #else /* ! _KERNEL */
 
 __BEGIN_DECLS


More information about the p4-projects mailing list