diff -u -p -L linux-2.2.16/arch/i386/kernel/entry.S.orig linux-2.2.16/arch/i386/kernel/entry.S --- linux-2.2.16/arch/i386/kernel/entry.S +++ linux-2.2.16/arch/i386/kernel/entry.S Mon Aug 28 07:36:51 2000 @@ -564,6 +564,16 @@ ENTRY(sys_call_table) .long SYMBOL_NAME(sys_ni_syscall) /* streams1 */ .long SYMBOL_NAME(sys_ni_syscall) /* streams2 */ .long SYMBOL_NAME(sys_vfork) /* 190 */ + .long SYMBOL_NAME(sys_ni_syscall) /* ugetrlimit */ + .long SYMBOL_NAME(sys_ni_syscall) /* mmap2 */ + .long SYMBOL_NAME(sys_ni_syscall) /* truncate64 */ + .long SYMBOL_NAME(sys_ni_syscall) /* ftruncate64 */ + .long SYMBOL_NAME(sys_ni_syscall) /* 195 */ /* stat64 */ + .long SYMBOL_NAME(sys_ni_syscall) /* lstat64 */ + .long SYMBOL_NAME(sys_ni_syscall) /* fstat64 */ + .long SYMBOL_NAME(sys_smp_processor) + .long SYMBOL_NAME(sys_smp_lockto) + .long SYMBOL_NAME(sys_smp_num_cpus) /* 200 */ /* * NOTE!! This doesn't have to be exact - we just have @@ -571,6 +581,6 @@ ENTRY(sys_call_table) * entries. Don't panic if you notice that this hasn't * been shrunk every time we add a new system call. */ - .rept NR_syscalls-190 + .rept NR_syscalls-200 .long SYMBOL_NAME(sys_ni_syscall) .endr diff -u -p -L linux-2.2.16/include/asm-i386/unistd.h.orig linux-2.2.16/include/asm-i386/unistd.h --- linux-2.2.16/include/asm-i386/unistd.h +++ linux-2.2.16/include/asm-i386/unistd.h Mon Aug 28 07:32:36 2000 @@ -202,6 +202,9 @@ #define __NR_stat64 195 #define __NR_lstat64 196 #define __NR_fstat64 197 +#define __NR_smp_processor 198 +#define __NR_smp_lockto 199 +#define __NR_smp_num_cpus 200 /* user-visible error numbers are in the range -1 - -124: see */ diff -u -p -L linux-2.2.16/include/linux/sched.h.orig linux-2.2.16/include/linux/sched.h --- linux-2.2.16/include/linux/sched.h +++ linux-2.2.16/include/linux/sched.h Mon Aug 28 12:57:12 2000 @@ -248,6 +248,7 @@ struct task_struct { int processor; int last_processor; int lock_depth; /* Lock depth. We can context switch in and out of holding a syscall kernel lock... */ + int locked_processor; struct task_struct *next_task, *prev_task; struct task_struct *next_run, *prev_run; @@ -368,7 +369,7 @@ struct task_struct { #define INIT_TASK \ /* state etc */ { 0,0,0,KERNEL_DS,&default_exec_domain,0, \ /* counter */ DEF_PRIORITY,DEF_PRIORITY,0, \ -/* SMP */ 0,0,0,-1, \ +/* SMP */ 0,0,0,-1,-1, \ /* schedlink */ &init_task,&init_task, &init_task, &init_task, \ /* binfmt */ NULL, \ /* ec,brk... */ 0,0,0,0,0,0, \ diff -u -p -L linux-2.2.16/kernel/fork.c.orig linux-2.2.16/kernel/fork.c --- linux-2.2.16/kernel/fork.c +++ linux-2.2.16/kernel/fork.c Mon Aug 28 07:27:55 2000 @@ -656,6 +656,8 @@ int do_fork(unsigned long clone_flags, u int i; p->has_cpu = 0; p->processor = current->processor; + /* New process will follow parent's locking */ + p->locked_processor = current->locked_processor; /* ?? should we just memset this ?? */ for(i = 0; i < smp_num_cpus; i++) p->per_cpu_utime[i] = p->per_cpu_stime[i] = 0; diff -u -p -L linux-2.2.16/kernel/sched.c.orig linux-2.2.16/kernel/sched.c --- linux-2.2.16/kernel/sched.c +++ linux-2.2.16/kernel/sched.c Mon Aug 28 07:27:55 2000 @@ -15,6 +15,7 @@ * Copyright (C) 1998 Andrea Arcangeli * 1998-12-28 Implemented better SMP scheduling by Ingo Molnar * 1999-03-10 Improved NTP compatibility by Ulrich Windl + * 2000-02-01 SMP processor locking by Fred Barnes */ /* @@ -171,6 +172,13 @@ static inline int goodness (struct task_ /* (this is equivalent to penalizing other processors) */ if (p->processor == this_cpu) weight += PROC_CHANGE_PENALTY; + /* + * If process locked to a processor, never select it + */ + if( (p->locked_processor > -1) && (p->locked_processor != this_cpu) ) { + weight = -1000; + goto out; + } #endif /* .. and a slight advantage to the current MM */ @@ -280,7 +288,15 @@ static inline void reschedule_idle_slow( * shortcut if the woken up task's last CPU is * idle now. */ - best_cpu = p->processor; + + /* + * if process is locked to a processor, preferred CPU is that one + */ + if (p->locked_processor > -1) { + best_cpu = p->locked_processor; + } else { + best_cpu = p->processor; + } target_tsk = idle_task(best_cpu); if (cpu_curr(best_cpu) == target_tsk) goto send_now; @@ -301,8 +317,16 @@ static inline void reschedule_idle_slow( /* * found any suitable CPU? */ - if (!target_tsk) + if (!target_tsk) { goto out_no_target; + } else { + /* + * avoid scheduling on another processor + */ + if ((p->locked_processor > -1) && (p->locked_processor != target_tsk->processor)) { + goto out_no_target; + } + } send_now: target_cpu = target_tsk->processor; @@ -2067,6 +2091,7 @@ void __init sched_init(void) int nr = NR_TASKS; init_task.processor=cpu; + init_task.locked_processor = -1; /* Init task array free list and pidhash table. */ while(--nr > 0) diff -u -p -L linux-2.2.16/kernel/sys.c.orig linux-2.2.16/kernel/sys.c --- linux-2.2.16/kernel/sys.c +++ linux-2.2.16/kernel/sys.c Mon Aug 28 07:27:55 2000 @@ -1023,3 +1023,39 @@ asmlinkage int sys_prctl(int option, uns return error; } +asmlinkage int sys_smp_num_cpus (void) +{ + #ifdef __SMP__ + return smp_num_cpus; + #else + return -ENOSYS; + #endif +} + +asmlinkage int sys_smp_processor (void) +{ + #ifdef __SMP__ + return smp_processor_id (); + #else + return -ENOSYS; + #endif +} + +asmlinkage int sys_smp_lockto (int proc_id) +{ + #ifdef __SMP__ + if ((proc_id != -1) && (proc_id >= smp_num_cpus)) { + return -EINVAL; + } + if (proc_id != current->locked_processor) { + current->locked_processor = proc_id; + schedule (); + } + return 0; + #else + return -ENOSYS; + #endif +} + + +