X-Git-Url: http://git.liburcu.org/?p=lttng-modules.git;a=blobdiff_plain;f=src%2Flttng-context.c;h=311dd6e1cd2d40898d85d277e494123e92b358d1;hp=9d6b71e0fdd7304491a0c541e2b3abaa420a99aa;hb=HEAD;hpb=c02eb85907f43fe17d97604633ae9aa1ed2afb36 diff --git a/src/lttng-context.c b/src/lttng-context.c index 9d6b71e0..6f39ee06 100644 --- a/src/lttng-context.c +++ b/src/lttng-context.c @@ -13,6 +13,7 @@ #include #include /* for wrapper_vmalloc_sync_mappings() */ #include +#include #include /* @@ -23,26 +24,32 @@ /* * Static array of contexts, for $ctx filters. */ -struct lttng_ctx *lttng_static_ctx; +struct lttng_kernel_ctx *lttng_static_ctx; -int lttng_find_context(struct lttng_ctx *ctx, const char *name) +int lttng_kernel_find_context(struct lttng_kernel_ctx *ctx, const char *name) { unsigned int i; + const char *subname; if (!ctx) return 0; + if (strncmp(name, "$ctx.", strlen("$ctx.")) == 0) { + subname = name + strlen("$ctx."); + } else { + subname = name; + } for (i = 0; i < ctx->nr_fields; i++) { /* Skip allocated (but non-initialized) contexts */ - if (!ctx->fields[i].event_field.name) + if (!ctx->fields[i].event_field->name) continue; - if (!strcmp(ctx->fields[i].event_field.name, name)) + if (!strcmp(ctx->fields[i].event_field->name, subname)) return 1; } return 0; } -EXPORT_SYMBOL_GPL(lttng_find_context); +EXPORT_SYMBOL_GPL(lttng_kernel_find_context); -int lttng_get_context_index(struct lttng_ctx *ctx, const char *name) +int lttng_kernel_get_context_index(struct lttng_kernel_ctx *ctx, const char *name) { unsigned int i; const char *subname; @@ -56,187 +63,137 @@ int lttng_get_context_index(struct lttng_ctx *ctx, const char *name) } for (i = 0; i < ctx->nr_fields; i++) { /* Skip allocated (but non-initialized) contexts */ - if (!ctx->fields[i].event_field.name) + if (!ctx->fields[i].event_field->name) continue; - if (!strcmp(ctx->fields[i].event_field.name, subname)) + if (!strcmp(ctx->fields[i].event_field->name, subname)) return i; } return -1; } -EXPORT_SYMBOL_GPL(lttng_get_context_index); +EXPORT_SYMBOL_GPL(lttng_kernel_get_context_index); -struct lttng_ctx_field *lttng_get_context_field_from_index(struct lttng_ctx *ctx, +struct lttng_kernel_ctx_field *lttng_kernel_get_context_field_from_index(struct lttng_kernel_ctx *ctx, size_t index) { if (index >= ctx->nr_fields) return NULL; return &ctx->fields[index]; } -EXPORT_SYMBOL_GPL(lttng_get_context_field_from_index); +EXPORT_SYMBOL_GPL(lttng_kernel_get_context_field_from_index); /* * Note: as we append context information, the pointer location may change. + * lttng_kernel_context_add_field leaves the new last context initialized to NULL. */ -ssize_t lttng_append_context_index(struct lttng_ctx **ctx_p) +static +int lttng_kernel_context_add_field(struct lttng_kernel_ctx **ctx_p) { - struct lttng_ctx *ctx; - ssize_t pos = -1; + struct lttng_kernel_ctx *ctx; if (!*ctx_p) { - *ctx_p = kzalloc(sizeof(struct lttng_ctx), GFP_KERNEL); + *ctx_p = kzalloc(sizeof(struct lttng_kernel_ctx), GFP_KERNEL); if (!*ctx_p) - goto end; + return -ENOMEM; (*ctx_p)->largest_align = 1; } ctx = *ctx_p; if (ctx->nr_fields + 1 > ctx->allocated_fields) { - struct lttng_ctx_field *new_fields; + struct lttng_kernel_ctx_field *new_fields; ctx->allocated_fields = max_t(size_t, 1, 2 * ctx->allocated_fields); - new_fields = lttng_kvzalloc(ctx->allocated_fields * sizeof(struct lttng_ctx_field), GFP_KERNEL); + new_fields = lttng_kvzalloc(ctx->allocated_fields * sizeof(*new_fields), GFP_KERNEL); if (!new_fields) - goto end; + return -ENOMEM; if (ctx->fields) memcpy(new_fields, ctx->fields, sizeof(*ctx->fields) * ctx->nr_fields); lttng_kvfree(ctx->fields); ctx->fields = new_fields; } - pos = ctx->nr_fields++; -end: - return pos; + ctx->nr_fields++; + return 0; } -EXPORT_SYMBOL_GPL(lttng_append_context_index); -/* - * Note: as we append context information, the pointer location may change. - */ -struct lttng_ctx_field *lttng_append_context(struct lttng_ctx **ctx_p) +static size_t get_type_max_align(const struct lttng_kernel_type_common *type) { - ssize_t pos; - - pos = lttng_append_context_index(ctx_p); - if (pos < 0) - return NULL; - return &(*ctx_p)->fields[pos]; + switch (type->type) { + case lttng_kernel_type_integer: + return lttng_kernel_get_type_integer(type)->alignment; + case lttng_kernel_type_string: + return CHAR_BIT; + case lttng_kernel_type_enum: + return get_type_max_align(lttng_kernel_get_type_enum(type)->container_type); + case lttng_kernel_type_array: + return max_t(size_t, get_type_max_align(lttng_kernel_get_type_array(type)->elem_type), + lttng_kernel_get_type_array(type)->alignment); + case lttng_kernel_type_sequence: + return max_t(size_t, get_type_max_align(lttng_kernel_get_type_sequence(type)->elem_type), + lttng_kernel_get_type_sequence(type)->alignment); + case lttng_kernel_type_struct: + { + unsigned int i; + size_t field_align = 0; + const struct lttng_kernel_type_struct *struct_type = lttng_kernel_get_type_struct(type); + + for (i = 0; i < struct_type->nr_fields; i++) { + field_align = max_t(size_t, + get_type_max_align(struct_type->fields[i]->type), + field_align); + } + return field_align; + } + case lttng_kernel_type_variant: + /* Variants are not accounted in the overall alignment of the type they are embedded in. */ + return 0; + default: + WARN_ON_ONCE(1); + return 0; + } } -EXPORT_SYMBOL_GPL(lttng_append_context); /* * lttng_context_update() should be called at least once between context * modification and trace start. */ -void lttng_context_update(struct lttng_ctx *ctx) +static +void lttng_context_update(struct lttng_kernel_ctx *ctx) { int i; size_t largest_align = 8; /* in bits */ for (i = 0; i < ctx->nr_fields; i++) { - struct lttng_type *type; size_t field_align = 8; - type = &ctx->fields[i].event_field.type; - switch (type->atype) { - case atype_integer: - field_align = type->u.integer.alignment; - break; - case atype_array_nestable: - { - const struct lttng_type *nested_type; - - nested_type = type->u.array_nestable.elem_type; - switch (nested_type->atype) { - case atype_integer: - field_align = nested_type->u.integer.alignment; - break; - case atype_string: - break; - - case atype_array_nestable: - case atype_sequence_nestable: - case atype_struct_nestable: - case atype_variant_nestable: - default: - WARN_ON_ONCE(1); - break; - } - field_align = max_t(size_t, field_align, - type->u.array_nestable.alignment); - break; - } - case atype_sequence_nestable: - { - const struct lttng_type *nested_type; - - nested_type = type->u.sequence_nestable.elem_type; - switch (nested_type->atype) { - case atype_integer: - field_align = nested_type->u.integer.alignment; - break; - - case atype_string: - break; - - case atype_array_nestable: - case atype_sequence_nestable: - case atype_struct_nestable: - case atype_variant_nestable: - default: - WARN_ON_ONCE(1); - break; - } - field_align = max_t(size_t, field_align, - type->u.sequence_nestable.alignment); - break; - } - case atype_string: - break; - - case atype_struct_nestable: - case atype_variant_nestable: - break; - - case atype_enum_nestable: - default: - WARN_ON_ONCE(1); - break; - } + field_align = get_type_max_align(ctx->fields[i].event_field->type); largest_align = max_t(size_t, largest_align, field_align); } ctx->largest_align = largest_align >> 3; /* bits to bytes */ } -/* Keep same order. */ -void lttng_remove_context_field_index(struct lttng_ctx **ctx_p, size_t index) +int lttng_kernel_context_append(struct lttng_kernel_ctx **ctx_p, + const struct lttng_kernel_ctx_field *f) { - struct lttng_ctx *ctx = *ctx_p; + int ret; - WARN_ON_ONCE(ctx->nr_fields >= index); - if (index != ctx->nr_fields - 1) { - memmove(&ctx->fields[index], &ctx->fields[index + 1], - (ctx->nr_fields - index - 1) * sizeof(struct lttng_ctx_field)); - } - /* Clear last item. */ - memset(&ctx->fields[ctx->nr_fields - 1], 0, sizeof(struct lttng_ctx_field)); - ctx->nr_fields--; + ret = lttng_kernel_context_add_field(ctx_p); + if (ret) + return ret; + (*ctx_p)->fields[(*ctx_p)->nr_fields - 1] = *f; + lttng_context_update(*ctx_p); + return 0; } -EXPORT_SYMBOL_GPL(lttng_remove_context_field_index); -/* - * Remove last context field. - */ -void lttng_remove_context_field(struct lttng_ctx **ctx_p, - struct lttng_ctx_field *field) +void lttng_kernel_context_remove_last(struct lttng_kernel_ctx **ctx_p) { - struct lttng_ctx *ctx; + struct lttng_kernel_ctx *ctx = *ctx_p; - ctx = *ctx_p; + if (!ctx->nr_fields) + return; + memset(&ctx->fields[ctx->nr_fields - 1], 0, sizeof(struct lttng_kernel_ctx_field)); ctx->nr_fields--; - WARN_ON_ONCE(&ctx->fields[ctx->nr_fields] != field); - memset(&ctx->fields[ctx->nr_fields], 0, sizeof(struct lttng_ctx_field)); + lttng_context_update(ctx); } -EXPORT_SYMBOL_GPL(lttng_remove_context_field); -void lttng_destroy_context(struct lttng_ctx *ctx) +void lttng_kernel_destroy_context(struct lttng_kernel_ctx *ctx) { int i; @@ -244,7 +201,7 @@ void lttng_destroy_context(struct lttng_ctx *ctx) return; for (i = 0; i < ctx->nr_fields; i++) { if (ctx->fields[i].destroy) - ctx->fields[i].destroy(&ctx->fields[i]); + ctx->fields[i].destroy(ctx->fields[i].priv); } lttng_kvfree(ctx->fields); kfree(ctx); @@ -256,91 +213,95 @@ int lttng_context_init(void) ret = lttng_add_hostname_to_ctx(<tng_static_ctx); if (ret) { - printk(KERN_WARNING "Cannot add context lttng_add_hostname_to_ctx"); + printk(KERN_WARNING "LTTng: Cannot add context lttng_add_hostname_to_ctx"); } ret = lttng_add_nice_to_ctx(<tng_static_ctx); if (ret) { - printk(KERN_WARNING "Cannot add context lttng_add_nice_to_ctx"); + printk(KERN_WARNING "LTTng: Cannot add context lttng_add_nice_to_ctx"); } ret = lttng_add_pid_to_ctx(<tng_static_ctx); if (ret) { - printk(KERN_WARNING "Cannot add context lttng_add_pid_to_ctx"); + printk(KERN_WARNING "LTTng: Cannot add context lttng_add_pid_to_ctx"); } ret = lttng_add_ppid_to_ctx(<tng_static_ctx); if (ret) { - printk(KERN_WARNING "Cannot add context lttng_add_ppid_to_ctx"); + printk(KERN_WARNING "LTTng: Cannot add context lttng_add_ppid_to_ctx"); } ret = lttng_add_prio_to_ctx(<tng_static_ctx); if (ret) { - printk(KERN_WARNING "Cannot add context lttng_add_prio_to_ctx"); + printk(KERN_WARNING "LTTng: Cannot add context lttng_add_prio_to_ctx"); } ret = lttng_add_procname_to_ctx(<tng_static_ctx); if (ret) { - printk(KERN_WARNING "Cannot add context lttng_add_procname_to_ctx"); + printk(KERN_WARNING "LTTng: Cannot add context lttng_add_procname_to_ctx"); } ret = lttng_add_tid_to_ctx(<tng_static_ctx); if (ret) { - printk(KERN_WARNING "Cannot add context lttng_add_tid_to_ctx"); + printk(KERN_WARNING "LTTng: Cannot add context lttng_add_tid_to_ctx"); } ret = lttng_add_vppid_to_ctx(<tng_static_ctx); if (ret) { - printk(KERN_WARNING "Cannot add context lttng_add_vppid_to_ctx"); + printk(KERN_WARNING "LTTng: Cannot add context lttng_add_vppid_to_ctx"); } ret = lttng_add_vtid_to_ctx(<tng_static_ctx); if (ret) { - printk(KERN_WARNING "Cannot add context lttng_add_vtid_to_ctx"); + printk(KERN_WARNING "LTTng: Cannot add context lttng_add_vtid_to_ctx"); } ret = lttng_add_vpid_to_ctx(<tng_static_ctx); if (ret) { - printk(KERN_WARNING "Cannot add context lttng_add_vpid_to_ctx"); + printk(KERN_WARNING "LTTng: Cannot add context lttng_add_vpid_to_ctx"); } ret = lttng_add_cpu_id_to_ctx(<tng_static_ctx); if (ret) { - printk(KERN_WARNING "Cannot add context lttng_add_cpu_id_to_ctx"); + printk(KERN_WARNING "LTTng: Cannot add context lttng_add_cpu_id_to_ctx"); } ret = lttng_add_interruptible_to_ctx(<tng_static_ctx); if (ret) { - printk(KERN_WARNING "Cannot add context lttng_add_interruptible_to_ctx"); + printk(KERN_WARNING "LTTng: Cannot add context lttng_add_interruptible_to_ctx"); } ret = lttng_add_need_reschedule_to_ctx(<tng_static_ctx); if (ret) { - printk(KERN_WARNING "Cannot add context lttng_add_need_reschedule_to_ctx"); + printk(KERN_WARNING "LTTng: Cannot add context lttng_add_need_reschedule_to_ctx"); } ret = lttng_add_preemptible_to_ctx(<tng_static_ctx); if (ret && ret != -ENOSYS) { - printk(KERN_WARNING "Cannot add context lttng_add_preemptible_to_ctx"); + printk(KERN_WARNING "LTTng: Cannot add context lttng_add_preemptible_to_ctx"); } ret = lttng_add_migratable_to_ctx(<tng_static_ctx); if (ret && ret != -ENOSYS) { - printk(KERN_WARNING "Cannot add context lttng_add_migratable_to_ctx"); + printk(KERN_WARNING "LTTng: Cannot add context lttng_add_migratable_to_ctx"); } ret = lttng_add_cgroup_ns_to_ctx(<tng_static_ctx); if (ret && ret != -ENOSYS) { - printk(KERN_WARNING "Cannot add context lttng_add_cgroup_ns_to_ctx"); + printk(KERN_WARNING "LTTng: Cannot add context lttng_add_cgroup_ns_to_ctx"); } ret = lttng_add_ipc_ns_to_ctx(<tng_static_ctx); if (ret && ret != -ENOSYS) { - printk(KERN_WARNING "Cannot add context lttng_add_ipc_ns_to_ctx"); + printk(KERN_WARNING "LTTng: Cannot add context lttng_add_ipc_ns_to_ctx"); } ret = lttng_add_mnt_ns_to_ctx(<tng_static_ctx); if (ret && ret != -ENOSYS) { - printk(KERN_WARNING "Cannot add context lttng_add_mnt_ns_to_ctx"); + printk(KERN_WARNING "LTTng: Cannot add context lttng_add_mnt_ns_to_ctx"); } ret = lttng_add_net_ns_to_ctx(<tng_static_ctx); if (ret && ret != -ENOSYS) { - printk(KERN_WARNING "Cannot add context lttng_add_net_ns_to_ctx"); + printk(KERN_WARNING "LTTng: Cannot add context lttng_add_net_ns_to_ctx"); } ret = lttng_add_pid_ns_to_ctx(<tng_static_ctx); if (ret && ret != -ENOSYS) { - printk(KERN_WARNING "Cannot add context lttng_add_pid_ns_to_ctx"); + printk(KERN_WARNING "LTTng: Cannot add context lttng_add_pid_ns_to_ctx"); } ret = lttng_add_user_ns_to_ctx(<tng_static_ctx); if (ret && ret != -ENOSYS) { - printk(KERN_WARNING "Cannot add context lttng_add_user_ns_to_ctx"); + printk(KERN_WARNING "LTTng: Cannot add context lttng_add_user_ns_to_ctx"); } ret = lttng_add_uts_ns_to_ctx(<tng_static_ctx); if (ret && ret != -ENOSYS) { - printk(KERN_WARNING "Cannot add context lttng_add_uts_ns_to_ctx"); + printk(KERN_WARNING "LTTng: 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 "LTTng: Cannot add context lttng_add_time_ns_to_ctx"); } /* TODO: perf counters for filtering */ return 0; @@ -348,6 +309,6 @@ int lttng_context_init(void) void lttng_context_exit(void) { - lttng_destroy_context(lttng_static_ctx); + lttng_kernel_destroy_context(lttng_static_ctx); lttng_static_ctx = NULL; }