The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/kern_pmc.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2003-2008 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: releng/9.0/sys/kern/kern_pmc.c 222813 2011-06-07 08:46:13Z attilio $");
   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 #include <sys/sysctl.h>
   41 
   42 #ifdef  HWPMC_HOOKS
   43 FEATURE(hwpmc_hooks, "Kernel support for HW PMC");
   44 #define PMC_KERNEL_VERSION      PMC_VERSION
   45 #else
   46 #define PMC_KERNEL_VERSION      0
   47 #endif
   48 
   49 const int pmc_kernel_version = PMC_KERNEL_VERSION;
   50 
   51 /* Hook variable. */
   52 int (*pmc_hook)(struct thread *td, int function, void *arg) = NULL;
   53 
   54 /* Interrupt handler */
   55 int (*pmc_intr)(int cpu, struct trapframe *tf) = NULL;
   56 
   57 /* Bitmask of CPUs requiring servicing at hardclock time */
   58 volatile cpuset_t pmc_cpumask;
   59 
   60 /*
   61  * A global count of SS mode PMCs.  When non-zero, this means that
   62  * we have processes that are sampling the system as a whole.
   63  */
   64 volatile int pmc_ss_count;
   65 
   66 /*
   67  * Since PMC(4) may not be loaded in the current kernel, the
   68  * convention followed is that a non-NULL value of 'pmc_hook' implies
   69  * the presence of this kernel module.
   70  *
   71  * This requires us to protect 'pmc_hook' with a
   72  * shared (sx) lock -- thus making the process of calling into PMC(4)
   73  * somewhat more expensive than a simple 'if' check and indirect call.
   74  */
   75 struct sx pmc_sx;
   76 
   77 static void
   78 pmc_init_sx(void)
   79 {
   80         sx_init_flags(&pmc_sx, "pmc-sx", SX_NOWITNESS);
   81 }
   82 
   83 SYSINIT(pmcsx, SI_SUB_LOCK, SI_ORDER_MIDDLE, pmc_init_sx, NULL);
   84 
   85 /*
   86  * Helper functions.
   87  */
   88 
   89 /*
   90  * A note on the CPU numbering scheme used by the hwpmc(4) driver.
   91  *
   92  * CPUs are denoted using numbers in the range 0..[pmc_cpu_max()-1].
   93  * CPUs could be numbered "sparsely" in this range; the predicate
   94  * `pmc_cpu_is_present()' is used to test whether a given CPU is
   95  * physically present.
   96  *
   97  * Further, a CPU that is physically present may be administratively
   98  * disabled or otherwise unavailable for use by hwpmc(4).  The
   99  * `pmc_cpu_is_active()' predicate tests for CPU usability.  An
  100  * "active" CPU participates in thread scheduling and can field
  101  * interrupts raised by PMC hardware.
  102  *
  103  * On systems with hyperthreaded CPUs, multiple logical CPUs may share
  104  * PMC hardware resources.  For such processors one logical CPU is
  105  * denoted as the primary owner of the in-CPU PMC resources. The
  106  * pmc_cpu_is_primary() predicate is used to distinguish this primary
  107  * CPU from the others.
  108  */
  109 
  110 int
  111 pmc_cpu_is_active(int cpu)
  112 {
  113 #ifdef  SMP
  114         return (pmc_cpu_is_present(cpu) &&
  115             !CPU_ISSET(cpu, &hlt_cpus_mask));
  116 #else
  117         return (1);
  118 #endif
  119 }
  120 
  121 /* Deprecated. */
  122 int
  123 pmc_cpu_is_disabled(int cpu)
  124 {
  125         return (!pmc_cpu_is_active(cpu));
  126 }
  127 
  128 int
  129 pmc_cpu_is_present(int cpu)
  130 {
  131 #ifdef  SMP
  132         return (!CPU_ABSENT(cpu));
  133 #else
  134         return (1);
  135 #endif
  136 }
  137 
  138 int
  139 pmc_cpu_is_primary(int cpu)
  140 {
  141 #ifdef  SMP
  142         return (!CPU_ISSET(cpu, &logical_cpus_mask));
  143 #else
  144         return (1);
  145 #endif
  146 }
  147 
  148 
  149 /*
  150  * Return the maximum CPU number supported by the system.  The return
  151  * value is used for scaling internal data structures and for runtime
  152  * checks.
  153  */
  154 unsigned int
  155 pmc_cpu_max(void)
  156 {
  157 #ifdef  SMP
  158         return (mp_maxid+1);
  159 #else
  160         return (1);
  161 #endif
  162 }
  163 
  164 #ifdef  INVARIANTS
  165 
  166 /*
  167  * Return the count of CPUs in the `active' state in the system.
  168  */
  169 int
  170 pmc_cpu_max_active(void)
  171 {
  172 #ifdef  SMP
  173         /*
  174          * When support for CPU hot-plugging is added to the kernel,
  175          * this function would change to return the current number
  176          * of "active" CPUs.
  177          */
  178         return (mp_ncpus);
  179 #else
  180         return (1);
  181 #endif
  182 }
  183 
  184 #endif

Cache object: b771a0c440c52b331026e274a2af03d6


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.