// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
/* Copyright (c) 2018 Mellanox Technologies. All rights reserved */

#include <linux/module.h>
#include <linux/slab.h>
#include <linux/rhashtable.h>
#include <linux/idr.h>
#include <linux/list.h>
#include <linux/sort.h>
#include <linux/objagg.h>

#define CREATE_TRACE_POINTS
#include <trace/events/objagg.h>

struct objagg_hints {
	struct rhashtable node_ht;
	struct rhashtable_params ht_params;
	struct list_head node_list;
	unsigned int node_count;
	unsigned int root_count;
	unsigned int refcount;
	const struct objagg_ops *ops;
};

struct objagg_hints_node {
	struct rhash_head ht_node; /* member of objagg_hints->node_ht */
	struct list_head list; /* member of objagg_hints->node_list */
	struct objagg_hints_node *parent;
	unsigned int root_id;
	struct objagg_obj_stats_info stats_info;
	unsigned long obj[];
};

static struct objagg_hints_node *
objagg_hints_lookup(struct objagg_hints *objagg_hints, void *obj)
{
	if (!objagg_hints)
		return NULL;
	return rhashtable_lookup_fast(&objagg_hints->node_ht, obj,
				      objagg_hints->ht_params);
}

struct objagg {
	const struct objagg_ops *ops;
	void *priv;
	struct rhashtable obj_ht;
	struct rhashtable_params ht_params;
	struct list_head obj_list;
	unsigned int obj_count;
	struct ida root_ida;
	struct objagg_hints *hints;
};

struct objagg_obj {
	struct rhash_head ht_node; /* member of objagg->obj_ht */
	struct list_head list; /* member of objagg->obj_list */
	struct objagg_obj *parent; /* if the object is nested, this
				    * holds pointer to parent, otherwise NULL
				    */
	union {
		void *delta_priv; /* user delta private */
		void *root_priv; /* user root private */
	};
	unsigned int root_id;
	unsigned int refcount; /* counts number of users of this object
				* including nested objects
				*/
	struct objagg_obj_stats stats;
	unsigned long obj[];
};

static unsigned int objagg_obj_ref_inc(struct objagg_obj *objagg_obj)
{
	return ++objagg_obj->refcount;
}

static unsigned int objagg_obj_ref_dec(struct objagg_obj *objagg_obj)
{
	return --objagg_obj->refcount;
}

static void objagg_obj_stats_inc(struct objagg_obj *objagg_obj)
{
	objagg_obj->stats.user_count++;
	objagg_obj->stats.delta_user_count++;
	if (objagg_obj->parent)
		objagg_obj->parent->stats.delta_user_count++;
}

static void objagg_obj_stats_dec(struct objagg_obj *objagg_obj)
{
	objagg_obj->stats.user_count--;
	objagg_obj->stats.delta_user_count--;
	if (objagg_obj->parent)
		objagg_obj->parent->stats.delta_user_count--;
}

static bool objagg_obj_is_root(const struct objagg_obj *objagg_obj)
{
	/* Nesting is not supported, so we can use ->parent
	 * to figure out if the object is root.
	 */
	return !objagg_obj->parent;
}

/**
 * objagg_obj_root_priv - obtains root private for an object
 * @objagg_obj:	objagg object instance
 *
 * Note: all locking must be provided by the caller.
 *
 * Either the object is root itself when the private is returned
 * directly, or the parent is root and its private is returned
 * instead.
 *
 * Returns a user private root pointer.
 */
const void *objagg_obj_root_priv(const struct objagg_obj *objagg_obj)
{
	if (objagg_obj_is_root(objagg_obj))
		return objagg_obj->root_priv;
	WARN_ON(!objagg_obj_is_root(objagg_obj->parent));
	return objagg_obj->parent->root_priv;
}
EXPORT_SYMBOL(objagg_obj_root_priv);

/**
 * objagg_obj_delta_priv - obtains delta private for an object
 * @objagg_obj:	objagg object instance
 *
 * Note: all locking must be provided by the caller.
 *
 * Returns user private delta pointer or NULL in case the passed
 * object is root.
 */
const void *objagg_obj_delta_priv(const struct objagg_obj *objagg_obj)
{
	if (objagg_obj_is_root(objagg_obj))
		return NULL;
	return objagg_obj->delta_priv;
}
EXPORT_SYMBOL(objagg_obj_delta_priv);

/**
 * objagg_obj_raw - obtains object user private pointer
 * @objagg_obj:	objagg object instance
 *
 * Note: all locking must be provided by the caller.
 *
 * Returns user private pointer as was passed to objagg_obj_get() by "obj" arg.
 */
const void *objagg_obj_raw(const struct objagg_obj *objagg_obj)
{
	return objagg_obj->obj;
}
EXPORT_SYMBOL(objagg_obj_raw);

static struct objagg_obj *objagg_obj_lookup(struct objagg *objagg, void *obj)
{
	return rhashtable_lookup_fast(&objagg->obj_ht, obj, objagg->ht_params);
}

static int objagg_obj_parent_assign(struct objagg *objagg,
				    struct objagg_obj *objagg_obj,
				    struct objagg_obj *parent,
				    bool take_parent_ref)
{
	void *delta_priv;

	delta_priv = objagg->ops->delta_create(objagg->priv, parent->obj,
					       objagg_obj->obj);
	if (IS_ERR(delta_priv))
		return PTR_ERR(delta_priv);

	/* User returned a delta private, that means that
	 * our object can be aggregated into the parent.
	 */
	objagg_obj->parent = parent;
	objagg_obj->delta_priv = delta_priv;
	if (take_parent_ref)
		objagg_obj_ref_inc(objagg_obj->parent);
	trace_objagg_obj_parent_assign(objagg, objagg_obj,
				       parent,
				       parent->refcount);
	return 0;
}

static int objagg_obj_parent_lookup_assign(struct objagg *objagg,
					   struct objagg_obj *objagg_obj)
{
	struct objagg_obj *objagg_obj_cur;
	int err;

	list_for_each_entry(objagg_obj_cur, &objagg->obj_list, list) {
		/* Nesting is not supported. In case the object
		 * is not root, it cannot be assigned as parent.
		 */
		if (!objagg_obj_is_root(objagg_obj_cur))
			continue;
		err = objagg_obj_parent_assign(objagg, objagg_obj,
					       objagg_obj_cur, true);
		if (!err)
			return 0;
	}
	return -ENOENT;
}

static void __objagg_obj_put(struct objagg *objagg,
			     struct objagg_obj *objagg_obj);

static void objagg_obj_parent_unassign(struct objagg *objagg,
				       struct objagg_obj *objagg_obj)
{
	trace_objagg_obj_parent_unassign(objagg, objagg_obj,
					 objagg_obj->parent,
					 objagg_obj->parent->refcount);
	objagg->ops->delta_destroy(objagg->priv, objagg_obj->delta_priv);
	__objagg_obj_put(objagg, objagg_obj->parent);
}

static int objagg_obj_root_id_alloc(struct objagg *objagg,
				    struct objagg_obj *objagg_obj,
				    struct objagg_hints_node *hnode)
{
	unsigned int min, max;
	int root_id;

	/* In case there are no hints available, the root id is invalid. */
	if (!objagg->hints) {
		objagg_obj->root_id = OBJAGG_OBJ_ROOT_ID_INVALID;
		return 0;
	}

	if (hnode) {
		min = hnode->root_id;
		max = hnode->root_id;
	} else {
		/* For objects with no hint, start after the last
		 * hinted root_id.
		 */
		min = objagg->hints->root_count;
		max = ~0;
	}

	root_id = ida_alloc_range(&objagg->root_ida, min, max, GFP_KERNEL);

	if (root_id < 0)
		return root_id;
	objagg_obj->root_id = root_id;
	return 0;
}

static void objagg_obj_root_id_free(struct objagg *objagg,
				    struct objagg_obj *objagg_obj)
{
	if (!objagg->hints)
		return;
	ida_free(&objagg->root_ida, objagg_obj->root_id);
}

static int objagg_obj_root_create(struct objagg *objagg,
				  struct objagg_obj *objagg_obj,
				  struct objagg_hints_node *hnode)
{
	int err;

	err = objagg_obj_root_id_alloc(objagg, objagg_obj, hnode);
	if (err)
		return err;
	objagg_obj->root_priv = objagg->ops->root_create(objagg->priv,
							 objagg_obj->obj,
							 objagg_obj->root_id);
	if (IS_ERR(objagg_obj->root_priv)) {
		err = PTR_ERR(objagg_obj->root_priv);
		goto err_root_create;
	}
	trace_objagg_obj_root_create(objagg, objagg_obj);
	return 0;

err_root_create:
	objagg_obj_root_id_free(objagg, objagg_obj);
	return err;
}

static void objagg_obj_root_destroy(struct objagg *objagg,
				    struct objagg_obj *objagg_obj)
{
	trace_objagg_obj_root_destroy(objagg, objagg_obj);
	objagg->ops->root_destroy(objagg->priv, objagg_obj->root_priv);
	objagg_obj_root_id_free(objagg, objagg_obj);
}

static struct objagg_obj *__objagg_obj_get(struct objagg *objagg, void *obj);

static int objagg_obj_init_with_hints(struct objagg *objagg,
				      struct objagg_obj *objagg_obj,
				      bool *hint_found)
{
	struct objagg_hints_node *hnode;
	struct objagg_obj *parent;
	int err;

	hnode = objagg_hints_lookup(objagg->hints, objagg_obj->obj);
	if (!hnode) {
		*hint_found = false;
		return 0;
	}
	*hint_found = true;

	if (!hnode->parent)
		return objagg_obj_root_create(objagg, objagg_obj, hnode);

	parent = __objagg_obj_get(objagg, hnode->parent->obj);
	if (IS_ERR(parent))
		return PTR_ERR(parent);

	err = objagg_obj_parent_assign(objagg, objagg_obj, parent, false);
	if (err) {
		*hint_found = false;
		err = 0;
		goto err_parent_assign;
	}

	return 0;

err_parent_assign:
	objagg_obj_put(objagg, parent);
	return err;
}

static int objagg_obj_init(struct objagg *objagg,
			   struct objagg_obj *objagg_obj)
{
	bool hint_found;
	int err;

	/* First, try to use hints if they are available and
	 * if they provide result.
	 */
	err = objagg_obj_init_with_hints(objagg, objagg_obj, &hint_found);
	if (err)
		return err;

	if (hint_found)
		return 0;

	/* Try to find if the object can be aggregated under an existing one. */
	err = objagg_obj_parent_lookup_assign(objagg, objagg_obj);
	if (!err)
		return 0;
	/* If aggregation is not possible, make the object a root. */
	return objagg_obj_root_create(objagg, objagg_obj, NULL);
}

static void objagg_obj_fini(struct objagg *objagg,
			    struct objagg_obj *objagg_obj)
{
	if (!objagg_obj_is_root(objagg_obj))
		objagg_obj_parent_unassign(objagg, objagg_obj);
	else
		objagg_obj_root_destroy(objagg, objagg_obj);
}

static struct objagg_obj *objagg_obj_create(struct objagg *objagg, void *obj)
{
	struct objagg_obj *objagg_obj;
	int err;

	objagg_obj = kzalloc(sizeof(*objagg_obj) + objagg->ops->obj_size,
			     GFP_KERNEL);
	if (!objagg_obj)
		return ERR_PTR(-ENOMEM);
	objagg_obj_ref_inc(objagg_obj);
	memcpy(objagg_obj->obj, obj, objagg->ops->obj_size);

	err = objagg_obj_init(objagg, objagg_obj);
	if (err)
		goto err_obj_init;

	err = rhashtable_insert_fast(&objagg->obj_ht, &objagg_obj->ht_node,
				     objagg->ht_params);
	if (err)
		goto err_ht_insert;
	list_add(&objagg_obj->list, &objagg->obj_list);
	objagg->obj_count++;
	trace_objagg_obj_create(objagg, objagg_obj);

	return objagg_obj;

err_ht_insert:
	objagg_obj_fini(objagg, objagg_obj);
err_obj_init:
	kfree(objagg_obj);
	return ERR_PTR(err);
}

static struct objagg_obj *__objagg_obj_get(struct objagg *objagg, void *obj)
{
	struct objagg_obj *objagg_obj;

	/* First, try to find the object exactly as user passed it,
	 * perhaps it is already in use.
	 */
	objagg_obj = objagg_obj_lookup(objagg, obj);
	if (objagg_obj) {
		objagg_obj_ref_inc(objagg_obj);
		return objagg_obj;
	}

	return objagg_obj_create(objagg, obj);
}

/**
 * objagg_obj_get - gets an object within objagg instance
 * @objagg:	objagg instance
 * @obj:	user-specific private object pointer
 *
 * Note: all locking must be provided by the caller.
 *
 * Size of the "obj" memory is specified in "objagg->ops".
 *
 * There are 3 main options this function wraps:
 * 1) The object according to "obj" already exist. In that case
 *    the reference counter is incrementes and the object is returned.
 * 2) The object does not exist, but it can be aggregated within
 *    another object. In that case, user ops->delta_create() is called
 *    to obtain delta data and a new object is created with returned
 *    user-delta private pointer.
 * 3) The object does not exist and cannot be aggregated into
 *    any of the existing objects. In that case, user ops->root_create()
 *    is called to create the root and a new object is created with
 *    returned user-root private pointer.
 *
 * Returns a pointer to objagg object instance in case of success,
 * otherwise it returns pointer error using ERR_PTR macro.
 */
struct objagg_obj *objagg_obj_get(struct objagg *objagg, void *obj)
{
	struct objagg_obj *objagg_obj;

	objagg_obj = __objagg_obj_get(objagg, obj);
	if (IS_ERR(objagg_obj))
		return objagg_obj;
	objagg_obj_stats_inc(objagg_obj);
	trace_objagg_obj_get(objagg, objagg_obj, objagg_obj->refcount);
	return objagg_obj;
}
EXPORT_SYMBOL(objagg_obj_get);

static void objagg_obj_destroy(struct objagg *objagg,
			       struct objagg_obj *objagg_obj)
{
	trace_objagg_obj_destroy(objagg, objagg_obj);
	--objagg->obj_count;
	list_del(&objagg_obj->list);
	rhashtable_remove_fast(&objagg->obj_ht, &objagg_obj->ht_node,
			       objagg->ht_params);
	objagg_obj_fini(objagg, objagg_obj);
	kfree(objagg_obj);
}

static void __objagg_obj_put(struct objagg *objagg,
			     struct objagg_obj *objagg_obj)
{
	if (!objagg_obj_ref_dec(objagg_obj))
		objagg_obj_destroy(objagg, objagg_obj);
}

/**
 * objagg_obj_put - puts an object within objagg instance
 * @objagg:	objagg instance
 * @objagg_obj:	objagg object instance
 *
 * Note: all locking must be provided by the caller.
 *
 * Symmetric to objagg_obj_get().
 */
void objagg_obj_put(struct objagg *objagg, struct objagg_obj *objagg_obj)
{
	trace_objagg_obj_put(objagg, objagg_obj, objagg_obj->refcount);
	objagg_obj_stats_dec(objagg_obj);
	__objagg_obj_put(objagg, objagg_obj);
}
EXPORT_SYMBOL(objagg_obj_put);

/**
 * objagg_create - creates a new objagg instance
 * @ops:		user-specific callbacks
 * @objagg_hints:	hints, can be NULL
 * @priv:		pointer to a private data passed to the ops
 *
 * Note: all locking must be provided by the caller.
 *
 * The purpose of the library is to provide an infrastructure to
 * aggregate user-specified objects. Library does not care about the type
 * of the object. User fills-up ops which take care of the specific
 * user object manipulation.
 *
 * As a very stupid example, consider integer numbers. For example
 * number 8 as a root object. That can aggregate number 9 with delta 1,
 * number 10 with delta 2, etc. This example is implemented as
 * a part of a testing module in test_objagg.c file.
 *
 * Each objagg instance contains multiple trees. Each tree node is
 * represented by "an object". In the current implementation there can be
 * only roots and leafs nodes. Leaf nodes are called deltas.
 * But in general, this can be easily extended for intermediate nodes.
 * In that extension, a delta would be associated with all non-root
 * nodes.
 *
 * Returns a pointer to newly created objagg instance in case of success,
 * otherwise it returns pointer error using ERR_PTR macro.
 */
struct objagg *objagg_create(const struct objagg_ops *ops,
			     struct objagg_hints *objagg_hints, void *priv)
{
	struct objagg *objagg;
	int err;

	if (WARN_ON(!ops || !ops->root_create || !ops->root_destroy ||
		    !ops->delta_check || !ops->delta_create ||
		    !ops->delta_destroy))
		return ERR_PTR(-EINVAL);

	objagg = kzalloc(sizeof(*objagg), GFP_KERNEL);
	if (!objagg)
		return ERR_PTR(-ENOMEM);
	objagg->ops = ops;
	if (objagg_hints) {
		objagg->hints = objagg_hints;
		objagg_hints->refcount++;
	}
	objagg->priv = priv;
	INIT_LIST_HEAD(&objagg->obj_list);

	objagg->ht_params.key_len = ops->obj_size;
	objagg->ht_params.key_offset = offsetof(struct objagg_obj, obj);
	objagg->ht_params.head_offset = offsetof(struct objagg_obj, ht_node);

	err = rhashtable_init(&objagg->obj_ht, &objagg->ht_params);
	if (err)
		goto err_rhashtable_init;

	ida_init(&objagg->root_ida);

	trace_objagg_create(objagg);
	return objagg;

err_rhashtable_init:
	kfree(objagg);
	return ERR_PTR(err);
}
EXPORT_SYMBOL(objagg_create);

/**
 * objagg_destroy - destroys a new objagg instance
 * @objagg:	objagg instance
 *
 * Note: all locking must be provided by the caller.
 */
void objagg_destroy(struct objagg *objagg)
{
	trace_objagg_destroy(objagg);
	ida_destroy(&objagg->root_ida);
	WARN_ON(!list_empty(&objagg->obj_list));
	rhashtable_destroy(&objagg->obj_ht);
	if (objagg->hints)
		objagg_hints_put(objagg->hints);
	kfree(objagg);
}
EXPORT_SYMBOL(objagg_destroy);

static int objagg_stats_info_sort_cmp_func(const void *a, const void *b)
{
	const struct objagg_obj_stats_info *stats_info1 = a;
	const struct objagg_obj_stats_info *stats_info2 = b;

	if (stats_info1->is_root != stats_info2->is_root)
		return stats_info2->is_root - stats_info1->is_root;
	if (stats_info1->stats.delta_user_count !=
	    stats_info2->stats.delta_user_count)
		return stats_info2->stats.delta_user_count -
		       stats_info1->stats.delta_user_count;
	return stats_info2->stats.user_count - stats_info1->stats.user_count;
}

/**
 * objagg_stats_get - obtains stats of the objagg instance
 * @objagg:	objagg instance
 *
 * Note: all locking must be provided by the caller.
 *
 * The returned structure contains statistics of all object
 * currently in use, ordered by following rules:
 * 1) Root objects are always on lower indexes than the rest.
 * 2) Objects with higher delta user count are always on lower
 *    indexes.
 * 3) In case more objects have the same delta user count,
 *    the objects are ordered by user count.
 *
 * Returns a pointer to stats instance in case of success,
 * otherwise it returns pointer error using ERR_PTR macro.
 */
const struct objagg_stats *objagg_stats_get(struct objagg *objagg)
{
	struct objagg_stats *objagg_stats;
	struct objagg_obj *objagg_obj;
	int i;

	objagg_stats = kzalloc(struct_size(objagg_stats, stats_info,
					   objagg->obj_count), GFP_KERNEL);
	if (!objagg_stats)
		return ERR_PTR(-ENOMEM);

	i = 0;
	list_for_each_entry(objagg_obj, &objagg->obj_list, list) {
		memcpy(&objagg_stats->stats_info[i].stats, &objagg_obj->stats,
		       sizeof(objagg_stats->stats_info[0].stats));
		objagg_stats->stats_info[i].objagg_obj = objagg_obj;
		objagg_stats->stats_info[i].is_root =
					objagg_obj_is_root(objagg_obj);
		if (objagg_stats->stats_info[i].is_root)
			objagg_stats->root_count++;
		i++;
	}
	objagg_stats->stats_info_count = i;

	sort(objagg_stats->stats_info, objagg_stats->stats_info_count,
	     sizeof(struct objagg_obj_stats_info),
	     objagg_stats_info_sort_cmp_func, NULL);

	return objagg_stats;
}
EXPORT_SYMBOL(objagg_stats_get);

/**
 * objagg_stats_put - puts stats of the objagg instance
 * @objagg_stats:	objagg instance stats
 *
 * Note: all locking must be provided by the caller.
 */
void objagg_stats_put(const struct objagg_stats *objagg_stats)
{
	kfree(objagg_stats);
}
EXPORT_SYMBOL(objagg_stats_put);

static struct objagg_hints_node *
objagg_hints_node_create(struct objagg_hints *objagg_hints,
			 struct objagg_obj *objagg_obj, size_t obj_size,
			 struct objagg_hints_node *parent_hnode)
{
	unsigned int user_count = objagg_obj->stats.user_count;
	struct objagg_hints_node *hnode;
	int err;

	hnode = kzalloc(sizeof(*hnode) + obj_size, GFP_KERNEL);
	if (!hnode)
		return ERR_PTR(-ENOMEM);
	memcpy(hnode->obj, &objagg_obj->obj, obj_size);
	hnode->stats_info.stats.user_count = user_count;
	hnode->stats_info.stats.delta_user_count = user_count;
	if (parent_hnode) {
		parent_hnode->stats_info.stats.delta_user_count += user_count;
	} else {
		hnode->root_id = objagg_hints->root_count++;
		hnode->stats_info.is_root = true;
	}
	hnode->stats_info.objagg_obj = objagg_obj;

	err = rhashtable_insert_fast(&objagg_hints->node_ht, &hnode->ht_node,
				     objagg_hints->ht_params);
	if (err)
		goto err_ht_insert;

	list_add(&hnode->list, &objagg_hints->node_list);
	hnode->parent = parent_hnode;
	objagg_hints->node_count++;

	return hnode;

err_ht_insert:
	kfree(hnode);
	return ERR_PTR(err);
}

static void objagg_hints_flush(struct objagg_hints *objagg_hints)
{
	struct objagg_hints_node *hnode, *tmp;

	list_for_each_entry_safe(hnode, tmp, &objagg_hints->node_list, list) {
		list_del(&hnode->list);
		rhashtable_remove_fast(&objagg_hints->node_ht, &hnode->ht_node,
				       objagg_hints->ht_params);
		kfree(hnode);
	}
}

struct objagg_tmp_node {
	struct objagg_obj *objagg_obj;
	bool crossed_out;
};

struct objagg_tmp_graph {
	struct objagg_tmp_node *nodes;
	unsigned long nodes_count;
	unsigned long *edges;
};

static int objagg_tmp_graph_edge_index(struct objagg_tmp_graph *graph,
				       int parent_index, int index)
{
	return index * graph->nodes_count + parent_index;
}

static void objagg_tmp_graph_edge_set(struct objagg_tmp_graph *graph,
				      int parent_index, int index)
{
	int edge_index = objagg_tmp_graph_edge_index(graph, index,
						     parent_index);

	__set_bit(edge_index, graph->edges);
}

static bool objagg_tmp_graph_is_edge(struct objagg_tmp_graph *graph,
				     int parent_index, int index)
{
	int edge_index = objagg_tmp_graph_edge_index(graph, index,
						     parent_index);

	return test_bit(edge_index, graph->edges);
}

static unsigned int objagg_tmp_graph_node_weight(struct objagg_tmp_graph *graph,
						 unsigned int index)
{
	struct objagg_tmp_node *node = &graph->nodes[index];
	unsigned int weight = node->objagg_obj->stats.user_count;
	int j;

	/* Node weight is sum of node users and all other nodes users
	 * that this node can represent with delta.
	 */

	for (j = 0; j < graph->nodes_count; j++) {
		if (!objagg_tmp_graph_is_edge(graph, index, j))
			continue;
		node = &graph->nodes[j];
		if (node->crossed_out)
			continue;
		weight += node->objagg_obj->stats.user_count;
	}
	return weight;
}

static int objagg_tmp_graph_node_max_weight(struct objagg_tmp_graph *graph)
{
	struct objagg_tmp_node *node;
	unsigned int max_weight = 0;
	unsigned int weight;
	int max_index = -1;
	int i;

	for (i = 0; i < graph->nodes_count; i++) {
		node = &graph->nodes[i];
		if (node->crossed_out)
			continue;
		weight = objagg_tmp_graph_node_weight(graph, i);
		if (weight >= max_weight) {
			max_weight = weight;
			max_index = i;
		}
	}
	return max_index;
}

static struct objagg_tmp_graph *objagg_tmp_graph_create(struct objagg *objagg)
{
	unsigned int nodes_count = objagg->obj_count;
	struct objagg_tmp_graph *graph;
	struct objagg_tmp_node *node;
	struct objagg_tmp_node *pnode;
	struct objagg_obj *objagg_obj;
	size_t alloc_size;
	int i, j;

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

	graph->nodes = kcalloc(nodes_count, sizeof(*graph->nodes), GFP_KERNEL);
	if (!graph->nodes)
		goto err_nodes_alloc;
	graph->nodes_count = nodes_count;

	alloc_size = BITS_TO_LONGS(nodes_count * nodes_count) *
		     sizeof(unsigned long);
	graph->edges = kzalloc(alloc_size, GFP_KERNEL);
	if (!graph->edges)
		goto err_edges_alloc;

	i = 0;
	list_for_each_entry(objagg_obj, &objagg->obj_list, list) {
		node = &graph->nodes[i++];
		node->objagg_obj = objagg_obj;
	}

	/* Assemble a temporary graph. Insert edge X->Y in case Y can be
	 * in delta of X.
	 */
	for (i = 0; i < nodes_count; i++) {
		for (j = 0; j < nodes_count; j++) {
			if (i == j)
				continue;
			pnode = &graph->nodes[i];
			node = &graph->nodes[j];
			if (objagg->ops->delta_check(objagg->priv,
						     pnode->objagg_obj->obj,
						     node->objagg_obj->obj)) {
				objagg_tmp_graph_edge_set(graph, i, j);

			}
		}
	}
	return graph;

err_edges_alloc:
	kfree(graph->nodes);
err_nodes_alloc:
	kfree(graph);
	return NULL;
}

static void objagg_tmp_graph_destroy(struct objagg_tmp_graph *graph)
{
	kfree(graph->edges);
	kfree(graph->nodes);
	kfree(graph);
}

static int
objagg_opt_simple_greedy_fillup_hints(struct objagg_hints *objagg_hints,
				      struct objagg *objagg)
{
	struct objagg_hints_node *hnode, *parent_hnode;
	struct objagg_tmp_graph *graph;
	struct objagg_tmp_node *node;
	int index;
	int j;
	int err;

	graph = objagg_tmp_graph_create(objagg);
	if (!graph)
		return -ENOMEM;

	/* Find the nodes from the ones that can accommodate most users
	 * and cross them out of the graph. Save them to the hint list.
	 */
	while ((index = objagg_tmp_graph_node_max_weight(graph)) != -1) {
		node = &graph->nodes[index];
		node->crossed_out = true;
		hnode = objagg_hints_node_create(objagg_hints,
						 node->objagg_obj,
						 objagg->ops->obj_size,
						 NULL);
		if (IS_ERR(hnode)) {
			err = PTR_ERR(hnode);
			goto out;
		}
		parent_hnode = hnode;
		for (j = 0; j < graph->nodes_count; j++) {
			if (!objagg_tmp_graph_is_edge(graph, index, j))
				continue;
			node = &graph->nodes[j];
			if (node->crossed_out)
				continue;
			node->crossed_out = true;
			hnode = objagg_hints_node_create(objagg_hints,
							 node->objagg_obj,
							 objagg->ops->obj_size,
							 parent_hnode);
			if (IS_ERR(hnode)) {
				err = PTR_ERR(hnode);
				goto out;
			}
		}
	}

	err = 0;
out:
	objagg_tmp_graph_destroy(graph);
	return err;
}

struct objagg_opt_algo {
	int (*fillup_hints)(struct objagg_hints *objagg_hints,
			    struct objagg *objagg);
};

static const struct objagg_opt_algo objagg_opt_simple_greedy = {
	.fillup_hints = objagg_opt_simple_greedy_fillup_hints,
};


static const struct objagg_opt_algo *objagg_opt_algos[] = {
	[OBJAGG_OPT_ALGO_SIMPLE_GREEDY] = &objagg_opt_simple_greedy,
};

static int objagg_hints_obj_cmp(struct rhashtable_compare_arg *arg,
				const void *obj)
{
	struct rhashtable *ht = arg->ht;
	struct objagg_hints *objagg_hints =
			container_of(ht, struct objagg_hints, node_ht);
	const struct objagg_ops *ops = objagg_hints->ops;
	const char *ptr = obj;

	ptr += ht->p.key_offset;
	return ops->hints_obj_cmp ? ops->hints_obj_cmp(ptr, arg->key) :
				    memcmp(ptr, arg->key, ht->p.key_len);
}

/**
 * objagg_hints_get - obtains hints instance
 * @objagg:		objagg instance
 * @opt_algo_type:	type of hints finding algorithm
 *
 * Note: all locking must be provided by the caller.
 *
 * According to the algo type, the existing objects of objagg instance
 * are going to be went-through to assemble an optimal tree. We call this
 * tree hints. These hints can be later on used for creation of
 * a new objagg instance. There, the future object creations are going
 * to be consulted with these hints in order to find out, where exactly
 * the new object should be put as a root or delta.
 *
 * Returns a pointer to hints instance in case of success,
 * otherwise it returns pointer error using ERR_PTR macro.
 */
struct objagg_hints *objagg_hints_get(struct objagg *objagg,
				      enum objagg_opt_algo_type opt_algo_type)
{
	const struct objagg_opt_algo *algo = objagg_opt_algos[opt_algo_type];
	struct objagg_hints *objagg_hints;
	int err;

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

	objagg_hints->ops = objagg->ops;
	objagg_hints->refcount = 1;

	INIT_LIST_HEAD(&objagg_hints->node_list);

	objagg_hints->ht_params.key_len = objagg->ops->obj_size;
	objagg_hints->ht_params.key_offset =
				offsetof(struct objagg_hints_node, obj);
	objagg_hints->ht_params.head_offset =
				offsetof(struct objagg_hints_node, ht_node);
	objagg_hints->ht_params.obj_cmpfn = objagg_hints_obj_cmp;

	err = rhashtable_init(&objagg_hints->node_ht, &objagg_hints->ht_params);
	if (err)
		goto err_rhashtable_init;

	err = algo->fillup_hints(objagg_hints, objagg);
	if (err)
		goto err_fillup_hints;

	if (WARN_ON(objagg_hints->node_count != objagg->obj_count)) {
		err = -EINVAL;
		goto err_node_count_check;
	}

	return objagg_hints;

err_node_count_check:
err_fillup_hints:
	objagg_hints_flush(objagg_hints);
	rhashtable_destroy(&objagg_hints->node_ht);
err_rhashtable_init:
	kfree(objagg_hints);
	return ERR_PTR(err);
}
EXPORT_SYMBOL(objagg_hints_get);

/**
 * objagg_hints_put - puts hints instance
 * @objagg_hints:	objagg hints instance
 *
 * Note: all locking must be provided by the caller.
 */
void objagg_hints_put(struct objagg_hints *objagg_hints)
{
	if (--objagg_hints->refcount)
		return;
	objagg_hints_flush(objagg_hints);
	rhashtable_destroy(&objagg_hints->node_ht);
	kfree(objagg_hints);
}
EXPORT_SYMBOL(objagg_hints_put);

/**
 * objagg_hints_stats_get - obtains stats of the hints instance
 * @objagg_hints:	hints instance
 *
 * Note: all locking must be provided by the caller.
 *
 * The returned structure contains statistics of all objects
 * currently in use, ordered by following rules:
 * 1) Root objects are always on lower indexes than the rest.
 * 2) Objects with higher delta user count are always on lower
 *    indexes.
 * 3) In case multiple objects have the same delta user count,
 *    the objects are ordered by user count.
 *
 * Returns a pointer to stats instance in case of success,
 * otherwise it returns pointer error using ERR_PTR macro.
 */
const struct objagg_stats *
objagg_hints_stats_get(struct objagg_hints *objagg_hints)
{
	struct objagg_stats *objagg_stats;
	struct objagg_hints_node *hnode;
	int i;

	objagg_stats = kzalloc(struct_size(objagg_stats, stats_info,
					   objagg_hints->node_count),
			       GFP_KERNEL);
	if (!objagg_stats)
		return ERR_PTR(-ENOMEM);

	i = 0;
	list_for_each_entry(hnode, &objagg_hints->node_list, list) {
		memcpy(&objagg_stats->stats_info[i], &hnode->stats_info,
		       sizeof(objagg_stats->stats_info[0]));
		if (objagg_stats->stats_info[i].is_root)
			objagg_stats->root_count++;
		i++;
	}
	objagg_stats->stats_info_count = i;

	sort(objagg_stats->stats_info, objagg_stats->stats_info_count,
	     sizeof(struct objagg_obj_stats_info),
	     objagg_stats_info_sort_cmp_func, NULL);

	return objagg_stats;
}
EXPORT_SYMBOL(objagg_hints_stats_get);

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
MODULE_DESCRIPTION("Object aggregation manager");
