Changeset View
Changeset View
Standalone View
Standalone View
sys/vm/vm_page.c
Show First 20 Lines • Show All 3,075 Lines • ▼ Show 20 Lines | vm_pqbatch_process_page(struct vm_pagequeue *pq, vm_page_t m) | ||||
CRITICAL_ASSERT(curthread); | CRITICAL_ASSERT(curthread); | ||||
vm_pagequeue_assert_locked(pq); | vm_pagequeue_assert_locked(pq); | ||||
/* | /* | ||||
* The page daemon is allowed to set m->queue = PQ_NONE without | * The page daemon is allowed to set m->queue = PQ_NONE without | ||||
* the page queue lock held. In this case it is about to free the page, | * the page queue lock held. In this case it is about to free the page, | ||||
* which must not have any queue state. | * which must not have any queue state. | ||||
*/ | */ | ||||
qflags = atomic_load_8(&m->aflags) & PGA_QUEUE_STATE_MASK; | qflags = atomic_load_8(&m->aflags); | ||||
KASSERT(pq == vm_page_pagequeue(m) || qflags == 0, | KASSERT(pq == vm_page_pagequeue(m) || | ||||
("page %p doesn't belong to queue %p but has queue state %#x", | (qflags & PGA_QUEUE_STATE_MASK) == 0, | ||||
("page %p doesn't belong to queue %p but has aflags %#x", | |||||
m, pq, qflags)); | m, pq, qflags)); | ||||
kib: () around '&' are excessive. May be print raw qflags value instead, just in case. | |||||
Done Inline ActionsI will fix it before committing. markj: I will fix it before committing. | |||||
if ((qflags & PGA_DEQUEUE) != 0) { | if ((qflags & PGA_DEQUEUE) != 0) { | ||||
if (__predict_true((qflags & PGA_ENQUEUED) != 0)) | if (__predict_true((qflags & PGA_ENQUEUED) != 0)) | ||||
vm_pagequeue_remove(pq, m); | vm_pagequeue_remove(pq, m); | ||||
vm_page_dequeue_complete(m); | vm_page_dequeue_complete(m); | ||||
} else if ((qflags & (PGA_REQUEUE | PGA_REQUEUE_HEAD)) != 0) { | } else if ((qflags & (PGA_REQUEUE | PGA_REQUEUE_HEAD)) != 0) { | ||||
if ((qflags & PGA_ENQUEUED) != 0) | if ((qflags & PGA_ENQUEUED) != 0) | ||||
TAILQ_REMOVE(&pq->pq_pl, m, plinks.q); | TAILQ_REMOVE(&pq->pq_pl, m, plinks.q); | ||||
else { | else { | ||||
vm_pagequeue_cnt_inc(pq); | vm_pagequeue_cnt_inc(pq); | ||||
vm_page_aflag_set(m, PGA_ENQUEUED); | vm_page_aflag_set(m, PGA_ENQUEUED); | ||||
} | } | ||||
/* | |||||
* Give PGA_REQUEUE_HEAD precedence over PGA_REQUEUE. | |||||
* In particular, if both flags are set in close succession, | |||||
* only PGA_REQUEUE_HEAD will be applied, even if it was set | |||||
* first. | |||||
*/ | |||||
if ((qflags & PGA_REQUEUE_HEAD) != 0) { | if ((qflags & PGA_REQUEUE_HEAD) != 0) { | ||||
KASSERT(m->queue == PQ_INACTIVE, | KASSERT(m->queue == PQ_INACTIVE, | ||||
("head enqueue not supported for page %p", m)); | ("head enqueue not supported for page %p", m)); | ||||
vmd = vm_pagequeue_domain(m); | vmd = vm_pagequeue_domain(m); | ||||
TAILQ_INSERT_BEFORE(&vmd->vmd_inacthead, m, plinks.q); | TAILQ_INSERT_BEFORE(&vmd->vmd_inacthead, m, plinks.q); | ||||
} else | } else | ||||
TAILQ_INSERT_TAIL(&pq->pq_pl, m, plinks.q); | TAILQ_INSERT_TAIL(&pq->pq_pl, m, plinks.q); | ||||
/* | vm_page_aflag_clear(m, qflags & (PGA_REQUEUE | | ||||
* PGA_REQUEUE and PGA_REQUEUE_HEAD must be cleared after | PGA_REQUEUE_HEAD)); | ||||
* setting PGA_ENQUEUED in order to synchronize with the | |||||
* page daemon. | |||||
*/ | |||||
vm_page_aflag_clear(m, PGA_REQUEUE | PGA_REQUEUE_HEAD); | |||||
} | } | ||||
Done Inline ActionsIn effect, PGA_REQUEUE_HEAD takes precedence over PGA_REQUEUE. I would suggest adding a comment to that effect. alc: In effect, PGA_REQUEUE_HEAD takes precedence over PGA_REQUEUE. I would suggest adding a… | |||||
} | } | ||||
static void | static void | ||||
vm_pqbatch_process(struct vm_pagequeue *pq, struct vm_batchqueue *bq, | vm_pqbatch_process(struct vm_pagequeue *pq, struct vm_batchqueue *bq, | ||||
uint8_t queue) | uint8_t queue) | ||||
{ | { | ||||
vm_page_t m; | vm_page_t m; | ||||
int i; | int i; | ||||
▲ Show 20 Lines • Show All 1,444 Lines • Show Last 20 Lines |
() around '&' are excessive. May be print raw qflags value instead, just in case.