// SPDX-License-Identifier: GPL-2.0
/*
 * tracing_map - lock-free map for tracing
 *
 * Copyright (C) 2015 Tom Zanussi <tom.zanussi@linux.intel.com>
 *
 * tracing_map implementation inspired by lock-free map algorithms
 * originated by Dr. Cliff Click:
 *
 * http://www.azulsystems.com/blog/cliff/2007-03-26-non-blocking-hashtable
 * http://www.azulsystems.com/events/javaone_2007/2007_LockFreeHash.pdf
 */

#include <linux/vmalloc.h>
#include <linux/jhash.h>
#include <linux/slab.h>
#include <linux/sort.h>

#include "tracing_map.h"
#include "trace.h"

/*
 * NOTE: For a detailed description of the data structures used by
 * these functions (such as tracing_map_elt) please see the overview
 * of tracing_map data structures at the beginning of tracing_map.h.
 */

/**
 * tracing_map_update_sum - Add a value to a tracing_map_elt's sum field
 * @elt: The tracing_map_elt
 * @i: The index of the given sum associated with the tracing_map_elt
 * @n: The value to add to the sum
 *
 * Add n to sum i associated with the specified tracing_map_elt
 * instance.  The index i is the index returned by the call to
 * tracing_map_add_sum_field() when the tracing map was set up.
 */
void tracing_map_update_sum(struct tracing_map_elt *elt, unsigned int i, u64 n)
{
	atomic64_add(n, &elt->fields[i].sum);
}

/**
 * tracing_map_read_sum - Return the value of a tracing_map_elt's sum field
 * @elt: The tracing_map_elt
 * @i: The index of the given sum associated with the tracing_map_elt
 *
 * Retrieve the value of the sum i associated with the specified
 * tracing_map_elt instance.  The index i is the index returned by the
 * call to tracing_map_add_sum_field() when the tracing map was set
 * up.
 *
 * Return: The sum associated with field i for elt.
 */
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;
	char *b = val_b;

	return strcmp(a, b);
}

int tracing_map_cmp_none(void *val_a, void *val_b)
{
	return 0;
}

static int tracing_map_cmp_atomic64(void *val_a, void *val_b)
{
	u64 a = atomic64_read((atomic64_t *)val_a);
	u64 b = atomic64_read((atomic64_t *)val_b);

	return (a > b) ? 1 : ((a < b) ? -1 : 0);
}

#define DEFINE_TRACING_MAP_CMP_FN(type)					\
static int tracing_map_cmp_##type(void *val_a, void *val_b)		\
{									\
	type a = (type)(*(u64 *)val_a);					\
	type b = (type)(*(u64 *)val_b);					\
									\
	return (a > b) ? 1 : ((a < b) ? -1 : 0);			\
}

DEFINE_TRACING_MAP_CMP_FN(s64);
DEFINE_TRACING_MAP_CMP_FN(u64);
DEFINE_TRACING_MAP_CMP_FN(s32);
DEFINE_TRACING_MAP_CMP_FN(u32);
DEFINE_TRACING_MAP_CMP_FN(s16);
DEFINE_TRACING_MAP_CMP_FN(u16);
DEFINE_TRACING_MAP_CMP_FN(s8);
DEFINE_TRACING_MAP_CMP_FN(u8);

tracing_map_cmp_fn_t tracing_map_cmp_num(int field_size,
					 int field_is_signed)
{
	tracing_map_cmp_fn_t fn = tracing_map_cmp_none;

	switch (field_size) {
	case 8:
		if (field_is_signed)
			fn = tracing_map_cmp_s64;
		else
			fn = tracing_map_cmp_u64;
		break;
	case 4:
		if (field_is_signed)
			fn = tracing_map_cmp_s32;
		else
			fn = tracing_map_cmp_u32;
		break;
	case 2:
		if (field_is_signed)
			fn = tracing_map_cmp_s16;
		else
			fn = tracing_map_cmp_u16;
		break;
	case 1:
		if (field_is_signed)
			fn = tracing_map_cmp_s8;
		else
			fn = tracing_map_cmp_u8;
		break;
	}

	return fn;
}

static int tracing_map_add_field(struct tracing_map *map,
				 tracing_map_cmp_fn_t cmp_fn)
{
	int ret = -EINVAL;

	if (map->n_fields < TRACING_MAP_FIELDS_MAX) {
		ret = map->n_fields;
		map->fields[map->n_fields++].cmp_fn = cmp_fn;
	}

	return ret;
}

/**
 * tracing_map_add_sum_field - Add a field describing a tracing_map sum
 * @map: The tracing_map
 *
 * Add a sum field to the key and return the index identifying it in
 * the map and associated tracing_map_elts.  This is the index used
 * for instance to update a sum for a particular tracing_map_elt using
 * tracing_map_update_sum() or reading it via tracing_map_read_sum().
 *
 * Return: The index identifying the field in the map and associated
 * tracing_map_elts, or -EINVAL on error.
 */
int tracing_map_add_sum_field(struct tracing_map *map)
{
	return tracing_map_add_field(map, tracing_map_cmp_atomic64);
}

/**
 * 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
 * @cmp_fn: The comparison function that will be used to sort on the key
 *
 * Let the map know there is a key and that if it's used as a sort key
 * to use cmp_fn.
 *
 * A key can be a subset of a compound key; for that purpose, the
 * offset param is used to describe where within the the compound key
 * the key referenced by this key field resides.
 *
 * Return: The index identifying the field in the map and associated
 * tracing_map_elts, or -EINVAL on error.
 */
int tracing_map_add_key_field(struct tracing_map *map,
			      unsigned int offset,
			      tracing_map_cmp_fn_t cmp_fn)

{
	int idx = tracing_map_add_field(map, cmp_fn);

	if (idx < 0)
		return idx;

	map->fields[idx].offset = offset;

	map->key_idx[map->n_keys++] = idx;

	return idx;
}

void tracing_map_array_clear(struct tracing_map_array *a)
{
	unsigned int i;

	if (!a->pages)
		return;

	for (i = 0; i < a->n_pages; i++)
		memset(a->pages[i], 0, PAGE_SIZE);
}

void tracing_map_array_free(struct tracing_map_array *a)
{
	unsigned int i;

	if (!a)
		return;

	if (!a->pages)
		goto free;

	for (i = 0; i < a->n_pages; i++) {
		if (!a->pages[i])
			break;
		free_page((unsigned long)a->pages[i]);
	}

	kfree(a->pages);

 free:
	kfree(a);
}

struct tracing_map_array *tracing_map_array_alloc(unsigned int n_elts,
						  unsigned int entry_size)
{
	struct tracing_map_array *a;
	unsigned int i;

	a = kzalloc(sizeof(*a), GFP_KERNEL);
	if (!a)
		return NULL;

	a->entry_size_shift = fls(roundup_pow_of_two(entry_size) - 1);
	a->entries_per_page = PAGE_SIZE / (1 << a->entry_size_shift);
	a->n_pages = n_elts / a->entries_per_page;
	if (!a->n_pages)
		a->n_pages = 1;
	a->entry_shift = fls(a->entries_per_page) - 1;
	a->entry_mask = (1 << a->entry_shift) - 1;

	a->pages = kcalloc(a->n_pages, sizeof(void *), GFP_KERNEL);
	if (!a->pages)
		goto free;

	for (i = 0; i < a->n_pages; i++) {
		a->pages[i] = (void *)get_zeroed_page(GFP_KERNEL);
		if (!a->pages[i])
			goto free;
	}
 out:
	return a;
 free:
	tracing_map_array_free(a);
	a = NULL;

	goto out;
}

static void tracing_map_elt_clear(struct tracing_map_elt *elt)
{
	unsigned i;

	for (i = 0; i < elt->map->n_fields; i++)
		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);
}

static void tracing_map_elt_init_fields(struct tracing_map_elt *elt)
{
	unsigned int i;

	tracing_map_elt_clear(elt);

	for (i = 0; i < elt->map->n_fields; i++) {
		elt->fields[i].cmp_fn = elt->map->fields[i].cmp_fn;

		if (elt->fields[i].cmp_fn != tracing_map_cmp_atomic64)
			elt->fields[i].offset = elt->map->fields[i].offset;
	}
}

static void tracing_map_elt_free(struct tracing_map_elt *elt)
{
	if (!elt)
		return;

	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);
}

static struct tracing_map_elt *tracing_map_elt_alloc(struct tracing_map *map)
{
	struct tracing_map_elt *elt;
	int err = 0;

	elt = kzalloc(sizeof(*elt), GFP_KERNEL);
	if (!elt)
		return ERR_PTR(-ENOMEM);

	elt->map = map;

	elt->key = kzalloc(map->key_size, GFP_KERNEL);
	if (!elt->key) {
		err = -ENOMEM;
		goto free;
	}

	elt->fields = kcalloc(map->n_fields, sizeof(*elt->fields), GFP_KERNEL);
	if (!elt->fields) {
		err = -ENOMEM;
		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) {
		err = map->ops->elt_alloc(elt);
		if (err)
			goto free;
	}
	return elt;
 free:
	tracing_map_elt_free(elt);

	return ERR_PTR(err);
}

static struct tracing_map_elt *get_free_elt(struct tracing_map *map)
{
	struct tracing_map_elt *elt = NULL;
	int idx;

	idx = atomic_inc_return(&map->next_elt);
	if (idx < map->max_elts) {
		elt = *(TRACING_MAP_ELT(map->elts, idx));
		if (map->ops && map->ops->elt_init)
			map->ops->elt_init(elt);
	}

	return elt;
}

static void tracing_map_free_elts(struct tracing_map *map)
{
	unsigned int i;

	if (!map->elts)
		return;

	for (i = 0; i < map->max_elts; i++) {
		tracing_map_elt_free(*(TRACING_MAP_ELT(map->elts, i)));
		*(TRACING_MAP_ELT(map->elts, i)) = NULL;
	}

	tracing_map_array_free(map->elts);
	map->elts = NULL;
}

static int tracing_map_alloc_elts(struct tracing_map *map)
{
	unsigned int i;

	map->elts = tracing_map_array_alloc(map->max_elts,
					    sizeof(struct tracing_map_elt *));
	if (!map->elts)
		return -ENOMEM;

	for (i = 0; i < map->max_elts; i++) {
		*(TRACING_MAP_ELT(map->elts, i)) = tracing_map_elt_alloc(map);
		if (IS_ERR(*(TRACING_MAP_ELT(map->elts, i)))) {
			*(TRACING_MAP_ELT(map->elts, i)) = NULL;
			tracing_map_free_elts(map);

			return -ENOMEM;
		}
	}

	return 0;
}

static inline bool keys_match(void *key, void *test_key, unsigned key_size)
{
	bool match = true;

	if (memcmp(key, test_key, key_size))
		match = false;

	return match;
}

static inline struct tracing_map_elt *
__tracing_map_insert(struct tracing_map *map, void *key, bool lookup_only)
{
	u32 idx, key_hash, test_key;
	int dup_try = 0;
	struct tracing_map_entry *entry;
	struct tracing_map_elt *val;

	key_hash = jhash(key, map->key_size, 0);
	if (key_hash == 0)
		key_hash = 1;
	idx = key_hash >> (32 - (map->map_bits + 1));

	while (1) {
		idx &= (map->map_size - 1);
		entry = TRACING_MAP_ENTRY(map->map, idx);
		test_key = entry->key;

		if (test_key && test_key == key_hash) {
			val = READ_ONCE(entry->val);
			if (val &&
			    keys_match(key, val->key, map->key_size)) {
				if (!lookup_only)
					atomic64_inc(&map->hits);
				return val;
			} else if (unlikely(!val)) {
				/*
				 * The key is present. But, val (pointer to elt
				 * struct) is still NULL. which means some other
				 * thread is in the process of inserting an
				 * element.
				 *
				 * On top of that, it's key_hash is same as the
				 * one being inserted right now. So, it's
				 * possible that the element has the same
				 * key as well.
				 */

				dup_try++;
				if (dup_try > map->map_size) {
					atomic64_inc(&map->drops);
					break;
				}
				continue;
			}
		}

		if (!test_key) {
			if (lookup_only)
				break;

			if (!cmpxchg(&entry->key, 0, key_hash)) {
				struct tracing_map_elt *elt;

				elt = get_free_elt(map);
				if (!elt) {
					atomic64_inc(&map->drops);
					entry->key = 0;
					break;
				}

				memcpy(elt->key, key, map->key_size);
				entry->val = elt;
				atomic64_inc(&map->hits);

				return entry->val;
			} else {
				/*
				 * cmpxchg() failed. Loop around once
				 * more to check what key was inserted.
				 */
				dup_try++;
				continue;
			}
		}

		idx++;
	}

	return NULL;
}

/**
 * tracing_map_insert - Insert key and/or retrieve val from a tracing_map
 * @map: The tracing_map to insert into
 * @key: The key to insert
 *
 * Inserts a key into a tracing_map and creates and returns a new
 * tracing_map_elt for it, or if the key has already been inserted by
 * a previous call, returns the tracing_map_elt already associated
 * with it.  When the map was created, the number of elements to be
 * allocated for the map was specified (internally maintained as
 * 'max_elts' in struct tracing_map), and that number of
 * tracing_map_elts was created by tracing_map_init().  This is the
 * pre-allocated pool of tracing_map_elts that tracing_map_insert()
 * will allocate from when adding new keys.  Once that pool is
 * exhausted, tracing_map_insert() is useless and will return NULL to
 * signal that state.  There are two user-visible tracing_map
 * variables, 'hits' and 'drops', which are updated by this function.
 * Every time an element is either successfully inserted or retrieved,
 * the 'hits' value is incrememented.  Every time an element insertion
 * fails, the 'drops' value is incremented.
 *
 * This is a lock-free tracing map insertion function implementing a
 * modified form of Cliff Click's basic insertion algorithm.  It
 * requires the table size be a power of two.  To prevent any
 * possibility of an infinite loop we always make the internal table
 * size double the size of the requested table size (max_elts * 2).
 * Likewise, we never reuse a slot or resize or delete elements - when
 * we've reached max_elts entries, we simply return NULL once we've
 * run out of entries.  Readers can at any point in time traverse the
 * tracing map and safely access the key/val pairs.
 *
 * Return: the tracing_map_elt pointer val associated with the key.
 * If this was a newly inserted key, the val will be a newly allocated
 * and associated tracing_map_elt pointer val.  If the key wasn't
 * found and the pool of tracing_map_elts has been exhausted, NULL is
 * returned and no further insertions will succeed.
 */
struct tracing_map_elt *tracing_map_insert(struct tracing_map *map, void *key)
{
	return __tracing_map_insert(map, key, false);
}

/**
 * tracing_map_lookup - Retrieve val from a tracing_map
 * @map: The tracing_map to perform the lookup on
 * @key: The key to look up
 *
 * Looks up key in tracing_map and if found returns the matching
 * tracing_map_elt.  This is a lock-free lookup; see
 * tracing_map_insert() for details on tracing_map and how it works.
 * Every time an element is retrieved, the 'hits' value is
 * incrememented.  There is one user-visible tracing_map variable,
 * 'hits', which is updated by this function.  Every time an element
 * is successfully retrieved, the 'hits' value is incrememented.  The
 * 'drops' value is never updated by this function.
 *
 * Return: the tracing_map_elt pointer val associated with the key.
 * If the key wasn't found, NULL is returned.
 */
struct tracing_map_elt *tracing_map_lookup(struct tracing_map *map, void *key)
{
	return __tracing_map_insert(map, key, true);
}

/**
 * tracing_map_destroy - Destroy a tracing_map
 * @map: The tracing_map to destroy
 *
 * Frees a tracing_map along with its associated array of
 * tracing_map_elts.
 *
 * Callers should make sure there are no readers or writers actively
 * reading or inserting into the map before calling this.
 */
void tracing_map_destroy(struct tracing_map *map)
{
	if (!map)
		return;

	tracing_map_free_elts(map);

	tracing_map_array_free(map->map);
	kfree(map);
}

/**
 * tracing_map_clear - Clear a tracing_map
 * @map: The tracing_map to clear
 *
 * Resets the tracing map to a cleared or initial state.  The
 * tracing_map_elts are all cleared, and the array of struct
 * tracing_map_entry is reset to an initialized state.
 *
 * Callers should make sure there are no writers actively inserting
 * into the map before calling this.
 */
void tracing_map_clear(struct tracing_map *map)
{
	unsigned int i;

	atomic_set(&map->next_elt, -1);
	atomic64_set(&map->hits, 0);
	atomic64_set(&map->drops, 0);

	tracing_map_array_clear(map->map);

	for (i = 0; i < map->max_elts; i++)
		tracing_map_elt_clear(*(TRACING_MAP_ELT(map->elts, i)));
}

static void set_sort_key(struct tracing_map *map,
			 struct tracing_map_sort_key *sort_key)
{
	map->sort_key = *sort_key;
}

/**
 * tracing_map_create - Create a lock-free map and element pool
 * @map_bits: The size of the map (2 ** map_bits)
 * @key_size: The size of the key for the map in bytes
 * @ops: Optional client-defined tracing_map_ops instance
 * @private_data: Client data associated with the map
 *
 * Creates and sets up a map to contain 2 ** map_bits number of
 * elements (internally maintained as 'max_elts' in struct
 * tracing_map).  Before using, map fields should be added to the map
 * with tracing_map_add_sum_field() and tracing_map_add_key_field().
 * tracing_map_init() should then be called to allocate the array of
 * tracing_map_elts, in order to avoid allocating anything in the map
 * insertion path.  The user-specified map size reflects the maximum
 * number of elements that can be contained in the table requested by
 * the user - internally we double that in order to keep the table
 * sparse and keep collisions manageable.
 *
 * A tracing_map is a special-purpose map designed to aggregate or
 * 'sum' one or more values associated with a specific object of type
 * tracing_map_elt, which is attached by the map to a given key.
 *
 * tracing_map_create() sets up the map itself, and provides
 * operations for inserting tracing_map_elts, but doesn't allocate the
 * tracing_map_elts themselves, or provide a means for describing the
 * keys or sums associated with the tracing_map_elts.  All
 * tracing_map_elts for a given map have the same set of sums and
 * keys, which are defined by the client using the functions
 * tracing_map_add_key_field() and tracing_map_add_sum_field().  Once
 * the fields are defined, the pool of elements allocated for the map
 * can be created, which occurs when the client code calls
 * tracing_map_init().
 *
 * When tracing_map_init() returns, tracing_map_elt elements can be
 * inserted into the map using tracing_map_insert().  When called,
 * tracing_map_insert() grabs a free tracing_map_elt from the pool, or
 * finds an existing match in the map and in either case returns it.
 * The client can then use tracing_map_update_sum() and
 * tracing_map_read_sum() to update or read a given sum field for the
 * tracing_map_elt.
 *
 * The client can at any point retrieve and traverse the current set
 * of inserted tracing_map_elts in a tracing_map, via
 * tracing_map_sort_entries().  Sorting can be done on any field,
 * including keys.
 *
 * See tracing_map.h for a description of tracing_map_ops.
 *
 * Return: the tracing_map pointer if successful, ERR_PTR if not.
 */
struct tracing_map *tracing_map_create(unsigned int map_bits,
				       unsigned int key_size,
				       const struct tracing_map_ops *ops,
				       void *private_data)
{
	struct tracing_map *map;
	unsigned int i;

	if (map_bits < TRACING_MAP_BITS_MIN ||
	    map_bits > TRACING_MAP_BITS_MAX)
		return ERR_PTR(-EINVAL);

	map = kzalloc(sizeof(*map), GFP_KERNEL);
	if (!map)
		return ERR_PTR(-ENOMEM);

	map->map_bits = map_bits;
	map->max_elts = (1 << map_bits);
	atomic_set(&map->next_elt, -1);

	map->map_size = (1 << (map_bits + 1));
	map->ops = ops;

	map->private_data = private_data;

	map->map = tracing_map_array_alloc(map->map_size,
					   sizeof(struct tracing_map_entry));
	if (!map->map)
		goto free;

	map->key_size = key_size;
	for (i = 0; i < TRACING_MAP_KEYS_MAX; i++)
		map->key_idx[i] = -1;
 out:
	return map;
 free:
	tracing_map_destroy(map);
	map = ERR_PTR(-ENOMEM);

	goto out;
}

/**
 * tracing_map_init - Allocate and clear a map's tracing_map_elts
 * @map: The tracing_map to initialize
 *
 * Allocates a clears a pool of tracing_map_elts equal to the
 * user-specified size of 2 ** map_bits (internally maintained as
 * 'max_elts' in struct tracing_map).  Before using, the map fields
 * should be added to the map with tracing_map_add_sum_field() and
 * tracing_map_add_key_field().  tracing_map_init() should then be
 * called to allocate the array of tracing_map_elts, in order to avoid
 * allocating anything in the map insertion path.  The user-specified
 * map size reflects the max number of elements requested by the user
 * - internally we double that in order to keep the table sparse and
 * keep collisions manageable.
 *
 * See tracing_map.h for a description of tracing_map_ops.
 *
 * Return: the tracing_map pointer if successful, ERR_PTR if not.
 */
int tracing_map_init(struct tracing_map *map)
{
	int err;

	if (map->n_fields < 2)
		return -EINVAL; /* need at least 1 key and 1 val */

	err = tracing_map_alloc_elts(map);
	if (err)
		return err;

	tracing_map_clear(map);

	return err;
}

static int cmp_entries_dup(const struct tracing_map_sort_entry **a,
			   const struct tracing_map_sort_entry **b)
{
	int ret = 0;

	if (memcmp((*a)->key, (*b)->key, (*a)->elt->map->key_size))
		ret = 1;

	return ret;
}

static int cmp_entries_sum(const struct tracing_map_sort_entry **a,
			   const struct tracing_map_sort_entry **b)
{
	const struct tracing_map_elt *elt_a, *elt_b;
	struct tracing_map_sort_key *sort_key;
	struct tracing_map_field *field;
	tracing_map_cmp_fn_t cmp_fn;
	void *val_a, *val_b;
	int ret = 0;

	elt_a = (*a)->elt;
	elt_b = (*b)->elt;

	sort_key = &elt_a->map->sort_key;

	field = &elt_a->fields[sort_key->field_idx];
	cmp_fn = field->cmp_fn;

	val_a = &elt_a->fields[sort_key->field_idx].sum;
	val_b = &elt_b->fields[sort_key->field_idx].sum;

	ret = cmp_fn(val_a, val_b);
	if (sort_key->descending)
		ret = -ret;

	return ret;
}

static int cmp_entries_key(const struct tracing_map_sort_entry **a,
			   const struct tracing_map_sort_entry **b)
{
	const struct tracing_map_elt *elt_a, *elt_b;
	struct tracing_map_sort_key *sort_key;
	struct tracing_map_field *field;
	tracing_map_cmp_fn_t cmp_fn;
	void *val_a, *val_b;
	int ret = 0;

	elt_a = (*a)->elt;
	elt_b = (*b)->elt;

	sort_key = &elt_a->map->sort_key;

	field = &elt_a->fields[sort_key->field_idx];

	cmp_fn = field->cmp_fn;

	val_a = elt_a->key + field->offset;
	val_b = elt_b->key + field->offset;

	ret = cmp_fn(val_a, val_b);
	if (sort_key->descending)
		ret = -ret;

	return ret;
}

static void destroy_sort_entry(struct tracing_map_sort_entry *entry)
{
	if (!entry)
		return;

	if (entry->elt_copied)
		tracing_map_elt_free(entry->elt);

	kfree(entry);
}

/**
 * tracing_map_destroy_sort_entries - Destroy an array of sort entries
 * @entries: The entries to destroy
 * @n_entries: The number of entries in the array
 *
 * Destroy the elements returned by a tracing_map_sort_entries() call.
 */
void tracing_map_destroy_sort_entries(struct tracing_map_sort_entry **entries,
				      unsigned int n_entries)
{
	unsigned int i;

	for (i = 0; i < n_entries; i++)
		destroy_sort_entry(entries[i]);

	vfree(entries);
}

static struct tracing_map_sort_entry *
create_sort_entry(void *key, struct tracing_map_elt *elt)
{
	struct tracing_map_sort_entry *sort_entry;

	sort_entry = kzalloc(sizeof(*sort_entry), GFP_KERNEL);
	if (!sort_entry)
		return NULL;

	sort_entry->key = key;
	sort_entry->elt = elt;

	return sort_entry;
}

static void detect_dups(struct tracing_map_sort_entry **sort_entries,
		      int n_entries, unsigned int key_size)
{
	unsigned int dups = 0, total_dups = 0;
	int i;
	void *key;

	if (n_entries < 2)
		return;

	sort(sort_entries, n_entries, sizeof(struct tracing_map_sort_entry *),
	     (int (*)(const void *, const void *))cmp_entries_dup, NULL);

	key = sort_entries[0]->key;
	for (i = 1; i < n_entries; i++) {
		if (!memcmp(sort_entries[i]->key, key, key_size)) {
			dups++; total_dups++;
			continue;
		}
		key = sort_entries[i]->key;
		dups = 0;
	}

	WARN_ONCE(total_dups > 0,
		  "Duplicates detected: %d\n", total_dups);
}

static bool is_key(struct tracing_map *map, unsigned int field_idx)
{
	unsigned int i;

	for (i = 0; i < map->n_keys; i++)
		if (map->key_idx[i] == field_idx)
			return true;
	return false;
}

static void sort_secondary(struct tracing_map *map,
			   const struct tracing_map_sort_entry **entries,
			   unsigned int n_entries,
			   struct tracing_map_sort_key *primary_key,
			   struct tracing_map_sort_key *secondary_key)
{
	int (*primary_fn)(const struct tracing_map_sort_entry **,
			  const struct tracing_map_sort_entry **);
	int (*secondary_fn)(const struct tracing_map_sort_entry **,
			    const struct tracing_map_sort_entry **);
	unsigned i, start = 0, n_sub = 1;

	if (is_key(map, primary_key->field_idx))
		primary_fn = cmp_entries_key;
	else
		primary_fn = cmp_entries_sum;

	if (is_key(map, secondary_key->field_idx))
		secondary_fn = cmp_entries_key;
	else
		secondary_fn = cmp_entries_sum;

	for (i = 0; i < n_entries - 1; i++) {
		const struct tracing_map_sort_entry **a = &entries[i];
		const struct tracing_map_sort_entry **b = &entries[i + 1];

		if (primary_fn(a, b) == 0) {
			n_sub++;
			if (i < n_entries - 2)
				continue;
		}

		if (n_sub < 2) {
			start = i + 1;
			n_sub = 1;
			continue;
		}

		set_sort_key(map, secondary_key);
		sort(&entries[start], n_sub,
		     sizeof(struct tracing_map_sort_entry *),
		     (int (*)(const void *, const void *))secondary_fn, NULL);
		set_sort_key(map, primary_key);

		start = i + 1;
		n_sub = 1;
	}
}

/**
 * tracing_map_sort_entries - Sort the current set of tracing_map_elts in a map
 * @map: The tracing_map
 * @sort_key: The sort key to use for sorting
 * @sort_entries: outval: pointer to allocated and sorted array of entries
 *
 * tracing_map_sort_entries() sorts the current set of entries in the
 * map and returns the list of tracing_map_sort_entries containing
 * them to the client in the sort_entries param.  The client can
 * access the struct tracing_map_elt element of interest directly as
 * the 'elt' field of a returned struct tracing_map_sort_entry object.
 *
 * The sort_key has only two fields: idx and descending.  'idx' refers
 * to the index of the field added via tracing_map_add_sum_field() or
 * tracing_map_add_key_field() when the tracing_map was initialized.
 * 'descending' is a flag that if set reverses the sort order, which
 * by default is ascending.
 *
 * The client should not hold on to the returned array but should use
 * it and call tracing_map_destroy_sort_entries() when done.
 *
 * Return: the number of sort_entries in the struct tracing_map_sort_entry
 * array, negative on error
 */
int tracing_map_sort_entries(struct tracing_map *map,
			     struct tracing_map_sort_key *sort_keys,
			     unsigned int n_sort_keys,
			     struct tracing_map_sort_entry ***sort_entries)
{
	int (*cmp_entries_fn)(const struct tracing_map_sort_entry **,
			      const struct tracing_map_sort_entry **);
	struct tracing_map_sort_entry *sort_entry, **entries;
	int i, n_entries, ret;

	entries = vmalloc(array_size(sizeof(sort_entry), map->max_elts));
	if (!entries)
		return -ENOMEM;

	for (i = 0, n_entries = 0; i < map->map_size; i++) {
		struct tracing_map_entry *entry;

		entry = TRACING_MAP_ENTRY(map->map, i);

		if (!entry->key || !entry->val)
			continue;

		entries[n_entries] = create_sort_entry(entry->val->key,
						       entry->val);
		if (!entries[n_entries++]) {
			ret = -ENOMEM;
			goto free;
		}
	}

	if (n_entries == 0) {
		ret = 0;
		goto free;
	}

	if (n_entries == 1) {
		*sort_entries = entries;
		return 1;
	}

	detect_dups(entries, n_entries, map->key_size);

	if (is_key(map, sort_keys[0].field_idx))
		cmp_entries_fn = cmp_entries_key;
	else
		cmp_entries_fn = cmp_entries_sum;

	set_sort_key(map, &sort_keys[0]);

	sort(entries, n_entries, sizeof(struct tracing_map_sort_entry *),
	     (int (*)(const void *, const void *))cmp_entries_fn, NULL);

	if (n_sort_keys > 1)
		sort_secondary(map,
			       (const struct tracing_map_sort_entry **)entries,
			       n_entries,
			       &sort_keys[0],
			       &sort_keys[1]);

	*sort_entries = entries;

	return n_entries;
 free:
	tracing_map_destroy_sort_entries(entries, n_entries);

	return ret;
}
