/*
 * Copyright(C) 2018 Samsung Electronics Co., Ltd.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published by
 * the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/device.h>
#include <linux/mm_types.h>
#include <linux/types.h>
#include <linux/miscdevice.h>
#include <linux/spinlock.h>
#include <linux/debugfs.h>
#include <linux/dma-buf.h>
#include <linux/anon_inodes.h>
#include <linux/sched/signal.h>
#include <linux/sched/mm.h>

#include "dma-buf-trace.h"

struct dmabuf_trace_ref {
	struct list_head task_node;
	struct list_head buffer_node;

	struct dmabuf_trace_task *task;
	struct dmabuf_trace_buffer *buffer;
	int refcount;
};

struct dmabuf_trace_task {
	struct list_head node;
	struct list_head ref_list;

	struct task_struct *task;
	struct file *file;
	struct dentry *debug_task;
};

struct dmabuf_trace_buffer {
	struct list_head node;
	struct list_head ref_list;

	struct dma_buf *dmabuf;
	int shared_count;
};

static struct list_head buffer_list = LIST_HEAD_INIT(buffer_list);

/*
 * head_task.node is the head node of all other dmabuf_trace_task.node.
 * At the same time, head_task itself maintains the buffer information allocated
 * by the kernel threads.
 */
static struct dmabuf_trace_task head_task;
static DEFINE_MUTEX(trace_lock);

#ifdef CONFIG_DEBUG_FS
static struct dentry *debug_root;
#endif

static int dmabuf_trace_debug_show(struct seq_file *s, void *unused)
{
	struct dmabuf_trace_task *task = s->private;
	struct dmabuf_trace_ref *ref;

	mutex_lock(&trace_lock);
	seq_puts(s, "\nDma-buf-trace Objects:\n");
	seq_printf(s, "%10s %12s %12s %10s\n",
		   "exp_name", "size", "share", "refcount");

	list_for_each_entry(ref, &task->ref_list, task_node) {
		seq_printf(s, "%10s %12zu %12zu %10d\n",
			   ref->buffer->dmabuf->exp_name,
			   ref->buffer->dmabuf->size,
			   ref->buffer->dmabuf->size /
			   ref->buffer->shared_count,
			   ref->refcount);
	}
	mutex_unlock(&trace_lock);

	return 0;
}

static int dmabuf_trace_debug_open(struct inode *inode, struct file *file)
{
	return single_open(file, dmabuf_trace_debug_show, inode->i_private);
}

static const struct file_operations dmabuf_trace_debug_fops = {
	.open = dmabuf_trace_debug_open,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = single_release,
};

static void dmabuf_trace_free_ref_force(struct dmabuf_trace_ref *ref)
{
	ref->buffer->shared_count--;

	list_del(&ref->buffer_node);
	list_del(&ref->task_node);

	kfree(ref);
}

static int dmabuf_trace_free_ref(struct dmabuf_trace_ref *ref)
{
	/* The reference has never been registered */
	if (WARN_ON(ref->refcount == 0))
		return -EINVAL;

	if (--ref->refcount == 0)
		dmabuf_trace_free_ref_force(ref);

	return 0;
}

static int dmabuf_trace_task_release(struct inode *inode, struct file *file)
{
	struct dmabuf_trace_task *task = file->private_data;
	struct dmabuf_trace_ref *ref, *tmp;

	if (!(task->task->flags & PF_EXITING)) {
		pr_err("%s: Invalid to close '%d' on process '%s'(%x, %lx)\n",
		       __func__, task->task->pid, task->task->comm,
		       task->task->flags, task->task->state);

		dump_stack();
	}

	put_task_struct(task->task);

	mutex_lock(&trace_lock);

	list_for_each_entry_safe(ref, tmp, &task->ref_list, task_node)
		dmabuf_trace_free_ref_force(ref);

	list_del(&task->node);

	mutex_unlock(&trace_lock);

	debugfs_remove(task->debug_task);

	kfree(task);

	return 0;
}

static const struct file_operations dmabuf_trace_task_fops = {
	.release = dmabuf_trace_task_release,
};

static struct dmabuf_trace_buffer *dmabuf_trace_get_buffer(
		struct dma_buf *dmabuf)
{
	struct dmabuf_trace_buffer *buffer;

	list_for_each_entry(buffer, &buffer_list, node)
		if (buffer->dmabuf == dmabuf)
			return buffer;

	return NULL;
}

static struct dmabuf_trace_task *dmabuf_trace_get_task_noalloc(void)
{
	struct dmabuf_trace_task *task;

	if (!current->mm && (current->flags & PF_KTHREAD))
		return &head_task;

	list_for_each_entry(task, &head_task.node, node)
		if (task->task == current->group_leader)
			return task;

	return NULL;
}

static struct dmabuf_trace_task *dmabuf_trace_get_task(void)
{
	struct dmabuf_trace_task *task;
	unsigned char name[10];
	int ret, fd;

	task = dmabuf_trace_get_task_noalloc();
	if (task)
		return task;

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

	INIT_LIST_HEAD(&task->node);
	INIT_LIST_HEAD(&task->ref_list);

	scnprintf(name, 10, "%d", current->group_leader->pid);

	get_task_struct(current->group_leader);

	task->task = current->group_leader;
#ifdef CONFIG_DEBUG_FS
	task->debug_task = debugfs_create_file(name, 0444,
					       debug_root, task,
					       &dmabuf_trace_debug_fops);
	if (IS_ERR(task->debug_task)) {
		ret = PTR_ERR(task->debug_task);
		goto err_debugfs;
	}
#endif

	ret = get_unused_fd_flags(O_RDONLY | O_CLOEXEC);
	if (ret < 0)
		goto err_fd;
	fd = ret;

	task->file = anon_inode_getfile(name, &dmabuf_trace_task_fops,
					task, O_RDWR);
	if (IS_ERR(task->file)) {
		ret = PTR_ERR(task->file);

		goto err_inode;
	}

	fd_install(fd, task->file);

	list_add_tail(&task->node, &head_task.node);

	return task;

err_inode:
	put_unused_fd(fd);
err_fd:
	debugfs_remove(task->debug_task);
#ifdef CONFIG_DEBUG_FS
err_debugfs:
#endif
	put_task_struct(current->group_leader);

	kfree(task);

	pr_err("%s: Failed to get task(err %d)\n", __func__, ret);

	return ERR_PTR(ret);

}

static struct dmabuf_trace_ref *dmabuf_trace_get_ref_noalloc(
		struct dmabuf_trace_buffer *buffer,
		struct dmabuf_trace_task *task)
{
	struct dmabuf_trace_ref *ref;

	list_for_each_entry(ref, &task->ref_list, task_node)
		if (ref->buffer == buffer)
			return ref;

	return NULL;
}

static struct dmabuf_trace_ref *dmabuf_trace_get_ref(
		struct dmabuf_trace_buffer *buffer,
		struct dmabuf_trace_task *task)
{
	struct dmabuf_trace_ref *ref;

	ref = dmabuf_trace_get_ref_noalloc(buffer, task);
	if (ref) {
		ref->refcount++;
		return ref;
	}

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

	INIT_LIST_HEAD(&ref->buffer_node);
	INIT_LIST_HEAD(&ref->task_node);

	ref->task = task;
	ref->buffer = buffer;
	ref->refcount = 1;

	list_add_tail(&ref->task_node, &task->ref_list);
	list_add_tail(&ref->buffer_node, &buffer->ref_list);

	buffer->shared_count++;

	return ref;
}

/**
 * dmabuf_trace_alloc - get reference after creating dmabuf.
 * @dmabuf : buffer to register reference.
 *
 * This create a ref that has relationship between dmabuf
 * and process that requested allocation, and also create
 * the buffer object to trace.
 */
int dmabuf_trace_alloc(struct dma_buf *dmabuf)
{
	struct dmabuf_trace_buffer *buffer;
	struct dmabuf_trace_task *task;
	struct dmabuf_trace_ref *ref;
	int ret = -ENOMEM;

	buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
	if (!buffer)
		return ret;

	INIT_LIST_HEAD(&buffer->ref_list);

	buffer->dmabuf = dmabuf;
	buffer->shared_count = 1;

	ref = kzalloc(sizeof(*ref), GFP_KERNEL);
	if (!ref)
		goto err_ref;

	ref->buffer = buffer;

	/*
	 * The interim ref created in dmabuf_trace_alloc is just for counting
	 * the buffer references correctly. The interim ref has zero refcount.
	 * If user explicitly registers a ref, it is handled in
	 * dmabuf_trace_track_buffer(). If first dmabuf_trace_track_buffer() is
	 * called in the same task that allocated the buffer, the interim ref
	 * becomes the regular ref that has larget refcount than 0. If the first
	 * call to dmabuf_trace_track_buffer() made in other tasks, the interim
	 * ref is removed and a new regular ref is created and registered
	 * instead of the interim ref.
	 */
	ref->refcount = 0;

	mutex_lock(&trace_lock);

	task = dmabuf_trace_get_task();
	if (IS_ERR(task)) {
		mutex_unlock(&trace_lock);
		ret = PTR_ERR(task);

		goto err_task;
	}

	ref->task = task;

	list_add_tail(&buffer->node, &buffer_list);

	list_add_tail(&ref->task_node, &task->ref_list);
	list_add_tail(&ref->buffer_node, &buffer->ref_list);

	mutex_unlock(&trace_lock);

	return 0;
err_task:
	kfree(ref);
err_ref:
	kfree(buffer);
	pr_err("%s: Failed to trace dmabuf after to export(err %d)\n",
	       __func__, ret);

	return ret;
}

/**
 * dmabuf_trace_free - release references after removing buffer.
 * @dmabuf : buffer to release reference.
 *
 * This remove refs that connected with released dmabuf.
 */
void dmabuf_trace_free(struct dma_buf *dmabuf)
{
	struct dmabuf_trace_buffer *buffer;
	struct dmabuf_trace_ref *ref, *tmp;

	mutex_lock(&trace_lock);

	buffer = dmabuf_trace_get_buffer(dmabuf);
	if (!buffer) {
		mutex_unlock(&trace_lock);
		return;
	}

	list_for_each_entry_safe(ref, tmp, &buffer->ref_list, buffer_node)
		dmabuf_trace_free_ref_force(ref);

	list_del(&buffer->node);

	mutex_unlock(&trace_lock);

	kfree(buffer);
}

/**
 * dmabuf_trace_register - create ref between task and buffer.
 * @dmabuf : buffer to register reference.
 *
 * This create ref between current task and buffer.
 */
int dmabuf_trace_track_buffer(struct dma_buf *dmabuf)
{
	struct dmabuf_trace_buffer *buffer;
	struct dmabuf_trace_task *task;
	struct dmabuf_trace_ref *ref;
	int ret = 0;

	mutex_lock(&trace_lock);
	task = dmabuf_trace_get_task();
	if (IS_ERR(task)) {
		ret = PTR_ERR(task);
		goto err;
	}

	buffer = dmabuf_trace_get_buffer(dmabuf);
	if (!buffer) {
		ret = -EINVAL;
		goto err;
	}

	ref = dmabuf_trace_get_ref(buffer, task);
	if (IS_ERR(ref)) {
		/*
		 * task allocated by dmabuf_trace_get_task() is not freed here.
		 * It is deallocated when the process exits.
		 */
		ret = PTR_ERR(ref);
		goto err;
	}

	ref = list_first_entry(&buffer->ref_list, struct dmabuf_trace_ref,
			       buffer_node);
	/*
	 * If first ref of buffer has zero refcount, it is an interim ref
	 * created in dmabuf_trace_alloc() called by other tasks than current.
	 * The interim ref should be removed after the regular ref created here
	 * is registered.
	 */
	if (ref->refcount == 0)
		dmabuf_trace_free_ref_force(ref);
err:
	mutex_unlock(&trace_lock);

	if (ret)
		pr_err("%s: Failed to trace dmabuf (err %d)\n", __func__, ret);
	return ret;
}

/**
 * dmabuf_trace_unregister - remove ref between task and buffer.
 * @dmabuf : buffer to unregister reference.
 *
 * This remove ref between current task and buffer.
 */
int dmabuf_trace_untrack_buffer(struct dma_buf *dmabuf)
{
	struct dmabuf_trace_buffer *buffer;
	struct dmabuf_trace_task *task;
	struct dmabuf_trace_ref *ref;
	int ret;

	mutex_lock(&trace_lock);
	task = dmabuf_trace_get_task_noalloc();
	if (!task) {
		ret = -ESRCH;
		goto err_unregister;
	}

	buffer = dmabuf_trace_get_buffer(dmabuf);
	if (!buffer) {
		ret = -EINVAL;
		goto err_unregister;
	}

	ref = dmabuf_trace_get_ref_noalloc(buffer, task);
	if (!ref) {
		ret = -ENOENT;
		goto err_unregister;
	}

	ret = dmabuf_trace_free_ref(ref);

err_unregister:
	if (ret)
		pr_err("%s: Failed to untrace dmabuf(err %d)", __func__, ret);

	mutex_unlock(&trace_lock);

	return ret;
}

static int __init dmabuf_trace_create(void)
{
#ifdef CONFIG_DEBUG_FS
	debug_root = debugfs_create_dir("footprint", dma_buf_debugfs_dir);
	if (IS_ERR(debug_root)) {
		pr_err("%s : Failed to create directory\n", __func__);

		return PTR_ERR(debug_root);
	}

	/*
	 * PID 1 is actually the pid of the init process. dma-buf trace borrows
	 * pid 1 for the buffers allocated by the kernel threads to provide
	 * full buffer information to Android Memory Tracker.
	 */
	head_task.debug_task = debugfs_create_file("0", 0444,
						   debug_root, &head_task,
						   &dmabuf_trace_debug_fops);
	if (IS_ERR(head_task.debug_task)) {
		debugfs_remove(debug_root);
		pr_err("%s: Failed to create task for kernel thread\n",
		       __func__);
		return PTR_ERR(head_task.debug_task);
	}
#endif

	INIT_LIST_HEAD(&head_task.node);
	INIT_LIST_HEAD(&head_task.ref_list);

	pr_info("Initialized dma-buf trace successfully.\n");

	return 0;
}
fs_initcall_sync(dmabuf_trace_create);
