Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 16 Nov 2015 07:03:01 +0000 (UTC)
From:      Garrett Cooper <ngie@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r290923 - in user/ngie/more-tests2: sys/mips/atheros sys/vm tools/regression/acct usr.sbin/ypserv
Message-ID:  <201511160703.tAG731OM081394@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ngie
Date: Mon Nov 16 07:03:00 2015
New Revision: 290923
URL: https://svnweb.freebsd.org/changeset/base/290923

Log:
  MFhead @ r290922

Deleted:
  user/ngie/more-tests2/tools/regression/acct/
Modified:
  user/ngie/more-tests2/sys/mips/atheros/apb.c
  user/ngie/more-tests2/sys/vm/vm_page.h
  user/ngie/more-tests2/sys/vm/vm_pageout.c
  user/ngie/more-tests2/usr.sbin/ypserv/yp_access.c
  user/ngie/more-tests2/usr.sbin/ypserv/yp_dblookup.c
  user/ngie/more-tests2/usr.sbin/ypserv/yp_dnslookup.c
Directory Properties:
  user/ngie/more-tests2/   (props changed)
  user/ngie/more-tests2/sys/   (props changed)

Modified: user/ngie/more-tests2/sys/mips/atheros/apb.c
==============================================================================
--- user/ngie/more-tests2/sys/mips/atheros/apb.c	Mon Nov 16 06:56:45 2015	(r290922)
+++ user/ngie/more-tests2/sys/mips/atheros/apb.c	Mon Nov 16 07:03:00 2015	(r290923)
@@ -364,6 +364,8 @@ apb_filter(void *arg)
 			case AR71XX_SOC_AR9341:
 			case AR71XX_SOC_AR9342:
 			case AR71XX_SOC_AR9344:
+			case AR71XX_SOC_QCA9533:
+			case AR71XX_SOC_QCA9533_V2:
 			case AR71XX_SOC_QCA9556:
 			case AR71XX_SOC_QCA9558:
 				/* ACK/clear the given interrupt */

Modified: user/ngie/more-tests2/sys/vm/vm_page.h
==============================================================================
--- user/ngie/more-tests2/sys/vm/vm_page.h	Mon Nov 16 06:56:45 2015	(r290922)
+++ user/ngie/more-tests2/sys/vm/vm_page.h	Mon Nov 16 07:03:00 2015	(r290923)
@@ -227,6 +227,7 @@ struct vm_domain {
 	long vmd_segs;	/* bitmask of the segments */
 	boolean_t vmd_oom;
 	int vmd_pass;	/* local pagedaemon pass */
+	int vmd_oom_seq;
 	int vmd_last_active_scan;
 	struct vm_page vmd_marker; /* marker for pagedaemon private use */
 	struct vm_page vmd_inacthead; /* marker for LRU-defeating insertions */

Modified: user/ngie/more-tests2/sys/vm/vm_pageout.c
==============================================================================
--- user/ngie/more-tests2/sys/vm/vm_pageout.c	Mon Nov 16 06:56:45 2015	(r290922)
+++ user/ngie/more-tests2/sys/vm/vm_pageout.c	Mon Nov 16 07:03:00 2015	(r290923)
@@ -122,7 +122,8 @@ static void vm_pageout_init(void);
 static int vm_pageout_clean(vm_page_t m);
 static int vm_pageout_cluster(vm_page_t m);
 static void vm_pageout_scan(struct vm_domain *vmd, int pass);
-static void vm_pageout_mightbe_oom(struct vm_domain *vmd, int pass);
+static void vm_pageout_mightbe_oom(struct vm_domain *vmd, int page_shortage,
+    int starting_page_shortage);
 
 SYSINIT(pagedaemon_init, SI_SUB_KTHREAD_PAGE, SI_ORDER_FIRST, vm_pageout_init,
     NULL);
@@ -158,6 +159,7 @@ SYSINIT(vmdaemon, SI_SUB_KTHREAD_VM, SI_
 int vm_pages_needed;		/* Event on which pageout daemon sleeps */
 int vm_pageout_deficit;		/* Estimated number of pages deficit */
 int vm_pageout_wakeup_thresh;
+static int vm_pageout_oom_seq = 12;
 
 #if !defined(NO_SWAPPING)
 static int vm_pageout_req_swapout;	/* XXX */
@@ -223,6 +225,10 @@ static int pageout_lock_miss;
 SYSCTL_INT(_vm, OID_AUTO, pageout_lock_miss,
 	CTLFLAG_RD, &pageout_lock_miss, 0, "vget() lock misses during pageout");
 
+SYSCTL_INT(_vm, OID_AUTO, pageout_oom_seq,
+	CTLFLAG_RW, &vm_pageout_oom_seq, 0,
+	"back-to-back calls to oom detector to start OOM");
+
 #define VM_PAGEOUT_PAGE_COUNT 16
 int vm_pageout_page_count = VM_PAGEOUT_PAGE_COUNT;
 
@@ -1041,7 +1047,8 @@ vm_pageout_scan(struct vm_domain *vmd, i
 	vm_object_t object;
 	long min_scan;
 	int act_delta, addl_page_shortage, deficit, error, maxlaunder, maxscan;
-	int page_shortage, scan_tick, scanned, vnodes_skipped;
+	int page_shortage, scan_tick, scanned, starting_page_shortage;
+	int vnodes_skipped;
 	boolean_t pageout_ok, queues_locked;
 
 	/*
@@ -1080,6 +1087,7 @@ vm_pageout_scan(struct vm_domain *vmd, i
 		page_shortage = vm_paging_target() + deficit;
 	} else
 		page_shortage = deficit = 0;
+	starting_page_shortage = page_shortage;
 
 	/*
 	 * maxlaunder limits the number of dirty pages we flush per scan.
@@ -1343,6 +1351,12 @@ relock_queues:
 		(void)speedup_syncer();
 
 	/*
+	 * If the inactive queue scan fails repeatedly to meet its
+	 * target, kill the largest process.
+	 */
+	vm_pageout_mightbe_oom(vmd, page_shortage, starting_page_shortage);
+
+	/*
 	 * Compute the number of pages we want to try to move from the
 	 * active queue to the inactive queue.
 	 */
@@ -1453,15 +1467,6 @@ relock_queues:
 		}
 	}
 #endif
-
-	/*
-	 * If we are critically low on one of RAM or swap and low on
-	 * the other, kill the largest process.  However, we avoid
-	 * doing this on the first pass in order to give ourselves a
-	 * chance to flush out dirty vnode-backed pages and to allow
-	 * active pages to be moved to the inactive queue and reclaimed.
-	 */
-	vm_pageout_mightbe_oom(vmd, pass);
 }
 
 static int vm_pageout_oom_vote;
@@ -1472,12 +1477,17 @@ static int vm_pageout_oom_vote;
  * failed to reach free target is premature.
  */
 static void
-vm_pageout_mightbe_oom(struct vm_domain *vmd, int pass)
+vm_pageout_mightbe_oom(struct vm_domain *vmd, int page_shortage,
+    int starting_page_shortage)
 {
 	int old_vote;
 
-	if (pass <= 1 || !((swap_pager_avail < 64 && vm_page_count_min()) ||
-	    (swap_pager_full && vm_paging_target() > 0))) {
+	if (starting_page_shortage <= 0 || starting_page_shortage !=
+	    page_shortage)
+		vmd->vmd_oom_seq = 0;
+	else
+		vmd->vmd_oom_seq++;
+	if (vmd->vmd_oom_seq < vm_pageout_oom_seq) {
 		if (vmd->vmd_oom) {
 			vmd->vmd_oom = FALSE;
 			atomic_subtract_int(&vm_pageout_oom_vote, 1);
@@ -1485,6 +1495,12 @@ vm_pageout_mightbe_oom(struct vm_domain 
 		return;
 	}
 
+	/*
+	 * Do not follow the call sequence until OOM condition is
+	 * cleared.
+	 */
+	vmd->vmd_oom_seq = 0;
+
 	if (vmd->vmd_oom)
 		return;
 
@@ -1510,6 +1526,65 @@ vm_pageout_mightbe_oom(struct vm_domain 
 	atomic_subtract_int(&vm_pageout_oom_vote, 1);
 }
 
+/*
+ * The OOM killer is the page daemon's action of last resort when
+ * memory allocation requests have been stalled for a prolonged period
+ * of time because it cannot reclaim memory.  This function computes
+ * the approximate number of physical pages that could be reclaimed if
+ * the specified address space is destroyed.
+ *
+ * Private, anonymous memory owned by the address space is the
+ * principal resource that we expect to recover after an OOM kill.
+ * Since the physical pages mapped by the address space's COW entries
+ * are typically shared pages, they are unlikely to be released and so
+ * they are not counted.
+ *
+ * To get to the point where the page daemon runs the OOM killer, its
+ * efforts to write-back vnode-backed pages may have stalled.  This
+ * could be caused by a memory allocation deadlock in the write path
+ * that might be resolved by an OOM kill.  Therefore, physical pages
+ * belonging to vnode-backed objects are counted, because they might
+ * be freed without being written out first if the address space holds
+ * the last reference to an unlinked vnode.
+ *
+ * Similarly, physical pages belonging to OBJT_PHYS objects are
+ * counted because the address space might hold the last reference to
+ * the object.
+ */
+static long
+vm_pageout_oom_pagecount(struct vmspace *vmspace)
+{
+	vm_map_t map;
+	vm_map_entry_t entry;
+	vm_object_t obj;
+	long res;
+
+	map = &vmspace->vm_map;
+	KASSERT(!map->system_map, ("system map"));
+	sx_assert(&map->lock, SA_LOCKED);
+	res = 0;
+	for (entry = map->header.next; entry != &map->header;
+	    entry = entry->next) {
+		if ((entry->eflags & MAP_ENTRY_IS_SUB_MAP) != 0)
+			continue;
+		obj = entry->object.vm_object;
+		if (obj == NULL)
+			continue;
+		if ((entry->eflags & MAP_ENTRY_NEEDS_COPY) != 0 &&
+		    obj->ref_count != 1)
+			continue;
+		switch (obj->type) {
+		case OBJT_DEFAULT:
+		case OBJT_SWAP:
+		case OBJT_PHYS:
+		case OBJT_VNODE:
+			res += obj->resident_page_count;
+			break;
+		}
+	}
+	return (res);
+}
+
 void
 vm_pageout_oom(int shortage)
 {
@@ -1583,12 +1658,13 @@ vm_pageout_oom(int shortage)
 		}
 		PROC_UNLOCK(p);
 		size = vmspace_swap_count(vm);
-		vm_map_unlock_read(&vm->vm_map);
 		if (shortage == VM_OOM_MEM)
-			size += vmspace_resident_count(vm);
+			size += vm_pageout_oom_pagecount(vm);
+		vm_map_unlock_read(&vm->vm_map);
 		vmspace_free(vm);
+
 		/*
-		 * if the this process is bigger than the biggest one
+		 * If this process is bigger than the biggest one,
 		 * remember it.
 		 */
 		if (size > bigsize) {

Modified: user/ngie/more-tests2/usr.sbin/ypserv/yp_access.c
==============================================================================
--- user/ngie/more-tests2/usr.sbin/ypserv/yp_access.c	Mon Nov 16 06:56:45 2015	(r290922)
+++ user/ngie/more-tests2/usr.sbin/ypserv/yp_access.c	Mon Nov 16 07:03:00 2015	(r290923)
@@ -129,7 +129,7 @@ load_securenets(void)
 
 	if ((fp = fopen(path, "r")) == NULL) {
 		if (errno == ENOENT) {
-			securenets = (struct securenet *)malloc(sizeof(struct securenet));
+			securenets = malloc(sizeof(struct securenet));
 			securenets->net.s_addr = INADDR_ANY;
 			securenets->mask.s_addr = INADDR_ANY;
 			securenets->next = NULL;
@@ -154,7 +154,7 @@ load_securenets(void)
 			continue;
 		}
 
-		tmp = (struct securenet *)malloc(sizeof(struct securenet));
+		tmp = malloc(sizeof(struct securenet));
 
 		if (!inet_aton((char *)&addr1, (struct in_addr *)&tmp->net)) {
 			yp_error("badly formatted securenets entry: %s", addr1);

Modified: user/ngie/more-tests2/usr.sbin/ypserv/yp_dblookup.c
==============================================================================
--- user/ngie/more-tests2/usr.sbin/ypserv/yp_dblookup.c	Mon Nov 16 06:56:45 2015	(r290922)
+++ user/ngie/more-tests2/usr.sbin/ypserv/yp_dblookup.c	Mon Nov 16 07:03:00 2015	(r290923)
@@ -103,13 +103,13 @@ yp_malloc_qent(void)
 {
 	register struct circleq_entry *q;
 
-	q = (struct circleq_entry *)malloc(sizeof(struct circleq_entry));
+	q = malloc(sizeof(struct circleq_entry));
 	if (q == NULL) {
 		yp_error("failed to malloc() circleq entry");
 		return(NULL);
 	}
 	bzero((char *)q, sizeof(struct circleq_entry));
-	q->dbptr = (struct dbent *)malloc(sizeof(struct dbent));
+	q->dbptr = malloc(sizeof(struct dbent));
 	if (q->dbptr == NULL) {
 		yp_error("failed to malloc() circleq entry");
 		free(q);

Modified: user/ngie/more-tests2/usr.sbin/ypserv/yp_dnslookup.c
==============================================================================
--- user/ngie/more-tests2/usr.sbin/ypserv/yp_dnslookup.c	Mon Nov 16 06:56:45 2015	(r290922)
+++ user/ngie/more-tests2/usr.sbin/ypserv/yp_dnslookup.c	Mon Nov 16 07:03:00 2015	(r290923)
@@ -149,7 +149,7 @@ circleq_dnsentry *yp_malloc_dnsent(void)
 {
 	register struct circleq_dnsentry *q;
 
-	q = (struct circleq_dnsentry *)malloc(sizeof(struct circleq_dnsentry));
+	q = malloc(sizeof(struct circleq_dnsentry));
 
 	if (q == NULL) {
 		yp_error("failed to malloc() circleq dns entry");



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201511160703.tAG731OM081394>