/*
 * Copyright (C) 2017 Red Hat. All rights reserved.
 *
 * This file is released under the GPL.
 */

#include "dm-cache-background-tracker.h"

/*----------------------------------------------------------------*/

#define DM_MSG_PREFIX "dm-background-tracker"

struct bt_work {
	struct list_head list;
	struct rb_node node;
	struct policy_work work;
};

struct background_tracker {
	unsigned max_work;
	atomic_t pending_promotes;
	atomic_t pending_writebacks;
	atomic_t pending_demotes;

	struct list_head issued;
	struct list_head queued;
	struct rb_root pending;

	struct kmem_cache *work_cache;
};

struct background_tracker *btracker_create(unsigned max_work)
{
	struct background_tracker *b = kmalloc(sizeof(*b), GFP_KERNEL);

	b->max_work = max_work;
	atomic_set(&b->pending_promotes, 0);
	atomic_set(&b->pending_writebacks, 0);
	atomic_set(&b->pending_demotes, 0);

	INIT_LIST_HEAD(&b->issued);
	INIT_LIST_HEAD(&b->queued);

	b->pending = RB_ROOT;
	b->work_cache = KMEM_CACHE(bt_work, 0);
	if (!b->work_cache) {
		DMERR("couldn't create mempool for background work items");
		kfree(b);
		b = NULL;
	}

	return b;
}
EXPORT_SYMBOL_GPL(btracker_create);

void btracker_destroy(struct background_tracker *b)
{
	kmem_cache_destroy(b->work_cache);
	kfree(b);
}
EXPORT_SYMBOL_GPL(btracker_destroy);

static int cmp_oblock(dm_oblock_t lhs, dm_oblock_t rhs)
{
	if (from_oblock(lhs) < from_oblock(rhs))
		return -1;

	if (from_oblock(rhs) < from_oblock(lhs))
		return 1;

	return 0;
}

static bool __insert_pending(struct background_tracker *b,
			     struct bt_work *nw)
{
	int cmp;
	struct bt_work *w;
	struct rb_node **new = &b->pending.rb_node, *parent = NULL;

	while (*new) {
		w = container_of(*new, struct bt_work, node);

		parent = *new;
		cmp = cmp_oblock(w->work.oblock, nw->work.oblock);
		if (cmp < 0)
			new = &((*new)->rb_left);

		else if (cmp > 0)
			new = &((*new)->rb_right);

		else
			/* already present */
			return false;
	}

	rb_link_node(&nw->node, parent, new);
	rb_insert_color(&nw->node, &b->pending);

	return true;
}

static struct bt_work *__find_pending(struct background_tracker *b,
				      dm_oblock_t oblock)
{
	int cmp;
	struct bt_work *w;
	struct rb_node **new = &b->pending.rb_node;

	while (*new) {
		w = container_of(*new, struct bt_work, node);

		cmp = cmp_oblock(w->work.oblock, oblock);
		if (cmp < 0)
			new = &((*new)->rb_left);

		else if (cmp > 0)
			new = &((*new)->rb_right);

		else
			break;
	}

	return *new ? w : NULL;
}


static void update_stats(struct background_tracker *b, struct policy_work *w, int delta)
{
	switch (w->op) {
	case POLICY_PROMOTE:
		atomic_add(delta, &b->pending_promotes);
		break;

	case POLICY_DEMOTE:
		atomic_add(delta, &b->pending_demotes);
		break;

	case POLICY_WRITEBACK:
		atomic_add(delta, &b->pending_writebacks);
		break;
	}
}

unsigned btracker_nr_writebacks_queued(struct background_tracker *b)
{
	return atomic_read(&b->pending_writebacks);
}
EXPORT_SYMBOL_GPL(btracker_nr_writebacks_queued);

unsigned btracker_nr_demotions_queued(struct background_tracker *b)
{
	return atomic_read(&b->pending_demotes);
}
EXPORT_SYMBOL_GPL(btracker_nr_demotions_queued);

static bool max_work_reached(struct background_tracker *b)
{
	// FIXME: finish
	return false;
}

int btracker_queue(struct background_tracker *b,
		   struct policy_work *work,
		   struct policy_work **pwork)
{
	struct bt_work *w;

	if (pwork)
		*pwork = NULL;

	if (max_work_reached(b))
		return -ENOMEM;

	w = kmem_cache_alloc(b->work_cache, GFP_NOWAIT);
	if (!w)
		return -ENOMEM;

	memcpy(&w->work, work, sizeof(*work));

	if (!__insert_pending(b, w)) {
		/*
		 * There was a race, we'll just ignore this second
		 * bit of work for the same oblock.
		 */
		kmem_cache_free(b->work_cache, w);
		return -EINVAL;
	}

	if (pwork) {
		*pwork = &w->work;
		list_add(&w->list, &b->issued);
	} else
		list_add(&w->list, &b->queued);
	update_stats(b, &w->work, 1);

	return 0;
}
EXPORT_SYMBOL_GPL(btracker_queue);

/*
 * Returns -ENODATA if there's no work.
 */
int btracker_issue(struct background_tracker *b, struct policy_work **work)
{
	struct bt_work *w;

	if (list_empty(&b->queued))
		return -ENODATA;

	w = list_first_entry(&b->queued, struct bt_work, list);
	list_move(&w->list, &b->issued);
	*work = &w->work;

	return 0;
}
EXPORT_SYMBOL_GPL(btracker_issue);

void btracker_complete(struct background_tracker *b,
		       struct policy_work *op)
{
	struct bt_work *w = container_of(op, struct bt_work, work);

	update_stats(b, &w->work, -1);
	rb_erase(&w->node, &b->pending);
	list_del(&w->list);
	kmem_cache_free(b->work_cache, w);
}
EXPORT_SYMBOL_GPL(btracker_complete);

bool btracker_promotion_already_present(struct background_tracker *b,
					dm_oblock_t oblock)
{
	return __find_pending(b, oblock) != NULL;
}
EXPORT_SYMBOL_GPL(btracker_promotion_already_present);

/*----------------------------------------------------------------*/
