1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-02-01 17:00:36 +00:00

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
This commit is contained in:
Tim J. Robbins 2003-11-10 07:22:41 +00:00
parent 9422d61a1f
commit 541c3b66b5
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=122390

View File

@ -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;
}
}