Index: head/sys/vm/vm_meter.c =================================================================== --- head/sys/vm/vm_meter.c +++ head/sys/vm/vm_meter.c @@ -364,7 +364,6 @@ VM_STATS_VM(v_intrans, "In transit page faults"); VM_STATS_VM(v_reactivated, "Pages reactivated by pagedaemon"); VM_STATS_VM(v_pdwakeups, "Pagedaemon wakeups"); -VM_STATS_VM(v_pdpages, "Pages analyzed by pagedaemon"); VM_STATS_VM(v_pdshortfalls, "Page reclamation shortfalls"); VM_STATS_VM(v_dfree, "Pages freed by pagedaemon"); VM_STATS_VM(v_pfree, "Pages freed by exiting processes"); @@ -436,8 +435,7 @@ return (v); } -static -u_int +static u_int vm_pagequeue_count(int pq) { u_int v; @@ -454,23 +452,42 @@ vm_active_count(void) { - return vm_pagequeue_count(PQ_ACTIVE); + return (vm_pagequeue_count(PQ_ACTIVE)); } u_int vm_inactive_count(void) { - return vm_pagequeue_count(PQ_INACTIVE); + return (vm_pagequeue_count(PQ_INACTIVE)); } u_int vm_laundry_count(void) { - return vm_pagequeue_count(PQ_LAUNDRY); + return (vm_pagequeue_count(PQ_LAUNDRY)); } +static int +sysctl_vm_pdpages(SYSCTL_HANDLER_ARGS) +{ + struct vm_pagequeue *pq; + uint64_t ret; + int dom, i; + + ret = counter_u64_fetch(vm_cnt.v_pdpages); + for (dom = 0; dom < vm_ndomains; dom++) + for (i = 0; i < PQ_COUNT; i++) { + pq = &VM_DOMAIN(dom)->vmd_pagequeues[i]; + ret += pq->pq_pdpages; + } + return (SYSCTL_OUT(req, &ret, sizeof(ret))); +} +SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_pdpages, + CTLTYPE_U64 | CTLFLAG_MPSAFE | CTLFLAG_RD, NULL, 0, sysctl_vm_pdpages, "QU", + "Pages analyzed by pagedaemon"); + static void vm_domain_stats_init(struct vm_domain *vmd, struct sysctl_oid *parent) { @@ -486,15 +503,31 @@ SYSCTL_ADD_UINT(NULL, SYSCTL_CHILDREN(oid), OID_AUTO, "active", CTLFLAG_RD, &vmd->vmd_pagequeues[PQ_ACTIVE].pq_cnt, 0, "Active pages"); + SYSCTL_ADD_U64(NULL, SYSCTL_CHILDREN(oid), OID_AUTO, + "actpdpgs", CTLFLAG_RD, + &vmd->vmd_pagequeues[PQ_ACTIVE].pq_pdpages, 0, + "Active pages scanned by the page daemon"); SYSCTL_ADD_UINT(NULL, SYSCTL_CHILDREN(oid), OID_AUTO, "inactive", CTLFLAG_RD, &vmd->vmd_pagequeues[PQ_INACTIVE].pq_cnt, 0, "Inactive pages"); + SYSCTL_ADD_U64(NULL, SYSCTL_CHILDREN(oid), OID_AUTO, + "inactpdpgs", CTLFLAG_RD, + &vmd->vmd_pagequeues[PQ_INACTIVE].pq_pdpages, 0, + "Inactive pages scanned by the page daemon"); SYSCTL_ADD_UINT(NULL, SYSCTL_CHILDREN(oid), OID_AUTO, "laundry", CTLFLAG_RD, &vmd->vmd_pagequeues[PQ_LAUNDRY].pq_cnt, 0, "laundry pages"); + SYSCTL_ADD_U64(NULL, SYSCTL_CHILDREN(oid), OID_AUTO, + "laundpdpgs", CTLFLAG_RD, + &vmd->vmd_pagequeues[PQ_LAUNDRY].pq_pdpages, 0, + "Laundry pages scanned by the page daemon"); SYSCTL_ADD_UINT(NULL, SYSCTL_CHILDREN(oid), OID_AUTO, "unswappable", CTLFLAG_RD, &vmd->vmd_pagequeues[PQ_UNSWAPPABLE].pq_cnt, 0, "Unswappable pages"); + SYSCTL_ADD_U64(NULL, SYSCTL_CHILDREN(oid), OID_AUTO, + "unswppdpgs", CTLFLAG_RD, + &vmd->vmd_pagequeues[PQ_UNSWAPPABLE].pq_pdpages, 0, + "Unswappable pages scanned by the page daemon"); SYSCTL_ADD_UINT(NULL, SYSCTL_CHILDREN(oid), OID_AUTO, "inactive_target", CTLFLAG_RD, &vmd->vmd_inactive_target, 0, "Target inactive pages"); Index: head/sys/vm/vm_page.c =================================================================== --- head/sys/vm/vm_page.c +++ head/sys/vm/vm_page.c @@ -481,6 +481,7 @@ TAILQ_INIT(&pq->pq_pl); mtx_init(&pq->pq_mutex, pq->pq_name, "vm pagequeue", MTX_DEF | MTX_DUPOK); + pq->pq_pdpages = 0; vm_page_init_marker(&vmd->vmd_markers[i], i, 0); } mtx_init(&vmd->vmd_free_mtx, "vm page free queue", NULL, MTX_DEF); Index: head/sys/vm/vm_pageout.c =================================================================== --- head/sys/vm/vm_pageout.c +++ head/sys/vm/vm_pageout.c @@ -246,7 +246,7 @@ TAILQ_REMOVE(&pq->pq_pl, ss->marker, plinks.q); vm_page_aflag_clear(ss->marker, PGA_ENQUEUED); - VM_CNT_ADD(v_pdpages, ss->scanned); + pq->pq_pdpages += ss->scanned; } /* Index: head/sys/vm/vm_pagequeue.h =================================================================== --- head/sys/vm/vm_pagequeue.h +++ head/sys/vm/vm_pagequeue.h @@ -71,6 +71,7 @@ struct pglist pq_pl; int pq_cnt; const char * const pq_name; + uint64_t pq_pdpages; } __aligned(CACHE_LINE_SIZE); #ifndef VM_BATCHQUEUE_SIZE