Commit | Line | Data |
---|---|---|
9f36eaed MJ |
1 | /* SPDX-License-Identifier: (GPL-2.0 or LGPL-2.1) |
2 | * | |
2754583e MD |
3 | * lttng-clock.c |
4 | * | |
5 | * Copyright (C) 2014 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | |
2754583e MD |
6 | */ |
7 | ||
8 | #include <linux/module.h> | |
9 | #include <linux/kmod.h> | |
10 | #include <linux/mutex.h> | |
11 | ||
241ae9a8 MD |
12 | #include <wrapper/trace-clock.h> |
13 | #include <lttng-events.h> | |
14 | #include <lttng-tracer.h> | |
2754583e MD |
15 | |
16 | struct lttng_trace_clock *lttng_trace_clock; | |
17 | EXPORT_SYMBOL_GPL(lttng_trace_clock); | |
18 | ||
19 | static DEFINE_MUTEX(clock_mutex); | |
20 | static struct module *lttng_trace_clock_mod; /* plugin */ | |
21 | static int clock_used; /* refcount */ | |
22 | ||
23 | int lttng_clock_register_plugin(struct lttng_trace_clock *ltc, | |
24 | struct module *mod) | |
25 | { | |
26 | int ret = 0; | |
27 | ||
28 | mutex_lock(&clock_mutex); | |
29 | if (clock_used) { | |
30 | ret = -EBUSY; | |
31 | goto end; | |
32 | } | |
33 | if (lttng_trace_clock_mod) { | |
34 | ret = -EEXIST; | |
35 | goto end; | |
36 | } | |
37 | /* set clock */ | |
a8f2d0c7 | 38 | WRITE_ONCE(lttng_trace_clock, ltc); |
2754583e MD |
39 | lttng_trace_clock_mod = mod; |
40 | end: | |
41 | mutex_unlock(&clock_mutex); | |
42 | return ret; | |
43 | } | |
44 | EXPORT_SYMBOL_GPL(lttng_clock_register_plugin); | |
45 | ||
46 | void lttng_clock_unregister_plugin(struct lttng_trace_clock *ltc, | |
47 | struct module *mod) | |
48 | { | |
49 | mutex_lock(&clock_mutex); | |
50 | WARN_ON_ONCE(clock_used); | |
51 | if (!lttng_trace_clock_mod) { | |
52 | goto end; | |
53 | } | |
54 | WARN_ON_ONCE(lttng_trace_clock_mod != mod); | |
55 | ||
a8f2d0c7 | 56 | WRITE_ONCE(lttng_trace_clock, NULL); |
2754583e MD |
57 | lttng_trace_clock_mod = NULL; |
58 | end: | |
59 | mutex_unlock(&clock_mutex); | |
60 | } | |
61 | EXPORT_SYMBOL_GPL(lttng_clock_unregister_plugin); | |
62 | ||
63 | void lttng_clock_ref(void) | |
64 | { | |
65 | mutex_lock(&clock_mutex); | |
66 | clock_used++; | |
67 | if (lttng_trace_clock_mod) { | |
68 | int ret; | |
69 | ||
70 | ret = try_module_get(lttng_trace_clock_mod); | |
71 | if (!ret) { | |
72 | printk(KERN_ERR "LTTng-clock cannot get clock plugin module\n"); | |
a8f2d0c7 | 73 | WRITE_ONCE(lttng_trace_clock, NULL); |
2754583e MD |
74 | lttng_trace_clock_mod = NULL; |
75 | } | |
76 | } | |
77 | mutex_unlock(&clock_mutex); | |
78 | } | |
79 | EXPORT_SYMBOL_GPL(lttng_clock_ref); | |
80 | ||
81 | void lttng_clock_unref(void) | |
82 | { | |
83 | mutex_lock(&clock_mutex); | |
84 | clock_used--; | |
85 | if (lttng_trace_clock_mod) | |
86 | module_put(lttng_trace_clock_mod); | |
87 | mutex_unlock(&clock_mutex); | |
88 | } | |
89 | EXPORT_SYMBOL_GPL(lttng_clock_unref); | |
90 | ||
91 | MODULE_LICENSE("GPL and additional rights"); | |
92 | MODULE_AUTHOR("Mathieu Desnoyers <mathieu.desnoyers@efficios.com>"); | |
93 | MODULE_DESCRIPTION("LTTng Clock"); | |
94 | MODULE_VERSION(__stringify(LTTNG_MODULES_MAJOR_VERSION) "." | |
95 | __stringify(LTTNG_MODULES_MINOR_VERSION) "." | |
96 | __stringify(LTTNG_MODULES_PATCHLEVEL_VERSION) | |
97 | LTTNG_MODULES_EXTRAVERSION); |