^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #ifndef __TRACING_MAP_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #define __TRACING_MAP_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #define TRACING_MAP_BITS_DEFAULT 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #define TRACING_MAP_BITS_MAX 17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #define TRACING_MAP_BITS_MIN 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #define TRACING_MAP_KEYS_MAX 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #define TRACING_MAP_VALS_MAX 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #define TRACING_MAP_FIELDS_MAX (TRACING_MAP_KEYS_MAX + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) TRACING_MAP_VALS_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #define TRACING_MAP_VARS_MAX 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define TRACING_MAP_SORT_KEYS_MAX 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) typedef int (*tracing_map_cmp_fn_t) (void *val_a, void *val_b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * This is an overview of the tracing_map data structures and how they
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * relate to the tracing_map API. The details of the algorithms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * aren't discussed here - this is just a general overview of the data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * structures and how they interact with the API.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * The central data structure of the tracing_map is an initially
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * zeroed array of struct tracing_map_entry (stored in the map field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * of struct tracing_map). tracing_map_entry is a very simple data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * structure containing only two fields: a 32-bit unsigned 'key'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * variable and a pointer named 'val'. This array of struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * tracing_map_entry is essentially a hash table which will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * modified by a single function, tracing_map_insert(), but which can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * be traversed and read by a user at any time (though the user does
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * this indirectly via an array of tracing_map_sort_entry - see the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * explanation of that data structure in the discussion of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * sorting-related data structures below).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * The central function of the tracing_map API is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * tracing_map_insert(). tracing_map_insert() hashes the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * arbitrarily-sized key passed into it into a 32-bit unsigned key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * It then uses this key, truncated to the array size, as an index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * into the array of tracing_map_entries. If the value of the 'key'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * field of the tracing_map_entry found at that location is 0, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * that entry is considered to be free and can be claimed, by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * replacing the 0 in the 'key' field of the tracing_map_entry with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * the new 32-bit hashed key. Once claimed, that tracing_map_entry's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * 'val' field is then used to store a unique element which will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * forever associated with that 32-bit hashed key in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * tracing_map_entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * That unique element now in the tracing_map_entry's 'val' field is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * an instance of tracing_map_elt, where 'elt' in the latter part of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * that variable name is short for 'element'. The purpose of a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * tracing_map_elt is to hold values specific to the particular
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * 32-bit hashed key it's assocated with. Things such as the unique
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * set of aggregated sums associated with the 32-bit hashed key, along
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * with a copy of the full key associated with the entry, and which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * was used to produce the 32-bit hashed key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * When tracing_map_create() is called to create the tracing map, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * user specifies (indirectly via the map_bits param, the details are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * unimportant for this discussion) the maximum number of elements
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * that the map can hold (stored in the max_elts field of struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * tracing_map). This is the maximum possible number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * tracing_map_entries in the tracing_map_entry array which can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * 'claimed' as described in the above discussion, and therefore is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * also the maximum number of tracing_map_elts that can be associated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * with the tracing_map_entry array in the tracing_map. Because of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * the way the insertion algorithm works, the size of the allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * tracing_map_entry array is always twice the maximum number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * elements (2 * max_elts). This value is stored in the map_size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * field of struct tracing_map.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * Because tracing_map_insert() needs to work from any context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * including from within the memory allocation functions themselves,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * both the tracing_map_entry array and a pool of max_elts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * tracing_map_elts are pre-allocated before any call is made to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * tracing_map_insert().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * The tracing_map_entry array is allocated as a single block by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * tracing_map_create().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * Because the tracing_map_elts are much larger objects and can't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * generally be allocated together as a single large array without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * failure, they're allocated individually, by tracing_map_init().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * The pool of tracing_map_elts are allocated by tracing_map_init()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * rather than by tracing_map_create() because at the time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * tracing_map_create() is called, there isn't enough information to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * create the tracing_map_elts. Specifically,the user first needs to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * tell the tracing_map implementation how many fields the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * tracing_map_elts contain, and which types of fields they are (key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * or sum). The user does this via the tracing_map_add_sum_field()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * and tracing_map_add_key_field() functions, following which the user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * calls tracing_map_init() to finish up the tracing map setup. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * array holding the pointers which make up the pre-allocated pool of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * tracing_map_elts is allocated as a single block and is stored in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * the elts field of struct tracing_map.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * There is also a set of structures used for sorting that might
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * benefit from some minimal explanation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * struct tracing_map_sort_key is used to drive the sort at any given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * time. By 'any given time' we mean that a different
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * tracing_map_sort_key will be used at different times depending on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * whether the sort currently being performed is a primary or a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * secondary sort.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * The sort key is very simple, consisting of the field index of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * tracing_map_elt field to sort on (which the user saved when adding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * the field), and whether the sort should be done in an ascending or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * descending order.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * For the convenience of the sorting code, a tracing_map_sort_entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * is created for each tracing_map_elt, again individually allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * to avoid failures that might be expected if allocated as a single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * large array of struct tracing_map_sort_entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * tracing_map_sort_entry instances are the objects expected by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * various internal sorting functions, and are also what the user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * ultimately receives after calling tracing_map_sort_entries().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * Because it doesn't make sense for users to access an unordered and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * sparsely populated tracing_map directly, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * tracing_map_sort_entries() function is provided so that users can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * retrieve a sorted list of all existing elements. In addition to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * the associated tracing_map_elt 'elt' field contained within the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * tracing_map_sort_entry, which is the object of interest to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * user, tracing_map_sort_entry objects contain a number of additional
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * fields which are used for caching and internal purposes and can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * safely be ignored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct tracing_map_field {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) tracing_map_cmp_fn_t cmp_fn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) atomic64_t sum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) unsigned int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct tracing_map_elt {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct tracing_map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct tracing_map_field *fields;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) atomic64_t *vars;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) bool *var_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) void *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) void *private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) struct tracing_map_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) u32 key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct tracing_map_elt *val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct tracing_map_sort_key {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) unsigned int field_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) bool descending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct tracing_map_sort_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) void *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct tracing_map_elt *elt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) bool elt_copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) bool dup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct tracing_map_array {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) unsigned int entries_per_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) unsigned int entry_size_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) unsigned int entry_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) unsigned int entry_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) unsigned int n_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) void **pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #define TRACING_MAP_ARRAY_ELT(array, idx) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) (array->pages[idx >> array->entry_shift] + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) ((idx & array->entry_mask) << array->entry_size_shift))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #define TRACING_MAP_ENTRY(array, idx) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) ((struct tracing_map_entry *)TRACING_MAP_ARRAY_ELT(array, idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #define TRACING_MAP_ELT(array, idx) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) ((struct tracing_map_elt **)TRACING_MAP_ARRAY_ELT(array, idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct tracing_map {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) unsigned int key_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) unsigned int map_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) unsigned int map_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) unsigned int max_elts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) atomic_t next_elt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct tracing_map_array *elts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct tracing_map_array *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) const struct tracing_map_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) void *private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) struct tracing_map_field fields[TRACING_MAP_FIELDS_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) unsigned int n_fields;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) int key_idx[TRACING_MAP_KEYS_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) unsigned int n_keys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct tracing_map_sort_key sort_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) unsigned int n_vars;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) atomic64_t hits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) atomic64_t drops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * struct tracing_map_ops - callbacks for tracing_map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * The methods in this structure define callback functions for various
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * operations on a tracing_map or objects related to a tracing_map.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * For a detailed description of tracing_map_elt objects please see
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * the overview of tracing_map data structures at the beginning of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * this file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * All the methods below are optional.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * @elt_alloc: When a tracing_map_elt is allocated, this function, if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * defined, will be called and gives clients the opportunity to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * allocate additional data and attach it to the element
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * (tracing_map_elt->private_data is meant for that purpose).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * Element allocation occurs before tracing begins, when the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * tracing_map_init() call is made by client code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * @elt_free: When a tracing_map_elt is freed, this function is called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * and allows client-allocated per-element data to be freed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * @elt_clear: This callback allows per-element client-defined data to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * be cleared, if applicable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * @elt_init: This callback allows per-element client-defined data to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * be initialized when used i.e. when the element is actually
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * claimed by tracing_map_insert() in the context of the map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * insertion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) struct tracing_map_ops {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) int (*elt_alloc)(struct tracing_map_elt *elt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) void (*elt_free)(struct tracing_map_elt *elt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) void (*elt_clear)(struct tracing_map_elt *elt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) void (*elt_init)(struct tracing_map_elt *elt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) extern struct tracing_map *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) tracing_map_create(unsigned int map_bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) unsigned int key_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) const struct tracing_map_ops *ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) void *private_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) extern int tracing_map_init(struct tracing_map *map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) extern int tracing_map_add_sum_field(struct tracing_map *map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) extern int tracing_map_add_var(struct tracing_map *map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) extern int tracing_map_add_key_field(struct tracing_map *map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) unsigned int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) tracing_map_cmp_fn_t cmp_fn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) extern void tracing_map_destroy(struct tracing_map *map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) extern void tracing_map_clear(struct tracing_map *map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) extern struct tracing_map_elt *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) tracing_map_insert(struct tracing_map *map, void *key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) extern struct tracing_map_elt *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) tracing_map_lookup(struct tracing_map *map, void *key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) extern tracing_map_cmp_fn_t tracing_map_cmp_num(int field_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) int field_is_signed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) extern int tracing_map_cmp_string(void *val_a, void *val_b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) extern int tracing_map_cmp_none(void *val_a, void *val_b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) extern void tracing_map_update_sum(struct tracing_map_elt *elt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) unsigned int i, u64 n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) extern void tracing_map_set_var(struct tracing_map_elt *elt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) unsigned int i, u64 n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) extern bool tracing_map_var_set(struct tracing_map_elt *elt, unsigned int i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) extern u64 tracing_map_read_sum(struct tracing_map_elt *elt, unsigned int i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) extern u64 tracing_map_read_var(struct tracing_map_elt *elt, unsigned int i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) extern u64 tracing_map_read_var_once(struct tracing_map_elt *elt, unsigned int i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) extern void tracing_map_set_field_descr(struct tracing_map *map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) unsigned int i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) unsigned int key_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) tracing_map_cmp_fn_t cmp_fn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) extern int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) tracing_map_sort_entries(struct tracing_map *map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct tracing_map_sort_key *sort_keys,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) unsigned int n_sort_keys,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) struct tracing_map_sort_entry ***sort_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) extern void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) tracing_map_destroy_sort_entries(struct tracing_map_sort_entry **entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) unsigned int n_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) #endif /* __TRACING_MAP_H */