/*
 * Copyright (C) 2007 IBM Deutschland Entwicklung GmbH
 *	Released under GPL v2.
 *
 * Partially based on net/ipv4/tcp_probe.c.
 *
 * Simple tracing facility for spu contexts.
 */
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/marker.h>
#include <linux/proc_fs.h>
#include <linux/wait.h>
#include <asm/atomic.h>
#include <asm/uaccess.h>
#include "spufs.h"

struct spu_probe {
	const char *name;
	const char *format;
	marker_probe_func *probe_func;
};

struct sputrace {
	ktime_t tstamp;
	int owner_tid; /* owner */
	int curr_tid;
	const char *name;
	int number;
};

static int bufsize __read_mostly = 16384;
MODULE_PARM_DESC(bufsize, "Log buffer size (number of records)");
module_param(bufsize, int, 0);


static DEFINE_SPINLOCK(sputrace_lock);
static DECLARE_WAIT_QUEUE_HEAD(sputrace_wait);
static ktime_t sputrace_start;
static unsigned long sputrace_head, sputrace_tail;
static struct sputrace *sputrace_log;

static int sputrace_used(void)
{
	return (sputrace_head - sputrace_tail) % bufsize;
}

static inline int sputrace_avail(void)
{
	return bufsize - sputrace_used();
}

static int sputrace_sprint(char *tbuf, int n)
{
	const struct sputrace *t = sputrace_log + sputrace_tail % bufsize;
	struct timespec tv =
		ktime_to_timespec(ktime_sub(t->tstamp, sputrace_start));

	return snprintf(tbuf, n,
		"[%lu.%09lu] %d: %s (ctxthread = %d, spu = %d)\n",
		(unsigned long) tv.tv_sec,
		(unsigned long) tv.tv_nsec,
		t->curr_tid,
		t->name,
		t->owner_tid,
		t->number);
}

static ssize_t sputrace_read(struct file *file, char __user *buf,
		size_t len, loff_t *ppos)
{
	int error = 0, cnt = 0;

	if (!buf || len < 0)
		return -EINVAL;

	while (cnt < len) {
		char tbuf[128];
		int width;

		error = wait_event_interruptible(sputrace_wait,
						 sputrace_used() > 0);
		if (error)
			break;

		spin_lock(&sputrace_lock);
		if (sputrace_head == sputrace_tail) {
			spin_unlock(&sputrace_lock);
			continue;
		}

		width = sputrace_sprint(tbuf, sizeof(tbuf));
		if (width < len)
			sputrace_tail = (sputrace_tail + 1) % bufsize;
		spin_unlock(&sputrace_lock);

		if (width >= len)
			break;

		error = copy_to_user(buf + cnt, tbuf, width);
		if (error)
			break;
		cnt += width;
	}

	return cnt == 0 ? error : cnt;
}

static int sputrace_open(struct inode *inode, struct file *file)
{
	spin_lock(&sputrace_lock);
	sputrace_head = sputrace_tail = 0;
	sputrace_start = ktime_get();
	spin_unlock(&sputrace_lock);

	return 0;
}

static const struct file_operations sputrace_fops = {
	.owner	= THIS_MODULE,
	.open	= sputrace_open,
	.read	= sputrace_read,
};

static void sputrace_log_item(const char *name, struct spu_context *ctx,
		struct spu *spu)
{
	spin_lock(&sputrace_lock);
	if (sputrace_avail() > 1) {
		struct sputrace *t = sputrace_log + sputrace_head;

		t->tstamp = ktime_get();
		t->owner_tid = ctx->tid;
		t->name = name;
		t->curr_tid = current->pid;
		t->number = spu ? spu->number : -1;

		sputrace_head = (sputrace_head + 1) % bufsize;
	} else {
		printk(KERN_WARNING
		       "sputrace: lost samples due to full buffer.\n");
	}
	spin_unlock(&sputrace_lock);

	wake_up(&sputrace_wait);
}

static void spu_context_event(void *probe_private, void *call_data,
		const char *format, va_list *args)
{
	struct spu_probe *p = probe_private;
	struct spu_context *ctx;
	struct spu *spu;

	ctx = va_arg(*args, struct spu_context *);
	spu = va_arg(*args, struct spu *);

	sputrace_log_item(p->name, ctx, spu);
}

static void spu_context_nospu_event(void *probe_private, void *call_data,
		const char *format, va_list *args)
{
	struct spu_probe *p = probe_private;
	struct spu_context *ctx;

	ctx = va_arg(*args, struct spu_context *);

	sputrace_log_item(p->name, ctx, NULL);
}

struct spu_probe spu_probes[] = {
	{ "spu_bind_context__enter", "ctx %p spu %p", spu_context_event },
	{ "spu_unbind_context__enter", "ctx %p spu %p", spu_context_event },
	{ "spu_get_idle__enter", "ctx %p", spu_context_nospu_event },
	{ "spu_get_idle__found", "ctx %p spu %p", spu_context_event },
	{ "spu_get_idle__not_found", "ctx %p", spu_context_nospu_event },
	{ "spu_find_victim__enter", "ctx %p", spu_context_nospu_event },
	{ "spusched_tick__preempt", "ctx %p spu %p", spu_context_event },
	{ "spusched_tick__newslice", "ctx %p", spu_context_nospu_event },
	{ "spu_yield__enter", "ctx %p", spu_context_nospu_event },
	{ "spu_deactivate__enter", "ctx %p", spu_context_nospu_event },
	{ "__spu_deactivate__unload", "ctx %p spu %p", spu_context_event },
	{ "spufs_ps_nopfn__enter", "ctx %p", spu_context_nospu_event },
	{ "spufs_ps_nopfn__sleep", "ctx %p", spu_context_nospu_event },
	{ "spufs_ps_nopfn__wake", "ctx %p spu %p", spu_context_event },
	{ "spufs_ps_nopfn__insert", "ctx %p spu %p", spu_context_event },
	{ "spu_acquire_saved__enter", "ctx %p", spu_context_nospu_event },
	{ "destroy_spu_context__enter", "ctx %p", spu_context_nospu_event },
	{ "spufs_stop_callback__enter", "ctx %p spu %p", spu_context_event },
};

static int __init sputrace_init(void)
{
	struct proc_dir_entry *entry;
	int i, error = -ENOMEM;

	sputrace_log = kcalloc(sizeof(struct sputrace),
				bufsize, GFP_KERNEL);
	if (!sputrace_log)
		goto out;

	entry = proc_create("sputrace", S_IRUSR, NULL, &sputrace_fops);
	if (!entry)
		goto out_free_log;

	for (i = 0; i < ARRAY_SIZE(spu_probes); i++) {
		struct spu_probe *p = &spu_probes[i];

		error = marker_probe_register(p->name, p->format,
					      p->probe_func, p);
		if (error)
			printk(KERN_INFO "Unable to register probe %s\n",
					p->name);
	}

	return 0;

out_free_log:
	kfree(sputrace_log);
out:
	return -ENOMEM;
}

static void __exit sputrace_exit(void)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(spu_probes); i++)
		marker_probe_unregister(spu_probes[i].name,
			spu_probes[i].probe_func, &spu_probes[i]);

	remove_proc_entry("sputrace", NULL);
	kfree(sputrace_log);
}

module_init(sputrace_init);
module_exit(sputrace_exit);

MODULE_LICENSE("GPL");
