From d2be88406fdc1d28a7cf0b1a13ca761d625820a5 Mon Sep 17 00:00:00 2001 From: Denis Cheng Date: Fri, 4 Jan 2008 14:50:54 +0800 Subject: [PATCH] PROC_FS: get and set the smp affinity of tasks by read-write /proc//smp_affinity this adds a read-write /proc//smp_affinity entry, just like what /proc/irq//smp_affinity does, so now we can get and set the affinity of tasks by procfs, this is especially useful used in shell scripts. this also adds a read-write /proc//tasks//smp_affinity for the same purpose. Cc: Eli M Dow Signed-off-by: Denis Cheng --- fs/proc/base.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 65 insertions(+), 0 deletions(-) diff --git a/fs/proc/base.c b/fs/proc/base.c index 7411bfb..d768d66 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -1083,6 +1083,65 @@ static const struct file_operations proc_pid_sched_operations = { #endif +#ifdef CONFIG_SMP +static ssize_t smp_affinity_read(struct file *file, + char __user *buf, size_t count, loff_t *ppos) +{ + cpumask_t mask; + char *page; + ssize_t length; + pid_t pid = pid_nr(proc_pid(file->f_dentry->d_inode)); + + length = sched_getaffinity(pid, &mask); + if (length < 0) + return length; + + if (count > PROC_BLOCK_SIZE) + count = PROC_BLOCK_SIZE; + + page = (char *)__get_free_page(GFP_TEMPORARY); + if (!page) { + length = -ENOMEM; + goto out; + } + + length = cpumask_scnprintf(page, count, mask); + if (count - length < 2) { + length = -EINVAL; + goto out_free_page; + } + length += sprintf(page + length, "\n"); + length = simple_read_from_buffer(buf, count, ppos, page, length); + +out_free_page: + free_page((unsigned long)page); +out: + return length; +} + +static ssize_t smp_affinity_write(struct file *file, + const char __user *buf, size_t count, loff_t *ppos) +{ + cpumask_t mask; + int ret; + pid_t pid = pid_nr(proc_pid(file->f_dentry->d_inode)); + + ret = cpumask_parse_user(buf, count, mask); + if (ret < 0) + return ret; + ret = sched_setaffinity(pid, mask); + if (ret < 0) + return ret; + + return count; +} + +static const struct file_operations proc_smp_affinity_operations = { + .read = smp_affinity_read, + .write = smp_affinity_write, +}; +#endif + static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd) { struct inode *inode = dentry->d_inode; @@ -2230,6 +2289,9 @@ static const struct pid_entry tgid_base_stuff[] = { #ifdef CONFIG_SCHEDSTATS INF("schedstat", S_IRUGO, pid_schedstat), #endif +#ifdef CONFIG_SMP + REG("smp_affinity", S_IRUGO|S_IWUSR, smp_affinity), +#endif #ifdef CONFIG_PROC_PID_CPUSET REG("cpuset", S_IRUGO, cpuset), #endif @@ -2555,6 +2617,9 @@ static const struct pid_entry tid_base_stuff[] = { #ifdef CONFIG_SCHEDSTATS INF("schedstat", S_IRUGO, pid_schedstat), #endif +#ifdef CONFIG_SMP + REG("smp_affinity", S_IRUGO|S_IWUSR, smp_affinity), +#endif #ifdef CONFIG_PROC_PID_CPUSET REG("cpuset", S_IRUGO, cpuset), #endif -- 1.5.3.5