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);
 }
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to