subr_smp.c (70798) | subr_smp.c (70861) |
---|---|
1/* 2 * Copyright (c) 1996, by Steve Passe 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 8 unchanged lines hidden (view full) --- 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 * | 1/* 2 * Copyright (c) 1996, by Steve Passe 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 8 unchanged lines hidden (view full) --- 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 * |
25 * $FreeBSD: head/sys/kern/subr_smp.c 70798 2001-01-08 15:25:45Z jake $ | 25 * $FreeBSD: head/sys/kern/subr_smp.c 70861 2001-01-10 04:43:51Z jake $ |
26 */ 27 28#include "opt_cpu.h" 29#include "opt_user_ldt.h" 30 31#ifdef SMP 32#include <machine/smptests.h> 33#else --- 445 unchanged lines hidden (view full) --- 479 480 lldt(_default_ldt); 481#ifdef USER_LDT 482 PCPU_SET(currentldt, _default_ldt); 483#endif 484 485 gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); 486 gdt[myid * NGDT + GPROC0_SEL].sd.sd_type = SDT_SYS386TSS; | 26 */ 27 28#include "opt_cpu.h" 29#include "opt_user_ldt.h" 30 31#ifdef SMP 32#include <machine/smptests.h> 33#else --- 445 unchanged lines hidden (view full) --- 479 480 lldt(_default_ldt); 481#ifdef USER_LDT 482 PCPU_SET(currentldt, _default_ldt); 483#endif 484 485 gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); 486 gdt[myid * NGDT + GPROC0_SEL].sd.sd_type = SDT_SYS386TSS; |
487 common_tss.tss_esp0 = 0; /* not used until after switch */ 488 common_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL); 489 common_tss.tss_ioopt = (sizeof common_tss) << 16; 490 tss_gdt = &gdt[myid * NGDT + GPROC0_SEL].sd; 491 common_tssd = *tss_gdt; | 487 PCPU_SET(common_tss.tss_esp0, 0); /* not used until after switch */ 488 PCPU_SET(common_tss.tss_ss0, GSEL(GDATA_SEL, SEL_KPL)); 489 PCPU_SET(common_tss.tss_ioopt, (sizeof (struct i386tss)) << 16); 490 PCPU_SET(tss_gdt, &gdt[myid * NGDT + GPROC0_SEL].sd); 491 PCPU_SET(common_tssd, *PCPU_GET(tss_gdt)); |
492 ltr(gsel_tss); 493 494 pmap_set_opt(); 495} 496 497 498#if defined(APIC_IO) 499/* --- 1540 unchanged lines hidden (view full) --- 2040 2041 /* record its version info */ 2042 cpu_apic_versions[x] = cpu_apic_versions[0]; 2043 2044 all_cpus |= (1 << x); /* record AP in CPU map */ 2045 } 2046 2047 /* build our map of 'other' CPUs */ | 492 ltr(gsel_tss); 493 494 pmap_set_opt(); 495} 496 497 498#if defined(APIC_IO) 499/* --- 1540 unchanged lines hidden (view full) --- 2040 2041 /* record its version info */ 2042 cpu_apic_versions[x] = cpu_apic_versions[0]; 2043 2044 all_cpus |= (1 << x); /* record AP in CPU map */ 2045 } 2046 2047 /* build our map of 'other' CPUs */ |
2048 other_cpus = all_cpus & ~(1 << cpuid); | 2048 PCPU_SET(other_cpus, all_cpus & ~(1 << PCPU_GET(cpuid))); |
2049 2050 /* fill in our (BSP) APIC version */ 2051 cpu_apic_versions[0] = lapic.version; 2052 2053 /* restore the warmstart vector */ 2054 *(u_long *) WARMBOOT_OFF = mpbioswarmvec; 2055#ifndef PC98 2056 outb(CMOS_REG, BIOS_RESET); --- 336 unchanged lines hidden (view full) --- 2393 2394 smp_cpus++; 2395 2396#if defined(I586_CPU) && !defined(NO_F00F_HACK) 2397 lidt(&r_idt); 2398#endif 2399 2400 /* Build our map of 'other' CPUs. */ | 2049 2050 /* fill in our (BSP) APIC version */ 2051 cpu_apic_versions[0] = lapic.version; 2052 2053 /* restore the warmstart vector */ 2054 *(u_long *) WARMBOOT_OFF = mpbioswarmvec; 2055#ifndef PC98 2056 outb(CMOS_REG, BIOS_RESET); --- 336 unchanged lines hidden (view full) --- 2393 2394 smp_cpus++; 2395 2396#if defined(I586_CPU) && !defined(NO_F00F_HACK) 2397 lidt(&r_idt); 2398#endif 2399 2400 /* Build our map of 'other' CPUs. */ |
2401 other_cpus = all_cpus & ~(1 << cpuid); | 2401 PCPU_SET(other_cpus, all_cpus & ~(1 << PCPU_GET(cpuid))); |
2402 | 2402 |
2403 printf("SMP: AP CPU #%d Launched!\n", cpuid); | 2403 printf("SMP: AP CPU #%d Launched!\n", PCPU_GET(cpuid)); |
2404 2405 /* set up CPU registers and state */ 2406 cpu_setregs(); 2407 2408 /* set up FPU state on the AP */ 2409 npxinit(__INITIAL_NPXCW__); 2410 2411 /* A quick check from sanity claus */ 2412 apic_id = (apic_id_to_logical[(lapic.id & 0x0f000000) >> 24]); | 2404 2405 /* set up CPU registers and state */ 2406 cpu_setregs(); 2407 2408 /* set up FPU state on the AP */ 2409 npxinit(__INITIAL_NPXCW__); 2410 2411 /* A quick check from sanity claus */ 2412 apic_id = (apic_id_to_logical[(lapic.id & 0x0f000000) >> 24]); |
2413 if (cpuid != apic_id) { 2414 printf("SMP: cpuid = %d\n", cpuid); | 2413 if (PCPU_GET(cpuid) != apic_id) { 2414 printf("SMP: cpuid = %d\n", PCPU_GET(cpuid)); |
2415 printf("SMP: apic_id = %d\n", apic_id); 2416 printf("PTD[MPPTDI] = %p\n", (void *)PTD[MPPTDI]); 2417 panic("cpuid mismatch! boom!!"); 2418 } 2419 2420 /* Init local apic for irq's */ 2421 apic_initialize(); 2422 --- 17 unchanged lines hidden (view full) --- 2440 /* wait until all the AP's are up */ 2441 while (smp_started == 0) 2442 ; /* nothing */ 2443 2444 /* 2445 * Set curproc to our per-cpu idleproc so that mutexes have 2446 * something unique to lock with. 2447 */ | 2415 printf("SMP: apic_id = %d\n", apic_id); 2416 printf("PTD[MPPTDI] = %p\n", (void *)PTD[MPPTDI]); 2417 panic("cpuid mismatch! boom!!"); 2418 } 2419 2420 /* Init local apic for irq's */ 2421 apic_initialize(); 2422 --- 17 unchanged lines hidden (view full) --- 2440 /* wait until all the AP's are up */ 2441 while (smp_started == 0) 2442 ; /* nothing */ 2443 2444 /* 2445 * Set curproc to our per-cpu idleproc so that mutexes have 2446 * something unique to lock with. 2447 */ |
2448 PCPU_SET(curproc,idleproc); | 2448 PCPU_SET(curproc, PCPU_GET(idleproc)); |
2449 | 2449 |
2450 microuptime(&switchtime); 2451 switchticks = ticks; | 2450 microuptime(PCPU_PTR(switchtime)); 2451 PCPU_SET(switchticks, ticks); |
2452 2453 /* ok, now grab sched_lock and enter the scheduler */ 2454 enable_intr(); 2455 mtx_enter(&sched_lock, MTX_SPIN); 2456 cpu_throw(); /* doesn't return */ 2457 2458 panic("scheduler returned us to ap_init"); 2459} --- 145 unchanged lines hidden (view full) --- 2605 * work ourself. 2606 */ 2607 2608 if (!smp_started || !invltlb_ok || cold || panicstr) 2609 return; 2610 2611 /* Step 1: Probe state (user, cpu, interrupt, spinlock, idle ) */ 2612 | 2452 2453 /* ok, now grab sched_lock and enter the scheduler */ 2454 enable_intr(); 2455 mtx_enter(&sched_lock, MTX_SPIN); 2456 cpu_throw(); /* doesn't return */ 2457 2458 panic("scheduler returned us to ap_init"); 2459} --- 145 unchanged lines hidden (view full) --- 2605 * work ourself. 2606 */ 2607 2608 if (!smp_started || !invltlb_ok || cold || panicstr) 2609 return; 2610 2611 /* Step 1: Probe state (user, cpu, interrupt, spinlock, idle ) */ 2612 |
2613 map = other_cpus & ~stopped_cpus ; | 2613 map = PCPU_GET(other_cpus) & ~stopped_cpus ; |
2614 checkstate_probed_cpus = 0; 2615 if (map != 0) 2616 selected_apic_ipi(map, 2617 XCPUCHECKSTATE_OFFSET, APIC_DELMODE_FIXED); 2618 2619 i = 0; 2620 while (checkstate_probed_cpus != map) { 2621 /* spin */ --- 9 unchanged lines hidden (view full) --- 2631 2632 /* 2633 * Step 2: walk through other processors processes, update ticks and 2634 * profiling info. 2635 */ 2636 2637 map = 0; 2638 for (id = 0; id < mp_ncpus; id++) { | 2614 checkstate_probed_cpus = 0; 2615 if (map != 0) 2616 selected_apic_ipi(map, 2617 XCPUCHECKSTATE_OFFSET, APIC_DELMODE_FIXED); 2618 2619 i = 0; 2620 while (checkstate_probed_cpus != map) { 2621 /* spin */ --- 9 unchanged lines hidden (view full) --- 2631 2632 /* 2633 * Step 2: walk through other processors processes, update ticks and 2634 * profiling info. 2635 */ 2636 2637 map = 0; 2638 for (id = 0; id < mp_ncpus; id++) { |
2639 if (id == cpuid) | 2639 if (id == PCPU_GET(cpuid)) |
2640 continue; 2641 if (((1 << id) & checkstate_probed_cpus) == 0) 2642 continue; 2643 forwarded_statclock(id, pscnt, &map); 2644 } 2645 if (map != 0) { 2646 checkstate_need_ast |= map; 2647 selected_apic_ipi(map, XCPUAST_OFFSET, APIC_DELMODE_FIXED); --- 32 unchanged lines hidden (view full) --- 2680 * work ourself. 2681 */ 2682 2683 if (!smp_started || !invltlb_ok || cold || panicstr) 2684 return; 2685 2686 /* Step 1: Probe state (user, cpu, interrupt, spinlock, idle) */ 2687 | 2640 continue; 2641 if (((1 << id) & checkstate_probed_cpus) == 0) 2642 continue; 2643 forwarded_statclock(id, pscnt, &map); 2644 } 2645 if (map != 0) { 2646 checkstate_need_ast |= map; 2647 selected_apic_ipi(map, XCPUAST_OFFSET, APIC_DELMODE_FIXED); --- 32 unchanged lines hidden (view full) --- 2680 * work ourself. 2681 */ 2682 2683 if (!smp_started || !invltlb_ok || cold || panicstr) 2684 return; 2685 2686 /* Step 1: Probe state (user, cpu, interrupt, spinlock, idle) */ 2687 |
2688 map = other_cpus & ~stopped_cpus ; | 2688 map = PCPU_GET(other_cpus) & ~stopped_cpus ; |
2689 checkstate_probed_cpus = 0; 2690 if (map != 0) 2691 selected_apic_ipi(map, 2692 XCPUCHECKSTATE_OFFSET, APIC_DELMODE_FIXED); 2693 2694 i = 0; 2695 while (checkstate_probed_cpus != map) { 2696 /* spin */ --- 10 unchanged lines hidden (view full) --- 2707 /* 2708 * Step 2: walk through other processors processes, update virtual 2709 * timer and profiling timer. If stathz == 0, also update ticks and 2710 * profiling info. 2711 */ 2712 2713 map = 0; 2714 for (id = 0; id < mp_ncpus; id++) { | 2689 checkstate_probed_cpus = 0; 2690 if (map != 0) 2691 selected_apic_ipi(map, 2692 XCPUCHECKSTATE_OFFSET, APIC_DELMODE_FIXED); 2693 2694 i = 0; 2695 while (checkstate_probed_cpus != map) { 2696 /* spin */ --- 10 unchanged lines hidden (view full) --- 2707 /* 2708 * Step 2: walk through other processors processes, update virtual 2709 * timer and profiling timer. If stathz == 0, also update ticks and 2710 * profiling info. 2711 */ 2712 2713 map = 0; 2714 for (id = 0; id < mp_ncpus; id++) { |
2715 if (id == cpuid) | 2715 if (id == PCPU_GET(cpuid)) |
2716 continue; 2717 if (((1 << id) & checkstate_probed_cpus) == 0) 2718 continue; 2719 p = checkstate_curproc[id]; 2720 if (p) { 2721 pstats = p->p_stats; 2722 if (checkstate_cpustate[id] == CHECKSTATE_USER && 2723 timevalisset(&pstats->p_timer[ITIMER_VIRTUAL].it_value) && --- 84 unchanged lines hidden (view full) --- 2808{ 2809 u_int map; 2810 int i; 2811 2812 if (!smp_started || !invltlb_ok || cold || panicstr) 2813 return; 2814 if (!forward_roundrobin_enabled) 2815 return; | 2716 continue; 2717 if (((1 << id) & checkstate_probed_cpus) == 0) 2718 continue; 2719 p = checkstate_curproc[id]; 2720 if (p) { 2721 pstats = p->p_stats; 2722 if (checkstate_cpustate[id] == CHECKSTATE_USER && 2723 timevalisset(&pstats->p_timer[ITIMER_VIRTUAL].it_value) && --- 84 unchanged lines hidden (view full) --- 2808{ 2809 u_int map; 2810 int i; 2811 2812 if (!smp_started || !invltlb_ok || cold || panicstr) 2813 return; 2814 if (!forward_roundrobin_enabled) 2815 return; |
2816 resched_cpus |= other_cpus; 2817 map = other_cpus & ~stopped_cpus ; | 2816 resched_cpus |= PCPU_GET(other_cpus); 2817 map = PCPU_GET(other_cpus) & ~stopped_cpus ; |
2818#if 1 2819 selected_apic_ipi(map, XCPUAST_OFFSET, APIC_DELMODE_FIXED); 2820#else 2821 (void) all_but_self_ipi(XCPUAST_OFFSET); 2822#endif 2823 i = 0; 2824 while ((checkstate_need_ast & map) != 0) { 2825 /* spin */ --- 108 unchanged lines hidden --- | 2818#if 1 2819 selected_apic_ipi(map, XCPUAST_OFFSET, APIC_DELMODE_FIXED); 2820#else 2821 (void) all_but_self_ipi(XCPUAST_OFFSET); 2822#endif 2823 i = 0; 2824 while ((checkstate_need_ast & map) != 0) { 2825 /* spin */ --- 108 unchanged lines hidden --- |