svn commit: r355003 - head/sys/vm
Mark Johnston
markj at FreeBSD.org
Fri Nov 22 16:31:10 UTC 2019
Author: markj
Date: Fri Nov 22 16:31:10 2019
New Revision: 355003
URL: https://svnweb.freebsd.org/changeset/base/355003
Log:
Update the checks in vm_page_zone_import().
- Remove the cnt == 1 check. UMA passes cnt == 1 when it has disabled
per-CPU caching. In this case we might as well just allocate a single
page and return it to the caller, since the caller is going to do
exactly that anyway if the UMA cache allocation attempt fails.
- Don't replenish caches if the domain is severely short on free pages.
With large buckets we may otherwise quickly exacerbate a situation
where the page daemon is failing to keep up.
- Don't replenish caches if the calling thread belongs to the page
daemon, which should avoid creating extra memory pressure when it is
trying to free memory. Virtually all such allocations while occur in
the context of laundering, where the laundry thread must allocate
slabs for various swap and I/O-related UMA zones.
Reviewed by: kib
Discussed with: alc, jeff
MFC after: 2 weeks
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D22394
Modified:
head/sys/vm/vm_page.c
Modified: head/sys/vm/vm_page.c
==============================================================================
--- head/sys/vm/vm_page.c Fri Nov 22 16:30:47 2019 (r355002)
+++ head/sys/vm/vm_page.c Fri Nov 22 16:31:10 2019 (r355003)
@@ -1829,21 +1829,14 @@ vm_page_alloc_after(vm_object_t object, vm_pindex_t pi
* Returns true if the number of free pages exceeds the minimum
* for the request class and false otherwise.
*/
-int
-vm_domain_allocate(struct vm_domain *vmd, int req, int npages)
+static int
+_vm_domain_allocate(struct vm_domain *vmd, int req_class, int npages)
{
u_int limit, old, new;
- req = req & VM_ALLOC_CLASS_MASK;
-
- /*
- * The page daemon is allowed to dig deeper into the free page list.
- */
- if (curproc == pageproc && req != VM_ALLOC_INTERRUPT)
- req = VM_ALLOC_SYSTEM;
- if (req == VM_ALLOC_INTERRUPT)
+ if (req_class == VM_ALLOC_INTERRUPT)
limit = 0;
- else if (req == VM_ALLOC_SYSTEM)
+ else if (req_class == VM_ALLOC_SYSTEM)
limit = vmd->vmd_interrupt_free_min;
else
limit = vmd->vmd_free_reserved;
@@ -1871,6 +1864,20 @@ vm_domain_allocate(struct vm_domain *vmd, int req, int
return (1);
}
+int
+vm_domain_allocate(struct vm_domain *vmd, int req, int npages)
+{
+ int req_class;
+
+ /*
+ * The page daemon is allowed to dig deeper into the free page list.
+ */
+ req_class = req & VM_ALLOC_CLASS_MASK;
+ if (curproc == pageproc && req_class != VM_ALLOC_INTERRUPT)
+ req_class = VM_ALLOC_SYSTEM;
+ return (_vm_domain_allocate(vmd, req_class, npages));
+}
+
vm_page_t
vm_page_alloc_domain_after(vm_object_t object, vm_pindex_t pindex, int domain,
int req, vm_page_t mpred)
@@ -2316,8 +2323,13 @@ vm_page_zone_import(void *arg, void **store, int cnt,
pgcache = arg;
vmd = VM_DOMAIN(pgcache->domain);
- /* Only import if we can bring in a full bucket. */
- if (cnt == 1 || !vm_domain_allocate(vmd, VM_ALLOC_NORMAL, cnt))
+
+ /*
+ * The page daemon should avoid creating extra memory pressure since its
+ * main purpose is to replenish the store of free pages.
+ */
+ if (vmd->vmd_severeset || curproc == pageproc ||
+ !_vm_domain_allocate(vmd, VM_ALLOC_NORMAL, cnt))
return (0);
domain = vmd->vmd_domain;
vm_domain_free_lock(vmd);
More information about the svn-src-all
mailing list