/*
 * 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);

	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);
	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);
	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);
