1*699cd480SApple OSS Distributions /* 2*699cd480SApple OSS Distributions * Copyright (c) 2011-2021 Apple Computer, Inc. All rights reserved. 3*699cd480SApple OSS Distributions * 4*699cd480SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5*699cd480SApple OSS Distributions * 6*699cd480SApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code 7*699cd480SApple OSS Distributions * as defined in and that are subject to the Apple Public Source License 8*699cd480SApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in 9*699cd480SApple OSS Distributions * compliance with the License. The rights granted to you under the License 10*699cd480SApple OSS Distributions * may not be used to create, or enable the creation or redistribution of, 11*699cd480SApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to 12*699cd480SApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any 13*699cd480SApple OSS Distributions * terms of an Apple operating system software license agreement. 14*699cd480SApple OSS Distributions * 15*699cd480SApple OSS Distributions * Please obtain a copy of the License at 16*699cd480SApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file. 17*699cd480SApple OSS Distributions * 18*699cd480SApple OSS Distributions * The Original Code and all software distributed under the License are 19*699cd480SApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20*699cd480SApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21*699cd480SApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22*699cd480SApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23*699cd480SApple OSS Distributions * Please see the License for the specific language governing rights and 24*699cd480SApple OSS Distributions * limitations under the License. 25*699cd480SApple OSS Distributions * 26*699cd480SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27*699cd480SApple OSS Distributions */ 28*699cd480SApple OSS Distributions 29*699cd480SApple OSS Distributions #ifndef KPERF_KPTIMER_H 30*699cd480SApple OSS Distributions #define KPERF_KPTIMER_H 31*699cd480SApple OSS Distributions 32*699cd480SApple OSS Distributions /* 33*699cd480SApple OSS Distributions * kptimer is responsible for managing the kperf's on-CPU timers. These 34*699cd480SApple OSS Distributions * timers sample threads that are running on CPUs at a cadence determined by a 35*699cd480SApple OSS Distributions * specified period. When they fire, a handler runs the specified action and 36*699cd480SApple OSS Distributions * reprograms the timer to fire again. To get everything started or stopped, 37*699cd480SApple OSS Distributions * kptimer issues a broadcast IPI to modify kperf's multiplexed per-CPU timer, 38*699cd480SApple OSS Distributions * stored in the machine-dependent per-CPU structure. 39*699cd480SApple OSS Distributions * 40*699cd480SApple OSS Distributions * On-CPU timers are disabled when the CPU they've been programmed for goes idle 41*699cd480SApple OSS Distributions * to prevent waking up the idle CPU when it's not running anything interesting. 42*699cd480SApple OSS Distributions * This logic lives in the platform code that's responsible for entering and 43*699cd480SApple OSS Distributions * exiting idle. 44*699cd480SApple OSS Distributions * 45*699cd480SApple OSS Distributions * Traditional PET is configured here (since it's defined by identifying a timer 46*699cd480SApple OSS Distributions * to use for PET) but its mechanism is in osfmk/kperf/pet.c. Lightweight PET 47*699cd480SApple OSS Distributions * does use kptimer to increment its generation count, however. 48*699cd480SApple OSS Distributions */ 49*699cd480SApple OSS Distributions 50*699cd480SApple OSS Distributions /* 51*699cd480SApple OSS Distributions * The minimum allowed timer period depends on the type of client (foreground vs. 52*699cd480SApple OSS Distributions * background) and timer (on-CPU vs. PET). 53*699cd480SApple OSS Distributions */ 54*699cd480SApple OSS Distributions enum kptimer_period_limit { 55*699cd480SApple OSS Distributions KTPL_FG, 56*699cd480SApple OSS Distributions KTPL_BG, 57*699cd480SApple OSS Distributions KTPL_FG_PET, 58*699cd480SApple OSS Distributions KTPL_BG_PET, 59*699cd480SApple OSS Distributions KTPL_MAX, 60*699cd480SApple OSS Distributions }; 61*699cd480SApple OSS Distributions 62*699cd480SApple OSS Distributions /* 63*699cd480SApple OSS Distributions * The minimum timer periods allowed by kperf. There's no other mechanism 64*699cd480SApple OSS Distributions * to prevent interrupt storms due to kptimer. 65*699cd480SApple OSS Distributions */ 66*699cd480SApple OSS Distributions extern const uint64_t kptimer_minperiods_ns[KTPL_MAX]; 67*699cd480SApple OSS Distributions 68*699cd480SApple OSS Distributions /* 69*699cd480SApple OSS Distributions * Called from the kernel startup thread to set up kptimer. 70*699cd480SApple OSS Distributions */ 71*699cd480SApple OSS Distributions void kptimer_init(void); 72*699cd480SApple OSS Distributions 73*699cd480SApple OSS Distributions /* 74*699cd480SApple OSS Distributions * Return the minimum timer period in Mach time units. 75*699cd480SApple OSS Distributions */ 76*699cd480SApple OSS Distributions uint64_t kptimer_min_period_abs(bool pet); 77*699cd480SApple OSS Distributions 78*699cd480SApple OSS Distributions /* 79*699cd480SApple OSS Distributions * Return the number of timers available. 80*699cd480SApple OSS Distributions */ 81*699cd480SApple OSS Distributions unsigned int kptimer_get_count(void); 82*699cd480SApple OSS Distributions 83*699cd480SApple OSS Distributions /* 84*699cd480SApple OSS Distributions * Set the number of timers available to `count`. 85*699cd480SApple OSS Distributions * 86*699cd480SApple OSS Distributions * Returns 0 on success, and non-0 on error. 87*699cd480SApple OSS Distributions */ 88*699cd480SApple OSS Distributions int kptimer_set_count(unsigned int count); 89*699cd480SApple OSS Distributions 90*699cd480SApple OSS Distributions /* 91*699cd480SApple OSS Distributions * Return the period of the timer identified by `timerid` in `period_out`. 92*699cd480SApple OSS Distributions * 93*699cd480SApple OSS Distributions * Returns 0 on success, and non-0 on error. 94*699cd480SApple OSS Distributions */ 95*699cd480SApple OSS Distributions int kptimer_get_period(unsigned int timerid, uint64_t *period_out); 96*699cd480SApple OSS Distributions 97*699cd480SApple OSS Distributions /* 98*699cd480SApple OSS Distributions * Set the period of the timer identified by `timerid` to `period`. 99*699cd480SApple OSS Distributions * 100*699cd480SApple OSS Distributions * Returns non-zero on error, and zero otherwise. 101*699cd480SApple OSS Distributions */ 102*699cd480SApple OSS Distributions int kptimer_set_period(unsigned int timerid, uint64_t period); 103*699cd480SApple OSS Distributions 104*699cd480SApple OSS Distributions /* 105*699cd480SApple OSS Distributions * Return the action of the timer identified by `timerid` in 106*699cd480SApple OSS Distributions * `actionid_out`. 107*699cd480SApple OSS Distributions */ 108*699cd480SApple OSS Distributions int kptimer_get_action(unsigned int timerid, uint32_t *actionid_out); 109*699cd480SApple OSS Distributions 110*699cd480SApple OSS Distributions /* 111*699cd480SApple OSS Distributions * Set the action of the timer identified by `timerid` to `actionid`. 112*699cd480SApple OSS Distributions */ 113*699cd480SApple OSS Distributions int kptimer_set_action(unsigned int timer, uint32_t actionid); 114*699cd480SApple OSS Distributions 115*699cd480SApple OSS Distributions /* 116*699cd480SApple OSS Distributions * Set the PET timer to the timer identified by `timerid`. 117*699cd480SApple OSS Distributions */ 118*699cd480SApple OSS Distributions int kptimer_set_pet_timerid(unsigned int timerid); 119*699cd480SApple OSS Distributions 120*699cd480SApple OSS Distributions /* 121*699cd480SApple OSS Distributions * Return the ID of the PET timer. 122*699cd480SApple OSS Distributions */ 123*699cd480SApple OSS Distributions unsigned int kptimer_get_pet_timerid(void); 124*699cd480SApple OSS Distributions 125*699cd480SApple OSS Distributions /* 126*699cd480SApple OSS Distributions * For PET to rearm its timer after its sampling thread took `sampledur_abs` 127*699cd480SApple OSS Distributions * to sample. 128*699cd480SApple OSS Distributions */ 129*699cd480SApple OSS Distributions void kptimer_pet_enter(uint64_t sampledur_abs); 130*699cd480SApple OSS Distributions 131*699cd480SApple OSS Distributions /* 132*699cd480SApple OSS Distributions * Start all active timers. The ktrace lock must be held. 133*699cd480SApple OSS Distributions */ 134*699cd480SApple OSS Distributions void kptimer_start(void); 135*699cd480SApple OSS Distributions 136*699cd480SApple OSS Distributions /* 137*699cd480SApple OSS Distributions * Stop all active timers, waiting for them to stop. The ktrace lock must be held. 138*699cd480SApple OSS Distributions */ 139*699cd480SApple OSS Distributions void kptimer_stop(void); 140*699cd480SApple OSS Distributions 141*699cd480SApple OSS Distributions /* 142*699cd480SApple OSS Distributions * Cancel outstanding kperf timer for this CPU. 143*699cd480SApple OSS Distributions */ 144*699cd480SApple OSS Distributions void kptimer_stop_curcpu(void); 145*699cd480SApple OSS Distributions 146*699cd480SApple OSS Distributions /* 147*699cd480SApple OSS Distributions * Reconfigure this CPU's kptimer expiration when it's brought online 148*699cd480SApple OSS Distributions */ 149*699cd480SApple OSS Distributions void kptimer_curcpu_up(void); 150*699cd480SApple OSS Distributions 151*699cd480SApple OSS Distributions /* 152*699cd480SApple OSS Distributions * To indicate the next timer has expired. 153*699cd480SApple OSS Distributions */ 154*699cd480SApple OSS Distributions void kptimer_expire(processor_t processor, int cpuid, uint64_t now); 155*699cd480SApple OSS Distributions 156*699cd480SApple OSS Distributions /* 157*699cd480SApple OSS Distributions * Reset the kptimer system. 158*699cd480SApple OSS Distributions */ 159*699cd480SApple OSS Distributions void kptimer_reset(void); 160*699cd480SApple OSS Distributions 161*699cd480SApple OSS Distributions #endif /* !defined(KPERF_KPTIMER_H) */ 162