6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
22 /* All Rights Reserved */
23
24 /*
25 * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
26 * Copyright (c) 2011, Joyent, Inc. All rights reserved.
27 */
28
29 #include <sys/param.h>
30 #include <sys/t_lock.h>
31 #include <sys/types.h>
32 #include <sys/tuneable.h>
33 #include <sys/sysmacros.h>
34 #include <sys/systm.h>
35 #include <sys/cpuvar.h>
36 #include <sys/lgrp.h>
37 #include <sys/user.h>
38 #include <sys/proc.h>
39 #include <sys/callo.h>
40 #include <sys/kmem.h>
41 #include <sys/var.h>
42 #include <sys/cmn_err.h>
43 #include <sys/swap.h>
44 #include <sys/vmsystm.h>
45 #include <sys/class.h>
46 #include <sys/time.h>
47 #include <sys/debug.h>
48 #include <sys/vtrace.h>
49 #include <sys/spl.h>
50 #include <sys/atomic.h>
51 #include <sys/dumphdr.h>
52 #include <sys/archsystm.h>
53 #include <sys/fs/swapnode.h>
54 #include <sys/panic.h>
55 #include <sys/disp.h>
56 #include <sys/msacct.h>
57 #include <sys/mem_cage.h>
58
59 #include <vm/page.h>
60 #include <vm/anon.h>
61 #include <vm/rm.h>
62 #include <sys/cyclic.h>
63 #include <sys/cpupart.h>
64 #include <sys/rctl.h>
65 #include <sys/task.h>
66 #include <sys/sdt.h>
67 #include <sys/ddi_timer.h>
68 #include <sys/random.h>
69 #include <sys/modctl.h>
70 #include <sys/zone.h>
71
72 /*
73 * for NTP support
74 */
75 #include <sys/timex.h>
76 #include <sys/inttypes.h>
77
78 #include <sys/sunddi.h>
79 #include <sys/clock_impl.h>
80
81 /*
82 * clock() is called straight from the clock cyclic; see clock_init().
83 *
84 * Functions:
85 * reprime clock
86 * maintain date
87 * jab the scheduler
299 /*
300 * Cache aligned, per CPU structure with lbolt usage statistics.
301 */
302 static lbolt_cpu_t *lb_cpu;
303
304 /*
305 * Single, cache aligned, structure with all the information required by
306 * the lbolt implementation.
307 */
308 lbolt_info_t *lb_info;
309
310
311 int one_sec = 1; /* turned on once every second */
312 static int fsflushcnt; /* counter for t_fsflushr */
313 int dosynctodr = 1; /* patchable; enable/disable sync to TOD chip */
314 int tod_needsync = 0; /* need to sync tod chip with software time */
315 static int tod_broken = 0; /* clock chip doesn't work */
316 time_t boot_time = 0; /* Boot time in seconds since 1970 */
317 cyclic_id_t clock_cyclic; /* clock()'s cyclic_id */
318 cyclic_id_t deadman_cyclic; /* deadman()'s cyclic_id */
319 cyclic_id_t ddi_timer_cyclic; /* cyclic_timer()'s cyclic_id */
320
321 extern void clock_tick_schedule(int);
322
323 static int lgrp_ticks; /* counter to schedule lgrp load calcs */
324
325 /*
326 * for tod fault detection
327 */
328 #define TOD_REF_FREQ ((longlong_t)(NANOSEC))
329 #define TOD_STALL_THRESHOLD (TOD_REF_FREQ * 3 / 2)
330 #define TOD_JUMP_THRESHOLD (TOD_REF_FREQ / 2)
331 #define TOD_FILTER_N 4
332 #define TOD_FILTER_SETTLE (4 * TOD_FILTER_N)
333 static int tod_faulted = TOD_NOFAULT;
334
335 static int tod_status_flag = 0; /* used by tod_validate() */
336
337 static hrtime_t prev_set_tick = 0; /* gethrtime() prior to tod_set() */
338 static time_t prev_set_tod = 0; /* tv_sec value passed to tod_set() */
339
930 */
931 if (wake_sched) {
932 t = &t0;
933 thread_lock(t);
934 if (t->t_state == TS_STOPPED) {
935 runin = runout = 0;
936 wake_sched = 0;
937 t->t_whystop = 0;
938 t->t_whatstop = 0;
939 t->t_schedflag &= ~TS_ALLSTART;
940 THREAD_TRANSITION(t);
941 setfrontdq(t);
942 }
943 thread_unlock(t);
944 }
945 }
946
947 void
948 clock_init(void)
949 {
950 cyc_handler_t clk_hdlr, timer_hdlr, lbolt_hdlr;
951 cyc_time_t clk_when, lbolt_when;
952 int i, sz;
953 intptr_t buf;
954
955 /*
956 * Setup handler and timer for the clock cyclic.
957 */
958 clk_hdlr.cyh_func = (cyc_func_t)clock;
959 clk_hdlr.cyh_level = CY_LOCK_LEVEL;
960 clk_hdlr.cyh_arg = NULL;
961
962 clk_when.cyt_when = 0;
963 clk_when.cyt_interval = nsec_per_tick;
964
965 /*
966 * cyclic_timer is dedicated to the ddi interface, which
967 * uses the same clock resolution as the system one.
968 */
969 timer_hdlr.cyh_func = (cyc_func_t)cyclic_timer;
970 timer_hdlr.cyh_level = CY_LOCK_LEVEL;
971 timer_hdlr.cyh_arg = NULL;
972
973 /*
974 * The lbolt cyclic will be reprogramed to fire at a nsec_per_tick
975 * interval to satisfy performance needs of the DDI lbolt consumers.
976 * It is off by default.
977 */
978 lbolt_hdlr.cyh_func = (cyc_func_t)lbolt_cyclic;
979 lbolt_hdlr.cyh_level = CY_LOCK_LEVEL;
980 lbolt_hdlr.cyh_arg = NULL;
981
982 lbolt_when.cyt_interval = nsec_per_tick;
983
984 /*
985 * Allocate cache line aligned space for the per CPU lbolt data and
986 * lbolt info structures, and initialize them with their default
987 * values. Note that these structures are also cache line sized.
988 */
989 sz = sizeof (lbolt_info_t) + CPU_CACHE_COHERENCE_SIZE;
990 buf = (intptr_t)kmem_zalloc(sz, KM_SLEEP);
991 lb_info = (lbolt_info_t *)P2ROUNDUP(buf, CPU_CACHE_COHERENCE_SIZE);
992
993 if (hz != HZ_DEFAULT)
1028 * lbolt_hybrid points at lbolt_bootstrap until now. The LBOLT_* macros
1029 * and lbolt_debug_{enter,return} use this value as an indication that
1030 * the initializaion above hasn't been completed. Setting lbolt_hybrid
1031 * to either lbolt_{cyclic,event}_driven here signals those code paths
1032 * that the lbolt related structures can be used.
1033 */
1034 if (lbolt_cyc_only) {
1035 lbolt_when.cyt_when = 0;
1036 lbolt_hybrid = lbolt_cyclic_driven;
1037 } else {
1038 lbolt_when.cyt_when = CY_INFINITY;
1039 lbolt_hybrid = lbolt_event_driven;
1040 }
1041
1042 /*
1043 * Grab cpu_lock and install all three cyclics.
1044 */
1045 mutex_enter(&cpu_lock);
1046
1047 clock_cyclic = cyclic_add(&clk_hdlr, &clk_when);
1048 ddi_timer_cyclic = cyclic_add(&timer_hdlr, &clk_when);
1049 lb_info->id.lbi_cyclic_id = cyclic_add(&lbolt_hdlr, &lbolt_when);
1050
1051 mutex_exit(&cpu_lock);
1052 }
1053
1054 /*
1055 * Called before calcloadavg to get 10-sec moving loadavg together
1056 */
1057
1058 static int
1059 genloadavg(struct loadavg_s *avgs)
1060 {
1061 int avg;
1062 int spos; /* starting position */
1063 int cpos; /* moving current position */
1064 int i;
1065 int slen;
1066 hrtime_t hr_avg;
1067
1068 /* 10-second snapshot, calculate first positon */
|
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
22 /* All Rights Reserved */
23
24 /*
25 * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
26 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
27 */
28
29 #include <sys/param.h>
30 #include <sys/t_lock.h>
31 #include <sys/types.h>
32 #include <sys/tuneable.h>
33 #include <sys/sysmacros.h>
34 #include <sys/systm.h>
35 #include <sys/cpuvar.h>
36 #include <sys/lgrp.h>
37 #include <sys/user.h>
38 #include <sys/proc.h>
39 #include <sys/callo.h>
40 #include <sys/kmem.h>
41 #include <sys/var.h>
42 #include <sys/cmn_err.h>
43 #include <sys/swap.h>
44 #include <sys/vmsystm.h>
45 #include <sys/class.h>
46 #include <sys/time.h>
47 #include <sys/debug.h>
48 #include <sys/vtrace.h>
49 #include <sys/spl.h>
50 #include <sys/atomic.h>
51 #include <sys/dumphdr.h>
52 #include <sys/archsystm.h>
53 #include <sys/fs/swapnode.h>
54 #include <sys/panic.h>
55 #include <sys/disp.h>
56 #include <sys/msacct.h>
57 #include <sys/mem_cage.h>
58
59 #include <vm/page.h>
60 #include <vm/anon.h>
61 #include <vm/rm.h>
62 #include <sys/cyclic.h>
63 #include <sys/cpupart.h>
64 #include <sys/rctl.h>
65 #include <sys/task.h>
66 #include <sys/sdt.h>
67 #include <sys/ddi_periodic.h>
68 #include <sys/random.h>
69 #include <sys/modctl.h>
70 #include <sys/zone.h>
71
72 /*
73 * for NTP support
74 */
75 #include <sys/timex.h>
76 #include <sys/inttypes.h>
77
78 #include <sys/sunddi.h>
79 #include <sys/clock_impl.h>
80
81 /*
82 * clock() is called straight from the clock cyclic; see clock_init().
83 *
84 * Functions:
85 * reprime clock
86 * maintain date
87 * jab the scheduler
299 /*
300 * Cache aligned, per CPU structure with lbolt usage statistics.
301 */
302 static lbolt_cpu_t *lb_cpu;
303
304 /*
305 * Single, cache aligned, structure with all the information required by
306 * the lbolt implementation.
307 */
308 lbolt_info_t *lb_info;
309
310
311 int one_sec = 1; /* turned on once every second */
312 static int fsflushcnt; /* counter for t_fsflushr */
313 int dosynctodr = 1; /* patchable; enable/disable sync to TOD chip */
314 int tod_needsync = 0; /* need to sync tod chip with software time */
315 static int tod_broken = 0; /* clock chip doesn't work */
316 time_t boot_time = 0; /* Boot time in seconds since 1970 */
317 cyclic_id_t clock_cyclic; /* clock()'s cyclic_id */
318 cyclic_id_t deadman_cyclic; /* deadman()'s cyclic_id */
319
320 extern void clock_tick_schedule(int);
321
322 static int lgrp_ticks; /* counter to schedule lgrp load calcs */
323
324 /*
325 * for tod fault detection
326 */
327 #define TOD_REF_FREQ ((longlong_t)(NANOSEC))
328 #define TOD_STALL_THRESHOLD (TOD_REF_FREQ * 3 / 2)
329 #define TOD_JUMP_THRESHOLD (TOD_REF_FREQ / 2)
330 #define TOD_FILTER_N 4
331 #define TOD_FILTER_SETTLE (4 * TOD_FILTER_N)
332 static int tod_faulted = TOD_NOFAULT;
333
334 static int tod_status_flag = 0; /* used by tod_validate() */
335
336 static hrtime_t prev_set_tick = 0; /* gethrtime() prior to tod_set() */
337 static time_t prev_set_tod = 0; /* tv_sec value passed to tod_set() */
338
929 */
930 if (wake_sched) {
931 t = &t0;
932 thread_lock(t);
933 if (t->t_state == TS_STOPPED) {
934 runin = runout = 0;
935 wake_sched = 0;
936 t->t_whystop = 0;
937 t->t_whatstop = 0;
938 t->t_schedflag &= ~TS_ALLSTART;
939 THREAD_TRANSITION(t);
940 setfrontdq(t);
941 }
942 thread_unlock(t);
943 }
944 }
945
946 void
947 clock_init(void)
948 {
949 cyc_handler_t clk_hdlr, lbolt_hdlr;
950 cyc_time_t clk_when, lbolt_when;
951 int i, sz;
952 intptr_t buf;
953
954 /*
955 * Setup handler and timer for the clock cyclic.
956 */
957 clk_hdlr.cyh_func = (cyc_func_t)clock;
958 clk_hdlr.cyh_level = CY_LOCK_LEVEL;
959 clk_hdlr.cyh_arg = NULL;
960
961 clk_when.cyt_when = 0;
962 clk_when.cyt_interval = nsec_per_tick;
963
964 /*
965 * The lbolt cyclic will be reprogramed to fire at a nsec_per_tick
966 * interval to satisfy performance needs of the DDI lbolt consumers.
967 * It is off by default.
968 */
969 lbolt_hdlr.cyh_func = (cyc_func_t)lbolt_cyclic;
970 lbolt_hdlr.cyh_level = CY_LOCK_LEVEL;
971 lbolt_hdlr.cyh_arg = NULL;
972
973 lbolt_when.cyt_interval = nsec_per_tick;
974
975 /*
976 * Allocate cache line aligned space for the per CPU lbolt data and
977 * lbolt info structures, and initialize them with their default
978 * values. Note that these structures are also cache line sized.
979 */
980 sz = sizeof (lbolt_info_t) + CPU_CACHE_COHERENCE_SIZE;
981 buf = (intptr_t)kmem_zalloc(sz, KM_SLEEP);
982 lb_info = (lbolt_info_t *)P2ROUNDUP(buf, CPU_CACHE_COHERENCE_SIZE);
983
984 if (hz != HZ_DEFAULT)
1019 * lbolt_hybrid points at lbolt_bootstrap until now. The LBOLT_* macros
1020 * and lbolt_debug_{enter,return} use this value as an indication that
1021 * the initializaion above hasn't been completed. Setting lbolt_hybrid
1022 * to either lbolt_{cyclic,event}_driven here signals those code paths
1023 * that the lbolt related structures can be used.
1024 */
1025 if (lbolt_cyc_only) {
1026 lbolt_when.cyt_when = 0;
1027 lbolt_hybrid = lbolt_cyclic_driven;
1028 } else {
1029 lbolt_when.cyt_when = CY_INFINITY;
1030 lbolt_hybrid = lbolt_event_driven;
1031 }
1032
1033 /*
1034 * Grab cpu_lock and install all three cyclics.
1035 */
1036 mutex_enter(&cpu_lock);
1037
1038 clock_cyclic = cyclic_add(&clk_hdlr, &clk_when);
1039 lb_info->id.lbi_cyclic_id = cyclic_add(&lbolt_hdlr, &lbolt_when);
1040
1041 mutex_exit(&cpu_lock);
1042 }
1043
1044 /*
1045 * Called before calcloadavg to get 10-sec moving loadavg together
1046 */
1047
1048 static int
1049 genloadavg(struct loadavg_s *avgs)
1050 {
1051 int avg;
1052 int spos; /* starting position */
1053 int cpos; /* moving current position */
1054 int i;
1055 int slen;
1056 hrtime_t hr_avg;
1057
1058 /* 10-second snapshot, calculate first positon */
|