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
This commit is contained in:
parent
543b2f425d
commit
736ff8c396
@ -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 { \
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user