30
31
#include "fatal-signal.h"
34
#include "ovs-thread.h"
33
35
#include "signals.h"
34
36
#include "unixctl.h"
38
/* backtrace() from <execinfo.h> is really useful, but it is not signal safe
39
* everywhere, such as on x86-64. */
40
#if HAVE_EXECINFO_H && !defined __x86_64__
41
# define USE_BACKTRACE 1
42
# include <execinfo.h>
44
# define USE_BACKTRACE 0
47
40
VLOG_DEFINE_THIS_MODULE(timeval);
49
/* The clock to use for measuring time intervals. This is CLOCK_MONOTONIC by
50
* preference, but on systems that don't have a monotonic clock we fall back
51
* to CLOCK_REALTIME. */
52
static clockid_t monotonic_clock;
54
/* Has a timer tick occurred? Only relevant if CACHE_TIME is true.
56
* We initialize these to true to force time_init() to get called on the first
57
* call to time_msec() or another function that queries the current time. */
58
static volatile sig_atomic_t wall_tick = true;
59
static volatile sig_atomic_t monotonic_tick = true;
61
/* The current time, as of the last refresh. */
62
static struct timespec wall_time;
63
static struct timespec monotonic_time;
43
clockid_t id; /* CLOCK_MONOTONIC or CLOCK_REALTIME. */
44
struct ovs_rwlock rwlock; /* Mutual exclusion for 'cache'. */
46
/* Features for use by unit tests. Protected by 'rwlock'. */
47
struct timespec warp; /* Offset added for unit tests. */
48
bool stopped; /* Disables real-time updates if true. */
50
/* Relevant only if CACHE_TIME is true. */
51
volatile sig_atomic_t tick; /* Has the timer ticked? Set by signal. */
52
struct timespec cache; /* Last time read from kernel. */
56
static struct clock monotonic_clock; /* CLOCK_MONOTONIC, if available. */
57
static struct clock wall_clock; /* CLOCK_REALTIME. */
65
59
/* The monotonic time at which the time module was initialized. */
66
60
static long long int boot_time;
68
/* features for use by unit tests. */
69
static struct timespec warp_offset; /* Offset added to monotonic_time. */
70
static bool time_stopped; /* Disables real-time updates, if true. */
72
/* Time in milliseconds at which to die with SIGALRM (if not LLONG_MAX). */
62
/* Monotonic time in milliseconds at which to die with SIGALRM (if not
73
64
static long long int deadline = LLONG_MAX;
76
void *backtrace[32]; /* Populated by backtrace(). */
77
size_t n_frames; /* Number of frames in 'backtrace'. */
79
/* format_backtraces() helper data. */
80
struct hmap_node node;
85
static struct trace traces[MAX_TRACES];
86
static size_t trace_head = 0;
66
/* Monotonic time, in milliseconds, at which the last call to time_poll() woke
68
DEFINE_PER_THREAD_DATA(long long int, last_wakeup, 0);
88
70
static void set_up_timer(void);
89
71
static void set_up_signal(int flags);
90
72
static void sigalrm_handler(int);
91
static void refresh_wall_if_ticked(void);
92
static void refresh_monotonic_if_ticked(void);
93
73
static void block_sigalrm(sigset_t *);
94
74
static void unblock_sigalrm(const sigset_t *);
95
75
static void log_poll_interval(long long int last_wakeup);
97
77
static void refresh_rusage(void);
98
78
static void timespec_add(struct timespec *sum,
99
79
const struct timespec *a, const struct timespec *b);
100
static unixctl_cb_func backtrace_cb;
104
backtrace(void **buffer OVS_UNUSED, int size OVS_UNUSED)
110
backtrace_symbols(void *const *buffer OVS_UNUSED, int size OVS_UNUSED)
114
#endif /* !USE_BACKTRACE */
82
init_clock(struct clock *c, clockid_t id)
84
memset(c, 0, sizeof *c);
86
ovs_rwlock_init(&c->rwlock);
87
xclock_gettime(c->id, &c->cache);
97
init_clock(&monotonic_clock, (!clock_gettime(CLOCK_MONOTONIC, &ts)
100
init_clock(&wall_clock, CLOCK_REALTIME);
101
boot_time = timespec_to_msec(&monotonic_clock.cache);
103
set_up_signal(SA_RESTART);
116
107
/* Initializes the timetracking module, if not already initialized. */
127
/* The implementation of backtrace() in glibc does some one time
128
* initialization which is not signal safe. This can cause deadlocks if
129
* run from the signal handler. As a workaround, force the initialization
134
backtrace(bt, ARRAY_SIZE(bt));
137
memset(traces, 0, sizeof traces);
139
if (USE_BACKTRACE && CACHE_TIME) {
140
unixctl_command_register("backtrace", "", 0, 0, backtrace_cb, NULL);
145
if (!clock_gettime(CLOCK_MONOTONIC, &monotonic_time)) {
146
monotonic_clock = CLOCK_MONOTONIC;
148
monotonic_clock = CLOCK_REALTIME;
149
VLOG_DBG("monotonic timer not available");
152
set_up_signal(SA_RESTART);
155
boot_time = time_msec();
111
static pthread_once_t once = PTHREAD_ONCE_INIT;
112
pthread_once(&once, do_init_time);
167
124
xsigaction(SIGALRM, &sa, NULL);
170
/* Remove SA_RESTART from the flags for SIGALRM, so that any system call that
171
* is interrupted by the periodic timer interrupt will return EINTR instead of
172
* continuing after the signal handler returns.
174
* time_disable_restart() and time_enable_restart() may be usefully wrapped
175
* around function calls that might otherwise block forever unless interrupted
178
* time_disable_restart();
179
* fcntl(fd, F_SETLKW, &lock);
180
* time_enable_restart();
183
time_disable_restart(void)
189
/* Add SA_RESTART to the flags for SIGALRM, so that any system call that
190
* is interrupted by the periodic timer interrupt will continue after the
191
* signal handler returns instead of returning EINTR. */
193
time_enable_restart(void)
196
set_up_signal(SA_RESTART);
200
128
set_up_timer(void)
228
156
time_postfork(void)
158
assert_single_threaded();
238
clock_gettime(CLOCK_REALTIME, &wall_time);
243
refresh_monotonic(void)
248
if (monotonic_clock == CLOCK_MONOTONIC) {
249
clock_gettime(monotonic_clock, &monotonic_time);
251
refresh_wall_if_ticked();
252
monotonic_time = wall_time;
254
timespec_add(&monotonic_time, &monotonic_time, &warp_offset);
256
monotonic_tick = false;
260
163
/* Forces a refresh of the current time from the kernel. It is not usually
261
164
* necessary to call this function, since the time will be refreshed
262
165
* automatically at least every TIME_UPDATE_INTERVAL milliseconds. If
266
169
time_refresh(void)
268
wall_tick = monotonic_tick = true;
171
monotonic_clock.tick = wall_clock.tick = true;
175
time_timespec__(struct clock *c, struct timespec *ts)
179
/* Use the cached time by preference, but fall through if there's been
181
ovs_rwlock_rdlock(&c->rwlock);
182
if (c->stopped || !c->tick) {
183
timespec_add(ts, &c->cache, &c->warp);
184
ovs_rwlock_unlock(&c->rwlock);
187
ovs_rwlock_unlock(&c->rwlock);
189
/* Refresh the cache. */
190
ovs_rwlock_wrlock(&c->rwlock);
193
xclock_gettime(c->id, &c->cache);
195
ovs_rwlock_unlock(&c->rwlock);
199
/* Stores a monotonic timer, accurate within TIME_UPDATE_INTERVAL ms, into
202
time_timespec(struct timespec *ts)
204
time_timespec__(&monotonic_clock, ts);
207
/* Stores the current time, accurate within TIME_UPDATE_INTERVAL ms, into
210
time_wall_timespec(struct timespec *ts)
212
time_timespec__(&wall_clock, ts);
216
time_sec__(struct clock *c)
220
time_timespec__(c, &ts);
271
224
/* Returns a monotonic timer, in seconds. */
275
refresh_monotonic_if_ticked();
276
return monotonic_time.tv_sec;
228
return time_sec__(&monotonic_clock);
279
231
/* Returns the current time, in seconds. */
283
refresh_wall_if_ticked();
284
return wall_time.tv_sec;
235
return time_sec__(&wall_clock);
239
time_msec__(struct clock *c)
243
time_timespec__(c, &ts);
244
return timespec_to_msec(&ts);
287
247
/* Returns a monotonic timer, in ms (within TIME_UPDATE_INTERVAL ms). */
291
refresh_monotonic_if_ticked();
292
return timespec_to_msec(&monotonic_time);
251
return time_msec__(&monotonic_clock);
295
254
/* Returns the current time, in ms (within TIME_UPDATE_INTERVAL ms). */
297
256
time_wall_msec(void)
299
refresh_wall_if_ticked();
300
return timespec_to_msec(&wall_time);
303
/* Stores a monotonic timer, accurate within TIME_UPDATE_INTERVAL ms, into
306
time_timespec(struct timespec *ts)
308
refresh_monotonic_if_ticked();
309
*ts = monotonic_time;
312
/* Stores the current time, accurate within TIME_UPDATE_INTERVAL ms, into
315
time_wall_timespec(struct timespec *ts)
317
refresh_wall_if_ticked();
258
return time_msec__(&wall_clock);
321
261
/* Configures the program to die with SIGALRM 'secs' seconds from now, if
412
349
unblock_sigalrm(&oldsigs);
414
last_wakeup = time_msec();
351
*last_wakeup = time_msec();
415
352
refresh_rusage();
416
*elapsed = last_wakeup - start;
353
*elapsed = *last_wakeup - start;
421
358
sigalrm_handler(int sig_nr OVS_UNUSED)
424
monotonic_tick = true;
426
if (USE_BACKTRACE && CACHE_TIME) {
427
struct trace *trace = &traces[trace_head];
429
trace->n_frames = backtrace(trace->backtrace,
430
ARRAY_SIZE(trace->backtrace));
431
trace_head = (trace_head + 1) % MAX_TRACES;
436
refresh_wall_if_ticked(void)
438
if (!CACHE_TIME || wall_tick) {
444
refresh_monotonic_if_ticked(void)
446
if (!CACHE_TIME || monotonic_tick) {
360
monotonic_clock.tick = wall_clock.tick = true;
454
366
sigset_t sigalrm;
455
367
sigemptyset(&sigalrm);
456
368
sigaddset(&sigalrm, SIGALRM);
457
xsigprocmask(SIG_BLOCK, &sigalrm, oldsigs);
369
xpthread_sigmask(SIG_BLOCK, &sigalrm, oldsigs);
461
373
unblock_sigalrm(const sigset_t *oldsigs)
463
xsigprocmask(SIG_SETMASK, oldsigs, NULL);
375
xpthread_sigmask(SIG_SETMASK, oldsigs, NULL);
488
400
xgettimeofday(struct timeval *tv)
490
402
if (gettimeofday(tv, NULL) == -1) {
491
VLOG_FATAL("gettimeofday failed (%s)", strerror(errno));
403
VLOG_FATAL("gettimeofday failed (%s)", ovs_strerror(errno));
408
xclock_gettime(clock_t id, struct timespec *ts)
410
if (clock_gettime(id, ts) == -1) {
411
/* It seems like a bad idea to try to use vlog here because it is
412
* likely to try to check the current time. */
413
ovs_abort(errno, "xclock_gettime() failed");
561
485
unsigned long long int cpu; /* Total user+system CPU usage when sampled. */
564
static struct rusage recent_rusage;
565
static struct cpu_usage older = { LLONG_MIN, 0 };
566
static struct cpu_usage newer = { LLONG_MIN, 0 };
567
static int cpu_usage = -1;
489
struct cpu_usage older;
490
struct cpu_usage newer;
493
struct rusage recent_rusage;
495
DEFINE_PER_THREAD_MALLOCED_DATA(struct cpu_tracker *, cpu_tracker_var);
497
static struct cpu_tracker *
498
get_cpu_tracker(void)
500
struct cpu_tracker *t = cpu_tracker_var_get();
502
t = xzalloc(sizeof *t);
503
t->older.when = LLONG_MIN;
504
t->newer.when = LLONG_MIN;
505
cpu_tracker_var_set_unsafe(t);
569
510
static struct rusage *
570
511
get_recent_rusage(void)
572
return &recent_rusage;
513
return &get_cpu_tracker()->recent_rusage;
517
getrusage_thread(struct rusage *rusage OVS_UNUSED)
520
return getrusage(RUSAGE_THREAD, rusage);
576
528
refresh_rusage(void)
581
getrusage(RUSAGE_SELF, &recent_rusage);
583
if (now >= newer.when + 3 * 1000) {
586
newer.cpu = (timeval_to_msec(&recent_rusage.ru_utime) +
587
timeval_to_msec(&recent_rusage.ru_stime));
589
if (older.when != LLONG_MIN && newer.cpu > older.cpu) {
590
unsigned int dividend = newer.cpu - older.cpu;
591
unsigned int divisor = (newer.when - older.when) / 100;
592
cpu_usage = divisor > 0 ? dividend / divisor : -1;
530
struct cpu_tracker *t = get_cpu_tracker();
531
struct rusage *recent_rusage = &t->recent_rusage;
533
if (!getrusage_thread(recent_rusage)) {
534
long long int now = time_msec();
535
if (now >= t->newer.when + 3 * 1000) {
538
t->newer.cpu = (timeval_to_msec(&recent_rusage->ru_utime) +
539
timeval_to_msec(&recent_rusage->ru_stime));
541
if (t->older.when != LLONG_MIN && t->newer.cpu > t->older.cpu) {
542
unsigned int dividend = t->newer.cpu - t->older.cpu;
543
unsigned int divisor = (t->newer.when - t->older.when) / 100;
544
t->cpu_usage = divisor > 0 ? dividend / divisor : -1;
604
557
get_cpu_usage(void)
610
hash_trace(struct trace *trace)
612
return hash_bytes(trace->backtrace,
613
trace->n_frames * sizeof *trace->backtrace, 0);
616
static struct trace *
617
trace_map_lookup(struct hmap *trace_map, struct trace *key)
621
HMAP_FOR_EACH_WITH_HASH (value, node, hash_trace(key), trace_map) {
622
if (key->n_frames == value->n_frames
623
&& !memcmp(key->backtrace, value->backtrace,
624
key->n_frames * sizeof *key->backtrace)) {
631
/* Appends a string to 'ds' representing backtraces recorded at regular
632
* intervals in the recent past. This information can be used to get a sense
633
* of what the process has been spending the majority of time doing. Will
634
* ommit any backtraces which have not occurred at least 'min_count' times. */
636
format_backtraces(struct ds *ds, size_t min_count)
640
if (USE_BACKTRACE && CACHE_TIME) {
641
struct hmap trace_map = HMAP_INITIALIZER(&trace_map);
642
struct trace *trace, *next;
646
block_sigalrm(&oldsigs);
648
for (i = 0; i < MAX_TRACES; i++) {
649
struct trace *trace = &traces[i];
650
struct trace *map_trace;
652
if (!trace->n_frames) {
656
map_trace = trace_map_lookup(&trace_map, trace);
660
hmap_insert(&trace_map, &trace->node, hash_trace(trace));
665
HMAP_FOR_EACH_SAFE (trace, next, node, &trace_map) {
669
hmap_remove(&trace_map, &trace->node);
671
if (trace->count < min_count) {
675
frame_strs = backtrace_symbols(trace->backtrace, trace->n_frames);
677
ds_put_format(ds, "Count %zu\n", trace->count);
678
for (j = 0; j < trace->n_frames; j++) {
679
ds_put_format(ds, "%s\n", frame_strs[j]);
681
ds_put_cstr(ds, "\n");
685
hmap_destroy(&trace_map);
688
unblock_sigalrm(&oldsigs);
559
return get_cpu_tracker()->cpu_usage;
692
562
/* Unixctl interface. */
723
596
ts.tv_sec = msecs / 1000;
724
597
ts.tv_nsec = (msecs % 1000) * 1000 * 1000;
725
timespec_add(&warp_offset, &warp_offset, &ts);
726
timespec_add(&monotonic_time, &monotonic_time, &ts);
599
ovs_rwlock_wrlock(&monotonic_clock.rwlock);
600
timespec_add(&monotonic_clock.warp, &monotonic_clock.warp, &ts);
601
ovs_rwlock_unlock(&monotonic_clock.rwlock);
727
603
unixctl_command_reply(conn, "warped");
731
backtrace_cb(struct unixctl_conn *conn,
732
int argc OVS_UNUSED, const char *argv[] OVS_UNUSED,
733
void *aux OVS_UNUSED)
735
struct ds ds = DS_EMPTY_INITIALIZER;
737
ovs_assert(USE_BACKTRACE && CACHE_TIME);
738
format_backtraces(&ds, 0);
739
unixctl_command_reply(conn, ds_cstr(&ds));
744
607
timeval_dummy_register(void)