/* Copyright (c) 2016 Google Inc
 * Barret Rhoden <brho@cs.berkeley.edu>
 * See LICENSE for details.
 *
 * #mem, memory diagnostics (arenas and slabs)
 */

#include <ns.h>
#include <kmalloc.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <error.h>
#include <syscall.h>
#include <sys/queue.h>

struct dev mem_devtab;

static char *devname(void)
{
	return mem_devtab.name;
}

enum {
	Qdir,
	Qarena_stats,
	Qslab_stats,
	Qfree,
	Qkmemstat,
	Qslab_trace,
};

static struct dirtab mem_dir[] = {
	{".", {Qdir, 0, QTDIR}, 0, DMDIR | 0555},
	{"arena_stats", {Qarena_stats, 0, QTFILE}, 0, 0444},
	{"slab_stats", {Qslab_stats, 0, QTFILE}, 0, 0444},
	{"free", {Qfree, 0, QTFILE}, 0, 0444},
	{"kmemstat", {Qkmemstat, 0, QTFILE}, 0, 0444},
	{"slab_trace", {Qslab_trace, 0, QTFILE}, 0, 0444},
};

/* Protected by the arenas_and_slabs_lock */
static struct sized_alloc *slab_trace_data;

static struct chan *mem_attach(char *spec)
{
	return devattach(devname(), spec);
}

static struct walkqid *mem_walk(struct chan *c, struct chan *nc, char **name,
				unsigned int nname)
{
	return devwalk(c, nc, name, nname, mem_dir, ARRAY_SIZE(mem_dir),
		       devgen);
}

static size_t mem_stat(struct chan *c, uint8_t *db, size_t n)
{
	return devstat(c, db, n, mem_dir, ARRAY_SIZE(mem_dir), devgen);
}

/* Prints arena's stats to the sza, adjusting the sza's sofar. */
static void fetch_arena_stats(struct arena *arena, struct sized_alloc *sza)
{
	struct btag *bt_i;
	struct rb_node *rb_i;
	struct arena *a_i;
	struct kmem_cache *kc_i;

	size_t nr_allocs = 0;
	size_t nr_imports = 0;
	size_t amt_alloc = 0;
	size_t amt_free = 0;
	size_t amt_imported = 0;
	size_t empty_hash_chain = 0;
	size_t longest_hash_chain = 0;

	sza_printf(sza, "Arena: %s (%p)\n--------------\n", arena->name, arena);
	sza_printf(sza, "\tquantum: %d, qcache_max: %d\n", arena->quantum,
	           arena->qcache_max);
	sza_printf(sza, "\tsource: %s\n",
	           arena->source ? arena->source->name : "none");
	spin_lock_irqsave(&arena->lock);
	for (int i = 0; i < ARENA_NR_FREE_LISTS; i++) {
		int j = 0;

		if (!BSD_LIST_EMPTY(&arena->free_segs[i])) {
			sza_printf(sza, "\tList of [2^%d - 2^%d):\n", i, i + 1);
			BSD_LIST_FOREACH(bt_i, &arena->free_segs[i], misc_link)
				j++;
			sza_printf(sza, "\t\tNr free segs: %d\n", j);
		}
	}
	for (int i = 0; i < arena->hh.nr_hash_lists; i++) {
		int j = 0;

		if (BSD_LIST_EMPTY(&arena->alloc_hash[i]))
			empty_hash_chain++;
		BSD_LIST_FOREACH(bt_i, &arena->alloc_hash[i], misc_link)
			j++;
		longest_hash_chain = MAX(longest_hash_chain, j);
	}
	sza_printf(sza, "\tSegments:\n\t--------------\n");
	for (rb_i = rb_first(&arena->all_segs); rb_i; rb_i = rb_next(rb_i)) {
		bt_i = container_of(rb_i, struct btag, all_link);
		if (bt_i->status == BTAG_SPAN) {
			nr_imports++;
			amt_imported += bt_i->size;
		}
		if (bt_i->status == BTAG_FREE)
			amt_free += bt_i->size;
		if (bt_i->status == BTAG_ALLOC) {
			nr_allocs++;
			amt_alloc += bt_i->size;
		}
	}
	sza_printf(sza, "\tStats:\n\t-----------------\n");
	sza_printf(sza, "\t\tAmt free: %llu (%p)\n", amt_free, amt_free);
	sza_printf(sza, "\t\tAmt alloc: %llu (%p), nr allocs %d\n",
	           amt_alloc, amt_alloc, nr_allocs);
	sza_printf(sza, "\t\tAmt total segs: %llu, amt alloc segs %llu\n",
	           arena->amt_total_segs, arena->amt_alloc_segs);
	sza_printf(sza, "\t\tAmt imported: %llu (%p), nr imports %d\n",
	           amt_imported, amt_imported, nr_imports);
	sza_printf(sza, "\t\tNr hash %d, empty hash: %d, longest hash %d\n",
	           arena->hh.nr_hash_lists, empty_hash_chain,
	           longest_hash_chain);
	spin_unlock_irqsave(&arena->lock);
	sza_printf(sza, "\tImporting Arenas:\n\t-----------------\n");
	TAILQ_FOREACH(a_i, &arena->__importing_arenas, import_link)
		sza_printf(sza, "\t\t%s\n", a_i->name);
	sza_printf(sza, "\tImporting Slabs:\n\t-----------------\n");
	TAILQ_FOREACH(kc_i, &arena->__importing_slabs, import_link)
		sza_printf(sza, "\t\t%s\n", kc_i->name);
}

static struct sized_alloc *build_arena_stats(void)
{
	struct sized_alloc *sza;
	size_t alloc_amt = 0;
	struct arena *a_i;

	qlock(&arenas_and_slabs_lock);
	/* Rough guess about how many chars per arena we'll need. */
	TAILQ_FOREACH(a_i, &all_arenas, next)
		alloc_amt += 1000;
	sza = sized_kzmalloc(alloc_amt, MEM_WAIT);
	TAILQ_FOREACH(a_i, &all_arenas, next)
		fetch_arena_stats(a_i, sza);
	qunlock(&arenas_and_slabs_lock);
	return sza;
}

/* Prints arena's stats to the sza, updating its sofar. */
static void fetch_slab_stats(struct kmem_cache *kc, struct sized_alloc *sza)
{
	struct kmem_slab *s_i;
	struct kmem_bufctl *bc_i;

	size_t nr_unalloc_objs = 0;
	size_t empty_hash_chain = 0;
	size_t longest_hash_chain = 0;

	spin_lock_irqsave(&kc->cache_lock);
	sza_printf(sza, "\nKmem_cache: %s\n---------------------\n", kc->name);
	sza_printf(sza, "Source: %s\n", kc->source->name);
	sza_printf(sza, "Objsize (incl align): %d\n", kc->obj_size);
	sza_printf(sza, "Align: %d\n", kc->align);
	TAILQ_FOREACH(s_i, &kc->empty_slab_list, link) {
		assert(!s_i->num_busy_obj);
		nr_unalloc_objs += s_i->num_total_obj;
	}
	TAILQ_FOREACH(s_i, &kc->partial_slab_list, link)
		nr_unalloc_objs += s_i->num_total_obj - s_i->num_busy_obj;
	sza_printf(sza, "Nr unallocated in slab layer: %lu\n", nr_unalloc_objs);
	sza_printf(sza, "Nr allocated from slab layer: %d\n", kc->nr_cur_alloc);
	for (int i = 0; i < kc->hh.nr_hash_lists; i++) {
		int j = 0;

		if (BSD_LIST_EMPTY(&kc->alloc_hash[i]))
			empty_hash_chain++;
		BSD_LIST_FOREACH(bc_i, &kc->alloc_hash[i], link)
			j++;
		longest_hash_chain = MAX(longest_hash_chain, j);
	}
	sza_printf(sza,
		   "Nr hash %d, empty hash: %d, longest hash %d, loadlim %d\n",
	           kc->hh.nr_hash_lists, empty_hash_chain,
	           longest_hash_chain, kc->hh.load_limit);
	spin_unlock_irqsave(&kc->cache_lock);
	spin_lock_irqsave(&kc->depot.lock);
	sza_printf(sza, "Depot magsize: %d\n", kc->depot.magsize);
	sza_printf(sza, "Nr empty mags: %d\n", kc->depot.nr_empty);
	sza_printf(sza, "Nr non-empty mags: %d\n", kc->depot.nr_not_empty);
	spin_unlock_irqsave(&kc->depot.lock);
}

static struct sized_alloc *build_slab_stats(void)
{
	struct sized_alloc *sza;
	size_t alloc_amt = 0;
	struct kmem_cache *kc_i;

	qlock(&arenas_and_slabs_lock);
	TAILQ_FOREACH(kc_i, &all_kmem_caches, all_kmc_link)
		alloc_amt += 500;
	sza = sized_kzmalloc(alloc_amt, MEM_WAIT);
	TAILQ_FOREACH(kc_i, &all_kmem_caches, all_kmc_link)
		fetch_slab_stats(kc_i, sza);
	qunlock(&arenas_and_slabs_lock);
	return sza;
}

static struct sized_alloc *build_free(void)
{
	struct arena *a_i;
	struct sized_alloc *sza;
	size_t amt_total = 0;
	size_t amt_alloc = 0;

	sza = sized_kzmalloc(500, MEM_WAIT);
	qlock(&arenas_and_slabs_lock);
	TAILQ_FOREACH(a_i, &all_arenas, next) {
		if (!a_i->is_base)
			continue;
		amt_total += a_i->amt_total_segs;
		amt_alloc += a_i->amt_alloc_segs;
	}
	qunlock(&arenas_and_slabs_lock);
	sza_printf(sza, "Total Memory : %15llu\n", amt_total);
	sza_printf(sza, "Used Memory  : %15llu\n", amt_alloc);
	sza_printf(sza, "Free Memory  : %15llu\n", amt_total - amt_alloc);
	return sza;
}

#define KMEMSTAT_NAME			30
#define KMEMSTAT_OBJSIZE		8
#define KMEMSTAT_TOTAL			15
#define KMEMSTAT_ALLOCED		15
#define KMEMSTAT_NR_ALLOCS		12
#define KMEMSTAT_LINE_LN (8 + KMEMSTAT_NAME + KMEMSTAT_OBJSIZE + KMEMSTAT_TOTAL\
                          + KMEMSTAT_ALLOCED + KMEMSTAT_NR_ALLOCS)

const char kmemstat_fmt[]     = "%-*s: %c :%*llu:%*llu:%*llu:%*llu\n";
const char kmemstat_hdr_fmt[] = "%-*s:Typ:%*s:%*s:%*s:%*s\n";

static void fetch_arena_line(struct arena *arena, struct sized_alloc *sza,
                             int indent)
{
	for (int i = 0; i < indent; i++)
		sza_printf(sza, "    ");
	sza_printf(sza, kmemstat_fmt,
	           KMEMSTAT_NAME - indent * 4, arena->name,
	           'A',
	           KMEMSTAT_OBJSIZE, arena->quantum,
	           KMEMSTAT_TOTAL, arena->amt_total_segs,
	           KMEMSTAT_ALLOCED, arena->amt_alloc_segs,
	           KMEMSTAT_NR_ALLOCS, arena->nr_allocs_ever);
}

static void fetch_slab_line(struct kmem_cache *kc, struct sized_alloc *sza,
                            int indent)
{
	struct kmem_pcpu_cache *pcc;
	struct kmem_slab *s_i;
	size_t nr_unalloc_objs = 0;
	size_t nr_allocs_ever = 0;

	spin_lock_irqsave(&kc->cache_lock);
	TAILQ_FOREACH(s_i, &kc->empty_slab_list, link)
		nr_unalloc_objs += s_i->num_total_obj;
	TAILQ_FOREACH(s_i, &kc->partial_slab_list, link)
		nr_unalloc_objs += s_i->num_total_obj - s_i->num_busy_obj;
	nr_allocs_ever = kc->nr_direct_allocs_ever;
	spin_unlock_irqsave(&kc->cache_lock);
	/* Lockless peak at the pcpu state */
	for (int i = 0; i < kmc_nr_pcpu_caches(); i++) {
		pcc = &kc->pcpu_caches[i];
		nr_allocs_ever += pcc->nr_allocs_ever;
	}

	for (int i = 0; i < indent; i++)
		sza_printf(sza, "    ");
	sza_printf(sza, kmemstat_fmt,
	           KMEMSTAT_NAME - indent * 4, kc->name,
	           'S',
	           KMEMSTAT_OBJSIZE, kc->obj_size,
	           KMEMSTAT_TOTAL, kc->obj_size * (nr_unalloc_objs +
	                                           kc->nr_cur_alloc),
	           KMEMSTAT_ALLOCED, kc->obj_size * kc->nr_cur_alloc,
	           KMEMSTAT_NR_ALLOCS, nr_allocs_ever);
}

static void fetch_arena_and_kids(struct arena *arena, struct sized_alloc *sza,
                                 int indent)
{
	struct arena *a_i;
	struct kmem_cache *kc_i;

	fetch_arena_line(arena, sza, indent);
	TAILQ_FOREACH(a_i, &arena->__importing_arenas, import_link)
		fetch_arena_and_kids(a_i, sza, indent + 1);
	TAILQ_FOREACH(kc_i, &arena->__importing_slabs, import_link)
		fetch_slab_line(kc_i, sza, indent + 1);
}

static struct sized_alloc *build_kmemstat(void)
{
	struct arena *a_i;
	struct kmem_cache *kc_i;
	struct sized_alloc *sza;
	size_t alloc_amt = 100;

	qlock(&arenas_and_slabs_lock);
	TAILQ_FOREACH(a_i, &all_arenas, next)
		alloc_amt += 100;
	TAILQ_FOREACH(kc_i, &all_kmem_caches, all_kmc_link)
		alloc_amt += 100;
	sza = sized_kzmalloc(alloc_amt, MEM_WAIT);
	sza_printf(sza, kmemstat_hdr_fmt,
	           KMEMSTAT_NAME, "Arena/Slab Name",
	           KMEMSTAT_OBJSIZE, "Objsize",
	           KMEMSTAT_TOTAL, "Total Amt",
	           KMEMSTAT_ALLOCED, "Alloc Amt",
	           KMEMSTAT_NR_ALLOCS, "Allocs Ever");
	for (int i = 0; i < KMEMSTAT_LINE_LN; i++)
		sza_printf(sza, "-");
	sza_printf(sza, "\n");
	TAILQ_FOREACH(a_i, &all_arenas, next) {
		if (a_i->source)
			continue;
		fetch_arena_and_kids(a_i, sza, 0);
	}
	qunlock(&arenas_and_slabs_lock);
	return sza;
}

static struct chan *mem_open(struct chan *c, int omode)
{
	if (c->qid.type & QTDIR) {
		if (openmode(omode) != O_READ)
			error(EPERM, "Tried opening directory not read-only");
	}
	switch (c->qid.path) {
	case Qarena_stats:
		c->synth_buf = build_arena_stats();
		break;
	case Qslab_stats:
		c->synth_buf = build_slab_stats();
		break;
	case Qfree:
		c->synth_buf = build_free();
		break;
	case Qkmemstat:
		c->synth_buf = build_kmemstat();
		break;
	}
	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	return c;
}

static void mem_close(struct chan *c)
{
	if (!(c->flag & COPEN))
		return;
	switch (c->qid.path) {
	case Qarena_stats:
	case Qslab_stats:
	case Qfree:
	case Qkmemstat:
		kfree(c->synth_buf);
		c->synth_buf = NULL;
		break;
	}
}

static size_t slab_trace_read(struct chan *c, void *ubuf, size_t n,
                              off64_t offset)
{
	size_t ret = 0;

	qlock(&arenas_and_slabs_lock);
	if (slab_trace_data)
		ret = readstr(offset, ubuf, n, slab_trace_data->buf);
	qunlock(&arenas_and_slabs_lock);
	return ret;
}

static size_t mem_read(struct chan *c, void *ubuf, size_t n, off64_t offset)
{
	struct sized_alloc *sza;

	switch (c->qid.path) {
	case Qdir:
		return devdirread(c, ubuf, n, mem_dir, ARRAY_SIZE(mem_dir),
						  devgen);
	case Qarena_stats:
	case Qslab_stats:
	case Qfree:
	case Qkmemstat:
		sza = c->synth_buf;
		return readstr(offset, ubuf, n, sza->buf);
	case Qslab_trace:
		return slab_trace_read(c, ubuf, n, offset);
	default:
		panic("Bad Qid %p!", c->qid.path);
	}
	return -1;
}

/* start, then stop, then print, then read to get the trace */
#define SLAB_TRACE_USAGE "start|stop|print|reset SLAB_NAME"

static void slab_trace_cmd(struct chan *c, struct cmdbuf *cb)
{
	ERRSTACK(1);
	struct sized_alloc *sza, *old_sza;
	struct kmem_cache *kc;

	if (cb->nf < 2)
		error(EFAIL, SLAB_TRACE_USAGE);

	qlock(&arenas_and_slabs_lock);
	if (waserror()) {
		qunlock(&arenas_and_slabs_lock);
		nexterror();
	}
	TAILQ_FOREACH(kc, &all_kmem_caches, all_kmc_link)
		if (!strcmp(kc->name, cb->f[1]))
			break;
	if (!kc)
		error(ENOENT, "No such slab %s", cb->f[1]);
	/* Note that the only time we have a real sza is when printing.
	 * Otherwise, it's NULL.  We still want this to be the chan's sza, since
	 * the reader should get nothing back until they ask for a print. */
	sza = NULL;
	if (!strcmp(cb->f[0], "start")) {
		if (kmem_trace_start(kc))
			error(EFAIL, "Unable to trace slab %s", kc->name);
	} else if (!strcmp(cb->f[0], "stop")) {
		kmem_trace_stop(kc);
	} else if (!strcmp(cb->f[0], "print")) {
		sza = kmem_trace_print(kc);
	} else if (!strcmp(cb->f[0], "reset")) {
		kmem_trace_reset(kc);
	} else {
		error(EFAIL, SLAB_TRACE_USAGE);
	}
	old_sza = slab_trace_data;
	slab_trace_data = sza;
	qunlock(&arenas_and_slabs_lock);
	poperror();
	kfree(old_sza);
}

static size_t mem_write(struct chan *c, void *ubuf, size_t n, off64_t unused)
{
	ERRSTACK(1);
	struct cmdbuf *cb = parsecmd(ubuf, n);

	if (waserror()) {
		kfree(cb);
		nexterror();
	}
	switch (c->qid.path) {
	case Qslab_trace:
		slab_trace_cmd(c, cb);
		break;
	default:
		error(EFAIL, "Unable to write to %s", devname());
	}
	kfree(cb);
	poperror();
	return n;
}

struct dev mem_devtab __devtab = {
	.name = "mem",
	.reset = devreset,
	.init = devinit,
	.shutdown = devshutdown,
	.attach = mem_attach,
	.walk = mem_walk,
	.stat = mem_stat,
	.open = mem_open,
	.create = devcreate,
	.close = mem_close,
	.read = mem_read,
	.bread = devbread,
	.write = mem_write,
	.bwrite = devbwrite,
	.remove = devremove,
	.wstat = devwstat,
	.power = devpower,
	.chaninfo = devchaninfo,
};
