From owner-svn-src-all@freebsd.org Tue Jan 24 22:00:17 2017 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id BEA94CBF3AD; Tue, 24 Jan 2017 22:00:17 +0000 (UTC) (envelope-from mjg@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 995EF1D01; Tue, 24 Jan 2017 22:00:17 +0000 (UTC) (envelope-from mjg@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v0OM0GMu042086; Tue, 24 Jan 2017 22:00:16 GMT (envelope-from mjg@FreeBSD.org) Received: (from mjg@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v0OM0GRO042084; Tue, 24 Jan 2017 22:00:16 GMT (envelope-from mjg@FreeBSD.org) Message-Id: <201701242200.v0OM0GRO042084@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mjg set sender to mjg@FreeBSD.org using -f From: Mateusz Guzik Date: Tue, 24 Jan 2017 22:00:16 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r312724 - in head/sys: sys vm X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 24 Jan 2017 22:00:17 -0000 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); }