svn commit: r215551 - stable/8/sys/vm

Ryan Stone rstone at FreeBSD.org
Sat Nov 20 04:54:59 UTC 2010


Author: rstone
Date: Sat Nov 20 04:54:58 2010
New Revision: 215551
URL: http://svn.freebsd.org/changeset/base/215551

Log:
  MFC r212281 and 212282
  
  In munmap() downgrade the vm_map_lock to a read lock before taking a read
  lock on the pmc-sx lock.  This prevents a deadlock with
  pmc_log_process_mappings, which has an exclusive lock on pmc-sx and tries
  to get a read lock on a vm_map.  Downgrading the vm_map_lock in munmap
  allows pmc_log_process_mappings to continue, preventing the deadlock.
  
  Without this change I could cause a deadlock on a multicore 8.1-RELEASE
  system by having one thread constantly mmap'ing and then munmap'ing a
  PROT_EXEC mapping in a loop while I repeatedly invoked and stopped pmcstat
  in system-wide sampling mode.
  
  Approved by:	emaste (mentor)

Modified:
  stable/8/sys/vm/vm_mmap.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/vm/vm_mmap.c
==============================================================================
--- stable/8/sys/vm/vm_mmap.c	Fri Nov 19 22:25:32 2010	(r215550)
+++ stable/8/sys/vm/vm_mmap.c	Sat Nov 20 04:54:58 2010	(r215551)
@@ -577,6 +577,7 @@ munmap(td, uap)
 	 * Inform hwpmc if the address range being unmapped contains
 	 * an executable region.
 	 */
+	pkm.pm_address = (uintptr_t) NULL;
 	if (vm_map_lookup_entry(map, addr, &entry)) {
 		for (;
 		     entry != &map->header && entry->start < addr + size;
@@ -585,16 +586,23 @@ munmap(td, uap)
 				entry->end, VM_PROT_EXECUTE) == TRUE) {
 				pkm.pm_address = (uintptr_t) addr;
 				pkm.pm_size = (size_t) size;
-				PMC_CALL_HOOK(td, PMC_FN_MUNMAP,
-				    (void *) &pkm);
 				break;
 			}
 		}
 	}
 #endif
-	/* returns nothing but KERN_SUCCESS anyway */
 	vm_map_delete(map, addr, addr + size);
+
+#ifdef HWPMC_HOOKS
+	/* downgrade the lock to prevent a LOR with the pmc-sx lock */
+	vm_map_lock_downgrade(map);
+	if (pkm.pm_address != (uintptr_t) NULL)
+		PMC_CALL_HOOK(td, PMC_FN_MUNMAP, (void *) &pkm);
+	vm_map_unlock_read(map);
+#else
 	vm_map_unlock(map);
+#endif
+	/* vm_map_delete returns nothing but KERN_SUCCESS anyway */
 	return (0);
 }
 


More information about the svn-src-stable-8 mailing list