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:
parent
9422d61a1f
commit
541c3b66b5
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=122390
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user