]> Zhao Yanbai Git Server - minix.git/commitdiff
SMP - Only a single APIC timer handler
authorTomas Hruby <tom@minix3.org>
Wed, 15 Sep 2010 14:10:09 +0000 (14:10 +0000)
committerTomas Hruby <tom@minix3.org>
Wed, 15 Sep 2010 14:10:09 +0000 (14:10 +0000)
- bsp_timer_int_handler() and ap_timer_int_handler() unified into
  timer_int_handler()

- global realtime updated only on BSP

kernel/arch/i386/apic.c
kernel/arch/i386/apic_asm.S
kernel/arch/i386/apic_asm.h
kernel/arch/i386/include/arch_clock.h
kernel/clock.c
kernel/clock.h

index ed6f48e03814176fd627348a53036b7beabcf348..979325be2a768fad6bbbbb05ca553695bc56b7b1 100644 (file)
@@ -484,6 +484,7 @@ PRIVATE void apic_calibrate_clocks(unsigned cpu)
        }
 
        intr_disable();
+       BKL_LOCK();
 
        /* remove the probe */
        rm_irq_handler(&calib_clk);
@@ -613,6 +614,8 @@ PRIVATE int lapic_enable_in_msr(void)
 
        ia32_msr_read(IA32_APIC_BASE, &msr.hi, &msr.lo);
 
+#if 0
+       /*FIXME this is a problem on AP */
        /*
         * FIXME if the location is different (unlikely) then the one we expect,
         * update it
@@ -625,6 +628,7 @@ PRIVATE int lapic_enable_in_msr(void)
                }
                lapic_addr = phys2vir(msr.lo & ~((1 << 12) - 1));
        }
+#endif
 
        msr.lo |= (1 << IA32_APIC_BASE_ENABLE_BIT);
        ia32_msr_write(IA32_APIC_BASE, msr.hi, msr.lo);
@@ -825,7 +829,6 @@ PUBLIC void apic_idt_init(const int reset)
 
        /* Set up idt tables for smp mode.
         */
-       vir_bytes local_timer_intr_handler;
        int is_bsp = is_boot_apic(apicid());
 
        if (reset) {
@@ -861,16 +864,12 @@ PUBLIC void apic_idt_init(const int reset)
 
        /* configure the timer interupt handler */
        if (is_bsp) {
-               local_timer_intr_handler = (vir_bytes) lapic_bsp_timer_int_handler;
-               BOOT_VERBOSE(printf("Initiating BSP timer handler\n"));
-       } else {
-               local_timer_intr_handler = (vir_bytes) lapic_ap_timer_int_handler;
-               BOOT_VERBOSE(printf("Initiating AP timer handler\n"));
+               BOOT_VERBOSE(printf("Initiating APIC timer handler\n"));
+               /* register the timer interrupt handler for this CPU */
+               int_gate(APIC_TIMER_INT_VECTOR, (vir_bytes) lapic_timer_int_handler,
+                               PRESENT | INT_GATE_TYPE | (INTR_PRIVILEGE << DPL_SHIFT));
        }
 
-       /* register the timer interrupt handler for this CPU */
-       int_gate(APIC_TIMER_INT_VECTOR, (vir_bytes) local_timer_intr_handler,
-               PRESENT | INT_GATE_TYPE | (INTR_PRIVILEGE << DPL_SHIFT));
 }
 
 PRIVATE int acpi_get_ioapics(struct io_apic * ioa, unsigned * nioa, unsigned max)
index 8faa3396319540f2ffadcebdf3c0153b7a2ed648..34c651baf4941f6e056c4f97faf1f3152442f6eb 100644 (file)
@@ -64,11 +64,8 @@ ENTRY(apic_hwint##irq)                                                       \
        iret                                                            ;
 
 /* apic timer tick handlers */
-ENTRY(lapic_bsp_timer_int_handler)
-       lapic_intr(_C_LABEL(bsp_timer_int_handler))
-
-ENTRY(lapic_ap_timer_int_handler)
-       lapic_intr(_C_LABEL(ap_timer_int_handler))
+ENTRY(lapic_timer_int_handler)
+       lapic_intr(_C_LABEL(timer_int_handler))
 
 #ifdef CONFIG_SMP
 #include "arch_smp.h"
index 8086100d98ebfea021c83b368bb799f12a9db194..cf398e629707ae6f1257a747985a4981015976c4 100644 (file)
@@ -71,8 +71,7 @@ _PROTOTYPE( void apic_hwint62, (void) );
 _PROTOTYPE( void apic_hwint63, (void) );
 
 /* The local APIC timer tick handlers */
-_PROTOTYPE(void lapic_bsp_timer_int_handler, (void));
-_PROTOTYPE(void lapic_ap_timer_int_handler, (void));
+_PROTOTYPE(void lapic_timer_int_handler, (void));
 
 #endif
 
index 61586474f2e75eab9ba3de92db0cbf594d518691..f9dd03ec0b73233fc23e2992ec060d3dd250aac7 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef __CLOCK_X86_H__
 #define __CLOCK_X86_H__
 
+#include "../apic_asm.h"
+
 _PROTOTYPE(int init_8253A_timer, (unsigned freq));
 _PROTOTYPE(void stop_8253A_timer, (void));
 
index 6963451fd5e99a4e40b9ed60179e9f6b4ae3539a..3f848b3cb111ed9528ea81755275c97ffc3fb8fd 100644 (file)
@@ -35,7 +35,6 @@
 #include <assert.h>
 
 #include "clock.h"
-#include "debug.h"
 
 #ifdef CONFIG_WATCHDOG
 #include "watchdog.h"
@@ -63,30 +62,87 @@ PRIVATE clock_t realtime = 0;                     /* real time clock */
  * The boot processos timer interrupt handler. In addition to non-boot cpus it
  * keeps real time and notifies the clock task if need be
  */
-extern unsigned ooq_msg;
-PUBLIC int bsp_timer_int_handler(void)
+PUBLIC int timer_int_handler(void)
 {
-       unsigned ticks;
+       /* Update user and system accounting times. Charge the current process
+        * for user time. If the current process is not billable, that is, if a
+        * non-user process is running, charge the billable process for system
+        * time as well.  Thus the unbillable process' user time is the billable
+        * user's system time.
+        */
+
+       struct proc * p, * billp;
+
+       /* FIXME watchdog for slave cpus! */
+#ifdef CONFIG_WATCHDOG
+       /*
+        * we need to know whether local timer ticks are happening or whether
+        * the kernel is locked up. We don't care about overflows as we only
+        * need to know that it's still ticking or not
+        */
+       watchdog_local_timer_ticks++;
+#endif
+
+       if (cpu_is_bsp(cpuid))
+               realtime++;
+
+       /* Update user and system accounting times. Charge the current process
+        * for user time. If the current process is not billable, that is, if a
+        * non-user process is running, charge the billable process for system
+        * time as well.  Thus the unbillable process' user time is the billable
+        * user's system time.
+        */
 
-       if(minix_panicing)
-               return 0;
+       p = get_cpulocal_var(proc_ptr);
+       billp = get_cpulocal_var(bill_ptr);
 
-       /* Get number of ticks and update realtime. */
-       ticks = lost_ticks + 1;
-       lost_ticks = 0;
-       realtime += ticks;
+       p->p_user_time++;
 
-       ap_timer_int_handler();
+       if (! (priv(p)->s_flags & BILLABLE)) {
+               billp->p_sys_time++;
+       }
 
-       /* if a timer expired, notify the clock task */
-       if ((next_timeout <= realtime)) {
-               tmrs_exptimers(&clock_timers, realtime, NULL);
-               next_timeout = (clock_timers == NULL) ?
-                       TMR_NEVER : clock_timers->tmr_exp_time;
+       /* Decrement virtual timers, if applicable. We decrement both the
+        * virtual and the profile timer of the current process, and if the
+        * current process is not billable, the timer of the billed process as
+        * well.  If any of the timers expire, do_clocktick() will send out
+        * signals.
+        */
+       if ((p->p_misc_flags & MF_VIRT_TIMER)){
+               p->p_virt_left--;
+       }
+       if ((p->p_misc_flags & MF_PROF_TIMER)){
+               p->p_prof_left--;
+       }
+       if (! (priv(p)->s_flags & BILLABLE) &&
+                       (billp->p_misc_flags & MF_PROF_TIMER)){
+               billp->p_prof_left--;
        }
 
-       if (do_serial_debug)
-               do_ser_debug();
+       /*
+        * Check if a process-virtual timer expired. Check current process, but
+        * also bill_ptr - one process's user time is another's system time, and
+        * the profile timer decreases for both!
+        */
+       vtimer_check(p);
+
+       if (p != billp)
+               vtimer_check(billp);
+
+       /* Update load average. */
+       load_update();
+
+       if (cpu_is_bsp(cpuid)) {
+               /* if a timer expired, notify the clock task */
+               if ((next_timeout <= realtime)) {
+                       tmrs_exptimers(&clock_timers, realtime, NULL);
+                       next_timeout = (clock_timers == NULL) ?
+                               TMR_NEVER : clock_timers->tmr_exp_time;
+               }
+
+               if (do_serial_debug)
+                       do_ser_debug();
+       }
 
        return(1);                                      /* reenable interrupts */
 }
@@ -152,9 +208,11 @@ PRIVATE void load_update(void)
        }
 
        /* Cumulation. How many processes are ready now? */
-       for(q = 0; q < NR_SCHED_QUEUES; q++)
-               for(p = rdy_head[q]; p; p = p->p_nextready)
+       for(q = 0; q < NR_SCHED_QUEUES; q++) {
+               for(p = rdy_head[q]; p != NULL; p = p->p_nextready) {
                        enqueued++;
+               }
+       }
 
        kloadinfo.proc_load_history[slot] += enqueued;
 
@@ -162,90 +220,20 @@ PRIVATE void load_update(void)
        kloadinfo.last_clock = realtime;
 }
 
-/*
- * Timer interupt handler. This is the only thing executed on non boot
- * processors. It is called by bsp_timer_int_handler() on the boot processor
- */
-PUBLIC int ap_timer_int_handler(void)
-{
-
-       /* Update user and system accounting times. Charge the current process
-        * for user time. If the current process is not billable, that is, if a
-        * non-user process is running, charge the billable process for system
-        * time as well.  Thus the unbillable process' user time is the billable
-        * user's system time.
-        */
-
-       const unsigned ticks = 1;
-       struct proc * p, * billp;
-
-#ifdef CONFIG_WATCHDOG
-       /*
-        * we need to know whether local timer ticks are happening or whether
-        * the kernel is locked up. We don't care about overflows as we only
-        * need to know that it's still ticking or not
-        */
-       watchdog_local_timer_ticks++;
-#endif
-
-       /* Update user and system accounting times. Charge the current process
-        * for user time. If the current process is not billable, that is, if a
-        * non-user process is running, charge the billable process for system
-        * time as well.  Thus the unbillable process' user time is the billable
-        * user's system time.
-        */
-
-       p = get_cpulocal_var(proc_ptr);
-       billp = get_cpulocal_var(bill_ptr);
-
-       p->p_user_time += ticks;
-
-       /* FIXME make this ms too */
-       if (! (priv(p)->s_flags & BILLABLE)) {
-               billp->p_sys_time += ticks;
-       }
-
-       /* Decrement virtual timers, if applicable. We decrement both the
-        * virtual and the profile timer of the current process, and if the
-        * current process is not billable, the timer of the billed process as
-        * well.  If any of the timers expire, do_clocktick() will send out
-        * signals.
-        */
-       if ((p->p_misc_flags & MF_VIRT_TIMER)){
-               p->p_virt_left -= ticks;
-       }
-       if ((p->p_misc_flags & MF_PROF_TIMER)){
-               p->p_prof_left -= ticks;
-       }
-       if (! (priv(p)->s_flags & BILLABLE) &&
-                       (billp->p_misc_flags & MF_PROF_TIMER)){
-               billp->p_prof_left -= ticks;
-       }
-
-       /*
-        * Check if a process-virtual timer expired. Check current process, but
-        * also bill_ptr - one process's user time is another's system time, and
-        * the profile timer decreases for both!
-        */
-       vtimer_check(p);
-
-       if (p != billp)
-               vtimer_check(billp);
-
-       /* Update load average. */
-       load_update();
-
-       return 1;
-}
-
 PUBLIC int boot_cpu_init_timer(unsigned freq)
 {
        if (arch_init_local_timer(freq))
                return -1;
 
        if (arch_register_local_timer_handler(
-                               (irq_handler_t) bsp_timer_int_handler))
+                               (irq_handler_t) timer_int_handler))
                return -1;
 
        return 0;
 }
+
+PUBLIC int app_cpu_init_timer(unsigned freq)
+{
+       if (arch_init_local_timer(freq))
+               return -1;
+}
index 5a9c70868655b56ed6d0bc03749b7e7b512e0ec2..ebd53fa92f43eca672335c475226adb637333ce5 100644 (file)
@@ -5,9 +5,9 @@
 #include "arch_clock.h"
 
 _PROTOTYPE(int boot_cpu_init_timer, (unsigned freq));
+_PROTOTYPE(int app_cpu_init_timer, (unsigned freq));
 
-_PROTOTYPE(int bsp_timer_int_handler, (void));
-_PROTOTYPE(int ap_timer_int_handler, (void));
+_PROTOTYPE(int timer_int_handler, (void));
 
 _PROTOTYPE(int arch_init_local_timer, (unsigned freq));
 _PROTOTYPE(void arch_stop_local_timer, (void));