Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/voyager-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/jejb/voyager-2.6:
[VOYAGER] add smp alternatives
[VOYAGER] Use modern techniques to setup and teardown low identiy mappings.
[VOYAGER] Convert the monitor thread to use the kthread API
[VOYAGER] clockevents driver: bring voyager in to line
[VOYAGER] clockevents: correct boot cpu is zero assumption
[VOYAGER] add smp_call_function_single

+83 -101
+1 -1
arch/i386/kernel/i8253.c
··· 110 110 * Start pit with the boot cpu mask and make it global after the 111 111 * IO_APIC has been initialized. 112 112 */ 113 - pit_clockevent.cpumask = cpumask_of_cpu(0); 113 + pit_clockevent.cpumask = cpumask_of_cpu(smp_processor_id()); 114 114 pit_clockevent.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, 32); 115 115 pit_clockevent.max_delta_ns = 116 116 clockevent_delta2ns(0x7FFF, &pit_clockevent);
+7 -1
arch/i386/mach-voyager/setup.c
··· 40 40 { 41 41 } 42 42 43 - static struct irqaction irq0 = { timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL}; 43 + static struct irqaction irq0 = { 44 + .handler = timer_interrupt, 45 + .flags = IRQF_DISABLED | IRQF_NOBALANCING, 46 + .mask = CPU_MASK_NONE, 47 + .name = "timer" 48 + }; 44 49 45 50 void __init time_init_hook(void) 46 51 { 52 + irq0.mask = cpumask_of_cpu(safe_smp_processor_id()); 47 53 setup_irq(0, &irq0); 48 54 } 49 55
+2 -2
arch/i386/mach-voyager/voyager_cat.c
··· 1111 1111 printk(KERN_ERR "Voyager front panel switch turned off\n"); 1112 1112 voyager_status.switch_off = 1; 1113 1113 voyager_status.request_from_kernel = 1; 1114 - up(&kvoyagerd_sem); 1114 + wake_up_process(voyager_thread); 1115 1115 } 1116 1116 /* Tell the hardware we're taking care of the 1117 1117 * shutdown, otherwise it will power the box off ··· 1157 1157 outb(VOYAGER_CAT_END, CAT_CMD); 1158 1158 voyager_status.power_fail = 1; 1159 1159 voyager_status.request_from_kernel = 1; 1160 - up(&kvoyagerd_sem); 1160 + wake_up_process(voyager_thread); 1161 1161 } 1162 1162 1163 1163
+51 -44
arch/i386/mach-voyager/voyager_smp.c
··· 536 536 & ~( voyager_extended_vic_processors 537 537 & voyager_allowed_boot_processors); 538 538 539 - /* For the 486, we can't use the 4Mb page table trick, so 540 - * must map a region of memory */ 541 - #ifdef CONFIG_M486 542 - int i; 543 - unsigned long *page_table_copies = (unsigned long *) 544 - __get_free_page(GFP_KERNEL); 545 - #endif 546 - pgd_t orig_swapper_pg_dir0; 547 - 548 539 /* This is an area in head.S which was used to set up the 549 540 * initial kernel stack. We need to alter this to give the 550 541 * booting CPU a new stack (taken from its idle process) */ ··· 564 573 hijack_source.idt.Segment = (start_phys_address >> 4) & 0xFFFF; 565 574 566 575 cpucount++; 576 + alternatives_smp_switch(1); 577 + 567 578 idle = fork_idle(cpu); 568 579 if(IS_ERR(idle)) 569 580 panic("failed fork for CPU%d", cpu); ··· 588 595 VDEBUG(("VOYAGER SMP: Booting CPU%d at 0x%lx[%x:%x], stack %p\n", cpu, 589 596 (unsigned long)hijack_source.val, hijack_source.idt.Segment, 590 597 hijack_source.idt.Offset, stack_start.esp)); 591 - /* set the original swapper_pg_dir[0] to map 0 to 4Mb transparently 592 - * (so that the booting CPU can find start_32 */ 593 - orig_swapper_pg_dir0 = swapper_pg_dir[0]; 594 - #ifdef CONFIG_M486 595 - if(page_table_copies == NULL) 596 - panic("No free memory for 486 page tables\n"); 597 - for(i = 0; i < PAGE_SIZE/sizeof(unsigned long); i++) 598 - page_table_copies[i] = (i * PAGE_SIZE) 599 - | _PAGE_RW | _PAGE_USER | _PAGE_PRESENT; 600 598 601 - ((unsigned long *)swapper_pg_dir)[0] = 602 - ((virt_to_phys(page_table_copies)) & PAGE_MASK) 603 - | _PAGE_RW | _PAGE_USER | _PAGE_PRESENT; 604 - #else 605 - ((unsigned long *)swapper_pg_dir)[0] = 606 - (virt_to_phys(pg0) & PAGE_MASK) 607 - | _PAGE_RW | _PAGE_USER | _PAGE_PRESENT; 608 - #endif 599 + /* init lowmem identity mapping */ 600 + clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS, 601 + min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS)); 602 + flush_tlb_all(); 609 603 610 604 if(quad_boot) { 611 605 printk("CPU %d: non extended Quad boot\n", cpu); ··· 635 655 udelay(100); 636 656 } 637 657 /* reset the page table */ 638 - swapper_pg_dir[0] = orig_swapper_pg_dir0; 639 - local_flush_tlb(); 640 - #ifdef CONFIG_M486 641 - free_page((unsigned long)page_table_copies); 642 - #endif 658 + zap_low_mappings(); 643 659 644 660 if (cpu_booted_map) { 645 661 VDEBUG(("CPU%d: Booted successfully, back in CPU %d\n", ··· 1058 1082 } 1059 1083 } 1060 1084 1061 - /* Call this function on all CPUs using the function_interrupt above 1062 - <func> The function to run. This must be fast and non-blocking. 1063 - <info> An arbitrary pointer to pass to the function. 1064 - <retry> If true, keep retrying until ready. 1065 - <wait> If true, wait until function has completed on other CPUs. 1066 - [RETURNS] 0 on success, else a negative status code. Does not return until 1067 - remote CPUs are nearly ready to execute <<func>> or are or have executed. 1068 - */ 1069 - int 1070 - smp_call_function (void (*func) (void *info), void *info, int retry, 1071 - int wait) 1085 + static int 1086 + __smp_call_function_mask (void (*func) (void *info), void *info, int retry, 1087 + int wait, __u32 mask) 1072 1088 { 1073 1089 struct call_data_struct data; 1074 - __u32 mask = cpus_addr(cpu_online_map)[0]; 1075 1090 1076 1091 mask &= ~(1<<smp_processor_id()); 1077 1092 ··· 1083 1116 call_data = &data; 1084 1117 wmb(); 1085 1118 /* Send a message to all other CPUs and wait for them to respond */ 1086 - send_CPI_allbutself(VIC_CALL_FUNCTION_CPI); 1119 + send_CPI(mask, VIC_CALL_FUNCTION_CPI); 1087 1120 1088 1121 /* Wait for response */ 1089 1122 while (data.started) ··· 1097 1130 1098 1131 return 0; 1099 1132 } 1133 + 1134 + /* Call this function on all CPUs using the function_interrupt above 1135 + <func> The function to run. This must be fast and non-blocking. 1136 + <info> An arbitrary pointer to pass to the function. 1137 + <retry> If true, keep retrying until ready. 1138 + <wait> If true, wait until function has completed on other CPUs. 1139 + [RETURNS] 0 on success, else a negative status code. Does not return until 1140 + remote CPUs are nearly ready to execute <<func>> or are or have executed. 1141 + */ 1142 + int 1143 + smp_call_function(void (*func) (void *info), void *info, int retry, 1144 + int wait) 1145 + { 1146 + __u32 mask = cpus_addr(cpu_online_map)[0]; 1147 + 1148 + return __smp_call_function_mask(func, info, retry, wait, mask); 1149 + } 1100 1150 EXPORT_SYMBOL(smp_call_function); 1151 + 1152 + /* 1153 + * smp_call_function_single - Run a function on another CPU 1154 + * @func: The function to run. This must be fast and non-blocking. 1155 + * @info: An arbitrary pointer to pass to the function. 1156 + * @nonatomic: Currently unused. 1157 + * @wait: If true, wait until function has completed on other CPUs. 1158 + * 1159 + * Retrurns 0 on success, else a negative status code. 1160 + * 1161 + * Does not return until the remote CPU is nearly ready to execute <func> 1162 + * or is or has executed. 1163 + */ 1164 + 1165 + int 1166 + smp_call_function_single(int cpu, void (*func) (void *info), void *info, 1167 + int nonatomic, int wait) 1168 + { 1169 + __u32 mask = 1 << cpu; 1170 + 1171 + return __smp_call_function_mask(func, info, nonatomic, wait, mask); 1172 + } 1173 + EXPORT_SYMBOL(smp_call_function_single); 1101 1174 1102 1175 /* Sorry about the name. In an APIC based system, the APICs 1103 1176 * themselves are programmed to send a timer interrupt. This is used
+21 -48
arch/i386/mach-voyager/voyager_thread.c
··· 24 24 #include <linux/kmod.h> 25 25 #include <linux/completion.h> 26 26 #include <linux/sched.h> 27 + #include <linux/kthread.h> 27 28 #include <asm/desc.h> 28 29 #include <asm/voyager.h> 29 30 #include <asm/vic.h> 30 31 #include <asm/mtrr.h> 31 32 #include <asm/msr.h> 32 33 33 - #define THREAD_NAME "kvoyagerd" 34 34 35 - /* external variables */ 36 - int kvoyagerd_running = 0; 37 - DECLARE_MUTEX_LOCKED(kvoyagerd_sem); 38 - 39 - static int thread(void *); 40 - 41 - static __u8 set_timeout = 0; 42 - 43 - /* Start the machine monitor thread. Return 1 if OK, 0 if fail */ 44 - static int __init 45 - voyager_thread_start(void) 46 - { 47 - if(kernel_thread(thread, NULL, CLONE_KERNEL) < 0) { 48 - /* This is serious, but not fatal */ 49 - printk(KERN_ERR "Voyager: Failed to create system monitor thread!!!\n"); 50 - return 1; 51 - } 52 - return 0; 53 - } 35 + struct task_struct *voyager_thread; 36 + static __u8 set_timeout; 54 37 55 38 static int 56 39 execute(const char *string) ··· 93 110 } 94 111 } 95 112 96 - static void 97 - wakeup(unsigned long unused) 98 - { 99 - up(&kvoyagerd_sem); 100 - } 101 - 102 113 static int 103 114 thread(void *unused) 104 115 { 105 - struct timer_list wakeup_timer; 106 - 107 - kvoyagerd_running = 1; 108 - 109 - daemonize(THREAD_NAME); 110 - 111 - set_timeout = 0; 112 - 113 - init_timer(&wakeup_timer); 114 - 115 - sigfillset(&current->blocked); 116 - 117 116 printk(KERN_NOTICE "Voyager starting monitor thread\n"); 118 117 119 - for(;;) { 120 - down_interruptible(&kvoyagerd_sem); 118 + for (;;) { 119 + set_current_state(TASK_INTERRUPTIBLE); 120 + schedule_timeout(set_timeout ? HZ : MAX_SCHEDULE_TIMEOUT); 121 + 121 122 VDEBUG(("Voyager Daemon awoken\n")); 122 123 if(voyager_status.request_from_kernel == 0) { 123 124 /* probably awoken from timeout */ ··· 110 143 check_from_kernel(); 111 144 voyager_status.request_from_kernel = 0; 112 145 } 113 - if(set_timeout) { 114 - del_timer(&wakeup_timer); 115 - wakeup_timer.expires = HZ + jiffies; 116 - wakeup_timer.function = wakeup; 117 - add_timer(&wakeup_timer); 118 - } 119 146 } 120 147 } 148 + 149 + static int __init 150 + voyager_thread_start(void) 151 + { 152 + voyager_thread = kthread_run(thread, NULL, "kvoyagerd"); 153 + if (IS_ERR(voyager_thread)) { 154 + printk(KERN_ERR "Voyager: Failed to create system monitor thread.\n"); 155 + return PTR_ERR(voyager_thread); 156 + } 157 + return 0; 158 + } 159 + 121 160 122 161 static void __exit 123 162 voyager_thread_stop(void) 124 163 { 125 - /* FIXME: do nothing at the moment */ 164 + kthread_stop(voyager_thread); 126 165 } 127 166 128 167 module_init(voyager_thread_start); 129 - //module_exit(voyager_thread_stop); 168 + module_exit(voyager_thread_stop);
+1 -5
include/asm-i386/voyager.h
··· 487 487 extern struct voyager_SUS *voyager_SUS; 488 488 489 489 /* variables exported always */ 490 + extern struct task_struct *voyager_thread; 490 491 extern int voyager_level; 491 - extern int kvoyagerd_running; 492 - extern struct semaphore kvoyagerd_sem; 493 492 extern struct voyager_status voyager_status; 494 493 495 - 496 - 497 494 /* functions exported by the voyager and voyager_smp modules */ 498 - 499 495 extern int voyager_cat_readb(__u8 module, __u8 asic, int reg); 500 496 extern void voyager_cat_init(void); 501 497 extern void voyager_detect(struct voyager_bios_info *);