summaryrefslogtreecommitdiffstats
path: root/sys/kern/sysv_sem.c
diff options
context:
space:
mode:
authortjr <tjr@FreeBSD.org>2003-11-10 07:22:41 +0000
committertjr <tjr@FreeBSD.org>2003-11-10 07:22:41 +0000
commit3fb83070b6fcc3fabeb295c2d502f70adba9573e (patch)
tree4cdf6b9d8d468aa257f8486e7c4620bcc0ea1697 /sys/kern/sysv_sem.c
parent2322554b505db97ea0be0318e61ed0a8d71c0add (diff)
downloadFreeBSD-src-3fb83070b6fcc3fabeb295c2d502f70adba9573e.zip
FreeBSD-src-3fb83070b6fcc3fabeb295c2d502f70adba9573e.tar.gz
When there are no free sem_undo structs available in semu_alloc(), only
free one sem_undo with un_cnt == 0 instead of all of them. This is a temporary workaround until the SLIST_FOREACH_PREVPTR loop gets fixed so that it doesn't cause cycles in semu_list when removing multiple adjacent items. It might be easier to just use (doubly-linked) LISTs here instead of complicated SLIST code to achieve O(1) removals. This bug manifested itself as a complete lockup under heavy semaphore use by multiple processes with the SEM_UNDO flag set. PR: 58984
Diffstat (limited to 'sys/kern/sysv_sem.c')
-rw-r--r--sys/kern/sysv_sem.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/sys/kern/sysv_sem.c b/sys/kern/sysv_sem.c
index 9fbbf8c..0887828 100644
--- a/sys/kern/sysv_sem.c
+++ b/sys/kern/sysv_sem.c
@@ -310,7 +310,7 @@ semu_alloc(td)
SEMUNDO_LOCKASSERT(MA_OWNED);
/*
* Try twice to allocate something.
- * (we'll purge any empty structures after the first pass so
+ * (we'll purge an empty structure after the first pass so
* two passes are always enough)
*/
@@ -332,11 +332,11 @@ semu_alloc(td)
/*
* We didn't find a free one, if this is the first attempt
- * then try to free some structures.
+ * then try to free a structure.
*/
if (attempt == 0) {
- /* All the structures are in use - try to free some */
+ /* All the structures are in use - try to free one */
int did_something = 0;
SLIST_FOREACH_PREVPTR(suptr, supptr, &semu_list,
@@ -345,6 +345,7 @@ semu_alloc(td)
suptr->un_proc = NULL;
did_something = 1;
*supptr = SLIST_NEXT(suptr, un_next);
+ break;
}
}
OpenPOWER on IntegriCloud