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:
Mark Johnston 2018-05-17 04:27:08 +00:00
parent b35822d9d0
commit ba2b3349e1
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=333703
2 changed files with 4 additions and 3 deletions

View File

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

View File

@ -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) */