diff -urNp ref/arch/x86_64/config.in 2.4.20pre5aa1/arch/x86_64/config.in --- ref/arch/x86_64/config.in Fri Aug 30 03:10:30 2002 +++ 2.4.20pre5aa1/arch/x86_64/config.in Fri Aug 30 03:10:32 2002 @@ -94,6 +94,8 @@ fi bool 'System V IPC' CONFIG_SYSVIPC bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT bool 'Sysctl support' CONFIG_SYSCTL +int 'Maximum User Real-Time Priority' CONFIG_MAX_USER_RT_PRIO 100 +int 'Maximum Kernel Real-time Priority' CONFIG_MAX_RT_PRIO 0 if [ "$CONFIG_PROC_FS" = "y" ]; then define_bool CONFIG_KCORE_ELF y fi diff -urNp ref/arch/x86_64/kernel/entry.S 2.4.20pre5aa1/arch/x86_64/kernel/entry.S --- ref/arch/x86_64/kernel/entry.S Thu Aug 29 02:13:06 2002 +++ 2.4.20pre5aa1/arch/x86_64/kernel/entry.S Fri Aug 30 03:10:32 2002 @@ -69,8 +69,10 @@ * A newly forked process directly context switches into this. */ ENTRY(ret_from_fork) +#ifdef CONFIG_SMP movq %rax,%rdi /* return value of __switch_to -> prev task */ call schedule_tail +#endif GET_CURRENT(%rcx) testb $PT_TRACESYS,tsk_ptrace(%rcx) jnz 2f diff -urNp ref/arch/x86_64/kernel/init_task.c 2.4.20pre5aa1/arch/x86_64/kernel/init_task.c --- ref/arch/x86_64/kernel/init_task.c Thu Aug 29 02:13:06 2002 +++ 2.4.20pre5aa1/arch/x86_64/kernel/init_task.c Fri Aug 30 03:10:32 2002 @@ -2,6 +2,7 @@ #include #include #include +#include #include #include diff -urNp ref/arch/x86_64/kernel/process.c 2.4.20pre5aa1/arch/x86_64/kernel/process.c --- ref/arch/x86_64/kernel/process.c Fri Aug 30 03:10:30 2002 +++ 2.4.20pre5aa1/arch/x86_64/kernel/process.c Fri Aug 30 03:10:32 2002 @@ -131,9 +131,6 @@ static void poll_idle (void) void cpu_idle (void) { /* endless idle loop with no priority at all */ - init_idle(); - current->nice = 20; - current->dyn_prio = -100; while (1) { void (*idle)(void) = pm_idle; diff -urNp ref/arch/x86_64/kernel/setup64.c 2.4.20pre5aa1/arch/x86_64/kernel/setup64.c --- ref/arch/x86_64/kernel/setup64.c Fri Aug 30 03:10:30 2002 +++ 2.4.20pre5aa1/arch/x86_64/kernel/setup64.c Fri Aug 30 03:10:32 2002 @@ -57,7 +57,7 @@ void pda_init(int cpu) if (cpu == 0) { /* others are initialized in smpboot.c */ - cpu_pda[cpu].pcurrent = init_tasks[cpu]; + cpu_pda[cpu].pcurrent = &init_task; cpu_pda[cpu].irqstackptr = boot_cpu_stack; level4 = init_level4_pgt; cpu_pda[cpu].cpudata = &boot_cpu_data; diff -urNp ref/arch/x86_64/kernel/smpboot.c 2.4.20pre5aa1/arch/x86_64/kernel/smpboot.c --- ref/arch/x86_64/kernel/smpboot.c Fri Aug 30 03:10:30 2002 +++ 2.4.20pre5aa1/arch/x86_64/kernel/smpboot.c Fri Aug 30 03:10:32 2002 @@ -346,7 +346,7 @@ void __init smp_callin(void) * (This works even if the APIC is not enabled.) */ phys_id = GET_APIC_ID(apic_read(APIC_ID)); - cpuid = current->processor; + cpuid = current->cpu; if (test_and_set_bit(cpuid, &cpu_online_map)) { printk("huh, phys CPU#%d, CPU#%d already present??\n", phys_id, cpuid); @@ -549,16 +549,15 @@ static void __init do_boot_cpu (int apic if (!idle) panic("No idle process for CPU %d", cpu); - idle->processor = cpu; + init_idle(idle, cpu); + x86_cpu_to_apicid[cpu] = apicid; x86_apicid_to_cpu[apicid] = cpu; - idle->cpus_runnable = 1<thread.rip = (unsigned long)start_secondary; idle->thread.rsp = (unsigned long)idle + THREAD_SIZE - 8; - del_from_runqueue(idle); unhash_process(idle); - cpu_pda[cpu].pcurrent = init_tasks[cpu] = idle; + cpu_pda[cpu].pcurrent = idle; /* start_eip had better be page-aligned! */ start_eip = setup_trampoline(); @@ -769,6 +768,7 @@ static void __init do_boot_cpu (int apic } cycles_t cacheflush_time; +unsigned long cache_decay_ticks; static void smp_tune_scheduling (void) { @@ -802,9 +802,13 @@ static void smp_tune_scheduling (void) cacheflush_time = (cpu_khz>>10) * (cachesize<<10) / bandwidth; } + cache_decay_ticks = (long)cacheflush_time/cpu_khz * HZ / 1000; + printk("per-CPU timeslice cutoff: %ld.%02ld usecs.\n", (long)cacheflush_time/(cpu_khz/1000), ((long)cacheflush_time*100/(cpu_khz/1000)) % 100); + printk("task migration cache decay timeout: %ld msecs.\n", + (cache_decay_ticks + 1) * 1000 / HZ); } /* @@ -849,8 +853,7 @@ void __init smp_boot_cpus(void) x86_apicid_to_cpu[boot_cpu_id] = 0; x86_cpu_to_apicid[0] = boot_cpu_id; global_irq_holder = 0; - current->processor = 0; - init_idle(); + current->cpu = 0; smp_tune_scheduling(); /* diff -urNp ref/arch/x86_64/kernel/x8664_ksyms.c 2.4.20pre5aa1/arch/x86_64/kernel/x8664_ksyms.c --- ref/arch/x86_64/kernel/x8664_ksyms.c Thu Aug 29 02:13:07 2002 +++ 2.4.20pre5aa1/arch/x86_64/kernel/x8664_ksyms.c Fri Aug 30 03:10:32 2002 @@ -194,6 +194,7 @@ EXPORT_SYMBOL(copy_from_user); EXPORT_SYMBOL(copy_to_user); EXPORT_SYMBOL(copy_user_generic); +#if 0 /* Export kernel syscalls */ EXPORT_SYMBOL(sys_wait4); EXPORT_SYMBOL(sys_exit); @@ -206,7 +207,7 @@ EXPORT_SYMBOL(sys_delete_module); EXPORT_SYMBOL(sys_sync); EXPORT_SYMBOL(sys_pause); EXPORT_SYMBOL(sys_setsid); /* Rather dubious */ - +#endif EXPORT_SYMBOL(memcpy_fromio); EXPORT_SYMBOL(memcpy_toio); diff -urNp ref/arch/x86_64/tools/offset.c 2.4.20pre5aa1/arch/x86_64/tools/offset.c --- ref/arch/x86_64/tools/offset.c Fri Aug 30 03:10:30 2002 +++ 2.4.20pre5aa1/arch/x86_64/tools/offset.c Fri Aug 30 03:10:32 2002 @@ -32,7 +32,6 @@ int main(void) ENTRY(need_resched); ENTRY(exec_domain); ENTRY(ptrace); - ENTRY(processor); ENTRY(need_resched); ENTRY(thread); #undef ENTRY diff -urNp ref/include/asm-x86_64/bitops.h 2.4.20pre5aa1/include/asm-x86_64/bitops.h --- ref/include/asm-x86_64/bitops.h Thu Aug 29 02:13:20 2002 +++ 2.4.20pre5aa1/include/asm-x86_64/bitops.h Fri Aug 30 03:10:32 2002 @@ -78,6 +78,15 @@ static __inline__ void clear_bit(long nr #define smp_mb__before_clear_bit() barrier() #define smp_mb__after_clear_bit() barrier() +static __inline__ void __clear_bit(long nr, volatile void * addr) +{ + __asm__ __volatile__( + "btrq %1,%0" + :"=m" (ADDR) + :"dIr" (nr)); +} + + /** * __change_bit - Toggle a bit in memory * @nr: the bit to set @@ -315,6 +324,63 @@ static __inline__ int find_next_zero_bit return (offset + set + res); } +#include +/** + * find_first_bit - find the first set bit in a memory region + * @addr: The address to start the search at + * @size: The maximum size to search + * + * Returns the bit-number of the first set bit, not the number of the byte + * containing a bit. + */ +static __inline__ int find_first_bit(void * addr, unsigned size) +{ + int d0, d1; + int res; + + /* This looks at memory. Mark it volatile to tell gcc not to move it around */ + __asm__ __volatile__( + "xorl %%eax,%%eax\n\t" + "repe; scasl\n\t" + "jz 1f\n\t" + "leaq -4(%%rdi),%%rdi\n\t" + "bsfl (%%rdi),%%eax\n" + "1:\tsubq %%rbx,%%rdi\n\t" + "shlq $3,%%rdi\n\t" + "addq %%rdi,%%rax" + :"=a" (res), "=&c" (d0), "=&D" (d1) + :"1" ((size + 31) >> 5), "2" (addr), "b" (addr)); + return res; +} + +static __inline__ int find_next_bit (void * addr, int size, int offset) +{ + unsigned int * p = ((unsigned int *) addr) + (offset >> 5); + int set = 0, bit = offset & 31, res; + + if (bit) { + /* + * Look for nonzero in the first 32 bits: + */ + __asm__("bsfl %1,%0\n\t" + "jne 1f\n\t" + "movl $32, %0\n" + "1:" + : "=r" (set) + : "r" (*p >> bit)); + if (set < (32 - bit)) + return set + offset; + set = 32 - bit; + p++; + } + /* + * No set bit yet, search remaining full words for a bit + */ + res = find_first_bit (p, size - 32 * (p - (unsigned int *) addr)); + return (offset + set + res); +} + + /* * Find string of zero bits in a bitmap. -1 when not found. */ @@ -376,6 +442,35 @@ static __inline__ int ffs(int x) return r+1; } +static __inline__ unsigned long __ffs(unsigned long word) +{ + __asm__("bsfq %1,%0" + :"=r" (word) + :"rm" (word)); + return word; +} + + +/* + * Every architecture must define this function. It's the fastest + * way of searching a 140-bit bitmap where the first 100 bits are + * unlikely to be set. It's guaranteed that at least one of the 140 + * bits is cleared. + */ +static inline int _sched_find_first_bit(unsigned long *b) +{ + if (unlikely(b[0])) + return __ffs(b[0]); + if (unlikely(b[1])) + return __ffs(b[1]) + 32; + if (unlikely(b[2])) + return __ffs(b[2]) + 64; + if (b[3]) + return __ffs(b[3]) + 96; + return __ffs(b[4]) + 128; +} + + /** * hweightN - returns the hamming weight of a N-bit word * @x: the word to weigh diff -urNp ref/include/asm-x86_64/mman.h 2.4.20pre5aa1/include/asm-x86_64/mman.h --- ref/include/asm-x86_64/mman.h Thu Aug 29 02:13:20 2002 +++ 2.4.20pre5aa1/include/asm-x86_64/mman.h Fri Aug 30 03:10:32 2002 @@ -4,6 +4,7 @@ #define PROT_READ 0x1 /* page can be read */ #define PROT_WRITE 0x2 /* page can be written */ #define PROT_EXEC 0x4 /* page can be executed */ +#define PROT_SEM 0x8 #define PROT_NONE 0x0 /* page can not be accessed */ #define MAP_SHARED 0x01 /* Share changes */ diff -urNp ref/include/asm-x86_64/smp.h 2.4.20pre5aa1/include/asm-x86_64/smp.h --- ref/include/asm-x86_64/smp.h Thu Aug 29 02:13:20 2002 +++ 2.4.20pre5aa1/include/asm-x86_64/smp.h Fri Aug 30 03:10:32 2002 @@ -79,7 +79,7 @@ extern void smp_store_cpu_info(int id); #define smp_processor_id() read_pda(cpunumber) -#define stack_smp_processor_id() (stack_current()->processor) +#define stack_smp_processor_id() (stack_current()->cpu) extern __inline int hard_smp_processor_id(void)