svn commit: r185764 - head/sys/kern

Konstantin Belousov kib at FreeBSD.org
Mon Dec 8 04:29:30 PST 2008


Author: kib
Date: Mon Dec  8 12:29:30 2008
New Revision: 185764
URL: http://svn.freebsd.org/changeset/base/185764

Log:
  Do drop vm map lock earlier in the sysctl_kern_proc_vmmap(), to avoid
  locking a vnode while having vm map locked.
  
  Reported and tested by:	pho
  MFC after:	1 week

Modified:
  head/sys/kern/kern_proc.c

Modified: head/sys/kern/kern_proc.c
==============================================================================
--- head/sys/kern/kern_proc.c	Mon Dec  8 12:28:48 2008	(r185763)
+++ head/sys/kern/kern_proc.c	Mon Dec  8 12:29:30 2008	(r185764)
@@ -1412,13 +1412,32 @@ sysctl_kern_proc_ovmmap(SYSCTL_HANDLER_A
 			lobj = tobj;
 		}
 
+		kve->kve_start = (void*)entry->start;
+		kve->kve_end = (void*)entry->end;
+		kve->kve_offset = (off_t)entry->offset;
+
+		if (entry->protection & VM_PROT_READ)
+			kve->kve_protection |= KVME_PROT_READ;
+		if (entry->protection & VM_PROT_WRITE)
+			kve->kve_protection |= KVME_PROT_WRITE;
+		if (entry->protection & VM_PROT_EXECUTE)
+			kve->kve_protection |= KVME_PROT_EXEC;
+
+		if (entry->eflags & MAP_ENTRY_COW)
+			kve->kve_flags |= KVME_FLAG_COW;
+		if (entry->eflags & MAP_ENTRY_NEEDS_COPY)
+			kve->kve_flags |= KVME_FLAG_NEEDS_COPY;
+
+		last_timestamp = map->timestamp;
+		vm_map_unlock_read(map);
+
 		kve->kve_fileid = 0;
 		kve->kve_fsid = 0;
 		freepath = NULL;
 		fullpath = "";
 		if (lobj) {
 			vp = NULL;
-			switch(lobj->type) {
+			switch (lobj->type) {
 			case OBJT_DEFAULT:
 				kve->kve_type = KVME_TYPE_DEFAULT;
 				break;
@@ -1468,28 +1487,10 @@ sysctl_kern_proc_ovmmap(SYSCTL_HANDLER_A
 			kve->kve_shadow_count = 0;
 		}
 
-		kve->kve_start = (void*)entry->start;
-		kve->kve_end = (void*)entry->end;
-		kve->kve_offset = (off_t)entry->offset;
-
-		if (entry->protection & VM_PROT_READ)
-			kve->kve_protection |= KVME_PROT_READ;
-		if (entry->protection & VM_PROT_WRITE)
-			kve->kve_protection |= KVME_PROT_WRITE;
-		if (entry->protection & VM_PROT_EXECUTE)
-			kve->kve_protection |= KVME_PROT_EXEC;
-
-		if (entry->eflags & MAP_ENTRY_COW)
-			kve->kve_flags |= KVME_FLAG_COW;
-		if (entry->eflags & MAP_ENTRY_NEEDS_COPY)
-			kve->kve_flags |= KVME_FLAG_NEEDS_COPY;
-
 		strlcpy(kve->kve_path, fullpath, sizeof(kve->kve_path));
 		if (freepath != NULL)
 			free(freepath, M_TEMP);
 
-		last_timestamp = map->timestamp;
-		vm_map_unlock_read(map);
 		error = SYSCTL_OUT(req, kve, sizeof(*kve));
 		vm_map_lock_read(map);
 		if (error)
@@ -1577,13 +1578,32 @@ sysctl_kern_proc_vmmap(SYSCTL_HANDLER_AR
 			lobj = tobj;
 		}
 
+		kve->kve_start = entry->start;
+		kve->kve_end = entry->end;
+		kve->kve_offset = entry->offset;
+
+		if (entry->protection & VM_PROT_READ)
+			kve->kve_protection |= KVME_PROT_READ;
+		if (entry->protection & VM_PROT_WRITE)
+			kve->kve_protection |= KVME_PROT_WRITE;
+		if (entry->protection & VM_PROT_EXECUTE)
+			kve->kve_protection |= KVME_PROT_EXEC;
+
+		if (entry->eflags & MAP_ENTRY_COW)
+			kve->kve_flags |= KVME_FLAG_COW;
+		if (entry->eflags & MAP_ENTRY_NEEDS_COPY)
+			kve->kve_flags |= KVME_FLAG_NEEDS_COPY;
+
+		last_timestamp = map->timestamp;
+		vm_map_unlock_read(map);
+
 		kve->kve_fileid = 0;
 		kve->kve_fsid = 0;
 		freepath = NULL;
 		fullpath = "";
 		if (lobj) {
 			vp = NULL;
-			switch(lobj->type) {
+			switch (lobj->type) {
 			case OBJT_DEFAULT:
 				kve->kve_type = KVME_TYPE_DEFAULT;
 				break;
@@ -1633,28 +1653,10 @@ sysctl_kern_proc_vmmap(SYSCTL_HANDLER_AR
 			kve->kve_shadow_count = 0;
 		}
 
-		kve->kve_start = entry->start;
-		kve->kve_end = entry->end;
-		kve->kve_offset = entry->offset;
-
-		if (entry->protection & VM_PROT_READ)
-			kve->kve_protection |= KVME_PROT_READ;
-		if (entry->protection & VM_PROT_WRITE)
-			kve->kve_protection |= KVME_PROT_WRITE;
-		if (entry->protection & VM_PROT_EXECUTE)
-			kve->kve_protection |= KVME_PROT_EXEC;
-
-		if (entry->eflags & MAP_ENTRY_COW)
-			kve->kve_flags |= KVME_FLAG_COW;
-		if (entry->eflags & MAP_ENTRY_NEEDS_COPY)
-			kve->kve_flags |= KVME_FLAG_NEEDS_COPY;
-
 		strlcpy(kve->kve_path, fullpath, sizeof(kve->kve_path));
 		if (freepath != NULL)
 			free(freepath, M_TEMP);
 
-		last_timestamp = map->timestamp;
-		vm_map_unlock_read(map);
 		/* Pack record size down */
 		kve->kve_structsize = offsetof(struct kinfo_vmentry, kve_path) +
 		    strlen(kve->kve_path) + 1;


More information about the svn-src-head mailing list