diff -u -p -L linux.2214.smp/arch/i386/kernel/entry.S.orig linux.2214.smp/arch/i386/kernel/entry.S --- linux.2214.smp/arch/i386/kernel/entry.S +++ linux.2214.smp/arch/i386/kernel/entry.S Tue Feb 1 14:12:42 2000 @@ -562,6 +562,9 @@ 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_smp_processor) + .long SYMBOL_NAME(sys_smp_lockto) + .long SYMBOL_NAME(sys_smp_num_cpus) /* 193 */ /* * NOTE!! This doesn't have to be exact - we just have @@ -569,6 +572,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-193 .long SYMBOL_NAME(sys_ni_syscall) .endr diff -u -p -L linux.2214.smp/include/asm-i386/unistd.h.orig linux.2214.smp/include/asm-i386/unistd.h --- linux.2214.smp/include/asm-i386/unistd.h +++ linux.2214.smp/include/asm-i386/unistd.h Tue Feb 1 17:41:52 2000 @@ -195,6 +195,9 @@ #define __NR_getpmsg 188 /* some people actually want streams */ #define __NR_putpmsg 189 /* some people actually want streams */ #define __NR_vfork 190 +#define __NR_smp_processor 191 +#define __NR_smp_lockto 192 +#define __NR_smp_num_cpus 193 /* user-visible error numbers are in the range -1 - -122: see */ diff -u -p -L linux.2214.smp/include/linux/sched.h.orig linux.2214.smp/include/linux/sched.h --- linux.2214.smp/include/linux/sched.h +++ linux.2214.smp/include/linux/sched.h Tue Feb 1 17:37:05 2000 @@ -364,7 +364,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.2214.smp/kernel/fork.c.orig linux.2214.smp/kernel/fork.c --- linux.2214.smp/kernel/fork.c +++ linux.2214.smp/kernel/fork.c Tue Feb 1 14:53:39 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.2214.smp/kernel/sched.c.orig linux.2214.smp/kernel/sched.c --- linux.2214.smp/kernel/sched.c +++ linux.2214.smp/kernel/sched.c Tue Feb 1 14:58:18 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; @@ -2052,6 +2076,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.2214.smp/kernel/sys.c.orig linux.2214.smp/kernel/sys.c --- linux.2214.smp/kernel/sys.c +++ linux.2214.smp/kernel/sys.c Tue Feb 1 17:40:54 2000 @@ -1002,3 +1002,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 +} + + +