Fix a race in vm_page_pagequeue_lockptr().
The value of m->queue must be cached after comparing it with PQ_NONE, since it may be concurrently changing. Reported by: glebius Reviewed by: jeff Differential Revision: https://reviews.freebsd.org/D15462
This commit is contained in:
parent
8d72b7a607
commit
870582131d
@ -3088,10 +3088,11 @@ vm_page_pagequeue(vm_page_t m)
|
||||
static struct mtx *
|
||||
vm_page_pagequeue_lockptr(vm_page_t m)
|
||||
{
|
||||
uint8_t queue;
|
||||
|
||||
if (m->queue == PQ_NONE)
|
||||
if ((queue = m->queue) == PQ_NONE)
|
||||
return (NULL);
|
||||
return (&vm_page_pagequeue(m)->pq_mutex);
|
||||
return (&vm_pagequeue_domain(m)->vmd_pagequeues[queue].pq_mutex);
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
@ -208,7 +208,7 @@ struct vm_page {
|
||||
uint16_t flags; /* page PG_* flags (P) */
|
||||
uint8_t aflags; /* access is atomic */
|
||||
uint8_t oflags; /* page VPO_* flags (O) */
|
||||
uint8_t queue; /* page queue index (Q) */
|
||||
volatile uint8_t queue; /* page queue index (Q) */
|
||||
int8_t psind; /* pagesizes[] index (O) */
|
||||
int8_t segind; /* vm_phys segment index (C) */
|
||||
uint8_t order; /* index of the buddy queue (F) */
|
||||
|
Loading…
x
Reference in New Issue
Block a user