svn commit: r312724 - in head/sys: sys vm
Mateusz Guzik
mjg at FreeBSD.org
Tue Jan 24 22:00:17 UTC 2017
Author: mjg
Date: Tue Jan 24 22:00:16 2017
New Revision: 312724
URL: https://svnweb.freebsd.org/changeset/base/312724
Log:
hwpmc: partially depessimize munmap handling if the module is not loaded
HWPMC_HOOKS is enabled in GENERIC and triggers some work avoidable in the
common (module not loaded) case.
In particular this avoids permission checks + lock downgrade
singlethreaded and in cases were an executable mapping is found the pmc
sx lock is no longer bounced.
Note this is a band aid.
MFC after: 1 week
Modified:
head/sys/sys/pmckern.h
head/sys/vm/vm_mmap.c
Modified: head/sys/sys/pmckern.h
==============================================================================
--- head/sys/sys/pmckern.h Tue Jan 24 21:48:57 2017 (r312723)
+++ head/sys/sys/pmckern.h Tue Jan 24 22:00:16 2017 (r312724)
@@ -174,6 +174,9 @@ extern const int pmc_kernel_version;
/* PMC soft per cpu trapframe */
extern struct trapframe pmc_tf[MAXCPU];
+/* Quick check if preparatory work is necessary */
+#define PMC_HOOK_INSTALLED(cmd) __predict_false(pmc_hook != NULL)
+
/* Hook invocation; for use within the kernel */
#define PMC_CALL_HOOK(t, cmd, arg) \
do { \
Modified: head/sys/vm/vm_mmap.c
==============================================================================
--- head/sys/vm/vm_mmap.c Tue Jan 24 21:48:57 2017 (r312723)
+++ head/sys/vm/vm_mmap.c Tue Jan 24 22:00:16 2017 (r312724)
@@ -526,6 +526,7 @@ sys_munmap(td, uap)
#ifdef HWPMC_HOOKS
struct pmckern_map_out pkm;
vm_map_entry_t entry;
+ bool pmc_handled;
#endif
vm_offset_t addr;
vm_size_t size, pageoff;
@@ -551,20 +552,24 @@ sys_munmap(td, uap)
return (EINVAL);
vm_map_lock(map);
#ifdef HWPMC_HOOKS
- /*
- * 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;
- entry = entry->next) {
- if (vm_map_check_protection(map, entry->start,
- entry->end, VM_PROT_EXECUTE) == TRUE) {
- pkm.pm_address = (uintptr_t) addr;
- pkm.pm_size = (size_t) size;
- break;
+ pmc_handled = false;
+ if (PMC_HOOK_INSTALLED(PMC_FN_MUNMAP)) {
+ pmc_handled = true;
+ /*
+ * 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;
+ entry = entry->next) {
+ if (vm_map_check_protection(map, entry->start,
+ entry->end, VM_PROT_EXECUTE) == TRUE) {
+ pkm.pm_address = (uintptr_t) addr;
+ pkm.pm_size = (size_t) size;
+ break;
+ }
}
}
}
@@ -572,14 +577,16 @@ sys_munmap(td, uap)
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);
+ if (__predict_false(pmc_handled)) {
+ /* 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
#endif
+ vm_map_unlock(map);
+
/* vm_map_delete returns nothing but KERN_SUCCESS anyway */
return (0);
}
More information about the svn-src-head
mailing list