lkml.org 
[lkml]   [2017]   [Sep]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2 15/40] tracing: Add per-element variable support to tracing_map
    Date
    In order to allow information to be passed between trace events, add
    support for per-element variables to tracing_map. This provides a
    means for histograms to associate a value or values with an entry when
    it's saved or updated, and retrieved by a subsequent event occurrences.

    Variables can be set using tracing_map_set_var() and read using
    tracing_map_read_var(). tracing_map_var_set() returns true or false
    depending on whether or not the variable has been set or not, which is
    important for event-matching applications.

    tracing_map_read_var_once() reads the variable and resets it to the
    'unset' state, implementing read-once variables, which are also
    important for event-matching uses.

    Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
    ---
    kernel/trace/tracing_map.c | 108 +++++++++++++++++++++++++++++++++++++++++++++
    kernel/trace/tracing_map.h | 11 +++++
    2 files changed, 119 insertions(+)

    diff --git a/kernel/trace/tracing_map.c b/kernel/trace/tracing_map.c
    index 421a0fa..a4e5a56 100644
    --- a/kernel/trace/tracing_map.c
    +++ b/kernel/trace/tracing_map.c
    @@ -66,6 +66,73 @@ u64 tracing_map_read_sum(struct tracing_map_elt *elt, unsigned int i)
    return (u64)atomic64_read(&elt->fields[i].sum);
    }

    +/**
    + * tracing_map_set_var - Assign a tracing_map_elt's variable field
    + * @elt: The tracing_map_elt
    + * @i: The index of the given variable associated with the tracing_map_elt
    + * @n: The value to assign
    + *
    + * Assign n to variable i associated with the specified tracing_map_elt
    + * instance. The index i is the index returned by the call to
    + * tracing_map_add_var() when the tracing map was set up.
    + */
    +void tracing_map_set_var(struct tracing_map_elt *elt, unsigned int i, u64 n)
    +{
    + atomic64_set(&elt->vars[i], n);
    + elt->var_set[i] = true;
    +}
    +
    +/**
    + * tracing_map_var_set - Return whether or not a variable has been set
    + * @elt: The tracing_map_elt
    + * @i: The index of the given variable associated with the tracing_map_elt
    + *
    + * Return true if the variable has been set, false otherwise. The
    + * index i is the index returned by the call to tracing_map_add_var()
    + * when the tracing map was set up.
    + */
    +bool tracing_map_var_set(struct tracing_map_elt *elt, unsigned int i)
    +{
    + return elt->var_set[i];
    +}
    +
    +/**
    + * tracing_map_read_var - Return the value of a tracing_map_elt's variable field
    + * @elt: The tracing_map_elt
    + * @i: The index of the given variable associated with the tracing_map_elt
    + *
    + * Retrieve the value of the variable i associated with the specified
    + * tracing_map_elt instance. The index i is the index returned by the
    + * call to tracing_map_add_var() when the tracing map was set
    + * up.
    + *
    + * Return: The variable value associated with field i for elt.
    + */
    +u64 tracing_map_read_var(struct tracing_map_elt *elt, unsigned int i)
    +{
    + return (u64)atomic64_read(&elt->vars[i]);
    +}
    +
    +/**
    + * tracing_map_read_var_once - Return and reset a tracing_map_elt's variable field
    + * @elt: The tracing_map_elt
    + * @i: The index of the given variable associated with the tracing_map_elt
    + *
    + * Retrieve the value of the variable i associated with the specified
    + * tracing_map_elt instance, and reset the variable to the 'not set'
    + * state. The index i is the index returned by the call to
    + * tracing_map_add_var() when the tracing map was set up. The reset
    + * essentially makes the variable a read-once variable if it's only
    + * accessed using this function.
    + *
    + * Return: The variable value associated with field i for elt.
    + */
    +u64 tracing_map_read_var_once(struct tracing_map_elt *elt, unsigned int i)
    +{
    + elt->var_set[i] = false;
    + return (u64)atomic64_read(&elt->vars[i]);
    +}
    +
    int tracing_map_cmp_string(void *val_a, void *val_b)
    {
    char *a = val_a;
    @@ -171,6 +238,28 @@ int tracing_map_add_sum_field(struct tracing_map *map)
    }

    /**
    + * tracing_map_add_var - Add a field describing a tracing_map var
    + * @map: The tracing_map
    + *
    + * Add a var to the map and return the index identifying it in the map
    + * and associated tracing_map_elts. This is the index used for
    + * instance to update a var for a particular tracing_map_elt using
    + * tracing_map_update_var() or reading it via tracing_map_read_var().
    + *
    + * Return: The index identifying the var in the map and associated
    + * tracing_map_elts, or -EINVAL on error.
    + */
    +int tracing_map_add_var(struct tracing_map *map)
    +{
    + int ret = -EINVAL;
    +
    + if (map->n_vars < TRACING_MAP_VARS_MAX)
    + ret = map->n_vars++;
    +
    + return ret;
    +}
    +
    +/**
    * tracing_map_add_key_field - Add a field describing a tracing_map key
    * @map: The tracing_map
    * @offset: The offset within the key
    @@ -280,6 +369,11 @@ static void tracing_map_elt_clear(struct tracing_map_elt *elt)
    if (elt->fields[i].cmp_fn == tracing_map_cmp_atomic64)
    atomic64_set(&elt->fields[i].sum, 0);

    + for (i = 0; i < elt->map->n_vars; i++) {
    + atomic64_set(&elt->vars[i], 0);
    + elt->var_set[i] = false;
    + }
    +
    if (elt->map->ops && elt->map->ops->elt_clear)
    elt->map->ops->elt_clear(elt);
    }
    @@ -306,6 +400,8 @@ static void tracing_map_elt_free(struct tracing_map_elt *elt)
    if (elt->map->ops && elt->map->ops->elt_free)
    elt->map->ops->elt_free(elt);
    kfree(elt->fields);
    + kfree(elt->vars);
    + kfree(elt->var_set);
    kfree(elt->key);
    kfree(elt);
    }
    @@ -333,6 +429,18 @@ static struct tracing_map_elt *tracing_map_elt_alloc(struct tracing_map *map)
    goto free;
    }

    + elt->vars = kcalloc(map->n_vars, sizeof(*elt->vars), GFP_KERNEL);
    + if (!elt->vars) {
    + err = -ENOMEM;
    + goto free;
    + }
    +
    + elt->var_set = kcalloc(map->n_vars, sizeof(*elt->var_set), GFP_KERNEL);
    + if (!elt->var_set) {
    + err = -ENOMEM;
    + goto free;
    + }
    +
    tracing_map_elt_init_fields(elt);

    if (map->ops && map->ops->elt_alloc) {
    diff --git a/kernel/trace/tracing_map.h b/kernel/trace/tracing_map.h
    index 98ef6d6..2800a6b 100644
    --- a/kernel/trace/tracing_map.h
    +++ b/kernel/trace/tracing_map.h
    @@ -9,6 +9,7 @@
    #define TRACING_MAP_VALS_MAX 3
    #define TRACING_MAP_FIELDS_MAX (TRACING_MAP_KEYS_MAX + \
    TRACING_MAP_VALS_MAX)
    +#define TRACING_MAP_VARS_MAX 16
    #define TRACING_MAP_SORT_KEYS_MAX 2

    typedef int (*tracing_map_cmp_fn_t) (void *val_a, void *val_b);
    @@ -136,6 +137,8 @@ struct tracing_map_field {
    struct tracing_map_elt {
    struct tracing_map *map;
    struct tracing_map_field *fields;
    + atomic64_t *vars;
    + bool *var_set;
    void *key;
    void *private_data;
    };
    @@ -191,6 +194,7 @@ struct tracing_map {
    int key_idx[TRACING_MAP_KEYS_MAX];
    unsigned int n_keys;
    struct tracing_map_sort_key sort_key;
    + unsigned int n_vars;
    atomic64_t hits;
    atomic64_t drops;
    };
    @@ -240,6 +244,7 @@ struct tracing_map_ops {
    extern int tracing_map_init(struct tracing_map *map);

    extern int tracing_map_add_sum_field(struct tracing_map *map);
    +extern int tracing_map_add_var(struct tracing_map *map);
    extern int tracing_map_add_key_field(struct tracing_map *map,
    unsigned int offset,
    tracing_map_cmp_fn_t cmp_fn);
    @@ -259,7 +264,13 @@ extern tracing_map_cmp_fn_t tracing_map_cmp_num(int field_size,

    extern void tracing_map_update_sum(struct tracing_map_elt *elt,
    unsigned int i, u64 n);
    +extern void tracing_map_set_var(struct tracing_map_elt *elt,
    + unsigned int i, u64 n);
    +extern bool tracing_map_var_set(struct tracing_map_elt *elt, unsigned int i);
    extern u64 tracing_map_read_sum(struct tracing_map_elt *elt, unsigned int i);
    +extern u64 tracing_map_read_var(struct tracing_map_elt *elt, unsigned int i);
    +extern u64 tracing_map_read_var_once(struct tracing_map_elt *elt, unsigned int i);
    +
    extern void tracing_map_set_field_descr(struct tracing_map *map,
    unsigned int i,
    unsigned int key_offset,
    --
    1.9.3
    \
     
     \ /
      Last update: 2017-09-06 00:07    [W:3.044 / U:0.064 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site