sequence and variant types: use previous field for length/tag if NULL
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sat, 24 Apr 2021 00:29:27 +0000 (20:29 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 28 Apr 2021 17:52:51 +0000 (13:52 -0400)
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 <mathieu.desnoyers@efficios.com>
Change-Id: I27053e8541beb4f8f8226e411c71595f7527f533

include/instrumentation/events/net.h
include/instrumentation/syscalls/headers/syscalls_pointers_override.h
include/lttng/events.h
include/lttng/tracepoint-event-impl.h
src/lttng-context-callstack.c
src/lttng-events.c

index be59533d4953e2e313f236bf4921cc455f041146..dc0e77b7f3d5b5477cd84697793807eb08be2266 100644 (file)
@@ -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(
index 2b4918104e24990597f8881f1eda099e056b2824..cbd226aa454a7ff93d7155045488d3c15a6d11b6 100644 (file)
@@ -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)                                                                   \
index 2f48f6ef252a99b3f9b3e81b805d24a9da8938f3..613b9c49d7fc5e6cd23eaffc2b04beddaed1d27a 100644 (file)
@@ -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;
index 5af11ba746820abd6cc8bae274de3a67cd1cd36d..a8a438b2bcc9e5d828ab12f2a8a99580c35315a8 100644 (file)
@@ -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),                                  \
index 3663168eb06cef9f0da996e898958ee4596bf6cd..e6ac259621b5f8b557228736cd2380fc97056fca 100644 (file)
@@ -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),
index d881bddceb4c94fc0033f42b23b8c9a89b012c40..51c5cb39a58bcecfeb23c4cc267a36b3356b4408 100644 (file)
@@ -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;
        }
This page took 0.032505 seconds and 4 git commands to generate.