From patchwork Mon Feb 8 23:23:16 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 61453 Delivered-To: patches@linaro.org Received: by 10.112.43.199 with SMTP id y7csp1721768lbl; Mon, 8 Feb 2016 15:23:26 -0800 (PST) X-Received: by 10.202.172.9 with SMTP id v9mr1194284oie.14.1454973804968; Mon, 08 Feb 2016 15:23:24 -0800 (PST) Return-Path: Received: from mail-oi0-x233.google.com (mail-oi0-x233.google.com. [2607:f8b0:4003:c06::233]) by mx.google.com with ESMTPS id p2si808263oia.113.2016.02.08.15.23.24 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 08 Feb 2016 15:23:24 -0800 (PST) Received-SPF: pass (google.com: domain of john.stultz@linaro.org designates 2607:f8b0:4003:c06::233 as permitted sender) client-ip=2607:f8b0:4003:c06::233; Authentication-Results: mx.google.com; spf=pass (google.com: domain of john.stultz@linaro.org designates 2607:f8b0:4003:c06::233 as permitted sender) smtp.mailfrom=john.stultz@linaro.org; dkim=pass header.i=@linaro.org Received: by mail-oi0-x233.google.com with SMTP id j125so5641257oih.1 for ; Mon, 08 Feb 2016 15:23:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=S4e5DrvorwUsjjmvn8PjuF+eA5G3HctMqcps4k/bOYg=; b=JMPqwITlhv9OtGw0EuG6C7GOgvMRKY4+9w9NczNXQfoYhL/zilwqD0OikZOPVE6/JG QFg5otYAyVGtYyD4GQ4hj/PMpnBBzA5n/HLjFPqgjbZLEHXrRPP0mC8x5FZOv2VPoluU hGWmCvwmHQlDwWN6Oq3hudsssUjFkdAKyxu/8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=S4e5DrvorwUsjjmvn8PjuF+eA5G3HctMqcps4k/bOYg=; b=cRRL1HPqTtQrVzgK4xW2SoxOT3Gs/tID+9nuLTYWtEJrj4eRNxrUI5NbQDnNT9Tuc0 FYfbaeYs//EaOUWMPqNlCUzSniwIt9dDJCn0iiJVtCdf/Q+EU4XjUsrdgGOWea/CUeiK rJ6tHJNokIZK+nfZwy0a1ghEecILu5/PUsUmhwkk32a8fIbRZON9M0dL5IQIPInS1eEy BXNdTyRXj6BK+3DQvzMzwL5RrMdseZ0JfWtZ/21K1VwYYmlx52K2iMADCkAxq6pQeUww QJZ/XOmGNFaB7O+L2tm22rNdd2OA1IYTDCDVTO8n0h6EFeIx4WnKfMcD94nyrQAQJUBt 70aA== X-Gm-Message-State: AG10YOQ5YjoBWPe3VD4X/u4wSjR1fcqmqW/dERwWGKrNS0FIdw1LBHVVuo3j34vEGOZxvmKKIPs= X-Received: by 10.202.83.74 with SMTP id h71mr1162205oib.10.1454973804588; Mon, 08 Feb 2016 15:23:24 -0800 (PST) Return-Path: Received: from localhost.localdomain (c-76-115-103-22.hsd1.or.comcast.net. [76.115.103.22]) by smtp.gmail.com with ESMTPSA id kg7sm18810142obb.27.2016.02.08.15.23.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 08 Feb 2016 15:23:24 -0800 (PST) From: John Stultz To: lkml Cc: John Stultz , Arjan van de Ven , Thomas Gleixner , Oren Laadan , Ruchi Kandoi , Rom Lemarchand , Kees Cook , Andrew Morton , Android Kernel Team Subject: [RFC][PATCH 2/2] proc: Add /proc//timerslack_ns interface Date: Mon, 8 Feb 2016 15:23:16 -0800 Message-Id: <1454973796-30616-3-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1454973796-30616-1-git-send-email-john.stultz@linaro.org> References: <1454973796-30616-1-git-send-email-john.stultz@linaro.org> This patch provides a proc/PID/timerslack_ns interface which exposes a task's timerslack value in nanoseconds and allows it to be changed. This allows power/performance management software to set timer slack for other threads according to its policy for the thread (such as when the thread is designated foreground vs. background activity) If the value written is non-zero, slack is set to that value. Otherwise sets it to the default for the thread. This interface checks that the calling task has permissions to to use PTRACE_MODE_ATTACH_FSCREDS on the target task, so that we can ensure arbitrary apps do not change the timer slack for other apps. Cc: Arjan van de Ven Cc: Thomas Gleixner Cc: Oren Laadan Cc: Ruchi Kandoi Cc: Rom Lemarchand Cc: Kees Cook Cc: Andrew Morton Cc: Android Kernel Team Signed-off-by: John Stultz --- Documentation/filesystems/proc.txt | 18 ++++++++++ fs/proc/base.c | 69 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) -- 1.9.1 diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index fde9fd0..047184a 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt @@ -43,6 +43,7 @@ Table of Contents 3.7 /proc//task//children - Information about task children 3.8 /proc//fdinfo/ - Information about opened file 3.9 /proc//map_files - Information about memory mapped files + 3.10 /proc//timerslack_ns - Task timerslack value 4 Configuring procfs 4.1 Mount options @@ -1865,6 +1866,23 @@ time one can open(2) mappings from the listings of two processes and comparing their inode numbers to figure out which anonymous memory areas are actually shared. +3.10 /proc//timerslack_ns - Task timerslack value +--------------------------------------------------------- +This file provides the value of the task's timerslack value in nanoseconds. +This value specifies a amount of time that normal timers may be deferred +in order to coalesce timers and avoid unnecessary wakeups. + +This allows a task's interactivity vs power consumption trade off to be +adjusted. + +Writing 0 to the file will set the tasks timerslack to the default value. + +Valid values are from 0 - ULLONG_MAX + +An application setting the value must have PTRACE_MODE_ATTACH_FSCREDS level +permissions on the task specified to change its timerslack_ns value. + + ------------------------------------------------------------------------------ Configuring procfs ------------------------------------------------------------------------------ diff --git a/fs/proc/base.c b/fs/proc/base.c index 4f764c2..d7c51ca 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2257,6 +2257,74 @@ static const struct file_operations proc_timers_operations = { .release = seq_release_private, }; +static ssize_t timerslack_ns_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]; + u64 slack_ns; + 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 = kstrtoull(strstrip(buffer), 10, &slack_ns); + if (err < 0) + return err; + + p = get_proc_task(inode); + if (!p) + return -ESRCH; + + if (ptrace_may_access(p, PTRACE_MODE_ATTACH_FSCREDS)) { + if (slack_ns == 0) + p->timer_slack_ns = p->default_timer_slack_ns; + else + p->timer_slack_ns = slack_ns; + } else + count = -EINVAL; + + put_task_struct(p); + + return count; +} + +static int timerslack_ns_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; + + task_lock(p); + seq_printf(m, "%llu\n", p->timer_slack_ns); + task_unlock(p); + + put_task_struct(p); + + return 0; +} + +static int timerslack_ns_open(struct inode *inode, struct file *filp) +{ + return single_open(filp, timerslack_ns_show, inode); +} + +static const struct file_operations proc_pid_set_timerslack_ns_operations = { + .open = timerslack_ns_open, + .read = seq_read, + .write = timerslack_ns_write, + .llseek = seq_lseek, + .release = single_release, +}; + static int proc_pident_instantiate(struct inode *dir, struct dentry *dentry, struct task_struct *task, const void *ptr) { @@ -2831,6 +2899,7 @@ static const struct pid_entry tgid_base_stuff[] = { #ifdef CONFIG_CHECKPOINT_RESTORE REG("timers", S_IRUGO, proc_timers_operations), #endif + REG("timerslack_ns", S_IRUGO|S_IWUSR, proc_pid_set_timerslack_ns_operations), }; static int proc_tgid_base_readdir(struct file *file, struct dir_context *ctx)