vm_reserv: Fix list locking in vm_reserv_reclaim_contig()
The per-domain partpop queue is locked by the combination of the per-domain lock and individual reservation mutexes. vm_reserv_reclaim_contig() scans the queue looking for partially populated reservations that can be reclaimed in order to satisfy the caller's allocation. During the scan, we drop the per-domain lock. At this point, the rvn pointer may be invalidated. Take care to load rvn after re-acquiring the per-domain lock. While here, simplify the condition used to check whether a reservation was dequeued while the per-domain lock was dropped. Reviewed by: alc, kib Reported by: gallatin MFC after: 3 days Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D29203
This commit is contained in:
parent
1645a4ae64
commit
968079f253
@ -1344,8 +1344,8 @@ vm_reserv_reclaim_contig(int domain, u_long npages, vm_paddr_t low,
|
||||
TAILQ_INSERT_AFTER(queue, rv, marker, partpopq);
|
||||
vm_reserv_domain_unlock(domain);
|
||||
vm_reserv_lock(rv);
|
||||
if (!rv->inpartpopq ||
|
||||
TAILQ_NEXT(rv, partpopq) != marker) {
|
||||
if (TAILQ_PREV(marker, vm_reserv_queue, partpopq) !=
|
||||
rv) {
|
||||
vm_reserv_unlock(rv);
|
||||
vm_reserv_domain_lock(domain);
|
||||
rvn = TAILQ_NEXT(marker, partpopq);
|
||||
@ -1363,8 +1363,9 @@ vm_reserv_reclaim_contig(int domain, u_long npages, vm_paddr_t low,
|
||||
vm_reserv_unlock(rv);
|
||||
return (true);
|
||||
}
|
||||
vm_reserv_unlock(rv);
|
||||
vm_reserv_domain_lock(domain);
|
||||
rvn = TAILQ_NEXT(rv, partpopq);
|
||||
vm_reserv_unlock(rv);
|
||||
}
|
||||
vm_reserv_domain_unlock(domain);
|
||||
vm_reserv_domain_scan_unlock(domain);
|
||||
|
Loading…
Reference in New Issue
Block a user