Index: sys/amd64/amd64/pmap.c =================================================================== --- sys/amd64/amd64/pmap.c +++ sys/amd64/amd64/pmap.c @@ -2219,14 +2219,9 @@ static __inline void pmap_free_zero_pages(struct spglist *free) { - vm_page_t m; int count; - for (count = 0; (m = SLIST_FIRST(free)) != NULL; count++) { - SLIST_REMOVE_HEAD(free, plinks.s.ss); - /* Preserve the page's PG_ZERO setting. */ - vm_page_free_toq(m); - } + count = vm_page_free_spglist(free); atomic_subtract_int(&vm_cnt.v_wire_count, count); } Index: sys/arm/arm/pmap-v6.c =================================================================== --- sys/arm/arm/pmap-v6.c +++ sys/arm/arm/pmap-v6.c @@ -2547,13 +2547,7 @@ static __inline void pmap_free_zero_pages(struct spglist *free) { - vm_page_t m; - - while ((m = SLIST_FIRST(free)) != NULL) { - SLIST_REMOVE_HEAD(free, plinks.s.ss); - /* Preserve the page's PG_ZERO setting. */ - vm_page_free_toq(m); - } + vm_page_free_spglist(free); } /* Index: sys/arm64/arm64/pmap.c =================================================================== --- sys/arm64/arm64/pmap.c +++ sys/arm64/arm64/pmap.c @@ -1263,13 +1263,7 @@ static __inline void pmap_free_zero_pages(struct spglist *free) { - vm_page_t m; - - while ((m = SLIST_FIRST(free)) != NULL) { - SLIST_REMOVE_HEAD(free, plinks.s.ss); - /* Preserve the page's PG_ZERO setting. */ - vm_page_free_toq(m); - } + vm_page_free_spglist(free); } /* Index: sys/i386/i386/pmap.c =================================================================== --- sys/i386/i386/pmap.c +++ sys/i386/i386/pmap.c @@ -1703,14 +1703,9 @@ static __inline void pmap_free_zero_pages(struct spglist *free) { - vm_page_t m; int count; - for (count = 0; (m = SLIST_FIRST(free)) != NULL; count++) { - SLIST_REMOVE_HEAD(free, plinks.s.ss); - /* Preserve the page's PG_ZERO setting. */ - vm_page_free_toq(m); - } + count = vm_page_free_spglist(free); atomic_subtract_int(&vm_cnt.v_wire_count, count); } Index: sys/riscv/riscv/pmap.c =================================================================== --- sys/riscv/riscv/pmap.c +++ sys/riscv/riscv/pmap.c @@ -1072,13 +1072,7 @@ static __inline void pmap_free_zero_pages(struct spglist *free) { - vm_page_t m; - - while ((m = SLIST_FIRST(free)) != NULL) { - SLIST_REMOVE_HEAD(free, plinks.s.ss); - /* Preserve the page's PG_ZERO setting. */ - vm_page_free_toq(m); - } + vm_page_free_spglist(free); } /* Index: sys/vm/vm_page.h =================================================================== --- sys/vm/vm_page.h +++ sys/vm/vm_page.h @@ -547,6 +547,7 @@ vm_page_bits_t vm_page_bits(int base, int size); void vm_page_zero_invalid(vm_page_t m, boolean_t setvalid); void vm_page_free_toq(vm_page_t m); +int vm_page_free_spglist(struct spglist* free); void vm_page_dirty_KBI(vm_page_t m); void vm_page_lock_KBI(vm_page_t m, const char *file, int line); Index: sys/vm/vm_page.c =================================================================== --- sys/vm/vm_page.c +++ sys/vm/vm_page.c @@ -3055,6 +3055,40 @@ } /* + * vm_page_free_spglist: + * + * Returns a list of pages to the free list, disassociating it + * from any VM object. In another word, this is equivalent to + * calling vm_page_free_toq() for each page of a list of VM objects. + * + * The objects must be locked. The pages must be locked if it is + * managed. + * + * Return value indicates the number of VM page objects freed. + */ +int +vm_page_free_spglist(struct spglist* free) +{ + vm_page_t m; + int count; + struct pglist pgl; + + TAILQ_INIT(&pgl); + count = 0; + if ((m = SLIST_FIRST(free)) != NULL) { + do { + count++; + SLIST_REMOVE_HEAD(free, plinks.s.ss); + if (vm_page_free_prep(m, false)) + TAILQ_INSERT_TAIL(&pgl, m, listq); + } while ((m = SLIST_FIRST(free)) != NULL); + if (!TAILQ_EMPTY(&pgl)) + vm_page_free_phys_pglist(&pgl); + } + return count; +} + +/* * vm_page_wire: * * Mark this page as wired down by yet