From 876e2e9225074dede98488270dee7226e73d2a63 Mon Sep 17 00:00:00 2001 From: Michael Jeanson Date: Wed, 12 Feb 2020 16:23:41 -0500 Subject: [PATCH] Add time namespace context Add a context for the new time namespace introduced in v5.6. Change-Id: Ic3393f65702b80c87670bb21049ee2a19413111d Signed-off-by: Michael Jeanson Signed-off-by: Mathieu Desnoyers --- .../instrumentation/events/lttng-statedump.h | 16 +++ include/lttng/abi.h | 1 + include/lttng/events.h | 11 ++ src/Kbuild | 4 + src/lttng-abi.c | 2 + src/lttng-context-time-ns.c | 104 ++++++++++++++++++ src/lttng-context.c | 4 + src/lttng-statedump-impl.c | 4 + 8 files changed, 146 insertions(+) create mode 100644 src/lttng-context-time-ns.c diff --git a/include/instrumentation/events/lttng-statedump.h b/include/instrumentation/events/lttng-statedump.h index 23fdd0e8..451314c9 100644 --- a/include/instrumentation/events/lttng-statedump.h +++ b/include/instrumentation/events/lttng-statedump.h @@ -17,6 +17,9 @@ #include #include #include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)) +#include +#endif #ifndef LTTNG_MNT_NS_MISSING_HEADER # ifndef ONCE_LTTNG_FS_MOUNT_H @@ -179,6 +182,19 @@ LTTNG_TRACEPOINT_EVENT(lttng_statedump_process_uts_ns, ) ) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)) +LTTNG_TRACEPOINT_EVENT(lttng_statedump_process_time_ns, + TP_PROTO(struct lttng_session *session, + struct task_struct *p, + struct time_namespace *time_ns), + TP_ARGS(session, p, time_ns), + TP_FIELDS( + ctf_integer(pid_t, tid, p->pid) + ctf_integer(unsigned int, ns_inum, time_ns ? time_ns->lttng_ns_inum : 0) + ) +) +#endif + LTTNG_TRACEPOINT_EVENT(lttng_statedump_file_descriptor, TP_PROTO(struct lttng_session *session, struct files_struct *files, diff --git a/include/lttng/abi.h b/include/lttng/abi.h index b8e2db39..7456f4a1 100644 --- a/include/lttng/abi.h +++ b/include/lttng/abi.h @@ -180,6 +180,7 @@ enum lttng_kernel_context_type { LTTNG_KERNEL_CONTEXT_VGID = 34, LTTNG_KERNEL_CONTEXT_VEGID = 35, LTTNG_KERNEL_CONTEXT_VSGID = 36, + LTTNG_KERNEL_CONTEXT_TIME_NS = 37, }; struct lttng_kernel_perf_counter_ctx { diff --git a/include/lttng/events.h b/include/lttng/events.h index 80358e92..605a48a5 100644 --- a/include/lttng/events.h +++ b/include/lttng/events.h @@ -805,6 +805,17 @@ int lttng_add_uts_ns_to_ctx(struct lttng_ctx **ctx) } #endif +#if defined(CONFIG_TIME_NS) && \ + (LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)) +int lttng_add_time_ns_to_ctx(struct lttng_ctx **ctx); +#else +static inline +int lttng_add_time_ns_to_ctx(struct lttng_ctx **ctx) +{ + return -ENOSYS; +} +#endif + int lttng_add_uid_to_ctx(struct lttng_ctx **ctx); int lttng_add_euid_to_ctx(struct lttng_ctx **ctx); int lttng_add_suid_to_ctx(struct lttng_ctx **ctx); diff --git a/src/Kbuild b/src/Kbuild index fad44601..a48e1cb1 100644 --- a/src/Kbuild +++ b/src/Kbuild @@ -105,6 +105,10 @@ ifneq ($(CONFIG_UTS_NS),) lttng-tracer-objs += lttng-context-uts-ns.o endif +ifneq ($(CONFIG_TIME_NS),) + lttng-tracer-objs += lttng-context-time-ns.o +endif + obj-$(CONFIG_LTTNG) += lttng-statedump.o lttng-statedump-objs := lttng-statedump-impl.o diff --git a/src/lttng-abi.c b/src/lttng-abi.c index c3721b93..312372fc 100644 --- a/src/lttng-abi.c +++ b/src/lttng-abi.c @@ -281,6 +281,8 @@ long lttng_abi_add_context(struct file *file, return lttng_add_vegid_to_ctx(ctx); case LTTNG_KERNEL_CONTEXT_VSGID: return lttng_add_vsgid_to_ctx(ctx); + case LTTNG_KERNEL_CONTEXT_TIME_NS: + return lttng_add_time_ns_to_ctx(ctx); default: return -EINVAL; } diff --git a/src/lttng-context-time-ns.c b/src/lttng-context-time-ns.c new file mode 100644 index 00000000..d3133aca --- /dev/null +++ b/src/lttng-context-time-ns.c @@ -0,0 +1,104 @@ +/* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only) + * + * lttng-context-time-ns.c + * + * LTTng time namespace context. + * + * Copyright (C) 2009-2012 Mathieu Desnoyers + * 2020 Michael Jeanson + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_TIME_NS) + +static +size_t time_ns_get_size(size_t offset) +{ + size_t size = 0; + + size += lib_ring_buffer_align(offset, lttng_alignof(unsigned int)); + size += sizeof(unsigned int); + return size; +} + +static +void time_ns_record(struct lttng_ctx_field *field, + struct lib_ring_buffer_ctx *ctx, + struct lttng_channel *chan) +{ + unsigned int time_ns_inum = 0; + + /* + * nsproxy can be NULL when scheduled out of exit. + * + * As documented in 'linux/nsproxy.h' namespaces access rules, no + * precautions should be taken when accessing the current task's + * namespaces, just dereference the pointers. + */ + if (current->nsproxy) + time_ns_inum = current->nsproxy->time_ns->lttng_ns_inum; + + lib_ring_buffer_align_ctx(ctx, lttng_alignof(time_ns_inum)); + chan->ops->event_write(ctx, &time_ns_inum, sizeof(time_ns_inum)); +} + +static +void time_ns_get_value(struct lttng_ctx_field *field, + struct lttng_probe_ctx *lttng_probe_ctx, + union lttng_ctx_value *value) +{ + unsigned int time_ns_inum = 0; + + /* + * nsproxy can be NULL when scheduled out of exit. + * + * As documented in 'linux/nsproxy.h' namespaces access rules, no + * precautions should be taken when accessing the current task's + * namespaces, just dereference the pointers. + */ + if (current->nsproxy) + time_ns_inum = current->nsproxy->time_ns->lttng_ns_inum; + + value->s64 = time_ns_inum; +} + +int lttng_add_time_ns_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, "time_ns")) { + lttng_remove_context_field(ctx, field); + return -EEXIST; + } + field->event_field.name = "time_ns"; + field->event_field.type.atype = atype_integer; + field->event_field.type.u.integer.size = sizeof(unsigned int) * CHAR_BIT; + field->event_field.type.u.integer.alignment = lttng_alignof(unsigned int) * CHAR_BIT; + field->event_field.type.u.integer.signedness = lttng_is_signed_type(unsigned int); + field->event_field.type.u.integer.reverse_byte_order = 0; + field->event_field.type.u.integer.base = 10; + field->event_field.type.u.integer.encoding = lttng_encode_none; + field->get_size = time_ns_get_size; + field->record = time_ns_record; + field->get_value = time_ns_get_value; + lttng_context_update(*ctx); + wrapper_vmalloc_sync_mappings(); + return 0; +} +EXPORT_SYMBOL_GPL(lttng_add_time_ns_to_ctx); + +#endif diff --git a/src/lttng-context.c b/src/lttng-context.c index 9d6b71e0..4b948ef8 100644 --- a/src/lttng-context.c +++ b/src/lttng-context.c @@ -342,6 +342,10 @@ int lttng_context_init(void) if (ret && ret != -ENOSYS) { printk(KERN_WARNING "Cannot add context lttng_add_uts_ns_to_ctx"); } + ret = lttng_add_time_ns_to_ctx(<tng_static_ctx); + if (ret && ret != -ENOSYS) { + printk(KERN_WARNING "Cannot add context lttng_add_time_ns_to_ctx"); + } /* TODO: perf counters for filtering */ return 0; } diff --git a/src/lttng-statedump-impl.c b/src/lttng-statedump-impl.c index 4105374e..153ddf8e 100644 --- a/src/lttng-statedump-impl.c +++ b/src/lttng-statedump-impl.c @@ -72,6 +72,7 @@ DEFINE_TRACE(lttng_statedump_process_mnt_ns); DEFINE_TRACE(lttng_statedump_process_net_ns); DEFINE_TRACE(lttng_statedump_process_user_ns); DEFINE_TRACE(lttng_statedump_process_uts_ns); +DEFINE_TRACE(lttng_statedump_process_time_ns); DEFINE_TRACE(lttng_statedump_network_interface); #ifdef LTTNG_HAVE_STATEDUMP_CPU_TOPOLOGY DEFINE_TRACE(lttng_statedump_cpu_topology); @@ -453,6 +454,9 @@ void lttng_statedump_process_ns(struct lttng_session *session, #endif trace_lttng_statedump_process_net_ns(session, p, proxy->net_ns); trace_lttng_statedump_process_uts_ns(session, p, proxy->uts_ns); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)) + trace_lttng_statedump_process_time_ns(session, p, proxy->time_ns); +#endif } #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) || \ LTTNG_UBUNTU_KERNEL_RANGE(3,13,11,36, 3,14,0,0) || \ -- 2.34.1