Fix: scsi: sd: Atomic write support added in 6.11-rc1
[lttng-modules.git] / src / lttng-counter-client-percpu-32-modular.c
1 /* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only)
2 *
3 * lttng-counter-client-percpu-32-modular.c
4 *
5 * LTTng lib counter client. Per-cpu 32-bit counters in overflow
6 * arithmetic.
7 *
8 * Copyright (C) 2020 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
9 */
10
11 #include <linux/module.h>
12 #include <lttng/tracer.h>
13 #include <lttng/events.h>
14 #include <lttng/events-internal.h>
15 #include <counter/counter.h>
16 #include <counter/counter-api.h>
17
18 static const struct lib_counter_config client_config = {
19 .alloc = COUNTER_ALLOC_PER_CPU,
20 .sync = COUNTER_SYNC_PER_CPU,
21 .arithmetic = COUNTER_ARITHMETIC_MODULAR,
22 .counter_size = COUNTER_SIZE_32_BIT,
23 };
24
25 static struct lttng_kernel_channel_counter *counter_create(size_t nr_dimensions,
26 const struct lttng_kernel_counter_dimension *dimensions,
27 int64_t global_sum_step)
28 {
29 size_t max_nr_elem[LTTNG_KERNEL_COUNTER_MAX_DIMENSIONS], i;
30 struct lttng_kernel_channel_counter *lttng_chan_counter;
31 struct lib_counter *counter;
32
33 if (nr_dimensions > LTTNG_KERNEL_COUNTER_MAX_DIMENSIONS)
34 return NULL;
35 for (i = 0; i < nr_dimensions; i++) {
36 if ((dimensions[i].flags & LTTNG_KERNEL_COUNTER_DIMENSION_FLAG_UNDERFLOW)
37 || (dimensions[i].flags & LTTNG_KERNEL_COUNTER_DIMENSION_FLAG_OVERFLOW))
38 return NULL;
39 max_nr_elem[i] = dimensions[i].size;
40 }
41 lttng_chan_counter = lttng_kernel_alloc_channel_counter();
42 if (!lttng_chan_counter)
43 return NULL;
44 counter = lttng_counter_create(&client_config, nr_dimensions, max_nr_elem,
45 global_sum_step);
46 if (!counter)
47 goto error;
48 lttng_chan_counter->priv->counter = counter;
49 return lttng_chan_counter;
50
51 error:
52 lttng_kernel_free_channel_common(&lttng_chan_counter->parent);
53 return NULL;
54 }
55
56 static void counter_destroy(struct lttng_kernel_channel_counter *counter)
57 {
58 lttng_counter_destroy(counter->priv->counter);
59 lttng_kernel_free_channel_common(&counter->parent);
60 }
61
62 static int counter_add(struct lttng_kernel_channel_counter *counter,
63 const size_t *dimension_indexes, int64_t v)
64 {
65 return lttng_counter_add(&client_config, counter->priv->counter, dimension_indexes, v);
66 }
67
68 static int counter_hit(struct lttng_kernel_event_counter *event_counter,
69 const char *stack_data __attribute__((unused)),
70 struct lttng_kernel_probe_ctx *probe_ctx __attribute__((unused)),
71 struct lttng_kernel_event_counter_ctx *event_counter_ctx __attribute__((unused)))
72 {
73 struct lttng_kernel_channel_counter *counter = event_counter->chan;
74
75 switch (event_counter->priv->action) {
76 case LTTNG_EVENT_COUNTER_ACTION_INCREMENT:
77 {
78 size_t index = event_counter->priv->parent.id;
79 return counter_add(counter, &index, 1);
80 }
81 default:
82 return -ENOSYS;
83 }
84 }
85
86 static int counter_read(struct lttng_kernel_channel_counter *counter, const size_t *dimension_indexes, int cpu,
87 int64_t *value, bool *overflow, bool *underflow)
88 {
89 return lttng_counter_read(&client_config, counter->priv->counter, dimension_indexes, cpu, value,
90 overflow, underflow);
91 }
92
93 static int counter_aggregate(struct lttng_kernel_channel_counter *counter, const size_t *dimension_indexes,
94 int64_t *value, bool *overflow, bool *underflow)
95 {
96 return lttng_counter_aggregate(&client_config, counter->priv->counter, dimension_indexes, value,
97 overflow, underflow);
98 }
99
100 static int counter_clear(struct lttng_kernel_channel_counter *counter, const size_t *dimension_indexes)
101 {
102 return lttng_counter_clear(&client_config, counter->priv->counter, dimension_indexes);
103 }
104
105 static int counter_get_nr_dimensions(struct lttng_kernel_channel_counter *counter, size_t *nr_dimensions)
106 {
107 return lttng_counter_get_nr_dimensions(&client_config, counter->priv->counter, nr_dimensions);
108 }
109
110 static int counter_get_max_nr_elem(struct lttng_kernel_channel_counter *counter, size_t *max_nr_elem)
111 {
112 return lttng_counter_get_max_nr_elem(&client_config, counter->priv->counter, max_nr_elem);
113 }
114
115 static struct lttng_counter_transport lttng_counter_transport = {
116 .name = "counter-per-cpu-32-modular",
117 .owner = THIS_MODULE,
118 .ops = {
119 .priv = __LTTNG_COMPOUND_LITERAL(struct lttng_kernel_channel_counter_ops_private, {
120 .pub = &lttng_counter_transport.ops,
121 .counter_create = counter_create,
122 .counter_destroy = counter_destroy,
123 .counter_add = counter_add,
124 .counter_read = counter_read,
125 .counter_aggregate = counter_aggregate,
126 .counter_clear = counter_clear,
127 .counter_get_nr_dimensions = counter_get_nr_dimensions,
128 .counter_get_max_nr_elem = counter_get_max_nr_elem,
129 }),
130 .counter_hit = counter_hit,
131 },
132 };
133
134 static int __init lttng_counter_client_init(void)
135 {
136 /*
137 * This vmalloc sync all also takes care of the lib counter
138 * vmalloc'd module pages when it is built as a module into LTTng.
139 */
140 wrapper_vmalloc_sync_mappings();
141 lttng_counter_transport_register(&lttng_counter_transport);
142 return 0;
143 }
144
145 module_init(lttng_counter_client_init);
146
147 static void __exit lttng_counter_client_exit(void)
148 {
149 lttng_counter_transport_unregister(&lttng_counter_transport);
150 }
151
152 module_exit(lttng_counter_client_exit);
153
154 MODULE_LICENSE("GPL and additional rights");
155 MODULE_AUTHOR("Mathieu Desnoyers <mathieu.desnoyers@efficios.com>");
156 MODULE_DESCRIPTION("LTTng counter per-cpu 32-bit overflow client");
157 MODULE_VERSION(__stringify(LTTNG_MODULES_MAJOR_VERSION) "."
158 __stringify(LTTNG_MODULES_MINOR_VERSION) "."
159 __stringify(LTTNG_MODULES_PATCHLEVEL_VERSION)
160 LTTNG_MODULES_EXTRAVERSION);
This page took 0.039296 seconds and 5 git commands to generate.