public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Process pinning
@ 2001-04-10  0:08 Nick Pollitt
  2001-04-11 11:05 ` Rusty Russell
  2001-04-18  1:24 ` Albert D. Cahalan
  0 siblings, 2 replies; 5+ messages in thread
From: Nick Pollitt @ 2001-04-10  0:08 UTC (permalink / raw)
  To: linux-kernel; +Cc: Linus Torvalds

[-- Attachment #1: Type: text/plain, Size: 250 bytes --]

This patch applies cleanly to 2.4.3-ac3.  

Changes to array.c expose cpus_allowed in proc/pid/stat.  

PR_GET_RUNON and PR_SET_RUNON were done by Ingo and Dimitris.  Added
MUSTRUN_PID and RUNANY_PID.

Also attached is runon and it's manpage.

Nick


[-- Attachment #2: linux-2.4.3-process-pinning.patch --]
[-- Type: text/plain, Size: 4239 bytes --]

diff -X /home/npollitt/dontdiff -Nur 243-ac3/linux/fs/proc/array.c mine/linux/fs/proc/array.c
--- 243-ac3/linux/fs/proc/array.c	Tue Mar 27 16:21:37 2001
+++ mine/linux/fs/proc/array.c	Tue Mar 27 16:23:24 2001
@@ -343,7 +343,7 @@
 	read_unlock(&tasklist_lock);
 	res = sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \
 %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu \
-%lu %lu %lu %lu %lu %lu %lu %lu %d %d\n",
+%lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu\n",
 		task->pid,
 		task->comm,
 		state,
@@ -386,7 +386,8 @@
 		task->nswap,
 		task->cnswap,
 		task->exit_signal,
-		task->processor);
+		task->processor,
+		task->cpus_allowed);
 	if(mm)
 		mmput(mm);
 	return res;
diff -X /home/npollitt/dontdiff -Nur 243-ac3/linux/include/linux/prctl.h mine/linux/include/linux/prctl.h
--- 243-ac3/linux/include/linux/prctl.h	Sun Mar 19 11:15:32 2000
+++ mine/linux/include/linux/prctl.h	Tue Mar 27 16:23:24 2001
@@ -20,4 +20,9 @@
 #define PR_GET_KEEPCAPS   7
 #define PR_SET_KEEPCAPS   8
 
+#define PR_GET_RUNON	  9
+#define PR_SET_RUNON	  10
+#define PR_MUSTRUN_PID    11
+#define PR_RUNANY_PID     12
+
 #endif /* _LINUX_PRCTL_H */
diff -X /home/npollitt/dontdiff -Nur 243-ac3/linux/kernel/sched.c mine/linux/kernel/sched.c
--- 243-ac3/linux/kernel/sched.c	Tue Mar 27 16:21:38 2001
+++ mine/linux/kernel/sched.c	Tue Mar 27 16:23:24 2001
@@ -112,6 +112,10 @@
 #ifdef CONFIG_SMP
 
 #define idle_task(cpu) (init_tasks[cpu_number_map(cpu)])
+#define can_schedule_goodness(p,cpu) ( (!(p)->has_cpu ||  \
+                                        p->processor == cpu) &&  \
+                                        ((p)->cpus_allowed & (1 << cpu)))
+
 #define can_schedule(p,cpu) ((!(p)->has_cpu) && \
 				((p)->cpus_allowed & (1 << cpu)))
 
@@ -119,6 +123,7 @@
 
 #define idle_task(cpu) (&init_task)
 #define can_schedule(p,cpu) (1)
+#define can_schedule_goodness(p,cpu) (1)
 
 #endif
 
@@ -594,7 +599,7 @@
 still_running_back:
 	list_for_each(tmp, &runqueue_head) {
 		p = list_entry(tmp, struct task_struct, run_list);
-		if (can_schedule(p, this_cpu)) {
+		if (can_schedule_goodness(p, this_cpu)) {
 			int weight = goodness(p, this_cpu, prev->active_mm);
 			if (weight > c)
 				c = weight, next = p;
diff -X /home/npollitt/dontdiff -Nur 243-ac3/linux/kernel/sys.c mine/linux/kernel/sys.c
--- 243-ac3/linux/kernel/sys.c	Tue Mar 27 16:21:38 2001
+++ mine/linux/kernel/sys.c	Tue Mar 27 16:23:24 2001
@@ -1255,12 +1255,95 @@
 			}
 			current->keep_capabilities = arg2;
 			break;
+		case PR_GET_RUNON:
+			error = put_user(current->cpus_allowed, (long *)arg2);
+			break;
+		case PR_SET_RUNON:
+			if (arg2 == 0)
+				arg2 = 1 << smp_processor_id();
+			arg2 &= cpu_online_map;
+			if (!arg2)
+				error = -EINVAL;
+			else {
+				current->cpus_allowed = arg2;
+				if (!(arg2 & (1 << smp_processor_id())))
+					current->need_resched = 1;
+			}
+			break;
+		case PR_MUSTRUN_PID:
+			/* arg2 is cpu, arg3 is pid */
+			if (arg2 == 0)
+				arg2 = 1 << smp_processor_id();
+			arg2 &= cpu_online_map;
+			if (!arg2)
+				error = -EINVAL;
+			error = mp_mustrun_pid(arg2, arg3);
+			break;
+		case PR_RUNANY_PID:
+			/* arg2 is pid */
+			if (!arg2)
+				error = -EINVAL;
+			error = mp_runany_pid(arg2);
+			break;
 		default:
 			error = -EINVAL;
 			break;
 	}
 	return error;
 }
+
+static int mp_mustrun_pid(int cpu, int pid) 
+{
+	struct task_struct *p;
+	int ret;
+
+	ret = -EPERM;
+	/* Not allowed to change 1 */
+	if (pid == 1) 
+		goto out;
+
+	read_lock(&tasklist_lock);
+	p = find_task_by_pid(pid);
+	if (p)
+		get_task_struct(p);
+	read_unlock(&tasklist_lock);
+	if (!p)
+		ret = -ESRCH;
+
+	p->cpus_allowed = cpu;
+	p->need_resched = 1;
+	free_task_struct(p);
+	ret = 0;
+out:
+	return ret;
+}
+
+static int mp_runany_pid(int pid) 
+{
+	struct task_struct *p;
+	int ret;
+
+	ret = -EPERM;
+	/* Not allowed to change 1 */
+	if (pid == 1) 
+		goto out;
+
+	read_lock(&tasklist_lock);
+	p = find_task_by_pid(pid);
+	if (p)
+		get_task_struct(p);
+	read_unlock(&tasklist_lock);
+	if (!p)
+		ret = -ESRCH;
+
+	p->cpus_allowed = 0xFFFFFFFF;
+	p->need_resched = 0;
+	free_task_struct(p);
+	ret = 0;
+out:
+	return ret;
+}
+
 
 EXPORT_SYMBOL(notifier_chain_register);
 EXPORT_SYMBOL(notifier_chain_unregister);

[-- Attachment #3: runon.c --]
[-- Type: text/plain, Size: 2677 bytes --]

/*
 * runon.c - assign a process to a named processor
 *
 * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
 * 
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it would be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * 
 * Further, this software is distributed without any warranty that it is
 * free of the rightful claim of any third person regarding infringement
 * or the like.  Any license provided herein, whether implied or
 * otherwise, applies only to this software file.  Patent licenses, if
 * any, provided herein do not apply to combinations of this program with
 * other software, or any other product whatsoever.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write the Free Software Foundation, Inc., 59
 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
 * 
 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
 * Mountain View, CA  94043, or:
 * 
 * http://www.sgi.com 
 * 
 * For further information regarding this notice, see: 
 * 
 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
 */

#include	<stdio.h>
#include	<unistd.h>
#include	<linux/prctl.h>

#define _POSIX_OPTION_ORDER

static void usage();

int main(argc, argv)
int argc;
char *argv[];
{
	extern	errno;
	extern	__const char *__const sys_errlist[];
	int	c, processor, pid;
	int usepid = 0;
	register char *p;

	if (argc < 3) {
		usage();
		exit(1);
	}

	while ((c = getopt (argc, argv, "p:")) != -1) {
		switch(c) {
		case 'p':
			usepid = 1;
			pid = atoi(optarg);
			break;
		}
	}

	p = argv[optind];
	while(*p) {
		if(!isdigit(*p)) {
			fprintf(stderr, "%s: cpu argument must be numeric.\n", argv[0]);
			exit(2);
		}
		p++;
	}
	processor = atoi(&argv[optind][0]);
	optind++;

	if (usepid) {
		if (prctl(PR_MUSTRUN_PID, processor, pid, 0, 0) < 0) {
			fprintf(stderr, "%s: could not attach pid %d to processor %d\n",
										 argv[0], pid, processor);
			exit(1);
		}
	}
	else {
		if (prctl(PR_SET_RUNON, processor, 0, 0, 0) < 0) { 
			fprintf(stderr,
				"%s: could not attach to processor %d -- %s\n ",
				argv[0], processor, sys_errlist[errno]);
			exit(1);
		}
	
		execvp(argv[optind], &argv[optind]);
		fprintf(stderr, "%s: %s\n", sys_errlist[errno], argv[optind]);
		exit(1);
	}
	return(0);
}

static void usage() {
	fprintf(stderr, "usage: runon processor (-p pid | command [args...])\n");
}

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] Process pinning
  2001-04-10  0:08 [PATCH] Process pinning Nick Pollitt
@ 2001-04-11 11:05 ` Rusty Russell
  2001-04-17 16:17   ` Tim Hockin
  2001-04-18  1:24 ` Albert D. Cahalan
  1 sibling, 1 reply; 5+ messages in thread
From: Rusty Russell @ 2001-04-11 11:05 UTC (permalink / raw)
  To: npollitt; +Cc: linux-kernel

In message <20010409170823.C2316@engr.sgi.com> you write:
> Changes to array.c expose cpus_allowed in proc/pid/stat.  

Call me old fashioned, but I prefer my bitmasks in hex.

Please also consider changing:

still_running:
	c = goodness(prev, this_cpu, prev->active_mm);
	next = prev;

to:

still_running:
	if (prev & (1 << this_cpu)) {
		c = goodness(prev, this_cpu, prev->active_mm);
		next = prev;
	}

Otherwise, you will keep scheduling a RT process forever on a
disallowed CPU on which it is already running.  And even a non-RT
process will stick on its disallowed CPU as long as nothing else runs
there.

Learnt this the hard way from the hotplug CPU patch...
Rusty.
--
Premature optmztion is rt of all evl. --DK

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] Process pinning
  2001-04-11 11:05 ` Rusty Russell
@ 2001-04-17 16:17   ` Tim Hockin
  2001-04-17 19:25     ` Andrew Morton
  0 siblings, 1 reply; 5+ messages in thread
From: Tim Hockin @ 2001-04-17 16:17 UTC (permalink / raw)
  To: Rusty Russell; +Cc: npollitt, linux-kernel

> disallowed CPU on which it is already running.  And even a non-RT
> process will stick on its disallowed CPU as long as nothing else runs
> there.

are we going to keep the cpus_allowed API?  If we want the (IMHO) more
flexible sysmp() API - I'll finish the 2.4 port.  If we are going to keep
cpus_allowed - I'll just abandon pset and sysmp.

Personally, I like sysmp() and the pset tools better, perhaps with a /proc
extension to it.



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] Process pinning
  2001-04-17 16:17   ` Tim Hockin
@ 2001-04-17 19:25     ` Andrew Morton
  0 siblings, 0 replies; 5+ messages in thread
From: Andrew Morton @ 2001-04-17 19:25 UTC (permalink / raw)
  To: Tim Hockin; +Cc: Rusty Russell, npollitt, linux-kernel

Tim Hockin wrote:
> 
> > disallowed CPU on which it is already running.  And even a non-RT
> > process will stick on its disallowed CPU as long as nothing else runs
> > there.
> 
> are we going to keep the cpus_allowed API?  If we want the (IMHO) more
> flexible sysmp() API - I'll finish the 2.4 port.  If we are going to keep
> cpus_allowed - I'll just abandon pset and sysmp.
> 
> Personally, I like sysmp() and the pset tools better, perhaps with a /proc
> extension to it.

http://www.uow.edu.au/~andrewm/linux/cpus_allowed.patch

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] Process pinning
  2001-04-10  0:08 [PATCH] Process pinning Nick Pollitt
  2001-04-11 11:05 ` Rusty Russell
@ 2001-04-18  1:24 ` Albert D. Cahalan
  1 sibling, 0 replies; 5+ messages in thread
From: Albert D. Cahalan @ 2001-04-18  1:24 UTC (permalink / raw)
  To: npollitt; +Cc: linux-kernel, Linus Torvalds

Nick Pollitt writes:

> Changes to array.c expose cpus_allowed in proc/pid/stat.  
...
> -%lu %lu %lu %lu %lu %lu %lu %lu %d %d\n",
> +%lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu\n",
...
> -		task->processor);
> +		task->processor,
> +		task->cpus_allowed);

This isn't good. While it might be reasonable to have
an 8*sizeof(long) processor limit in the kernel, it is
not OK to expose this in the API. The API's limit should
be insanely high, like 256 or more.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2001-04-18  1:25 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2001-04-10  0:08 [PATCH] Process pinning Nick Pollitt
2001-04-11 11:05 ` Rusty Russell
2001-04-17 16:17   ` Tim Hockin
2001-04-17 19:25     ` Andrew Morton
2001-04-18  1:24 ` Albert D. Cahalan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox