Date: Thu, 6 Nov 2003 18:50:21 -0800 (PST) From: Tim Robbins <tjr@freebsd.org> To: freebsd-bugs@FreeBSD.org Subject: Re: kern/58984: SYSV Semaphore exhaustion causes Giant deadlock Message-ID: <200311070250.hA72oLcf064096@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/58984; it has been noted by GNATS. From: Tim Robbins <tjr@freebsd.org> To: dwhite@gumbysoft.com Cc: bug-followup@freebsd.org Subject: Re: kern/58984: SYSV Semaphore exhaustion causes Giant deadlock Date: Fri, 7 Nov 2003 13:48:33 +1100 Try this patch: (http://perforce.freebsd.org/chv.cgi?CH=41609) --- sysv_sem.c.old Fri Nov 7 13:46:17 2003 +++ sysv_sem.c Fri Nov 7 13:44:18 2003 @@ -66,7 +66,7 @@ static struct semid_ds *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 */ +LIST_HEAD(, sem_undo) semu_list; /* list of active undo structures */ static int *semu; /* undo structure pool */ static eventhandler_tag semexit_tag; @@ -86,7 +86,7 @@ * Undo structure (one per process) */ struct sem_undo { - SLIST_ENTRY(sem_undo) un_next; /* ptr to next active undo structure */ + LIST_ENTRY(sem_undo) un_list; /* ptr to next active undo structure */ struct proc *un_proc; /* owner of this structure */ short un_cnt; /* # of active entries */ struct undo { @@ -205,7 +205,7 @@ struct sem_undo *suptr = SEMU(i); suptr->un_proc = NULL; } - SLIST_INIT(&semu_list); + LIST_INIT(&semu_list); mtx_init(&sem_mtx, "sem", NULL, MTX_DEF); semexit_tag = EVENTHANDLER_REGISTER(process_exit, semexit_myhook, NULL, EVENTHANDLER_PRI_ANY); @@ -303,8 +303,7 @@ struct thread *td; { int i; - struct sem_undo *suptr; - struct sem_undo **supptr; + struct sem_undo *suptr, *sutmpptr; int attempt; SEMUNDO_LOCKASSERT(MA_OWNED); @@ -323,7 +322,7 @@ for (i = 0; i < seminfo.semmnu; i++) { suptr = SEMU(i); if (suptr->un_proc == NULL) { - SLIST_INSERT_HEAD(&semu_list, suptr, un_next); + LIST_INSERT_HEAD(&semu_list, suptr, un_list); suptr->un_cnt = 0; suptr->un_proc = td->td_proc; return(suptr); @@ -339,12 +338,12 @@ /* All the structures are in use - try to free some */ int did_something = 0; - SLIST_FOREACH_PREVPTR(suptr, supptr, &semu_list, - un_next) { + LIST_FOREACH_SAFE(suptr, &semu_list, un_list, + sutmpptr) { if (suptr->un_cnt == 0) { suptr->un_proc = NULL; did_something = 1; - *supptr = SLIST_NEXT(suptr, un_next); + LIST_REMOVE(suptr, un_list); } } @@ -385,7 +384,7 @@ suptr = *supptr; if (suptr == NULL) { - SLIST_FOREACH(suptr, &semu_list, un_next) { + LIST_FOREACH(suptr, &semu_list, un_list) { if (suptr->un_proc == p) { *supptr = suptr; break; @@ -446,7 +445,7 @@ struct sem_undo *suptr; SEMUNDO_LOCKASSERT(MA_OWNED); - SLIST_FOREACH(suptr, &semu_list, un_next) { + LIST_FOREACH(suptr, &semu_list, un_list) { struct undo *sunptr = &suptr->un_ent[0]; int i = 0; @@ -1148,22 +1147,22 @@ void *arg; struct proc *p; { - struct sem_undo *suptr; - struct sem_undo **supptr; + struct sem_undo *suptr, *sutmpptr; /* * 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) { + LIST_FOREACH_SAFE(suptr, &semu_list, un_list, sutmpptr) { if (suptr->un_proc == p) break; } - SEMUNDO_UNLOCK(); - if (suptr == NULL) + if (suptr == NULL) { + SEMUNDO_UNLOCK(); return; + } DPRINTF(("proc @%08x has undo structure with %d entries\n", p, suptr->un_cnt)); @@ -1184,7 +1183,6 @@ semaptr = &sema[semid]; sema_mtxp = &sema_mtx[semid]; mtx_lock(sema_mtxp); - SEMUNDO_LOCK(); if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0) panic("semexit - semid not allocated"); if (semnum >= semaptr->sem_nsems) @@ -1209,7 +1207,6 @@ wakeup(semaptr); DPRINTF(("semexit: back from wakeup\n")); mtx_unlock(sema_mtxp); - SEMUNDO_UNLOCK(); } } @@ -1218,7 +1215,8 @@ */ DPRINTF(("removing vector\n")); suptr->un_proc = NULL; - *supptr = SLIST_NEXT(suptr, un_next); + LIST_REMOVE(suptr, un_list); + SEMUNDO_UNLOCK(); } static int
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200311070250.hA72oLcf064096>
