1d3d50737SRafael Vanoni /* 2d3d50737SRafael Vanoni * CDDL HEADER START 3d3d50737SRafael Vanoni * 4d3d50737SRafael Vanoni * The contents of this file are subject to the terms of the 5d3d50737SRafael Vanoni * Common Development and Distribution License (the "License"). 6d3d50737SRafael Vanoni * You may not use this file except in compliance with the License. 7d3d50737SRafael Vanoni * 8d3d50737SRafael Vanoni * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9d3d50737SRafael Vanoni * or http://www.opensolaris.org/os/licensing. 10d3d50737SRafael Vanoni * See the License for the specific language governing permissions 11d3d50737SRafael Vanoni * and limitations under the License. 12d3d50737SRafael Vanoni * 13d3d50737SRafael Vanoni * When distributing Covered Code, include this CDDL HEADER in each 14d3d50737SRafael Vanoni * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15d3d50737SRafael Vanoni * If applicable, add the following below this CDDL HEADER, with the 16d3d50737SRafael Vanoni * fields enclosed by brackets "[]" replaced with your own identifying 17d3d50737SRafael Vanoni * information: Portions Copyright [yyyy] [name of copyright owner] 18d3d50737SRafael Vanoni * 19d3d50737SRafael Vanoni * CDDL HEADER END 20d3d50737SRafael Vanoni */ 21d3d50737SRafael Vanoni 22d3d50737SRafael Vanoni /* 23*777222b7SRafael Vanoni * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 24d3d50737SRafael Vanoni */ 25d3d50737SRafael Vanoni 26d3d50737SRafael Vanoni #ifndef _SYS_CLOCK_IMPL_H 27d3d50737SRafael Vanoni #define _SYS_CLOCK_IMPL_H 28d3d50737SRafael Vanoni 29d3d50737SRafael Vanoni #ifdef __cplusplus 30d3d50737SRafael Vanoni extern "C" { 31d3d50737SRafael Vanoni #endif 32d3d50737SRafael Vanoni 33d3d50737SRafael Vanoni #if (defined(_KERNEL) || defined(_KMEMUSER)) 34d3d50737SRafael Vanoni #include <sys/types.h> 35d3d50737SRafael Vanoni #include <sys/cpuvar.h> 36d3d50737SRafael Vanoni #include <sys/cyclic.h> 37d3d50737SRafael Vanoni #include <sys/time.h> 38d3d50737SRafael Vanoni 39d3d50737SRafael Vanoni /* 40d3d50737SRafael Vanoni * Default clock rate in Hz. 41d3d50737SRafael Vanoni */ 42579a6895SRafael Vanoni #define HZ_DEFAULT (100) 43d3d50737SRafael Vanoni 44d3d50737SRafael Vanoni /* 45d3d50737SRafael Vanoni * Thresholds over which we switch between event and cyclic driven lbolt. The 46d3d50737SRafael Vanoni * current default values were derived experimentally and will keep the 47d3d50737SRafael Vanoni * system on event driven mode when idle and respond to activity around the 48d3d50737SRafael Vanoni * lbolt DDI functions by switching to cyclic mode. 49d3d50737SRafael Vanoni */ 50d3d50737SRafael Vanoni #define LBOLT_THRESH_CALLS (75) 51d3d50737SRafael Vanoni #define LBOLT_THRESH_INTERVAL (1) 52d3d50737SRafael Vanoni 53d3d50737SRafael Vanoni /* 54d3d50737SRafael Vanoni * Both lbolt_cpu_t and lbolt_info_t are cache line sized and aligned, 55d3d50737SRafael Vanoni * please take that in consideration if modifying these. 56d3d50737SRafael Vanoni */ 57d3d50737SRafael Vanoni typedef struct lbolt_cpu { 58d3d50737SRafael Vanoni int64_t lbc_counter; /* number of calls to the DDI lbolt routines */ 59d3d50737SRafael Vanoni int64_t lbc_cnt_start; /* beggining of the cnt interval (in ticks) */ 60d3d50737SRafael Vanoni char lbc_pad[CPU_CACHE_COHERENCE_SIZE - (2 * sizeof (int64_t))]; 61d3d50737SRafael Vanoni } lbolt_cpu_t; 62d3d50737SRafael Vanoni 63d3d50737SRafael Vanoni typedef struct lbolt_info { 64579a6895SRafael Vanoni union { 65d3d50737SRafael Vanoni cyclic_id_t lbi_cyclic_id; /* lbolt's cyclic id */ 66579a6895SRafael Vanoni int64_t lbi_id_pad; /* 64bit padding */ 67579a6895SRafael Vanoni } id; 68d3d50737SRafael Vanoni int64_t lbi_thresh_calls; /* max calls per interval */ 69d3d50737SRafael Vanoni int64_t lbi_thresh_interval; /* interval window for the # of calls */ 70*777222b7SRafael Vanoni int64_t lbi_debug_ts; /* last time we dropped into kmdb */ 71*777222b7SRafael Vanoni int64_t lbi_debug_time; /* time spent in the debugger */ 72*777222b7SRafael Vanoni int64_t lbi_internal; /* lbolt source when on cyclic mode */ 73d3d50737SRafael Vanoni uint32_t lbi_token; /* synchronize cyclic mode switch */ 74d3d50737SRafael Vanoni boolean_t lbi_cyc_deactivate; /* lbolt_cyclic self deactivation */ 75d3d50737SRafael Vanoni int64_t lbi_cyc_deac_start; /* deactivation interval */ 76d3d50737SRafael Vanoni } lbolt_info_t; 77d3d50737SRafael Vanoni 7883e866b9SRafael Vanoni extern int64_t lbolt_bootstrap(void); 79d3d50737SRafael Vanoni extern int64_t lbolt_event_driven(void); 80d3d50737SRafael Vanoni extern int64_t lbolt_cyclic_driven(void); 81d3d50737SRafael Vanoni extern int64_t (*lbolt_hybrid)(void); 82d3d50737SRafael Vanoni extern uint_t lbolt_ev_to_cyclic(caddr_t, caddr_t); 83d3d50737SRafael Vanoni 84d3d50737SRafael Vanoni extern void lbolt_softint_add(void); 85d3d50737SRafael Vanoni extern void lbolt_softint_post(void); 86d3d50737SRafael Vanoni 87d3d50737SRafael Vanoni extern void lbolt_debug_entry(void); 88d3d50737SRafael Vanoni extern void lbolt_debug_return(void); 89d3d50737SRafael Vanoni 90d3d50737SRafael Vanoni extern lbolt_info_t *lb_info; 91d3d50737SRafael Vanoni 92d3d50737SRafael Vanoni /* 931b7f7204SRafael Vanoni * LBOLT_WAITFREE{,64} provide a non-waiting version of lbolt. 94d3d50737SRafael Vanoni */ 951b7f7204SRafael Vanoni #define LBOLT_WAITFREE64 \ 9683e866b9SRafael Vanoni (lbolt_hybrid == lbolt_bootstrap ? 0 : \ 97d3d50737SRafael Vanoni (lbolt_hybrid == lbolt_event_driven ? \ 98d3d50737SRafael Vanoni ((gethrtime_waitfree()/nsec_per_tick) - \ 99d3d50737SRafael Vanoni lb_info->lbi_debug_time) : \ 10083e866b9SRafael Vanoni (lb_info->lbi_internal - lb_info->lbi_debug_time))) 101d3d50737SRafael Vanoni 1021b7f7204SRafael Vanoni #define LBOLT_WAITFREE (clock_t)LBOLT_WAITFREE64 103d3d50737SRafael Vanoni 104d3d50737SRafael Vanoni /* 1051b7f7204SRafael Vanoni * LBOLT_FASTPATH{,64} should *only* be used where the cost of calling the 1061b7f7204SRafael Vanoni * DDI lbolt routines affects performance. This is currently only used by 1071b7f7204SRafael Vanoni * the TCP/IP code and will be removed once it's no longer required. 1081b7f7204SRafael Vanoni */ 1091b7f7204SRafael Vanoni #define LBOLT_FASTPATH64 \ 11083e866b9SRafael Vanoni (lbolt_hybrid == lbolt_cyclic_driven ? \ 11183e866b9SRafael Vanoni (lb_info->lbi_internal - lb_info->lbi_debug_time) : \ 112*777222b7SRafael Vanoni lbolt_event_driven()) 1131b7f7204SRafael Vanoni 1141b7f7204SRafael Vanoni #define LBOLT_FASTPATH (clock_t)LBOLT_FASTPATH64 1151b7f7204SRafael Vanoni 1161b7f7204SRafael Vanoni /* 1171b7f7204SRafael Vanoni * LBOLT_NO_ACCOUNT{,64} is used by lbolt consumers who fire at a periodic 1181b7f7204SRafael Vanoni * rate, such as clock(), for which the lbolt usage statistics are not updated. 1191b7f7204SRafael Vanoni * This is especially important for consumers whose rate may be modified by 120d3d50737SRafael Vanoni * the user, resulting in an unaccounted for increase in activity around the 121d3d50737SRafael Vanoni * lbolt routines that could cause a mode switch. 122d3d50737SRafael Vanoni */ 1231b7f7204SRafael Vanoni #define LBOLT_NO_ACCOUNT64 \ 12483e866b9SRafael Vanoni (lbolt_hybrid == lbolt_bootstrap ? 0 : \ 125d3d50737SRafael Vanoni (lbolt_hybrid == lbolt_event_driven ? \ 126d3d50737SRafael Vanoni ((gethrtime()/nsec_per_tick) - lb_info->lbi_debug_time) : \ 12783e866b9SRafael Vanoni (lb_info->lbi_internal - lb_info->lbi_debug_time))) 128d3d50737SRafael Vanoni 1291b7f7204SRafael Vanoni #define LBOLT_NO_ACCOUNT (clock_t)LBOLT_NO_ACCOUNT64 1301b7f7204SRafael Vanoni 131d3d50737SRafael Vanoni #endif /* _KERNEL || _KMEMUSER */ 132d3d50737SRafael Vanoni 133d3d50737SRafael Vanoni #ifdef __cplusplus 134d3d50737SRafael Vanoni } 135d3d50737SRafael Vanoni #endif 136d3d50737SRafael Vanoni 137d3d50737SRafael Vanoni #endif /* _SYS_CLOCK_IMPL_H */ 138