HomeFreeBSD

vm pqbatch: move unmanaged page assert under pagequeue lock

Description

vm pqbatch: move unmanaged page assert under pagequeue lock

This KASSERT is overzealous because of the following race condition:

  1. A managed page which is currently in PQ_LAUNDRY is freed. vm_page_free_prep calls vm_page_dequeue_deferred()

    The page state is: PQ_LAUNDRY, PGA_DEQUEUE|PGA_ENQUEUED
  2. The laundry worker comes around and pick up the page and calls vm_pageout_defer(m, PQ_LAUNDRY, true) to check if page is still in the queue. We do a vm_page_astate_load and get PQ_LAUNDRY, PGA_DEQUEUE|PGA_ENQUEUED as per above.
  3. The laundry worker is pre-empted and another thread allocates our page from the free pool. For example vm_page_alloc_domain_after calls vm_page_dequeue() and sets VPO_UNMANAGED because we are allocating for an OBJT_UNMANAGED object.

    The page state is: PQ_NONE, 0 - VPO_UNMANAGED
  4. The laundry worker resumes, and processes vm_pageout_defer based on the stale astate which leads to a call to vm_page_pqbatch_submit, which will trip on the KASSERT.

Submitted by: mlaier
Reviewed by: markj, rlibby
Sponsored by: Dell EMC Isilon
Differential Revision: https://reviews.freebsd.org/D28563

Details

Provenance
mlaierAuthored on Feb 24 2021, 11:56 PM
rlibbyCommitted on Feb 24 2021, 11:56 PM
Reviewer
markj
Differential Revision
D28563: This KASSERT is overzealous because of the following race condition:
Parents
rG9a227a2fd642: Enable PIE by default on 64-bit architectures
Branches
Unknown
Tags
Unknown