kern_pmc.c (122ccdc1cae8922f3845fc4f44b4e0470d342b9b) | kern_pmc.c (ebccf1e3a6b11b97cbf5f813dd76636e892a9035) |
---|---|
1/*- | 1/*- |
2 * Copyright (c) 2003-2008 Joseph Koshy 3 * Copyright (c) 2007 The FreeBSD Foundation 4 * All rights reserved. | 2 * Copyright (c) 2003 Joseph Koshy |
5 * | 3 * |
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. --- 4 unchanged lines hidden (view full) --- 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. | 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. --- 4 unchanged lines hidden (view full) --- 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. |
24 * |
|
29 */ 30 31#include <sys/cdefs.h> 32__FBSDID("$FreeBSD$"); 33 | 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD$"); 29 |
34#include "opt_hwpmc_hooks.h" | 30#ifdef HWPMC_HOOKS |
35 | 31 |
36#include <sys/types.h> 37#include <sys/pmc.h> | |
38#include <sys/pmckern.h> 39#include <sys/smp.h> 40 | 32#include <sys/pmckern.h> 33#include <sys/smp.h> 34 |
41#ifdef HWPMC_HOOKS 42#define PMC_KERNEL_VERSION PMC_VERSION 43#else 44#define PMC_KERNEL_VERSION 0 45#endif | 35struct sx pmc_sx; |
46 | 36 |
47const int pmc_kernel_version = PMC_KERNEL_VERSION; 48 | |
49/* Hook variable. */ 50int (*pmc_hook)(struct thread *td, int function, void *arg) = NULL; 51 52/* Interrupt handler */ | 37/* Hook variable. */ 38int (*pmc_hook)(struct thread *td, int function, void *arg) = NULL; 39 40/* Interrupt handler */ |
53int (*pmc_intr)(int cpu, struct trapframe *tf) = NULL; | 41int (*pmc_intr)(int cpu, uintptr_t pc) = NULL; |
54 | 42 |
55/* Bitmask of CPUs requiring servicing at hardclock time */ 56volatile cpumask_t pmc_cpumask; 57 | |
58/* | 43/* |
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 */ 62volatile 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 */ | 44 * Since PMC(4) may not be loaded in the current kernel, the 45 * convention followed is that a non-NULL value of 'pmc_hook' implies 46 * the presence of this kernel module. 47 * 48 * This requires us to protect 'pmc_hook' with a 49 * shared (sx) lock -- thus making the process of calling into PMC(4) 50 * somewhat more expensive than a simple 'if' check and indirect call. 51 */ |
73struct sx pmc_sx; | |
74 | 52 |
75static void 76pmc_init_sx(void) 77{ 78 sx_init_flags(&pmc_sx, "pmc-sx", SX_NOWITNESS); 79} | |
80 | 53 |
81SYSINIT(pmcsx, SI_SUB_LOCK, SI_ORDER_MIDDLE, pmc_init_sx, NULL); | 54SX_SYSINIT(pmc, &pmc_sx, "pmc shared lock"); |
82 83/* | 55 56/* |
84 * Helper functions. 85 */ 86 87/* 88 * A note on the CPU numbering scheme used by the hwpmc(4) driver. | 57 * pmc_cpu_is_disabled |
89 * | 58 * |
90 * CPUs are denoted using numbers in the range 0..[pmc_cpu_max()-1]. 91 * CPUs could be numbered "sparsely" in this range; the predicate 92 * `pmc_cpu_is_present()' is used to test whether a given CPU is 93 * physically present. 94 * 95 * Further, a CPU that is physically present may be administratively 96 * disabled or otherwise unavailable for use by hwpmc(4). The 97 * `pmc_cpu_is_active()' predicate tests for CPU usability. An 98 * "active" CPU participates in thread scheduling and can field 99 * interrupts raised by PMC hardware. 100 * 101 * On systems with hyperthreaded CPUs, multiple logical CPUs may share 102 * PMC hardware resources. For such processors one logical CPU is 103 * denoted as the primary owner of the in-CPU PMC resources. The 104 * pmc_cpu_is_primary() predicate is used to distinguish this primary 105 * CPU from the others. | 59 * return TRUE if the cpu specified has been disabled. |
106 */ 107 108int | 60 */ 61 62int |
109pmc_cpu_is_active(int cpu) 110{ 111#ifdef SMP 112 return (pmc_cpu_is_present(cpu) && 113 (hlt_cpus_mask & (1 << cpu)) == 0); 114#else 115 return (1); 116#endif 117} 118 119/* Deprecated. */ 120int | |
121pmc_cpu_is_disabled(int cpu) 122{ | 63pmc_cpu_is_disabled(int cpu) 64{ |
123 return (!pmc_cpu_is_active(cpu)); 124} 125 126int 127pmc_cpu_is_present(int cpu) 128{ | |
129#ifdef SMP | 65#ifdef SMP |
130 return (!CPU_ABSENT(cpu)); | 66 return ((hlt_cpus_mask & (1 << cpu)) != 0); |
131#else | 67#else |
132 return (1); | 68 return 0; |
133#endif 134} 135 136int | 69#endif 70} 71 72int |
137pmc_cpu_is_primary(int cpu) | 73pmc_cpu_is_logical(int cpu) |
138{ 139#ifdef SMP | 74{ 75#ifdef SMP |
140 return ((logical_cpus_mask & (1 << cpu)) == 0); | 76 return ((logical_cpus_mask & (1 << cpu)) != 0); |
141#else | 77#else |
142 return (1); | 78 return 0; |
143#endif 144} 145 | 79#endif 80} 81 |
146 147/* 148 * Return the maximum CPU number supported by the system. The return 149 * value is used for scaling internal data structures and for runtime 150 * checks. 151 */ 152unsigned int 153pmc_cpu_max(void) 154{ 155#ifdef SMP 156 return (mp_maxid+1); 157#else 158 return (1); 159#endif 160} 161 162#ifdef INVARIANTS 163 164/* 165 * Return the count of CPUs in the `active' state in the system. 166 */ 167int 168pmc_cpu_max_active(void) 169{ 170#ifdef SMP 171 /* 172 * When support for CPU hot-plugging is added to the kernel, 173 * this function would change to return the current number 174 * of "active" CPUs. 175 */ 176 return (mp_ncpus); 177#else 178 return (1); 179#endif 180} 181 182#endif | 82#endif /* HWPMC_HOOKS */ |