// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2019 Google, Inc.
 *
 * Support for setting tasks as latency sensitive
 * using /proc/pid/tasks/tid/latency_sensitive interface.
 */

#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/ptrace.h>
#include <linux/sched/task.h>
#include <linux/sched/latsense.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/fs_struct.h>

#include "internal.h"

/*
 * Print out latsense related information:
 */
static int sched_latsense_show(struct seq_file *m, void *v)
{
	struct inode *inode = m->private;
	struct task_struct *p;

	p = get_proc_task(inode);
	if (!p)
		return -ESRCH;

	seq_printf(m, "%d\n", !!proc_sched_get_latency_sensitive(p));

	put_task_struct(p);

	return 0;
}

static ssize_t
sched_latsense_write(struct file *file, const char __user *buf,
	    size_t count, loff_t *offset)
{
	struct inode *inode = file_inode(file);
	struct task_struct *p;
	char buffer[PROC_NUMBUF];
	int val;
	int err;

	memset(buffer, 0, sizeof(buffer));
	if (count > sizeof(buffer) - 1)
		count = sizeof(buffer) - 1;
	if (copy_from_user(buffer, buf, count))
		return -EFAULT;

	err = kstrtoint(strstrip(buffer), 0, &val);
	if (err < 0)
		return err;

	if (val != 0 && val != 1)
		return -EINVAL;

	p = get_proc_task(inode);
	if (!p)
		return -ESRCH;

	err = proc_sched_set_latency_sensitive(p, val);
	if (err)
		count = err;

	put_task_struct(p);

	return count;
}

static int sched_latsense_access(struct inode *inode, fmode_t mode)
{
	struct task_struct *p;
	int ret = -EACCES;

	if (!(mode & FMODE_WRITE))
		return 0;

	p = get_proc_task(inode);
	if (!p)
		return -ESRCH;

	if (ptrace_may_access(p, PTRACE_MODE_ATTACH_REALCREDS) ||
			capable(CAP_SYS_NICE)) {
		ret = 0;
	}

	put_task_struct(p);
	return ret;
}

static int sched_latsense_open(struct inode *inode, struct file *filp)
{
	int ret;

	ret = sched_latsense_access(inode, filp->f_mode);
	if (ret < 0)
		return ret;

	ret = single_open(filp, sched_latsense_show, NULL);
	if (!ret) {
		struct seq_file *m = filp->private_data;

		m->private = inode;
	}
	return ret;
}

const struct file_operations proc_tid_latsense_operations = {
	.open		= sched_latsense_open,
	.read		= seq_read,
	.write		= sched_latsense_write,
	.llseek		= seq_lseek,
	.release	= single_release,
};
