svn commit: r327286 - head/sys/fs/procfs

Konstantin Belousov kib at FreeBSD.org
Thu Dec 28 13:23:14 UTC 2017


Author: kib
Date: Thu Dec 28 13:23:13 2017
New Revision: 327286
URL: https://svnweb.freebsd.org/changeset/base/327286

Log:
  Reuse kern_proc_vmmap_resident() for procfs_map resident count.
  
  The existing algorithm in procfs_map() to calculate count of resident
  pages in an entry is too primitive, resulting in too long run time for
  large sparse mapping entries.  Re-use the kern_proc_vmmap_resident()
  from kern_proc.c which only looks at the existing pages in the
  iterations.
  
  Also, this makes procfs to honor kern.proc_vmmap_skip_resident_count,
  if user does not need this information.
  
  Reported by:	Glenn Weinberg <glenn.weinberg at intel.com>
  PR:	224532
  No objections from:	des (procfs maintainer)
  Sponsored by:	The FreeBSD Foundation
  MFC after:	1 week
  Differential revision:	https://reviews.freebsd.org/D13595

Modified:
  head/sys/fs/procfs/procfs_map.c

Modified: head/sys/fs/procfs/procfs_map.c
==============================================================================
--- head/sys/fs/procfs/procfs_map.c	Thu Dec 28 13:16:32 2017	(r327285)
+++ head/sys/fs/procfs/procfs_map.c	Thu Dec 28 13:23:13 2017	(r327286)
@@ -84,12 +84,17 @@ procfs_doprocmap(PFS_FILL_ARGS)
 	vm_map_t map;
 	vm_map_entry_t entry, tmp_entry;
 	struct vnode *vp;
-	char *fullpath, *freepath;
+	char *fullpath, *freepath, *type;
 	struct ucred *cred;
-	int error;
+	vm_object_t obj, tobj, lobj;
+	int error, privateresident, ref_count, resident, shadow_count, flags;
+	vm_offset_t e_start, e_end;
+	vm_eflags_t e_eflags;
+	vm_prot_t e_prot;
 	unsigned int last_timestamp;
+	bool super;
 #ifdef COMPAT_FREEBSD32
-	int wrap32 = 0;
+	bool wrap32;
 #endif
 
 	PROC_LOCK(p);
@@ -102,11 +107,12 @@ procfs_doprocmap(PFS_FILL_ARGS)
 		return (EOPNOTSUPP);
 
 #ifdef COMPAT_FREEBSD32
-        if (SV_CURPROC_FLAG(SV_ILP32)) {
-                if (!(SV_PROC_FLAG(p, SV_ILP32)))
-                        return (EOPNOTSUPP);
-                wrap32 = 1;
-        }
+	wrap32 = false;
+	if (SV_CURPROC_FLAG(SV_ILP32)) {
+		if (!(SV_PROC_FLAG(p, SV_ILP32)))
+			return (EOPNOTSUPP);
+		wrap32 = true;
+	}
 #endif
 
 	vm = vmspace_acquire_ref(p);
@@ -116,14 +122,6 @@ procfs_doprocmap(PFS_FILL_ARGS)
 	vm_map_lock_read(map);
 	for (entry = map->header.next; entry != &map->header;
 	     entry = entry->next) {
-		vm_object_t obj, tobj, lobj;
-		int ref_count, shadow_count, flags;
-		vm_offset_t e_start, e_end, addr;
-		int resident, privateresident;
-		char *type;
-		vm_eflags_t e_eflags;
-		vm_prot_t e_prot;
-
 		if (entry->eflags & MAP_ENTRY_IS_SUB_MAP)
 			continue;
 
@@ -132,6 +130,7 @@ procfs_doprocmap(PFS_FILL_ARGS)
 		e_start = entry->start;
 		e_end = entry->end;
 		privateresident = 0;
+		resident = 0;
 		obj = entry->object.vm_object;
 		if (obj != NULL) {
 			VM_OBJECT_RLOCK(obj);
@@ -140,20 +139,17 @@ procfs_doprocmap(PFS_FILL_ARGS)
 		}
 		cred = (entry->cred) ? entry->cred : (obj ? obj->cred : NULL);
 
-		resident = 0;
-		addr = entry->start;
-		while (addr < entry->end) {
-			if (pmap_extract(map->pmap, addr))
-				resident++;
-			addr += PAGE_SIZE;
-		}
-
-		for (lobj = tobj = obj; tobj; tobj = tobj->backing_object) {
+		for (lobj = tobj = obj; tobj != NULL;
+		    tobj = tobj->backing_object) {
 			if (tobj != obj)
 				VM_OBJECT_RLOCK(tobj);
-			if (lobj != obj)
-				VM_OBJECT_RUNLOCK(lobj);
 			lobj = tobj;
+		}
+		if (obj != NULL)
+			kern_proc_vmmap_resident(map, entry, &resident, &super);
+		for (tobj = obj; tobj != NULL; tobj = tobj->backing_object) {
+			if (tobj != obj && tobj != lobj)
+				VM_OBJECT_RUNLOCK(tobj);
 		}
 		last_timestamp = map->timestamp;
 		vm_map_unlock_read(map);


More information about the svn-src-all mailing list