1 /*- 2 * Copyright (c) 2003-2007 Joseph Koshy 3 * Copyright (c) 2007 The FreeBSD Foundation 4 * All rights reserved. 5 * 6 * Portions of this software were developed by A. Joseph Koshy under 7 * sponsorship from the FreeBSD Foundation and Google, Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 #include <sys/cdefs.h> 32 __FBSDID("$FreeBSD$"); 33 34 #include "opt_hwpmc_hooks.h" 35 36 #include <sys/types.h> 37 #include <sys/pmc.h> 38 #include <sys/pmckern.h> 39 #include <sys/smp.h> 40 41 #ifdef HWPMC_HOOKS 42 #define PMC_KERNEL_VERSION PMC_VERSION 43 #else 44 #define PMC_KERNEL_VERSION 0 45 #endif 46 47 const int pmc_kernel_version = PMC_KERNEL_VERSION; 48 49 /* Hook variable. */ 50 int (*pmc_hook)(struct thread *td, int function, void *arg) = NULL; 51 52 /* Interrupt handler */ 53 int (*pmc_intr)(int cpu, struct trapframe *tf) = NULL; 54 55 /* Bitmask of CPUs requiring servicing at hardclock time */ 56 volatile cpumask_t pmc_cpumask; 57 58 /* 59 * A global count of SS mode PMCs. When non-zero, this means that 60 * we have processes that are sampling the system as a whole. 61 */ 62 volatile int pmc_ss_count; 63 64 /* 65 * Since PMC(4) may not be loaded in the current kernel, the 66 * convention followed is that a non-NULL value of 'pmc_hook' implies 67 * the presence of this kernel module. 68 * 69 * This requires us to protect 'pmc_hook' with a 70 * shared (sx) lock -- thus making the process of calling into PMC(4) 71 * somewhat more expensive than a simple 'if' check and indirect call. 72 */ 73 struct sx pmc_sx; 74 75 static void 76 pmc_init_sx(void) 77 { 78 sx_init_flags(&pmc_sx, "pmc-sx", SX_NOWITNESS); 79 } 80 81 SYSINIT(pmcsx, SI_SUB_LOCK, SI_ORDER_MIDDLE, pmc_init_sx, NULL); 82 83 /* 84 * Helper functions 85 */ 86 87 int 88 pmc_cpu_is_disabled(int cpu) 89 { 90 #ifdef SMP 91 return ((hlt_cpus_mask & (1 << cpu)) != 0); 92 #else 93 return 0; 94 #endif 95 } 96 97 int 98 pmc_cpu_is_logical(int cpu) 99 { 100 #ifdef SMP 101 return ((logical_cpus_mask & (1 << cpu)) != 0); 102 #else 103 return 0; 104 #endif 105 } 106