From: Mathieu Desnoyers Date: Sat, 24 Apr 2021 00:29:27 +0000 (-0400) Subject: sequence and variant types: use previous field for length/tag if NULL X-Git-Url: https://git.lttng.org/?p=lttng-modules.git;a=commitdiff_plain;h=51ef453614a6db2b778595b16d93283d25db974a sequence and variant types: use previous field for length/tag if NULL A common use-case for sequences and variants is to use the field located immediately prior to the type as length/tag. The fact that those types need to explicitly contain their length/tag name ties the sequence/variant type to where it is placed within the structure fields, preventing re-use of the sequence/variant type. In order to reduce the memory footprint of the field descriptions and allow re-use of common field types, special-case the NULL length name and tag name to use the field prior to the sequence/variant as length. This allows more efficient type descriptions without reducing the overall flexibility of sequence/variant layout. Signed-off-by: Mathieu Desnoyers Change-Id: I27053e8541beb4f8f8226e411c71595f7527f533 --- diff --git a/include/instrumentation/events/net.h b/include/instrumentation/events/net.h index be59533d..dc0e77b7 100644 --- a/include/instrumentation/events/net.h +++ b/include/instrumentation/events/net.h @@ -264,7 +264,7 @@ static const struct lttng_kernel_event_field *ipv4fields[] = { false, false, false), [12] = lttng_kernel_static_event_field("transport_header", lttng_kernel_static_type_variant(ARRAY_SIZE(transport_fields), transport_fields, - "transport_header_type", 0), + NULL, 0), /* Previous field as tag. */ false, false, false), }; @@ -300,7 +300,7 @@ static const struct lttng_kernel_event_field *ipv6fields[] = { false, false, false), [9] = lttng_kernel_static_event_field("transport_header", lttng_kernel_static_type_variant(ARRAY_SIZE(transport_fields), - transport_fields, "transport_header_type", 0), + transport_fields, NULL, 0), /* Previous field as tag. */ false, false, false), }; @@ -358,7 +358,7 @@ LTTNG_TRACEPOINT_EVENT_CLASS(net_dev_template, ctf_custom_field( ctf_custom_type( lttng_kernel_static_type_variant(ARRAY_SIZE(network_fields), - network_fields, "network_header_type", 0) + network_fields, NULL, 0) /* Previous field as tag. */ ), network_header, ctf_custom_code( diff --git a/include/instrumentation/syscalls/headers/syscalls_pointers_override.h b/include/instrumentation/syscalls/headers/syscalls_pointers_override.h index 2b491810..cbd226aa 100644 --- a/include/instrumentation/syscalls/headers/syscalls_pointers_override.h +++ b/include/instrumentation/syscalls/headers/syscalls_pointers_override.h @@ -306,8 +306,7 @@ end: ; /* Label at end of compound statement. */ \ ) \ ctf_custom_field( \ ctf_custom_type( \ - lttng_kernel_static_type_sequence( \ - "_" #name "_length", \ + lttng_kernel_static_type_sequence(NULL, \ lttng_kernel_static_type_integer_from_type(uint8_t, __BYTE_ORDER, 16), \ 0, \ none) \ @@ -352,7 +351,7 @@ end: ; /* Label at end of compound statement. */ \ ) \ ctf_custom_field( \ ctf_custom_type( \ - lttng_kernel_static_type_sequence("_" #name "_length", \ + lttng_kernel_static_type_sequence(NULL, \ lttng_kernel_static_type_integer_from_type(uint8_t, __BYTE_ORDER, 16), \ 0, \ none) \ diff --git a/include/lttng/events.h b/include/lttng/events.h index 2f48f6ef..613b9c49 100644 --- a/include/lttng/events.h +++ b/include/lttng/events.h @@ -109,7 +109,7 @@ struct lttng_kernel_type_array { struct lttng_kernel_type_sequence { struct lttng_kernel_type_common parent; - const char *length_name; /* Length field name. */ + const char *length_name; /* Length field name. If NULL, use previous field. */ const struct lttng_kernel_type_common *elem_type; unsigned int alignment; /* Alignment before elements. */ enum lttng_kernel_string_encoding encoding; @@ -124,7 +124,7 @@ struct lttng_kernel_type_struct { struct lttng_kernel_type_variant { struct lttng_kernel_type_common parent; - const char *tag_name; + const char *tag_name; /* Tag field name. If NULL, use previous field. */ const struct lttng_kernel_event_field **choices; /* Array of pointers to fields. */ unsigned int nr_choices; unsigned int alignment; diff --git a/include/lttng/tracepoint-event-impl.h b/include/lttng/tracepoint-event-impl.h index 5af11ba7..a8a438b2 100644 --- a/include/lttng/tracepoint-event-impl.h +++ b/include/lttng/tracepoint-event-impl.h @@ -252,7 +252,7 @@ void __event_template_proto___##_name(void); lttng_kernel_static_type_integer_from_type(_length_type, __BYTE_ORDER, 10), \ _nowrite, 0, 1), \ lttng_kernel_static_event_field(#_item, \ - lttng_kernel_static_type_sequence("_" #_item "_length", \ + lttng_kernel_static_type_sequence(NULL, /* Use previous field. */ \ lttng_kernel_static_type_integer_from_type(_type, _byte_order, _elem_type_base), \ 0, \ _encoding), \ @@ -266,7 +266,7 @@ void __event_template_proto___##_name(void); lttng_kernel_static_type_integer_from_type(_length_type, __BYTE_ORDER, 10), \ _nowrite, 0, 1), \ lttng_kernel_static_event_field(#_item, \ - lttng_kernel_static_type_sequence("_" #_item "_length", \ + lttng_kernel_static_type_sequence(NULL, /* Use previous field. */ \ lttng_kernel_static_type_integer(1, 1, 0, __LITTLE_ENDIAN, 10), \ lttng_alignof(_type), \ none), \ diff --git a/src/lttng-context-callstack.c b/src/lttng-context-callstack.c index 3663168e..e6ac2596 100644 --- a/src/lttng-context-callstack.c +++ b/src/lttng-context-callstack.c @@ -102,7 +102,7 @@ static const struct lttng_kernel_event_field *event_fields_kernel[NR_FIELDS] = { lttng_kernel_static_type_integer_from_type(unsigned int, __BYTE_ORDER, 10), false, false, false), lttng_kernel_static_event_field("callstack_kernel", - lttng_kernel_static_type_sequence("_callstack_kernel_length", + lttng_kernel_static_type_sequence(NULL, lttng_kernel_static_type_integer_from_type(unsigned long, __BYTE_ORDER, 16), 0, none), false, false, false), @@ -113,7 +113,7 @@ static const struct lttng_kernel_event_field *event_fields_user[NR_FIELDS] = { lttng_kernel_static_type_integer_from_type(unsigned int, __BYTE_ORDER, 10), false, false, false), lttng_kernel_static_event_field("callstack_user", - lttng_kernel_static_type_sequence("_callstack_user_length", + lttng_kernel_static_type_sequence(NULL, lttng_kernel_static_type_integer_from_type(unsigned long, __BYTE_ORDER, 16), 0, none), false, false, false), diff --git a/src/lttng-events.c b/src/lttng-events.c index d881bddc..51c5cb39 100644 --- a/src/lttng-events.c +++ b/src/lttng-events.c @@ -89,7 +89,7 @@ int _lttng_type_statedump(struct lttng_session *session, static int _lttng_field_statedump(struct lttng_session *session, const struct lttng_kernel_event_field *field, - size_t nesting); + size_t nesting, const char **prev_field_name_p); void synchronize_trace(void) { @@ -3052,6 +3052,7 @@ int _lttng_struct_type_statedump(struct lttng_session *session, const struct lttng_kernel_type_struct *type, size_t nesting) { + const char *prev_field_name = NULL; int ret; uint32_t i, nr_fields; unsigned int alignment; @@ -3068,7 +3069,7 @@ int _lttng_struct_type_statedump(struct lttng_session *session, const struct lttng_kernel_event_field *iter_field; iter_field = type->fields[i]; - ret = _lttng_field_statedump(session, iter_field, nesting + 1); + ret = _lttng_field_statedump(session, iter_field, nesting + 1, &prev_field_name); if (ret) return ret; } @@ -3110,11 +3111,18 @@ int _lttng_struct_field_statedump(struct lttng_session *session, static int _lttng_variant_type_statedump(struct lttng_session *session, const struct lttng_kernel_type_variant *type, - size_t nesting) + size_t nesting, + const char *prev_field_name) { + const char *tag_name; int ret; uint32_t i, nr_choices; + tag_name = type->tag_name; + if (!tag_name) + tag_name = prev_field_name; + if (!tag_name) + return -EINVAL; /* * CTF 1.8 does not allow expressing nonzero variant alignment in a nestable way. */ @@ -3125,7 +3133,7 @@ int _lttng_variant_type_statedump(struct lttng_session *session, return ret; ret = lttng_metadata_printf(session, "variant <_%s> {\n", - type->tag_name); + tag_name); if (ret) return ret; nr_choices = type->nr_choices; @@ -3133,7 +3141,7 @@ int _lttng_variant_type_statedump(struct lttng_session *session, const struct lttng_kernel_event_field *iter_field; iter_field = type->choices[i]; - ret = _lttng_field_statedump(session, iter_field, nesting + 1); + ret = _lttng_field_statedump(session, iter_field, nesting + 1, NULL); if (ret) return ret; } @@ -3151,12 +3159,14 @@ int _lttng_variant_type_statedump(struct lttng_session *session, static int _lttng_variant_field_statedump(struct lttng_session *session, const struct lttng_kernel_event_field *field, - size_t nesting) + size_t nesting, + const char *prev_field_name) { int ret; ret = _lttng_variant_type_statedump(session, - lttng_kernel_get_type_variant(field->type), nesting); + lttng_kernel_get_type_variant(field->type), nesting, + prev_field_name); if (ret) return ret; return lttng_field_name_statedump(session, field, nesting); @@ -3219,7 +3229,8 @@ int _lttng_array_field_statedump(struct lttng_session *session, static int _lttng_sequence_field_statedump(struct lttng_session *session, const struct lttng_kernel_event_field *field, - size_t nesting) + size_t nesting, + const char *prev_field_name) { int ret; const char *length_name; @@ -3230,6 +3241,10 @@ int _lttng_sequence_field_statedump(struct lttng_session *session, WARN_ON_ONCE(!sequence_type); length_name = sequence_type->length_name; + if (!length_name) + length_name = prev_field_name; + if (!length_name) + return -EINVAL; if (sequence_type->alignment) { ret = print_tabs(session, nesting); @@ -3264,7 +3279,7 @@ int _lttng_sequence_field_statedump(struct lttng_session *session, ret = lttng_metadata_printf(session, " _%s[ _%s ];\n", field->name, - sequence_type->length_name); + length_name); return ret; } @@ -3487,7 +3502,7 @@ int _lttng_type_statedump(struct lttng_session *session, case lttng_kernel_type_variant: ret = _lttng_variant_type_statedump(session, lttng_kernel_get_type_variant(type), - nesting); + nesting, NULL); break; /* Nested arrays and sequences are not supported yet. */ @@ -3506,10 +3521,14 @@ int _lttng_type_statedump(struct lttng_session *session, static int _lttng_field_statedump(struct lttng_session *session, const struct lttng_kernel_event_field *field, - size_t nesting) + size_t nesting, + const char **prev_field_name_p) { + const char *prev_field_name = NULL; int ret = 0; + if (prev_field_name_p) + prev_field_name = *prev_field_name_p; switch (field->type->type) { case lttng_kernel_type_integer: ret = _lttng_integer_field_statedump(session, field, nesting); @@ -3527,16 +3546,18 @@ int _lttng_field_statedump(struct lttng_session *session, ret = _lttng_array_field_statedump(session, field, nesting); break; case lttng_kernel_type_sequence: - ret = _lttng_sequence_field_statedump(session, field, nesting); + ret = _lttng_sequence_field_statedump(session, field, nesting, prev_field_name); break; case lttng_kernel_type_variant: - ret = _lttng_variant_field_statedump(session, field, nesting); + ret = _lttng_variant_field_statedump(session, field, nesting, prev_field_name); break; default: WARN_ON_ONCE(1); return -EINVAL; } + if (prev_field_name_p) + *prev_field_name_p = field->name; return ret; } @@ -3544,6 +3565,7 @@ static int _lttng_context_metadata_statedump(struct lttng_session *session, struct lttng_kernel_ctx *ctx) { + const char *prev_field_name = NULL; int ret = 0; int i; @@ -3552,7 +3574,7 @@ int _lttng_context_metadata_statedump(struct lttng_session *session, for (i = 0; i < ctx->nr_fields; i++) { const struct lttng_kernel_ctx_field *field = &ctx->fields[i]; - ret = _lttng_field_statedump(session, field->event_field, 2); + ret = _lttng_field_statedump(session, field->event_field, 2, &prev_field_name); if (ret) return ret; } @@ -3563,6 +3585,7 @@ static int _lttng_fields_metadata_statedump(struct lttng_session *session, struct lttng_kernel_event_recorder *event_recorder) { + const char *prev_field_name = NULL; const struct lttng_kernel_event_desc *desc = event_recorder->priv->parent.desc; int ret = 0; int i; @@ -3570,7 +3593,7 @@ int _lttng_fields_metadata_statedump(struct lttng_session *session, for (i = 0; i < desc->nr_fields; i++) { const struct lttng_kernel_event_field *field = desc->fields[i]; - ret = _lttng_field_statedump(session, field, 2); + ret = _lttng_field_statedump(session, field, 2, &prev_field_name); if (ret) return ret; }