Move headers under include/
[lttng-modules.git] / lttng-context-preemptible.c
1 /* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only)
2 *
3 * lttng-context-preemptible.c
4 *
5 * LTTng preemptible context.
6 *
7 * Copyright (C) 2009-2015 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 */
9
10 #include <linux/module.h>
11 #include <linux/slab.h>
12 #include <linux/sched.h>
13 #include <linux/irqflags.h>
14 #include <lttng/lttng-events.h>
15 #include <ringbuffer/frontend_types.h>
16 #include <lttng/lttng-tracer.h>
17
18 /*
19 * We nest twice in preempt disabling within LTTng: one nesting is done
20 * by the instrumentation (tracepoint, kprobes, kretprobes, syscall
21 * tracepoint), and the second is within the lib ring buffer
22 * lib_ring_buffer_get_cpu().
23 */
24 #define LTTNG_PREEMPT_DISABLE_NESTING 2
25
26 static
27 size_t preemptible_get_size(size_t offset)
28 {
29 size_t size = 0;
30
31 size += lib_ring_buffer_align(offset, lttng_alignof(uint8_t));
32 size += sizeof(uint8_t);
33 return size;
34 }
35
36 static
37 void preemptible_record(struct lttng_ctx_field *field,
38 struct lib_ring_buffer_ctx *ctx,
39 struct lttng_channel *chan)
40 {
41 int pc = preempt_count();
42 uint8_t preemptible = 0;
43
44 WARN_ON_ONCE(pc < LTTNG_PREEMPT_DISABLE_NESTING);
45 if (pc == LTTNG_PREEMPT_DISABLE_NESTING)
46 preemptible = 1;
47 lib_ring_buffer_align_ctx(ctx, lttng_alignof(preemptible));
48 chan->ops->event_write(ctx, &preemptible, sizeof(preemptible));
49 }
50
51 static
52 void preemptible_get_value(struct lttng_ctx_field *field,
53 struct lttng_probe_ctx *lttng_probe_ctx,
54 union lttng_ctx_value *value)
55 {
56 int pc = preempt_count();
57
58 WARN_ON_ONCE(pc < LTTNG_PREEMPT_DISABLE_NESTING);
59 if (pc == LTTNG_PREEMPT_DISABLE_NESTING)
60 value->s64 = 1;
61 else
62 value->s64 = 0;
63 }
64
65 int lttng_add_preemptible_to_ctx(struct lttng_ctx **ctx)
66 {
67 struct lttng_ctx_field *field;
68
69 field = lttng_append_context(ctx);
70 if (!field)
71 return -ENOMEM;
72 if (lttng_find_context(*ctx, "preemptible")) {
73 lttng_remove_context_field(ctx, field);
74 return -EEXIST;
75 }
76 field->event_field.name = "preemptible";
77 field->event_field.type.atype = atype_integer;
78 field->event_field.type.u.integer.size = sizeof(uint8_t) * CHAR_BIT;
79 field->event_field.type.u.integer.alignment = lttng_alignof(uint8_t) * CHAR_BIT;
80 field->event_field.type.u.integer.signedness = lttng_is_signed_type(uint8_t);
81 field->event_field.type.u.integer.reverse_byte_order = 0;
82 field->event_field.type.u.integer.base = 10;
83 field->event_field.type.u.integer.encoding = lttng_encode_none;
84 field->get_size = preemptible_get_size;
85 field->record = preemptible_record;
86 field->get_value = preemptible_get_value;
87 lttng_context_update(*ctx);
88 return 0;
89 }
90 EXPORT_SYMBOL_GPL(lttng_add_preemptible_to_ctx);
This page took 0.046833 seconds and 4 git commands to generate.