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-head mailing list