Contexts for RT debugging
authorJulien Desfossez <jdesfossez@efficios.com>
Thu, 12 Nov 2015 20:49:24 +0000 (15:49 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 17 Nov 2015 19:18:17 +0000 (14:18 -0500)
Add the interruptible, preemptible, need_resched and migratable
contexts.

Signed-off-by: Julien Desfossez <jdesfossez@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
28 files changed:
Makefile
lttng-abi.c
lttng-abi.h
lttng-context-cpu-id.c
lttng-context-hostname.c
lttng-context-interruptible.c [new file with mode: 0644]
lttng-context-migratable.c [new file with mode: 0644]
lttng-context-need-reschedule.c [new file with mode: 0644]
lttng-context-nice.c
lttng-context-pid.c
lttng-context-ppid.c
lttng-context-preemptible.c [new file with mode: 0644]
lttng-context-prio.c
lttng-context-procname.c
lttng-context-tid.c
lttng-context-vpid.c
lttng-context-vppid.c
lttng-context-vtid.c
lttng-context.c
lttng-events.h
lttng-filter-interpreter.c
lttng-filter.h
lttng-ring-buffer-client.h
probes/lttng-events.h
probes/lttng-ftrace.c
probes/lttng-kprobes.c
probes/lttng-kretprobes.c
wrapper/irqflags.h [new file with mode: 0644]

index f7aa23f6127959f0d3309790639b3f38fdf2d1c6..29204bc08e4ca3a5b3010d73bb756f54684864f0 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -41,7 +41,8 @@ lttng-tracer-objs :=  lttng-events.o lttng-abi.o \
                        lttng-context-vpid.o lttng-context-tid.o \
                        lttng-context-vtid.o lttng-context-ppid.o \
                        lttng-context-vppid.o lttng-context-cpu-id.o \
-                       lttng-calibrate.o \
+                       lttng-context-interruptible.o \
+                       lttng-context-need-reschedule.o lttng-calibrate.o \
                        lttng-context-hostname.o wrapper/random.o \
                        probes/lttng.o wrapper/trace-clock.o \
                        wrapper/page_alloc.o \
@@ -66,6 +67,15 @@ lttng-tracer-objs += $(shell \
                echo "lttng-context-perf-counters.o" ; fi;)
 endif # CONFIG_PERF_EVENTS
 
+ifneq ($(CONFIG_PREEMPT_RT_FULL),)
+lttng-tracer-objs += lttng-context-migratable.o
+lttng-tracer-objs += lttng-context-preemptible.o
+endif # CONFIG_PREEMPT_RT_FULL
+
+ifneq ($(CONFIG_PREEMPT),)
+lttng-tracer-objs += lttng-context-preemptible.o
+endif
+
 lttng-tracer-objs += $(shell \
        if [ $(VERSION) -ge 4 \
                -o \( $(VERSION) -eq 3 -a $(PATCHLEVEL) -ge 15 -a $(SUBLEVEL) -ge 0 \) ] ; then \
index f6f30430b9e89c4547d55f4c705fc233379ffe53..b3de09264783cd69c7996eb53515182aa205768f 100644 (file)
@@ -236,6 +236,14 @@ long lttng_abi_add_context(struct file *file,
                return lttng_add_hostname_to_ctx(ctx);
        case LTTNG_KERNEL_CONTEXT_CPU_ID:
                return lttng_add_cpu_id_to_ctx(ctx);
+       case LTTNG_KERNEL_CONTEXT_INTERRUPTIBLE:
+               return lttng_add_interruptible_to_ctx(ctx);
+       case LTTNG_KERNEL_CONTEXT_NEED_RESCHEDULE:
+               return lttng_add_need_reschedule_to_ctx(ctx);
+       case LTTNG_KERNEL_CONTEXT_PREEMPTIBLE:
+               return lttng_add_preemptible_to_ctx(ctx);
+       case LTTNG_KERNEL_CONTEXT_MIGRATABLE:
+               return lttng_add_migratable_to_ctx(ctx);
        default:
                return -EINVAL;
        }
index a40b58f51dec8487c3e3d5a3c6d1129faac65dc3..e53ff272306dfa5d91a7a910845b4f91a5ea5c44 100644 (file)
@@ -142,6 +142,10 @@ enum lttng_kernel_context_type {
        LTTNG_KERNEL_CONTEXT_VPPID              = 9,
        LTTNG_KERNEL_CONTEXT_HOSTNAME           = 10,
        LTTNG_KERNEL_CONTEXT_CPU_ID             = 11,
+       LTTNG_KERNEL_CONTEXT_INTERRUPTIBLE      = 12,
+       LTTNG_KERNEL_CONTEXT_PREEMPTIBLE        = 13,
+       LTTNG_KERNEL_CONTEXT_NEED_RESCHEDULE    = 14,
+       LTTNG_KERNEL_CONTEXT_MIGRATABLE         = 15,
 };
 
 struct lttng_kernel_perf_counter_ctx {
index 0738d9c7e5364f0b67b8afe38b36d8a821fb5ac9..ed2a2a926ebf0c9b38e768184d0fee1f15fec250 100644 (file)
@@ -52,6 +52,7 @@ void cpu_id_record(struct lttng_ctx_field *field,
 
 static
 void cpu_id_get_value(struct lttng_ctx_field *field,
+               struct lttng_probe_ctx *lttng_probe_ctx,
                union lttng_ctx_value *value)
 {
        value->s64 = smp_processor_id();
index 28881d05b771eae420114334862610b19b22a265..7d9f0816851697a9b96f76e87490d5d141c71214 100644 (file)
@@ -67,6 +67,7 @@ void hostname_record(struct lttng_ctx_field *field,
 
 static
 void hostname_get_value(struct lttng_ctx_field *field,
+               struct lttng_probe_ctx *lttng_probe_ctx,
                union lttng_ctx_value *value)
 {
        struct nsproxy *nsproxy;
diff --git a/lttng-context-interruptible.c b/lttng-context-interruptible.c
new file mode 100644 (file)
index 0000000..b608a6e
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * lttng-context-interruptible.c
+ *
+ * LTTng interruptible context.
+ *
+ * Copyright (C) 2009-2015 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; only
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/irqflags.h>
+#include "lttng-events.h"
+#include "wrapper/ringbuffer/frontend_types.h"
+#include "wrapper/vmalloc.h"
+#include "lttng-tracer.h"
+
+/*
+ * Interruptible at value -1 means "unknown".
+ */
+
+static
+size_t interruptible_get_size(size_t offset)
+{
+       size_t size = 0;
+
+       size += lib_ring_buffer_align(offset, lttng_alignof(int8_t));
+       size += sizeof(int8_t);
+       return size;
+}
+
+static
+void interruptible_record(struct lttng_ctx_field *field,
+               struct lib_ring_buffer_ctx *ctx,
+               struct lttng_channel *chan)
+{
+       struct lttng_probe_ctx *lttng_probe_ctx = ctx->priv;
+       int8_t interruptible = lttng_probe_ctx->interruptible;
+
+       lib_ring_buffer_align_ctx(ctx, lttng_alignof(interruptible));
+       chan->ops->event_write(ctx, &interruptible, sizeof(interruptible));
+}
+
+static
+void interruptible_get_value(struct lttng_ctx_field *field,
+               struct lttng_probe_ctx *lttng_probe_ctx,
+               union lttng_ctx_value *value)
+{
+       int8_t interruptible = lttng_probe_ctx->interruptible;
+
+       value->s64 = interruptible;
+}
+
+int lttng_add_interruptible_to_ctx(struct lttng_ctx **ctx)
+{
+       struct lttng_ctx_field *field;
+
+       field = lttng_append_context(ctx);
+       if (!field)
+               return -ENOMEM;
+       if (lttng_find_context(*ctx, "interruptible")) {
+               lttng_remove_context_field(ctx, field);
+               return -EEXIST;
+       }
+       field->event_field.name = "interruptible";
+       field->event_field.type.atype = atype_integer;
+       field->event_field.type.u.basic.integer.size = sizeof(int8_t) * CHAR_BIT;
+       field->event_field.type.u.basic.integer.alignment = lttng_alignof(int8_t) * CHAR_BIT;
+       field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(int8_t);
+       field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+       field->event_field.type.u.basic.integer.base = 10;
+       field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+       field->get_size = interruptible_get_size;
+       field->record = interruptible_record;
+       field->get_value = interruptible_get_value;
+       lttng_context_update(*ctx);
+       wrapper_vmalloc_sync_all();
+       return 0;
+}
+EXPORT_SYMBOL_GPL(lttng_add_interruptible_to_ctx);
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit interruptible Context");
+MODULE_VERSION(__stringify(LTTNG_MODULES_MAJOR_VERSION) "."
+       __stringify(LTTNG_MODULES_MINOR_VERSION) "."
+       __stringify(LTTNG_MODULES_PATCHLEVEL_VERSION)
+       LTTNG_MODULES_EXTRAVERSION);
diff --git a/lttng-context-migratable.c b/lttng-context-migratable.c
new file mode 100644 (file)
index 0000000..1aaedf6
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * lttng-context-migratable.c
+ *
+ * LTTng migratable context.
+ *
+ * Copyright (C) 2009-2015 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; only
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/irqflags.h>
+#include "lttng-events.h"
+#include "wrapper/ringbuffer/frontend_types.h"
+#include "wrapper/vmalloc.h"
+#include "lttng-tracer.h"
+
+static
+size_t migratable_get_size(size_t offset)
+{
+       size_t size = 0;
+
+       size += lib_ring_buffer_align(offset, lttng_alignof(uint8_t));
+       size += sizeof(uint8_t);
+       return size;
+}
+
+static
+void migratable_record(struct lttng_ctx_field *field,
+               struct lib_ring_buffer_ctx *ctx,
+               struct lttng_channel *chan)
+{
+       uint8_t migratable = !__migrate_disabled(current);
+
+       lib_ring_buffer_align_ctx(ctx, lttng_alignof(migratable));
+       chan->ops->event_write(ctx, &migratable, sizeof(migratable));
+}
+
+static
+void migratable_get_value(struct lttng_ctx_field *field,
+               struct lttng_probe_ctx *lttng_probe_ctx,
+               union lttng_ctx_value *value)
+{
+       value->s64 = !__migrate_disabled(current);
+}
+
+int lttng_add_migratable_to_ctx(struct lttng_ctx **ctx)
+{
+       struct lttng_ctx_field *field;
+
+       field = lttng_append_context(ctx);
+       if (!field)
+               return -ENOMEM;
+       if (lttng_find_context(*ctx, "migratable")) {
+               lttng_remove_context_field(ctx, field);
+               return -EEXIST;
+       }
+       field->event_field.name = "migratable";
+       field->event_field.type.atype = atype_integer;
+       field->event_field.type.u.basic.integer.size = sizeof(uint8_t) * CHAR_BIT;
+       field->event_field.type.u.basic.integer.alignment = lttng_alignof(uint8_t) * CHAR_BIT;
+       field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(uint8_t);
+       field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+       field->event_field.type.u.basic.integer.base = 10;
+       field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+       field->get_size = migratable_get_size;
+       field->record = migratable_record;
+       field->get_value = migratable_get_value;
+       lttng_context_update(*ctx);
+       wrapper_vmalloc_sync_all();
+       return 0;
+}
+EXPORT_SYMBOL_GPL(lttng_add_migratable_to_ctx);
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit migratable Context");
+MODULE_VERSION(__stringify(LTTNG_MODULES_MAJOR_VERSION) "."
+       __stringify(LTTNG_MODULES_MINOR_VERSION) "."
+       __stringify(LTTNG_MODULES_PATCHLEVEL_VERSION)
+       LTTNG_MODULES_EXTRAVERSION);
diff --git a/lttng-context-need-reschedule.c b/lttng-context-need-reschedule.c
new file mode 100644 (file)
index 0000000..82f2d61
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * lttng-context-need-reschedule.c
+ *
+ * LTTng need_reschedule context.
+ *
+ * Copyright (C) 2009-2015 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; only
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/irqflags.h>
+#include "lttng-events.h"
+#include "wrapper/ringbuffer/frontend_types.h"
+#include "wrapper/vmalloc.h"
+#include "lttng-tracer.h"
+
+static
+size_t need_reschedule_get_size(size_t offset)
+{
+       size_t size = 0;
+
+       size += lib_ring_buffer_align(offset, lttng_alignof(uint8_t));
+       size += sizeof(uint8_t);
+       return size;
+}
+
+static
+void need_reschedule_record(struct lttng_ctx_field *field,
+               struct lib_ring_buffer_ctx *ctx,
+               struct lttng_channel *chan)
+{
+       uint8_t need_reschedule = test_tsk_need_resched(current);
+
+       lib_ring_buffer_align_ctx(ctx, lttng_alignof(need_reschedule));
+       chan->ops->event_write(ctx, &need_reschedule, sizeof(need_reschedule));
+}
+
+static
+void need_reschedule_get_value(struct lttng_ctx_field *field,
+               struct lttng_probe_ctx *lttng_probe_ctx,
+               union lttng_ctx_value *value)
+{
+       value->s64 = test_tsk_need_resched(current);;
+}
+
+int lttng_add_need_reschedule_to_ctx(struct lttng_ctx **ctx)
+{
+       struct lttng_ctx_field *field;
+
+       field = lttng_append_context(ctx);
+       if (!field)
+               return -ENOMEM;
+       if (lttng_find_context(*ctx, "need_reschedule")) {
+               lttng_remove_context_field(ctx, field);
+               return -EEXIST;
+       }
+       field->event_field.name = "need_reschedule";
+       field->event_field.type.atype = atype_integer;
+       field->event_field.type.u.basic.integer.size = sizeof(uint8_t) * CHAR_BIT;
+       field->event_field.type.u.basic.integer.alignment = lttng_alignof(uint8_t) * CHAR_BIT;
+       field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(uint8_t);
+       field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+       field->event_field.type.u.basic.integer.base = 10;
+       field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+       field->get_size = need_reschedule_get_size;
+       field->record = need_reschedule_record;
+       field->get_value = need_reschedule_get_value;
+       lttng_context_update(*ctx);
+       wrapper_vmalloc_sync_all();
+       return 0;
+}
+EXPORT_SYMBOL_GPL(lttng_add_need_reschedule_to_ctx);
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit need_reschedule Context");
+MODULE_VERSION(__stringify(LTTNG_MODULES_MAJOR_VERSION) "."
+       __stringify(LTTNG_MODULES_MINOR_VERSION) "."
+       __stringify(LTTNG_MODULES_PATCHLEVEL_VERSION)
+       LTTNG_MODULES_EXTRAVERSION);
index 412dd93af5299f67e8b679d9f1acaf5ad3839442..b2d7705f43e535ebf2c1ed8667ba15fbcc15601b 100644 (file)
@@ -52,6 +52,7 @@ void nice_record(struct lttng_ctx_field *field,
 
 static
 void nice_get_value(struct lttng_ctx_field *field,
+               struct lttng_probe_ctx *lttng_probe_ctx,
                union lttng_ctx_value *value)
 {
        value->s64 = task_nice(current);
index 3211819d082097596e3802aa5c1620987c1162b7..5ad92c14e10ab923deb2c1cebe9240ad9c423c04 100644 (file)
@@ -52,6 +52,7 @@ void pid_record(struct lttng_ctx_field *field,
 
 static
 void pid_get_value(struct lttng_ctx_field *field,
+               struct lttng_probe_ctx *lttng_probe_ctx,
                union lttng_ctx_value *value)
 {
        value->s64 = task_tgid_nr(current);
index 33ea1a796e0503d203b64cbd74db7420cb3fb534..28c97b58ff77f70208c0d19f409966b19667e885 100644 (file)
@@ -62,6 +62,7 @@ void ppid_record(struct lttng_ctx_field *field,
 
 static
 void ppid_get_value(struct lttng_ctx_field *field,
+               struct lttng_probe_ctx *lttng_probe_ctx,
                union lttng_ctx_value *value)
 {
        pid_t ppid;
diff --git a/lttng-context-preemptible.c b/lttng-context-preemptible.c
new file mode 100644 (file)
index 0000000..d4d474c
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * lttng-context-preemptible.c
+ *
+ * LTTng preemptible context.
+ *
+ * Copyright (C) 2009-2015 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; only
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/irqflags.h>
+#include "lttng-events.h"
+#include "wrapper/ringbuffer/frontend_types.h"
+#include "wrapper/vmalloc.h"
+#include "lttng-tracer.h"
+
+/*
+ * We nest twice in preempt disabling within LTTng: one nesting is done
+ * by the instrumentation (tracepoint, kprobes, kretprobes, syscall
+ * tracepoint), and the second is within the lib ring buffer
+ * lib_ring_buffer_get_cpu().
+ */
+#define LTTNG_PREEMPT_DISABLE_NESTING  2
+
+static
+size_t preemptible_get_size(size_t offset)
+{
+       size_t size = 0;
+
+       size += lib_ring_buffer_align(offset, lttng_alignof(uint8_t));
+       size += sizeof(uint8_t);
+       return size;
+}
+
+static
+void preemptible_record(struct lttng_ctx_field *field,
+               struct lib_ring_buffer_ctx *ctx,
+               struct lttng_channel *chan)
+{
+       int pc = preempt_count();
+       uint8_t preemptible = 0;
+
+       WARN_ON_ONCE(pc < LTTNG_PREEMPT_DISABLE_NESTING);
+       if (pc == LTTNG_PREEMPT_DISABLE_NESTING)
+               preemptible = 1;
+       lib_ring_buffer_align_ctx(ctx, lttng_alignof(preemptible));
+       chan->ops->event_write(ctx, &preemptible, sizeof(preemptible));
+}
+
+static
+void preemptible_get_value(struct lttng_ctx_field *field,
+               struct lttng_probe_ctx *lttng_probe_ctx,
+               union lttng_ctx_value *value)
+{
+       int pc = preempt_count();
+
+       WARN_ON_ONCE(pc < LTTNG_PREEMPT_DISABLE_NESTING);
+       if (pc == LTTNG_PREEMPT_DISABLE_NESTING)
+               value->s64 = 1;
+       else
+               value->s64 = 0;
+}
+
+int lttng_add_preemptible_to_ctx(struct lttng_ctx **ctx)
+{
+       struct lttng_ctx_field *field;
+
+       field = lttng_append_context(ctx);
+       if (!field)
+               return -ENOMEM;
+       if (lttng_find_context(*ctx, "preemptible")) {
+               lttng_remove_context_field(ctx, field);
+               return -EEXIST;
+       }
+       field->event_field.name = "preemptible";
+       field->event_field.type.atype = atype_integer;
+       field->event_field.type.u.basic.integer.size = sizeof(uint8_t) * CHAR_BIT;
+       field->event_field.type.u.basic.integer.alignment = lttng_alignof(uint8_t) * CHAR_BIT;
+       field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(uint8_t);
+       field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+       field->event_field.type.u.basic.integer.base = 10;
+       field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+       field->get_size = preemptible_get_size;
+       field->record = preemptible_record;
+       field->get_value = preemptible_get_value;
+       lttng_context_update(*ctx);
+       wrapper_vmalloc_sync_all();
+       return 0;
+}
+EXPORT_SYMBOL_GPL(lttng_add_preemptible_to_ctx);
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit preemptible Context");
+MODULE_VERSION(__stringify(LTTNG_MODULES_MAJOR_VERSION) "."
+       __stringify(LTTNG_MODULES_MINOR_VERSION) "."
+       __stringify(LTTNG_MODULES_PATCHLEVEL_VERSION)
+       LTTNG_MODULES_EXTRAVERSION);
index d9fb6f31da74ad0fec12898a279466c88f2957a5..9da51a22d983312d02a0b7d48e18734215d3a3b3 100644 (file)
@@ -66,6 +66,7 @@ void prio_record(struct lttng_ctx_field *field,
 
 static
 void prio_get_value(struct lttng_ctx_field *field,
+               struct lttng_probe_ctx *lttng_probe_ctx,
                union lttng_ctx_value *value)
 {
        value->s64 = wrapper_task_prio_sym(current);
index 5c1cd3a6b04f7bf23f16239cb2131dffa2f8c755..8a747acd3697f0ed61d12141866e09c3f3ae6965 100644 (file)
@@ -53,6 +53,7 @@ void procname_record(struct lttng_ctx_field *field,
 
 static
 void procname_get_value(struct lttng_ctx_field *field,
+               struct lttng_probe_ctx *lttng_probe_ctx,
                union lttng_ctx_value *value)
 {
        value->str = current->comm;
index 7b8e04bed21518520f3d3a2b45127b08dd2dfb15..12862659f18080d42496636185125d302cafa38c 100644 (file)
@@ -52,6 +52,7 @@ void tid_record(struct lttng_ctx_field *field,
 
 static
 void tid_get_value(struct lttng_ctx_field *field,
+               struct lttng_probe_ctx *lttng_probe_ctx,
                union lttng_ctx_value *value)
 {
        pid_t tid;
index 9a8df9a972b89f7c32dfa4335cde048f6b9ae1e5..6fa1c00d2c76be529d7e146b6cbb157d913d4ec2 100644 (file)
@@ -58,6 +58,7 @@ void vpid_record(struct lttng_ctx_field *field,
 
 static
 void vpid_get_value(struct lttng_ctx_field *field,
+               struct lttng_probe_ctx *lttng_probe_ctx,
                union lttng_ctx_value *value)
 {
        pid_t vpid;
index 9f36375db08f449d840742b831cfb04b25a213e4..8a7d172fca89bc543abd2e2f55cdb55392d0b5c8 100644 (file)
@@ -73,6 +73,7 @@ void vppid_record(struct lttng_ctx_field *field,
 
 static
 void vppid_get_value(struct lttng_ctx_field *field,
+               struct lttng_probe_ctx *lttng_probe_ctx,
                union lttng_ctx_value *value)
 {
        struct task_struct *parent;
index a264424fcf01510d766c1e053ea0e270dffd4efe..a37bb7673736fa1e10fbab451877cba7234c1576 100644 (file)
@@ -58,6 +58,7 @@ void vtid_record(struct lttng_ctx_field *field,
 
 static
 void vtid_get_value(struct lttng_ctx_field *field,
+               struct lttng_probe_ctx *lttng_probe_ctx,
                union lttng_ctx_value *value)
 {
        pid_t vtid;
index eca58ce1873b3ab18c25001ac362a086dda6ecbd..9bf4d80087bff96438d1919fbb1fb583abf401a6 100644 (file)
@@ -268,6 +268,26 @@ int lttng_context_init(void)
        if (ret) {
                printk(KERN_WARNING "Cannot add context lttng_add_cpu_id_to_ctx");
        }
+       ret = lttng_add_interruptible_to_ctx(&lttng_static_ctx);
+       if (ret) {
+               printk(KERN_WARNING "Cannot add context lttng_add_interruptible_to_ctx");
+       }
+       ret = lttng_add_need_reschedule_to_ctx(&lttng_static_ctx);
+       if (ret) {
+               printk(KERN_WARNING "Cannot add context lttng_add_need_reschedule_to_ctx");
+       }
+#if defined(CONFIG_PREEMPT_RT_FULL) || defined(CONFIG_PREEMPT)
+       ret = lttng_add_preemptible_to_ctx(&lttng_static_ctx);
+       if (ret != -ENOSYS) {
+               printk(KERN_WARNING "Cannot add context lttng_add_preemptible_to_ctx");
+       }
+#endif
+#ifdef CONFIG_PREEMPT_RT_FULL
+       ret = lttng_add_migratable_to_ctx(&lttng_static_ctx);
+       if (ret != -ENOSYS) {
+               printk(KERN_WARNING "Cannot add context lttng_add_migratable_to_ctx");
+       }
+#endif
        /* TODO: perf counters for filtering */
        return 0;
 }
index 234d4bcb9ff01f5aa83745f925e1775fd9eb5bd4..1b4f39c40ce22060e068f13bf31754acc738faeb 100644 (file)
@@ -162,6 +162,11 @@ struct lttng_perf_counter_field {
        struct perf_event **e;  /* per-cpu array */
 };
 
+struct lttng_probe_ctx {
+       struct lttng_event *event;
+       uint8_t interruptible;
+};
+
 struct lttng_ctx_field {
        struct lttng_event_field event_field;
        size_t (*get_size)(size_t offset);
@@ -169,6 +174,7 @@ struct lttng_ctx_field {
                       struct lib_ring_buffer_ctx *ctx,
                       struct lttng_channel *chan);
        void (*get_value)(struct lttng_ctx_field *field,
+                        struct lttng_probe_ctx *lttng_probe_ctx,
                         union lttng_ctx_value *value);
        union {
                struct lttng_perf_counter_field *perf_counter;
@@ -231,7 +237,8 @@ enum lttng_filter_ret {
 struct lttng_bytecode_runtime {
        /* Associated bytecode */
        struct lttng_filter_bytecode_node *bc;
-       uint64_t (*filter)(void *filter_data, const char *filter_stack_data);
+       uint64_t (*filter)(void *filter_data, struct lttng_probe_ctx *lttng_probe_ctx,
+                       const char *filter_stack_data);
        int link_failed;
        struct list_head node;  /* list of bytecode runtime in event */
 };
@@ -630,6 +637,26 @@ int lttng_add_vtid_to_ctx(struct lttng_ctx **ctx);
 int lttng_add_ppid_to_ctx(struct lttng_ctx **ctx);
 int lttng_add_vppid_to_ctx(struct lttng_ctx **ctx);
 int lttng_add_hostname_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_interruptible_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_need_reschedule_to_ctx(struct lttng_ctx **ctx);
+#if defined(CONFIG_PREEMPT_RT_FULL) || defined(CONFIG_PREEMPT)
+int lttng_add_preemptible_to_ctx(struct lttng_ctx **ctx);
+#else
+static inline
+int lttng_add_preemptible_to_ctx(struct lttng_ctx **ctx)
+{
+       return -ENOSYS;
+}
+#endif
+#ifdef CONFIG_PREEMPT_RT_FULL
+int lttng_add_migratable_to_ctx(struct lttng_ctx **ctx);
+#else
+static inline
+int lttng_add_migratable_to_ctx(struct lttng_ctx **ctx)
+{
+       return -ENOSYS;
+}
+#endif
 #if defined(CONFIG_PERF_EVENTS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
 int lttng_add_perf_counter_to_ctx(uint32_t type,
                                  uint64_t config,
index ffce2150af3aacdb62789a21e413f9d7bb50ccac..c288cc024ad90bcbc58f02a849aa074632f04ec3 100644 (file)
@@ -183,6 +183,7 @@ int stack_strcmp(struct estack *stack, int top, const char *cmp_type)
 }
 
 uint64_t lttng_filter_false(void *filter_data,
+               struct lttng_probe_ctx *lttng_probe_ctx,
                const char *filter_stack_data)
 {
        return 0;
@@ -240,6 +241,7 @@ LABEL_##name
  * effect.
  */
 uint64_t lttng_filter_interpret_bytecode(void *filter_data,
+               struct lttng_probe_ctx *lttng_probe_ctx,
                const char *filter_stack_data)
 {
        struct bytecode_runtime *bytecode = filter_data;
@@ -766,7 +768,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        dbg_printk("get context ref offset %u type string\n",
                                ref->offset);
                        ctx_field = &lttng_static_ctx->fields[ref->offset];
-                       ctx_field->get_value(ctx_field, &v);
+                       ctx_field->get_value(ctx_field, lttng_probe_ctx, &v);
                        estack_push(stack, top, ax, bx);
                        estack_ax(stack, top)->u.s.str = v.str;
                        if (unlikely(!estack_ax(stack, top)->u.s.str)) {
@@ -792,7 +794,7 @@ uint64_t lttng_filter_interpret_bytecode(void *filter_data,
                        dbg_printk("get context ref offset %u type s64\n",
                                ref->offset);
                        ctx_field = &lttng_static_ctx->fields[ref->offset];
-                       ctx_field->get_value(ctx_field, &v);
+                       ctx_field->get_value(ctx_field, lttng_probe_ctx, &v);
                        estack_push(stack, top, ax, bx);
                        estack_ax_v = v.s64;
                        dbg_printk("ref get context s64 %lld\n",
index 7eea1487e5774bd74458c9243bac17e9ad7101cc..a1bf79b9b4edc33a5731334e4fc5c9d80313a7ea 100644 (file)
@@ -171,8 +171,10 @@ int lttng_filter_validate_bytecode(struct bytecode_runtime *bytecode);
 int lttng_filter_specialize_bytecode(struct bytecode_runtime *bytecode);
 
 uint64_t lttng_filter_false(void *filter_data,
+               struct lttng_probe_ctx *lttng_probe_ctx,
                const char *filter_stack_data);
 uint64_t lttng_filter_interpret_bytecode(void *filter_data,
+               struct lttng_probe_ctx *lttng_probe_ctx,
                const char *filter_stack_data);
 
 #endif /* _LTTNG_FILTER_H */
index e882f4936316eb95e9bbc3a74dc64c89bec00133..d57dda192019a6f8bf78c825ff12bf7fddd01197 100644 (file)
@@ -130,7 +130,8 @@ size_t record_header_size(const struct lib_ring_buffer_config *config,
                                 struct lib_ring_buffer_ctx *ctx)
 {
        struct lttng_channel *lttng_chan = channel_get_private(chan);
-       struct lttng_event *event = ctx->priv;
+       struct lttng_probe_ctx *lttng_probe_ctx = ctx->priv;
+       struct lttng_event *event = lttng_probe_ctx->event;
        size_t orig_offset = offset;
        size_t padding;
 
@@ -198,7 +199,8 @@ void lttng_write_event_header(const struct lib_ring_buffer_config *config,
                            uint32_t event_id)
 {
        struct lttng_channel *lttng_chan = channel_get_private(ctx->chan);
-       struct lttng_event *event = ctx->priv;
+       struct lttng_probe_ctx *lttng_probe_ctx = ctx->priv;
+       struct lttng_event *event = lttng_probe_ctx->event;
 
        if (unlikely(ctx->rflags))
                goto slow_path;
@@ -249,7 +251,8 @@ void lttng_write_event_header_slow(const struct lib_ring_buffer_config *config,
                                 uint32_t event_id)
 {
        struct lttng_channel *lttng_chan = channel_get_private(ctx->chan);
-       struct lttng_event *event = ctx->priv;
+       struct lttng_probe_ctx *lttng_probe_ctx = ctx->priv;
+       struct lttng_event *event = lttng_probe_ctx->event;
 
        switch (lttng_chan->header_type) {
        case 1: /* compact */
index 0e3b713b46498f1e3272f4647f5bfb324040b7c1..6d8c71134dccbfc9842f9d9259baccb5856b596e 100644 (file)
@@ -903,6 +903,10 @@ static void __event_probe__##_name(void *__data, _proto)                 \
 {                                                                            \
        struct probe_local_vars { _locvar };                                  \
        struct lttng_event *__event = __data;                                 \
+       struct lttng_probe_ctx __lttng_probe_ctx = {                                  \
+               .event = __event,                                             \
+               .interruptible = irqs_disabled(),                             \
+       };                                                                    \
        struct lttng_channel *__chan = __event->chan;                         \
        struct lttng_session *__session = __chan->session;                    \
        struct lib_ring_buffer_ctx __ctx;                                     \
@@ -937,7 +941,7 @@ static void __event_probe__##_name(void *__data, _proto)                  \
                __event_prepare_filter_stack__##_name(__stackvar.__filter_stack_data, \
                                tp_locvar, _args);                                    \
                lttng_list_for_each_entry_rcu(bc_runtime, &__event->bytecode_runtime_head, node) { \
-                       if (unlikely(bc_runtime->filter(bc_runtime,           \
+                       if (unlikely(bc_runtime->filter(bc_runtime, &__lttng_probe_ctx,       \
                                        __stackvar.__filter_stack_data) & LTTNG_FILTER_RECORD_FLAG)) \
                                __filter_record = 1;                          \
                }                                                             \
@@ -947,7 +951,7 @@ static void __event_probe__##_name(void *__data, _proto)                  \
        __event_len = __event_get_size__##_name(__stackvar.__dynamic_len,     \
                                tp_locvar, _args);                            \
        __event_align = __event_get_align__##_name(tp_locvar, _args);         \
-       lib_ring_buffer_ctx_init(&__ctx, __chan->chan, __event, __event_len,  \
+       lib_ring_buffer_ctx_init(&__ctx, __chan->chan, &__lttng_probe_ctx, __event_len,  \
                                 __event_align, -1);                          \
        __ret = __chan->ops->event_reserve(&__ctx, __event->id);              \
        if (__ret < 0)                                                        \
@@ -965,6 +969,10 @@ static void __event_probe__##_name(void *__data)                         \
 {                                                                            \
        struct probe_local_vars { _locvar };                                  \
        struct lttng_event *__event = __data;                                 \
+       struct lttng_probe_ctx __lttng_probe_ctx = {                                  \
+               .event = __event,                                             \
+               .interruptible = irqs_disabled(),                             \
+       };                                                                    \
        struct lttng_channel *__chan = __event->chan;                         \
        struct lttng_session *__session = __chan->session;                    \
        struct lib_ring_buffer_ctx __ctx;                                     \
@@ -999,7 +1007,7 @@ static void __event_probe__##_name(void *__data)                         \
                __event_prepare_filter_stack__##_name(__stackvar.__filter_stack_data, \
                                tp_locvar);                                   \
                lttng_list_for_each_entry_rcu(bc_runtime, &__event->bytecode_runtime_head, node) { \
-                       if (unlikely(bc_runtime->filter(bc_runtime,           \
+                       if (unlikely(bc_runtime->filter(bc_runtime, &__lttng_probe_ctx, \
                                        __stackvar.__filter_stack_data) & LTTNG_FILTER_RECORD_FLAG)) \
                                __filter_record = 1;                          \
                }                                                             \
@@ -1008,7 +1016,7 @@ static void __event_probe__##_name(void *__data)                        \
        }                                                                     \
        __event_len = __event_get_size__##_name(__stackvar.__dynamic_len, tp_locvar); \
        __event_align = __event_get_align__##_name(tp_locvar);                \
-       lib_ring_buffer_ctx_init(&__ctx, __chan->chan, __event, __event_len,  \
+       lib_ring_buffer_ctx_init(&__ctx, __chan->chan, &__lttng_probe_ctx, __event_len,  \
                                 __event_align, -1);                          \
        __ret = __chan->ops->event_reserve(&__ctx, __event->id);              \
        if (__ret < 0)                                                        \
index bc4bd5baae6f90d7bf22eceb3e7cfa5e57ef07de..090843c902d676dd6a15899c5d1b2080063c9a28 100644 (file)
@@ -43,6 +43,10 @@ static
 void lttng_ftrace_handler(unsigned long ip, unsigned long parent_ip, void **data)
 {
        struct lttng_event *event = *data;
+       struct lttng_probe_ctx lttng_probe_ctx = {
+               .event = event,
+               .interruptible = irqs_disabled(),
+       };
        struct lttng_channel *chan = event->chan;
        struct lib_ring_buffer_ctx ctx;
        struct {
@@ -58,7 +62,7 @@ void lttng_ftrace_handler(unsigned long ip, unsigned long parent_ip, void **data
        if (unlikely(!ACCESS_ONCE(event->enabled)))
                return;
 
-       lib_ring_buffer_ctx_init(&ctx, chan->chan, event,
+       lib_ring_buffer_ctx_init(&ctx, chan->chan, &lttng_probe_ctx,
                                 sizeof(payload), lttng_alignof(payload), -1);
        ret = chan->ops->event_reserve(&ctx, event->id);
        if (ret < 0)
index 742af678c43cf9668b80e2104ad8fd8baa31c837..f4e4f2ea801e88f4b4d05bf4dd1472837a693799 100644 (file)
@@ -26,6 +26,7 @@
 #include "../lttng-events.h"
 #include "../wrapper/ringbuffer/frontend_types.h"
 #include "../wrapper/vmalloc.h"
+#include "../wrapper/irqflags.h"
 #include "../lttng-tracer.h"
 
 static
@@ -33,6 +34,10 @@ int lttng_kprobes_handler_pre(struct kprobe *p, struct pt_regs *regs)
 {
        struct lttng_event *event =
                container_of(p, struct lttng_event, u.kprobe.kp);
+       struct lttng_probe_ctx lttng_probe_ctx = {
+               .event = event,
+               .interruptible = lttng_regs_irqs_disabled(regs),
+       };
        struct lttng_channel *chan = event->chan;
        struct lib_ring_buffer_ctx ctx;
        int ret;
@@ -45,7 +50,7 @@ int lttng_kprobes_handler_pre(struct kprobe *p, struct pt_regs *regs)
        if (unlikely(!ACCESS_ONCE(event->enabled)))
                return 0;
 
-       lib_ring_buffer_ctx_init(&ctx, chan->chan, event, sizeof(data),
+       lib_ring_buffer_ctx_init(&ctx, chan->chan, &lttng_probe_ctx, sizeof(data),
                                 lttng_alignof(data), -1);
        ret = chan->ops->event_reserve(&ctx, event->id);
        if (ret < 0)
index 52b3f78138f94978427eedc8e197175527270274..eb3f68573dc895554af4484d0a8aad03ddcf284a 100644 (file)
@@ -27,6 +27,7 @@
 #include "../lttng-events.h"
 #include "../wrapper/ringbuffer/frontend_types.h"
 #include "../wrapper/vmalloc.h"
+#include "../wrapper/irqflags.h"
 #include "../lttng-tracer.h"
 
 enum lttng_kretprobe_type {
@@ -50,6 +51,10 @@ int _lttng_kretprobes_handler(struct kretprobe_instance *krpi,
                container_of(krpi->rp, struct lttng_krp, krp);
        struct lttng_event *event =
                lttng_krp->event[type];
+       struct lttng_probe_ctx lttng_probe_ctx = {
+               .event = event,
+               .interruptible = lttng_regs_irqs_disabled(regs),
+       };
        struct lttng_channel *chan = event->chan;
        struct lib_ring_buffer_ctx ctx;
        int ret;
@@ -68,7 +73,7 @@ int _lttng_kretprobes_handler(struct kretprobe_instance *krpi,
        payload.ip = (unsigned long) krpi->rp->kp.addr;
        payload.parent_ip = (unsigned long) krpi->ret_addr;
 
-       lib_ring_buffer_ctx_init(&ctx, chan->chan, event, sizeof(payload),
+       lib_ring_buffer_ctx_init(&ctx, chan->chan, &lttng_probe_ctx, sizeof(payload),
                                 lttng_alignof(payload), -1);
        ret = chan->ops->event_reserve(&ctx, event->id);
        if (ret < 0)
diff --git a/wrapper/irqflags.h b/wrapper/irqflags.h
new file mode 100644 (file)
index 0000000..77f8382
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef _LTTNG_WRAPPER_IRQFLAGS_H
+#define _LTTNG_WRAPPER_IRQFLAGS_H
+
+/*
+ * wrapper/irqflags.h
+ *
+ * wrapper around IRQ flags.
+ *
+ * Copyright (C) 2015 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; only
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/version.h>
+#include <linux/irqflags.h>
+
+#ifdef CONFIG_X86
+
+static inline
+int lttng_regs_irqs_disabled(struct pt_regs *regs)
+{
+       unsigned long flags = regs->flags;
+
+       return arch_irqs_disabled_flags(flags);
+}
+
+#else
+/*
+ * lttng_regs_irqs_disabled() returns -1 if irqoff state is unknown.
+ * TODO: should implement lttng_regs_irqs_disabled for each architecture
+ * to add interruptible context for kprobes and kretprobes.
+ */
+
+static inline
+int lttng_regs_irqs_disabled(struct pt_regs *regs)
+{
+       return -1;
+}
+#endif
+
+#endif /* _LTTNG_WRAPPER_IRQFLAGS_H */
This page took 0.045833 seconds and 4 git commands to generate.