diff options
Diffstat (limited to 'sys')
49 files changed, 466 insertions, 984 deletions
diff --git a/sys/alpha/alpha/trap.c b/sys/alpha/alpha/trap.c index 3e773d3..79019bd 100644 --- a/sys/alpha/alpha/trap.c +++ b/sys/alpha/alpha/trap.c @@ -784,6 +784,11 @@ ast(framep) sticks = p->p_sticks; p->p_md.md_tf = framep; + /* + * XXX - is this still correct? What about a clock interrupt + * that runs hardclock() and triggers a delayed SIGVTALRM or + * SIGPROF? + */ if ((framep->tf_regs[FRAME_PS] & ALPHA_PSL_USERMODE) == 0) panic("ast and not user"); @@ -795,6 +800,14 @@ ast(framep) addupc_task(p, p->p_stats->p_prof.pr_addr, p->p_stats->p_prof.pr_ticks); } + if (p->p_flag & P_ALRMPEND) { + p->p_flag &= ~P_ALRMPEND; + psignal(p, SIGVTALRM); + } + if (p->p_flag & P_PROFPEND) { + p->p_flag &= ~P_PROFPEND; + psignal(p, SIGPROF); + } userret(p, framep->tf_regs[FRAME_PC], sticks, 1); diff --git a/sys/alpha/include/cpu.h b/sys/alpha/include/cpu.h index cd60cc6..a45b4d1 100644 --- a/sys/alpha/include/cpu.h +++ b/sys/alpha/include/cpu.h @@ -62,8 +62,6 @@ struct clockframe { }; #define CLKF_USERMODE(framep) \ (((framep)->cf_tf.tf_regs[FRAME_PS] & ALPHA_PSL_USERMODE) != 0) -#define CLKF_BASEPRI(framep) \ - (((framep)->cf_tf.tf_regs[FRAME_PS] & ALPHA_PSL_IPL_MASK) == 0) #define CLKF_PC(framep) ((framep)->cf_tf.tf_regs[FRAME_PC]) #define CLKF_INTR(framep) (PCPU_GET(intr_nesting_level) >= 2) diff --git a/sys/alpha/include/globals.h b/sys/alpha/include/globals.h index 303efdf..f85a67c 100644 --- a/sys/alpha/include/globals.h +++ b/sys/alpha/include/globals.h @@ -56,7 +56,6 @@ register struct globaldata *globalp __asm__("$8"); #define switchtime PCPU_GET(switchtime) #define switchticks PCPU_GET(switchticks) #define cpuid PCPU_GET(cpuno) -#define prevproc PCPU_GET(curproc) /* XXX - until ithreads */ #endif /* _KERNEL */ diff --git a/sys/amd64/amd64/apic_vector.S b/sys/amd64/amd64/apic_vector.S index 11d9797..1f80224 100644 --- a/sys/amd64/amd64/apic_vector.S +++ b/sys/amd64/amd64/apic_vector.S @@ -15,6 +15,23 @@ /* make an index into the IO APIC from the IRQ# */ #define REDTBL_IDX(irq_num) (0x10 + ((irq_num) * 2)) +/* + * + */ +#define PUSH_FRAME \ + pushl $0 ; /* dummy error code */ \ + pushl $0 ; /* dummy trap type */ \ + pushal ; \ + pushl %ds ; /* save data and extra segments ... */ \ + pushl %es ; \ + pushl %fs + +#define POP_FRAME \ + popl %fs ; \ + popl %es ; \ + popl %ds ; \ + popal ; \ + addl $4+4,%esp /* * Macros for interrupt entry, call to handler, and exit. @@ -24,18 +41,14 @@ .text ; \ SUPERALIGN_TEXT ; \ IDTVEC(vec_name) ; \ - pushl %eax ; /* save only call-used registers */ \ - pushl %ecx ; \ - pushl %edx ; \ - pushl %ds ; \ - MAYBE_PUSHL_ES ; \ - pushl %fs ; \ + PUSH_FRAME ; \ movl $KDSEL,%eax ; \ mov %ax,%ds ; \ - MAYBE_MOVW_AX_ES ; \ + mov %ax,%es ; \ movl $KPSEL,%eax ; \ mov %ax,%fs ; \ - FAKE_MCOUNT((5+ACTUALLY_PUSHED)*4(%esp)) ; \ + FAKE_MCOUNT(13*4(%esp)) ; \ + incb _intr_nesting_level ; \ pushl _intr_unit + (irq_num) * 4 ; \ call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \ addl $4, %esp ; \ @@ -46,31 +59,7 @@ IDTVEC(vec_name) ; \ lock ; \ incl (%eax) ; \ MEXITCOUNT ; \ - popl %fs ; \ - MAYBE_POPL_ES ; \ - popl %ds ; \ - popl %edx ; \ - popl %ecx ; \ - popl %eax ; \ - iret - -/* - * - */ -#define PUSH_FRAME \ - pushl $0 ; /* dummy error code */ \ - pushl $0 ; /* dummy trap type */ \ - pushal ; \ - pushl %ds ; /* save data and extra segments ... */ \ - pushl %es ; \ - pushl %fs - -#define POP_FRAME \ - popl %fs ; \ - popl %es ; \ - popl %ds ; \ - popal ; \ - addl $4+4,%esp + jmp doreti_next #define IOAPICADDR(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 8 #define REDIRIDX(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 12 diff --git a/sys/amd64/amd64/cpu_switch.S b/sys/amd64/amd64/cpu_switch.S index ac71f0c..32dbe56 100644 --- a/sys/amd64/amd64/cpu_switch.S +++ b/sys/amd64/amd64/cpu_switch.S @@ -82,7 +82,6 @@ ENTRY(cpu_switch) /* switch to new process. first, save context as needed */ movl _curproc,%ecx - movl %ecx,_prevproc /* if no process to save, don't bother */ testl %ecx,%ecx diff --git a/sys/amd64/amd64/genassym.c b/sys/amd64/amd64/genassym.c index 78c6075..0566dd7 100644 --- a/sys/amd64/amd64/genassym.c +++ b/sys/amd64/amd64/genassym.c @@ -173,7 +173,6 @@ ASSYM(BI_ESYMTAB, offsetof(struct bootinfo, bi_esymtab)); ASSYM(BI_KERNEND, offsetof(struct bootinfo, bi_kernend)); ASSYM(GD_SIZEOF, sizeof(struct globaldata)); ASSYM(GD_CURPROC, offsetof(struct globaldata, gd_curproc)); -ASSYM(GD_PREVPROC, offsetof(struct globaldata, gd_prevproc)); ASSYM(GD_NPXPROC, offsetof(struct globaldata, gd_npxproc)); ASSYM(GD_IDLEPROC, offsetof(struct globaldata, gd_idleproc)); ASSYM(GD_CURPCB, offsetof(struct globaldata, gd_curpcb)); diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index 355a0a9..7055010 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -1883,7 +1883,6 @@ init386(first) /* setup curproc so that mutexes work */ PCPU_SET(curproc, &proc0); - PCPU_SET(prevproc, &proc0); /* make ldt memory segments */ /* @@ -1945,6 +1944,11 @@ init386(first) lidt(&r_idt); /* + * We need this mutex before the console probe. + */ + mtx_init(&clock_lock, "clk interrupt lock", MTX_SPIN); + + /* * Initialize the console before we print anything out. */ cninit(); @@ -1955,8 +1959,7 @@ init386(first) #endif /* - * Giant is used early for at least debugger traps, unexpected traps, - * and vm86bios initialization. + * Giant is used early for at least debugger traps and unexpected traps. */ mtx_init(&Giant, "Giant", MTX_DEF); diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index ea9aee8..5ef95b3 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -1900,11 +1900,6 @@ struct simplelock mcount_lock; struct simplelock com_lock; #endif /* USE_COMLOCK */ -#ifdef USE_CLOCKLOCK -/* lock regions around the clock hardware */ -struct simplelock clock_lock; -#endif /* USE_CLOCKLOCK */ - /* lock around the MP rendezvous */ static struct simplelock smp_rv_lock; @@ -1930,9 +1925,6 @@ init_locks(void) #ifdef USE_COMLOCK s_lock_init((struct simplelock*)&com_lock); #endif /* USE_COMLOCK */ -#ifdef USE_CLOCKLOCK - s_lock_init((struct simplelock*)&clock_lock); -#endif /* USE_CLOCKLOCK */ s_lock_init(&ap_boot_lock); } @@ -2425,7 +2417,6 @@ ap_init(void) * something unique to lock with. */ PCPU_SET(curproc,idleproc); - PCPU_SET(prevproc,idleproc); microuptime(&switchtime); switchticks = ticks; diff --git a/sys/amd64/amd64/mptable.c b/sys/amd64/amd64/mptable.c index ea9aee8..5ef95b3 100644 --- a/sys/amd64/amd64/mptable.c +++ b/sys/amd64/amd64/mptable.c @@ -1900,11 +1900,6 @@ struct simplelock mcount_lock; struct simplelock com_lock; #endif /* USE_COMLOCK */ -#ifdef USE_CLOCKLOCK -/* lock regions around the clock hardware */ -struct simplelock clock_lock; -#endif /* USE_CLOCKLOCK */ - /* lock around the MP rendezvous */ static struct simplelock smp_rv_lock; @@ -1930,9 +1925,6 @@ init_locks(void) #ifdef USE_COMLOCK s_lock_init((struct simplelock*)&com_lock); #endif /* USE_COMLOCK */ -#ifdef USE_CLOCKLOCK - s_lock_init((struct simplelock*)&clock_lock); -#endif /* USE_CLOCKLOCK */ s_lock_init(&ap_boot_lock); } @@ -2425,7 +2417,6 @@ ap_init(void) * something unique to lock with. */ PCPU_SET(curproc,idleproc); - PCPU_SET(prevproc,idleproc); microuptime(&switchtime); switchticks = ticks; diff --git a/sys/amd64/amd64/swtch.s b/sys/amd64/amd64/swtch.s index ac71f0c..32dbe56 100644 --- a/sys/amd64/amd64/swtch.s +++ b/sys/amd64/amd64/swtch.s @@ -82,7 +82,6 @@ ENTRY(cpu_switch) /* switch to new process. first, save context as needed */ movl _curproc,%ecx - movl %ecx,_prevproc /* if no process to save, don't bother */ testl %ecx,%ecx diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index 1cbfcfa..b9ebb60 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -1244,6 +1244,18 @@ ast(frame) addupc_task(p, p->p_stats->p_prof.pr_addr, p->p_stats->p_prof.pr_ticks); } + if (p->p_flag & P_ALRMPEND) { + if (!mtx_owned(&Giant)) + mtx_enter(&Giant, MTX_DEF); + p->p_flag &= ~P_ALRMPEND; + psignal(p, SIGVTALRM); + } + if (p->p_flag & P_PROFPEND) { + if (!mtx_owned(&Giant)) + mtx_enter(&Giant, MTX_DEF); + p->p_flag &= ~P_PROFPEND; + psignal(p, SIGPROF); + } if (userret(p, &frame, sticks, mtx_owned(&Giant)) != 0) mtx_exit(&Giant, MTX_DEF); } diff --git a/sys/amd64/amd64/tsc.c b/sys/amd64/amd64/tsc.c index 0e630d9..a164288 100644 --- a/sys/amd64/amd64/tsc.c +++ b/sys/amd64/amd64/tsc.c @@ -72,6 +72,7 @@ #include <machine/ipl.h> #include <machine/limits.h> #include <machine/md_var.h> +#include <machine/mutex.h> #include <machine/psl.h> #ifdef APIC_IO #include <machine/segments.h> @@ -139,6 +140,7 @@ int timer0_max_count; u_int tsc_freq; int tsc_is_broken; int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */ +struct mtx clock_lock; static int beeping = 0; static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31}; @@ -198,12 +200,9 @@ SYSCTL_OPAQUE(_debug, OID_AUTO, i8254_timecounter, CTLFLAG_RD, static void clkintr(struct clockframe frame) { - int intrsave; if (timecounter->tc_get_timecount == i8254_get_timecount) { - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); if (i8254_ticked) i8254_ticked = 0; else { @@ -211,8 +210,7 @@ clkintr(struct clockframe frame) i8254_lastcount = 0; } clkintr_pending = 0; - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); } timer_func(&frame); switch (timer0_state) { @@ -231,17 +229,14 @@ clkintr(struct clockframe frame) break; case ACQUIRE_PENDING: - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); i8254_offset = i8254_get_timecount(NULL); i8254_lastcount = 0; timer0_max_count = TIMER_DIV(new_rate); outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); timer_func = new_function; timer0_state = ACQUIRED; setdelayed(); @@ -250,9 +245,7 @@ clkintr(struct clockframe frame) case RELEASE_PENDING: if ((timer0_prescaler_count += timer0_max_count) >= hardclock_max_count) { - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); i8254_offset = i8254_get_timecount(NULL); i8254_lastcount = 0; timer0_max_count = hardclock_max_count; @@ -260,8 +253,7 @@ clkintr(struct clockframe frame) TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); timer0_prescaler_count = 0; timer_func = hardclock; timer0_state = RELEASED; @@ -408,11 +400,9 @@ DB_SHOW_COMMAND(rtc, rtc) static int getit(void) { - int high, low, intrsave; + int high, low; - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); /* Select timer0 and latch counter value. */ outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); @@ -420,8 +410,7 @@ getit(void) low = inb(TIMER_CNTR0); high = inb(TIMER_CNTR0); - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); return ((high << 8) | low); } @@ -527,7 +516,6 @@ sysbeepstop(void *chan) int sysbeep(int pitch, int period) { - int intrsave; int x = splclock(); if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT)) @@ -536,13 +524,10 @@ sysbeep(int pitch, int period) splx(x); return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */ } - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); outb(TIMER_CNTR2, pitch); outb(TIMER_CNTR2, (pitch>>8)); - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); if (!beeping) { /* enable counter2 output to speaker */ outb(IO_PPI, inb(IO_PPI) | 3); @@ -691,12 +676,9 @@ fail: static void set_timer_freq(u_int freq, int intr_freq) { - int intrsave; int new_timer0_max_count; - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); timer_freq = freq; new_timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq); if (new_timer0_max_count != timer0_max_count) { @@ -705,8 +687,7 @@ set_timer_freq(u_int freq, int intr_freq) outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); } - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); } /* @@ -720,16 +701,12 @@ set_timer_freq(u_int freq, int intr_freq) void i8254_restore(void) { - int intrsave; - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); } /* @@ -989,8 +966,8 @@ cpu_initclocks() { int diag; #ifdef APIC_IO - int apic_8254_trial, num_8254_ticks; - struct intrec *clkdesc, *rtcdesc; + int apic_8254_trial; + struct intrec *clkdesc; #endif /* APIC_IO */ if (statclock_disable) { @@ -1023,6 +1000,11 @@ cpu_initclocks() } else panic("APIC_IO: Cannot route 8254 interrupt to CPU"); } + + clkdesc = inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, + NULL, PI_REALTIME, INTR_FAST); + INTREN(1 << apic_8254_intr); + #else /* APIC_IO */ /* @@ -1030,9 +1012,8 @@ cpu_initclocks() * couldn't find anything suitable in the BSD/OS code (grog, * 19 July 2000). */ - /* Setup the PIC clk handler. The APIC handler is setup later */ inthand_add("clk", 0, (driver_intr_t *)clkintr, NULL, PI_REALTIME, - INTR_EXCL); + INTR_FAST); INTREN(IRQ0); #endif /* APIC_IO */ @@ -1042,18 +1023,8 @@ cpu_initclocks() writertc(RTC_STATUSB, RTCSB_24HR); /* Don't bother enabling the statistics clock. */ - if (statclock_disable) { -#ifdef APIC_IO - /* - * XXX - if statclock is disabled, don't attempt the APIC - * trial. Not sure this is sane for APIC_IO. - */ - inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, - NULL, PI_REALTIME, INTR_EXCL); - INTREN(1 << apic_8254_intr); -#endif /* APIC_IO */ + if (statclock_disable) return; - } diag = rtcin(RTC_DIAG); if (diag != 0) printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS); @@ -1061,44 +1032,34 @@ cpu_initclocks() #ifdef APIC_IO if (isa_apic_irq(8) != 8) panic("APIC RTC != 8"); +#endif /* APIC_IO */ - if (apic_8254_trial) { - /* - * XXX - We use fast interrupts for clk and rtc long enough to - * perform the APIC probe and then revert to exclusive - * interrupts. - */ - clkdesc = inthand_add("clk", apic_8254_intr, - (driver_intr_t *)clkintr, NULL, PI_REALTIME, INTR_FAST); - INTREN(1 << apic_8254_intr); + inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, PI_REALTIME, + INTR_FAST); - rtcdesc = inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, - PI_REALTIME, INTR_FAST); /* XXX */ - INTREN(APIC_IRQ8); - writertc(RTC_STATUSB, rtc_statusb); +#ifdef APIC_IO + INTREN(APIC_IRQ8); +#else + INTREN(IRQ8); +#endif /* APIC_IO */ + + writertc(RTC_STATUSB, rtc_statusb); + +#ifdef APIC_IO + if (apic_8254_trial) { printf("APIC_IO: Testing 8254 interrupt delivery\n"); while (read_intr_count(8) < 6) ; /* nothing */ - num_8254_ticks = read_intr_count(apic_8254_intr); - - /* disable and remove our fake handlers */ - INTRDIS(1 << apic_8254_intr); - inthand_remove(clkdesc); - - writertc(RTC_STATUSA, rtc_statusa); - writertc(RTC_STATUSB, RTCSB_24HR); - - INTRDIS(APIC_IRQ8); - inthand_remove(rtcdesc); - - if (num_8254_ticks < 3) { + if (read_intr_count(apic_8254_intr) < 3) { /* * The MP table is broken. * The 8254 was not connected to the specified pin * on the IO APIC. * Workaround: Limited variant of mixed mode. */ + INTRDIS(1 << apic_8254_intr); + inthand_remove(clkdesc); printf("APIC_IO: Broken MP table detected: " "8254 is not connected to " "IOAPIC #%d intpin %d\n", @@ -1117,27 +1078,13 @@ cpu_initclocks() } apic_8254_intr = apic_irq(0, 0); setup_8254_mixed_mode(); + inthand_add("clk", apic_8254_intr, + (driver_intr_t *)clkintr, NULL, + PI_REALTIME, INTR_FAST); + INTREN(1 << apic_8254_intr); } } - - /* Finally, setup the real clock handlers */ - inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, NULL, - PI_REALTIME, INTR_EXCL); - INTREN(1 << apic_8254_intr); -#endif - - inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, PI_REALTIME, - INTR_EXCL); -#ifdef APIC_IO - INTREN(APIC_IRQ8); -#else - INTREN(IRQ8); -#endif - - writertc(RTC_STATUSB, rtc_statusb); - -#ifdef APIC_IO if (apic_int_type(0, 0) != 3 || int_to_apicintpin[apic_8254_intr].ioapic != 0 || int_to_apicintpin[apic_8254_intr].int_pin != 0) @@ -1242,12 +1189,11 @@ static unsigned i8254_get_timecount(struct timecounter *tc) { u_int count; - int intrsave; u_int high, low; + u_int eflags; - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + eflags = read_eflags(); + mtx_enter(&clock_lock, MTX_SPIN); /* Select timer0 and latch counter value. */ outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); @@ -1257,7 +1203,7 @@ i8254_get_timecount(struct timecounter *tc) count = timer0_max_count - ((high << 8) | low); if (count < i8254_lastcount || (!i8254_ticked && (clkintr_pending || - ((count < 20 || (!(intrsave & PSL_I) && count < timer0_max_count / 2u)) && + ((count < 20 || (!(eflags & PSL_I) && count < timer0_max_count / 2u)) && #ifdef APIC_IO #define lapic_irr1 ((volatile u_int *)&lapic)[0x210 / 4] /* XXX XXX */ /* XXX this assumes that apic_8254_intr is < 24. */ @@ -1271,8 +1217,7 @@ i8254_get_timecount(struct timecounter *tc) } i8254_lastcount = count; count += i8254_offset; - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); return (count); } diff --git a/sys/amd64/include/cpu.h b/sys/amd64/include/cpu.h index 18822b8..d35b940 100644 --- a/sys/amd64/include/cpu.h +++ b/sys/amd64/include/cpu.h @@ -62,21 +62,6 @@ ((ISPL((framep)->cf_cs) == SEL_UPL) || (framep->cf_eflags & PSL_VM)) #define CLKF_INTR(framep) (intr_nesting_level >= 2) -#if 0 -/* - * XXX splsoftclock() is very broken and barely worth fixing. It doesn't - * turn off the clock bit in imen or in the icu. (This is not a serious - * problem at 100 Hz but it is serious at 16000 Hz for pcaudio. softclock() - * can take more than 62.5 usec so clock interrupts are lost.) It doesn't - * check for pending interrupts being unmasked. clkintr() and Xintr0() - * assume that the ipl is high when hardclock() returns. Our SWI_CLOCK - * handling is efficient enough that little is gained by calling - * softclock() directly. - */ -#define CLKF_BASEPRI(framep) ((framep)->cf_ppl == 0) -#else -#define CLKF_BASEPRI(framep) (0) -#endif #define CLKF_PC(framep) ((framep)->cf_eip) /* diff --git a/sys/amd64/include/mptable.h b/sys/amd64/include/mptable.h index ea9aee8..5ef95b3 100644 --- a/sys/amd64/include/mptable.h +++ b/sys/amd64/include/mptable.h @@ -1900,11 +1900,6 @@ struct simplelock mcount_lock; struct simplelock com_lock; #endif /* USE_COMLOCK */ -#ifdef USE_CLOCKLOCK -/* lock regions around the clock hardware */ -struct simplelock clock_lock; -#endif /* USE_CLOCKLOCK */ - /* lock around the MP rendezvous */ static struct simplelock smp_rv_lock; @@ -1930,9 +1925,6 @@ init_locks(void) #ifdef USE_COMLOCK s_lock_init((struct simplelock*)&com_lock); #endif /* USE_COMLOCK */ -#ifdef USE_CLOCKLOCK - s_lock_init((struct simplelock*)&clock_lock); -#endif /* USE_CLOCKLOCK */ s_lock_init(&ap_boot_lock); } @@ -2425,7 +2417,6 @@ ap_init(void) * something unique to lock with. */ PCPU_SET(curproc,idleproc); - PCPU_SET(prevproc,idleproc); microuptime(&switchtime); switchticks = ticks; diff --git a/sys/amd64/include/mutex.h b/sys/amd64/include/mutex.h index ca518d9..881cbfa 100644 --- a/sys/amd64/include/mutex.h +++ b/sys/amd64/include/mutex.h @@ -146,6 +146,7 @@ void _mtx_exit(struct mtx *mtxp, int type, const char *file, int line); /* Global locks */ extern struct mtx sched_lock; extern struct mtx Giant; +extern struct mtx clock_lock; /* * Used to replace return with an exit Giant and return. diff --git a/sys/amd64/include/pcpu.h b/sys/amd64/include/pcpu.h index ace3602..2788499 100644 --- a/sys/amd64/include/pcpu.h +++ b/sys/amd64/include/pcpu.h @@ -55,7 +55,6 @@ struct globaldata { struct privatespace *gd_prvspace; /* self-reference */ struct proc *gd_curproc; - struct proc *gd_prevproc; struct proc *gd_npxproc; struct pcb *gd_curpcb; struct proc *gd_idleproc; diff --git a/sys/amd64/isa/atpic_vector.S b/sys/amd64/isa/atpic_vector.S index 0a89492..7644c03 100644 --- a/sys/amd64/isa/atpic_vector.S +++ b/sys/amd64/isa/atpic_vector.S @@ -49,17 +49,18 @@ .text ; \ SUPERALIGN_TEXT ; \ IDTVEC(vec_name) ; \ - pushl %eax ; /* save only call-used registers */ \ - pushl %ecx ; \ - pushl %edx ; \ + pushl $0 ; /* dummy error code */ \ + pushl $0 ; /* dummy trap type */ \ + pushal ; \ pushl %ds ; \ + pushl %es ; \ pushl %fs ; \ - MAYBE_PUSHL_ES ; \ mov $KDSEL,%ax ; \ mov %ax,%ds ; \ + mov %ax,%es ; \ mov %ax,%fs ; \ - MAYBE_MOVW_AX_ES ; \ - FAKE_MCOUNT((4+ACTUALLY_PUSHED)*4(%esp)) ; \ + FAKE_MCOUNT((12+ACTUALLY_PUSHED)*4(%esp)) ; \ + incb _intr_nesting_level ; \ pushl _intr_unit + (irq_num) * 4 ; \ call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \ enable_icus ; /* (re)enable ASAP (helps edge trigger?) */ \ @@ -67,19 +68,8 @@ IDTVEC(vec_name) ; \ incl _cnt+V_INTR ; /* book-keeping can wait */ \ movl _intr_countp + (irq_num) * 4,%eax ; \ incl (%eax) ; \ -/* movl _cpl,%eax ; // are we unmasking pending SWIs? / \ - notl %eax ; \ - andl _spending,$SWI_MASK ; \ - jne 2f ; // yes, maybe handle them */ \ -1: ; \ MEXITCOUNT ; \ - MAYBE_POPL_ES ; \ - popl %fs ; \ - popl %ds ; \ - popl %edx ; \ - popl %ecx ; \ - popl %eax ; \ - iret ; \ + jmp doreti_next #if 0 ; \ @@ -141,7 +131,7 @@ IDTVEC(vec_name) ; \ movb %al,_imen + IRQ_BYTE(irq_num) ; \ outb %al,$icu+ICU_IMR_OFFSET ; \ enable_icus ; \ - incb _intr_nesting_level ; /* XXX do we need this? */ \ + incb _intr_nesting_level ; \ __CONCAT(Xresume,irq_num): ; \ FAKE_MCOUNT(13*4(%esp)) ; /* XXX late to avoid double count */ \ pushl $irq_num; /* pass the IRQ */ \ @@ -153,26 +143,6 @@ __CONCAT(Xresume,irq_num): ; \ /* _doreti, but it's probably better to use less cache. */ \ jmp doreti_next /* and catch up inside doreti */ -/* - * Reenable the interrupt mask after completing an interrupt. Called - * from ithd_loop. There are two separate functions, one for each - * ICU. - */ - .globl setimask0, setimask1 -setimask0: - cli - movb _imen,%al - outb %al,$IO_ICU1 + ICU_IMR_OFFSET - sti - ret - -setimask1: - cli - movb _imen + 1,%al - outb %al,$IO_ICU2 + ICU_IMR_OFFSET - sti - ret - MCOUNT_LABEL(bintr) FAST_INTR(0,fastintr0, ENABLE_ICU1) FAST_INTR(1,fastintr1, ENABLE_ICU1) diff --git a/sys/amd64/isa/clock.c b/sys/amd64/isa/clock.c index 0e630d9..a164288 100644 --- a/sys/amd64/isa/clock.c +++ b/sys/amd64/isa/clock.c @@ -72,6 +72,7 @@ #include <machine/ipl.h> #include <machine/limits.h> #include <machine/md_var.h> +#include <machine/mutex.h> #include <machine/psl.h> #ifdef APIC_IO #include <machine/segments.h> @@ -139,6 +140,7 @@ int timer0_max_count; u_int tsc_freq; int tsc_is_broken; int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */ +struct mtx clock_lock; static int beeping = 0; static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31}; @@ -198,12 +200,9 @@ SYSCTL_OPAQUE(_debug, OID_AUTO, i8254_timecounter, CTLFLAG_RD, static void clkintr(struct clockframe frame) { - int intrsave; if (timecounter->tc_get_timecount == i8254_get_timecount) { - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); if (i8254_ticked) i8254_ticked = 0; else { @@ -211,8 +210,7 @@ clkintr(struct clockframe frame) i8254_lastcount = 0; } clkintr_pending = 0; - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); } timer_func(&frame); switch (timer0_state) { @@ -231,17 +229,14 @@ clkintr(struct clockframe frame) break; case ACQUIRE_PENDING: - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); i8254_offset = i8254_get_timecount(NULL); i8254_lastcount = 0; timer0_max_count = TIMER_DIV(new_rate); outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); timer_func = new_function; timer0_state = ACQUIRED; setdelayed(); @@ -250,9 +245,7 @@ clkintr(struct clockframe frame) case RELEASE_PENDING: if ((timer0_prescaler_count += timer0_max_count) >= hardclock_max_count) { - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); i8254_offset = i8254_get_timecount(NULL); i8254_lastcount = 0; timer0_max_count = hardclock_max_count; @@ -260,8 +253,7 @@ clkintr(struct clockframe frame) TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); timer0_prescaler_count = 0; timer_func = hardclock; timer0_state = RELEASED; @@ -408,11 +400,9 @@ DB_SHOW_COMMAND(rtc, rtc) static int getit(void) { - int high, low, intrsave; + int high, low; - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); /* Select timer0 and latch counter value. */ outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); @@ -420,8 +410,7 @@ getit(void) low = inb(TIMER_CNTR0); high = inb(TIMER_CNTR0); - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); return ((high << 8) | low); } @@ -527,7 +516,6 @@ sysbeepstop(void *chan) int sysbeep(int pitch, int period) { - int intrsave; int x = splclock(); if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT)) @@ -536,13 +524,10 @@ sysbeep(int pitch, int period) splx(x); return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */ } - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); outb(TIMER_CNTR2, pitch); outb(TIMER_CNTR2, (pitch>>8)); - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); if (!beeping) { /* enable counter2 output to speaker */ outb(IO_PPI, inb(IO_PPI) | 3); @@ -691,12 +676,9 @@ fail: static void set_timer_freq(u_int freq, int intr_freq) { - int intrsave; int new_timer0_max_count; - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); timer_freq = freq; new_timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq); if (new_timer0_max_count != timer0_max_count) { @@ -705,8 +687,7 @@ set_timer_freq(u_int freq, int intr_freq) outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); } - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); } /* @@ -720,16 +701,12 @@ set_timer_freq(u_int freq, int intr_freq) void i8254_restore(void) { - int intrsave; - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); } /* @@ -989,8 +966,8 @@ cpu_initclocks() { int diag; #ifdef APIC_IO - int apic_8254_trial, num_8254_ticks; - struct intrec *clkdesc, *rtcdesc; + int apic_8254_trial; + struct intrec *clkdesc; #endif /* APIC_IO */ if (statclock_disable) { @@ -1023,6 +1000,11 @@ cpu_initclocks() } else panic("APIC_IO: Cannot route 8254 interrupt to CPU"); } + + clkdesc = inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, + NULL, PI_REALTIME, INTR_FAST); + INTREN(1 << apic_8254_intr); + #else /* APIC_IO */ /* @@ -1030,9 +1012,8 @@ cpu_initclocks() * couldn't find anything suitable in the BSD/OS code (grog, * 19 July 2000). */ - /* Setup the PIC clk handler. The APIC handler is setup later */ inthand_add("clk", 0, (driver_intr_t *)clkintr, NULL, PI_REALTIME, - INTR_EXCL); + INTR_FAST); INTREN(IRQ0); #endif /* APIC_IO */ @@ -1042,18 +1023,8 @@ cpu_initclocks() writertc(RTC_STATUSB, RTCSB_24HR); /* Don't bother enabling the statistics clock. */ - if (statclock_disable) { -#ifdef APIC_IO - /* - * XXX - if statclock is disabled, don't attempt the APIC - * trial. Not sure this is sane for APIC_IO. - */ - inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, - NULL, PI_REALTIME, INTR_EXCL); - INTREN(1 << apic_8254_intr); -#endif /* APIC_IO */ + if (statclock_disable) return; - } diag = rtcin(RTC_DIAG); if (diag != 0) printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS); @@ -1061,44 +1032,34 @@ cpu_initclocks() #ifdef APIC_IO if (isa_apic_irq(8) != 8) panic("APIC RTC != 8"); +#endif /* APIC_IO */ - if (apic_8254_trial) { - /* - * XXX - We use fast interrupts for clk and rtc long enough to - * perform the APIC probe and then revert to exclusive - * interrupts. - */ - clkdesc = inthand_add("clk", apic_8254_intr, - (driver_intr_t *)clkintr, NULL, PI_REALTIME, INTR_FAST); - INTREN(1 << apic_8254_intr); + inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, PI_REALTIME, + INTR_FAST); - rtcdesc = inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, - PI_REALTIME, INTR_FAST); /* XXX */ - INTREN(APIC_IRQ8); - writertc(RTC_STATUSB, rtc_statusb); +#ifdef APIC_IO + INTREN(APIC_IRQ8); +#else + INTREN(IRQ8); +#endif /* APIC_IO */ + + writertc(RTC_STATUSB, rtc_statusb); + +#ifdef APIC_IO + if (apic_8254_trial) { printf("APIC_IO: Testing 8254 interrupt delivery\n"); while (read_intr_count(8) < 6) ; /* nothing */ - num_8254_ticks = read_intr_count(apic_8254_intr); - - /* disable and remove our fake handlers */ - INTRDIS(1 << apic_8254_intr); - inthand_remove(clkdesc); - - writertc(RTC_STATUSA, rtc_statusa); - writertc(RTC_STATUSB, RTCSB_24HR); - - INTRDIS(APIC_IRQ8); - inthand_remove(rtcdesc); - - if (num_8254_ticks < 3) { + if (read_intr_count(apic_8254_intr) < 3) { /* * The MP table is broken. * The 8254 was not connected to the specified pin * on the IO APIC. * Workaround: Limited variant of mixed mode. */ + INTRDIS(1 << apic_8254_intr); + inthand_remove(clkdesc); printf("APIC_IO: Broken MP table detected: " "8254 is not connected to " "IOAPIC #%d intpin %d\n", @@ -1117,27 +1078,13 @@ cpu_initclocks() } apic_8254_intr = apic_irq(0, 0); setup_8254_mixed_mode(); + inthand_add("clk", apic_8254_intr, + (driver_intr_t *)clkintr, NULL, + PI_REALTIME, INTR_FAST); + INTREN(1 << apic_8254_intr); } } - - /* Finally, setup the real clock handlers */ - inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, NULL, - PI_REALTIME, INTR_EXCL); - INTREN(1 << apic_8254_intr); -#endif - - inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, PI_REALTIME, - INTR_EXCL); -#ifdef APIC_IO - INTREN(APIC_IRQ8); -#else - INTREN(IRQ8); -#endif - - writertc(RTC_STATUSB, rtc_statusb); - -#ifdef APIC_IO if (apic_int_type(0, 0) != 3 || int_to_apicintpin[apic_8254_intr].ioapic != 0 || int_to_apicintpin[apic_8254_intr].int_pin != 0) @@ -1242,12 +1189,11 @@ static unsigned i8254_get_timecount(struct timecounter *tc) { u_int count; - int intrsave; u_int high, low; + u_int eflags; - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + eflags = read_eflags(); + mtx_enter(&clock_lock, MTX_SPIN); /* Select timer0 and latch counter value. */ outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); @@ -1257,7 +1203,7 @@ i8254_get_timecount(struct timecounter *tc) count = timer0_max_count - ((high << 8) | low); if (count < i8254_lastcount || (!i8254_ticked && (clkintr_pending || - ((count < 20 || (!(intrsave & PSL_I) && count < timer0_max_count / 2u)) && + ((count < 20 || (!(eflags & PSL_I) && count < timer0_max_count / 2u)) && #ifdef APIC_IO #define lapic_irr1 ((volatile u_int *)&lapic)[0x210 / 4] /* XXX XXX */ /* XXX this assumes that apic_8254_intr is < 24. */ @@ -1271,8 +1217,7 @@ i8254_get_timecount(struct timecounter *tc) } i8254_lastcount = count; count += i8254_offset; - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); return (count); } diff --git a/sys/amd64/isa/icu_vector.S b/sys/amd64/isa/icu_vector.S index 0a89492..7644c03 100644 --- a/sys/amd64/isa/icu_vector.S +++ b/sys/amd64/isa/icu_vector.S @@ -49,17 +49,18 @@ .text ; \ SUPERALIGN_TEXT ; \ IDTVEC(vec_name) ; \ - pushl %eax ; /* save only call-used registers */ \ - pushl %ecx ; \ - pushl %edx ; \ + pushl $0 ; /* dummy error code */ \ + pushl $0 ; /* dummy trap type */ \ + pushal ; \ pushl %ds ; \ + pushl %es ; \ pushl %fs ; \ - MAYBE_PUSHL_ES ; \ mov $KDSEL,%ax ; \ mov %ax,%ds ; \ + mov %ax,%es ; \ mov %ax,%fs ; \ - MAYBE_MOVW_AX_ES ; \ - FAKE_MCOUNT((4+ACTUALLY_PUSHED)*4(%esp)) ; \ + FAKE_MCOUNT((12+ACTUALLY_PUSHED)*4(%esp)) ; \ + incb _intr_nesting_level ; \ pushl _intr_unit + (irq_num) * 4 ; \ call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \ enable_icus ; /* (re)enable ASAP (helps edge trigger?) */ \ @@ -67,19 +68,8 @@ IDTVEC(vec_name) ; \ incl _cnt+V_INTR ; /* book-keeping can wait */ \ movl _intr_countp + (irq_num) * 4,%eax ; \ incl (%eax) ; \ -/* movl _cpl,%eax ; // are we unmasking pending SWIs? / \ - notl %eax ; \ - andl _spending,$SWI_MASK ; \ - jne 2f ; // yes, maybe handle them */ \ -1: ; \ MEXITCOUNT ; \ - MAYBE_POPL_ES ; \ - popl %fs ; \ - popl %ds ; \ - popl %edx ; \ - popl %ecx ; \ - popl %eax ; \ - iret ; \ + jmp doreti_next #if 0 ; \ @@ -141,7 +131,7 @@ IDTVEC(vec_name) ; \ movb %al,_imen + IRQ_BYTE(irq_num) ; \ outb %al,$icu+ICU_IMR_OFFSET ; \ enable_icus ; \ - incb _intr_nesting_level ; /* XXX do we need this? */ \ + incb _intr_nesting_level ; \ __CONCAT(Xresume,irq_num): ; \ FAKE_MCOUNT(13*4(%esp)) ; /* XXX late to avoid double count */ \ pushl $irq_num; /* pass the IRQ */ \ @@ -153,26 +143,6 @@ __CONCAT(Xresume,irq_num): ; \ /* _doreti, but it's probably better to use less cache. */ \ jmp doreti_next /* and catch up inside doreti */ -/* - * Reenable the interrupt mask after completing an interrupt. Called - * from ithd_loop. There are two separate functions, one for each - * ICU. - */ - .globl setimask0, setimask1 -setimask0: - cli - movb _imen,%al - outb %al,$IO_ICU1 + ICU_IMR_OFFSET - sti - ret - -setimask1: - cli - movb _imen + 1,%al - outb %al,$IO_ICU2 + ICU_IMR_OFFSET - sti - ret - MCOUNT_LABEL(bintr) FAST_INTR(0,fastintr0, ENABLE_ICU1) FAST_INTR(1,fastintr1, ENABLE_ICU1) diff --git a/sys/amd64/isa/icu_vector.s b/sys/amd64/isa/icu_vector.s index 0a89492..7644c03 100644 --- a/sys/amd64/isa/icu_vector.s +++ b/sys/amd64/isa/icu_vector.s @@ -49,17 +49,18 @@ .text ; \ SUPERALIGN_TEXT ; \ IDTVEC(vec_name) ; \ - pushl %eax ; /* save only call-used registers */ \ - pushl %ecx ; \ - pushl %edx ; \ + pushl $0 ; /* dummy error code */ \ + pushl $0 ; /* dummy trap type */ \ + pushal ; \ pushl %ds ; \ + pushl %es ; \ pushl %fs ; \ - MAYBE_PUSHL_ES ; \ mov $KDSEL,%ax ; \ mov %ax,%ds ; \ + mov %ax,%es ; \ mov %ax,%fs ; \ - MAYBE_MOVW_AX_ES ; \ - FAKE_MCOUNT((4+ACTUALLY_PUSHED)*4(%esp)) ; \ + FAKE_MCOUNT((12+ACTUALLY_PUSHED)*4(%esp)) ; \ + incb _intr_nesting_level ; \ pushl _intr_unit + (irq_num) * 4 ; \ call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \ enable_icus ; /* (re)enable ASAP (helps edge trigger?) */ \ @@ -67,19 +68,8 @@ IDTVEC(vec_name) ; \ incl _cnt+V_INTR ; /* book-keeping can wait */ \ movl _intr_countp + (irq_num) * 4,%eax ; \ incl (%eax) ; \ -/* movl _cpl,%eax ; // are we unmasking pending SWIs? / \ - notl %eax ; \ - andl _spending,$SWI_MASK ; \ - jne 2f ; // yes, maybe handle them */ \ -1: ; \ MEXITCOUNT ; \ - MAYBE_POPL_ES ; \ - popl %fs ; \ - popl %ds ; \ - popl %edx ; \ - popl %ecx ; \ - popl %eax ; \ - iret ; \ + jmp doreti_next #if 0 ; \ @@ -141,7 +131,7 @@ IDTVEC(vec_name) ; \ movb %al,_imen + IRQ_BYTE(irq_num) ; \ outb %al,$icu+ICU_IMR_OFFSET ; \ enable_icus ; \ - incb _intr_nesting_level ; /* XXX do we need this? */ \ + incb _intr_nesting_level ; \ __CONCAT(Xresume,irq_num): ; \ FAKE_MCOUNT(13*4(%esp)) ; /* XXX late to avoid double count */ \ pushl $irq_num; /* pass the IRQ */ \ @@ -153,26 +143,6 @@ __CONCAT(Xresume,irq_num): ; \ /* _doreti, but it's probably better to use less cache. */ \ jmp doreti_next /* and catch up inside doreti */ -/* - * Reenable the interrupt mask after completing an interrupt. Called - * from ithd_loop. There are two separate functions, one for each - * ICU. - */ - .globl setimask0, setimask1 -setimask0: - cli - movb _imen,%al - outb %al,$IO_ICU1 + ICU_IMR_OFFSET - sti - ret - -setimask1: - cli - movb _imen + 1,%al - outb %al,$IO_ICU2 + ICU_IMR_OFFSET - sti - ret - MCOUNT_LABEL(bintr) FAST_INTR(0,fastintr0, ENABLE_ICU1) FAST_INTR(1,fastintr1, ENABLE_ICU1) diff --git a/sys/i386/i386/apic_vector.s b/sys/i386/i386/apic_vector.s index 11d9797..1f80224 100644 --- a/sys/i386/i386/apic_vector.s +++ b/sys/i386/i386/apic_vector.s @@ -15,6 +15,23 @@ /* make an index into the IO APIC from the IRQ# */ #define REDTBL_IDX(irq_num) (0x10 + ((irq_num) * 2)) +/* + * + */ +#define PUSH_FRAME \ + pushl $0 ; /* dummy error code */ \ + pushl $0 ; /* dummy trap type */ \ + pushal ; \ + pushl %ds ; /* save data and extra segments ... */ \ + pushl %es ; \ + pushl %fs + +#define POP_FRAME \ + popl %fs ; \ + popl %es ; \ + popl %ds ; \ + popal ; \ + addl $4+4,%esp /* * Macros for interrupt entry, call to handler, and exit. @@ -24,18 +41,14 @@ .text ; \ SUPERALIGN_TEXT ; \ IDTVEC(vec_name) ; \ - pushl %eax ; /* save only call-used registers */ \ - pushl %ecx ; \ - pushl %edx ; \ - pushl %ds ; \ - MAYBE_PUSHL_ES ; \ - pushl %fs ; \ + PUSH_FRAME ; \ movl $KDSEL,%eax ; \ mov %ax,%ds ; \ - MAYBE_MOVW_AX_ES ; \ + mov %ax,%es ; \ movl $KPSEL,%eax ; \ mov %ax,%fs ; \ - FAKE_MCOUNT((5+ACTUALLY_PUSHED)*4(%esp)) ; \ + FAKE_MCOUNT(13*4(%esp)) ; \ + incb _intr_nesting_level ; \ pushl _intr_unit + (irq_num) * 4 ; \ call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \ addl $4, %esp ; \ @@ -46,31 +59,7 @@ IDTVEC(vec_name) ; \ lock ; \ incl (%eax) ; \ MEXITCOUNT ; \ - popl %fs ; \ - MAYBE_POPL_ES ; \ - popl %ds ; \ - popl %edx ; \ - popl %ecx ; \ - popl %eax ; \ - iret - -/* - * - */ -#define PUSH_FRAME \ - pushl $0 ; /* dummy error code */ \ - pushl $0 ; /* dummy trap type */ \ - pushal ; \ - pushl %ds ; /* save data and extra segments ... */ \ - pushl %es ; \ - pushl %fs - -#define POP_FRAME \ - popl %fs ; \ - popl %es ; \ - popl %ds ; \ - popal ; \ - addl $4+4,%esp + jmp doreti_next #define IOAPICADDR(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 8 #define REDIRIDX(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 12 diff --git a/sys/i386/i386/genassym.c b/sys/i386/i386/genassym.c index 78c6075..0566dd7 100644 --- a/sys/i386/i386/genassym.c +++ b/sys/i386/i386/genassym.c @@ -173,7 +173,6 @@ ASSYM(BI_ESYMTAB, offsetof(struct bootinfo, bi_esymtab)); ASSYM(BI_KERNEND, offsetof(struct bootinfo, bi_kernend)); ASSYM(GD_SIZEOF, sizeof(struct globaldata)); ASSYM(GD_CURPROC, offsetof(struct globaldata, gd_curproc)); -ASSYM(GD_PREVPROC, offsetof(struct globaldata, gd_prevproc)); ASSYM(GD_NPXPROC, offsetof(struct globaldata, gd_npxproc)); ASSYM(GD_IDLEPROC, offsetof(struct globaldata, gd_idleproc)); ASSYM(GD_CURPCB, offsetof(struct globaldata, gd_curpcb)); diff --git a/sys/i386/i386/globals.s b/sys/i386/i386/globals.s index f318142..aaa6f81 100644 --- a/sys/i386/i386/globals.s +++ b/sys/i386/i386/globals.s @@ -61,11 +61,10 @@ globaldata: #else .set globaldata,0 #endif - .globl gd_curproc, gd_prevproc, gd_curpcb, gd_npxproc, gd_idleproc + .globl gd_curproc, gd_curpcb, gd_npxproc, gd_idleproc .globl gd_astpending, gd_common_tss, gd_switchtime, gd_switchticks .globl gd_intr_nesting_level .set gd_curproc,globaldata + GD_CURPROC - .set gd_prevproc,globaldata + GD_PREVPROC .set gd_astpending,globaldata + GD_ASTPENDING .set gd_curpcb,globaldata + GD_CURPCB .set gd_npxproc,globaldata + GD_NPXPROC @@ -96,11 +95,10 @@ globaldata: #endif #ifndef SMP - .globl _curproc, _prevproc, _curpcb, _npxproc, _idleproc, + .globl _curproc, _curpcb, _npxproc, _idleproc, .globl _astpending, _common_tss, _switchtime, _switchticks .global _intr_nesting_level .set _curproc,globaldata + GD_CURPROC - .set _prevproc,globaldata + GD_PREVPROC .set _astpending,globaldata + GD_ASTPENDING .set _curpcb,globaldata + GD_CURPCB .set _npxproc,globaldata + GD_NPXPROC diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index 355a0a9..7055010 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -1883,7 +1883,6 @@ init386(first) /* setup curproc so that mutexes work */ PCPU_SET(curproc, &proc0); - PCPU_SET(prevproc, &proc0); /* make ldt memory segments */ /* @@ -1945,6 +1944,11 @@ init386(first) lidt(&r_idt); /* + * We need this mutex before the console probe. + */ + mtx_init(&clock_lock, "clk interrupt lock", MTX_SPIN); + + /* * Initialize the console before we print anything out. */ cninit(); @@ -1955,8 +1959,7 @@ init386(first) #endif /* - * Giant is used early for at least debugger traps, unexpected traps, - * and vm86bios initialization. + * Giant is used early for at least debugger traps and unexpected traps. */ mtx_init(&Giant, "Giant", MTX_DEF); diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c index ea9aee8..5ef95b3 100644 --- a/sys/i386/i386/mp_machdep.c +++ b/sys/i386/i386/mp_machdep.c @@ -1900,11 +1900,6 @@ struct simplelock mcount_lock; struct simplelock com_lock; #endif /* USE_COMLOCK */ -#ifdef USE_CLOCKLOCK -/* lock regions around the clock hardware */ -struct simplelock clock_lock; -#endif /* USE_CLOCKLOCK */ - /* lock around the MP rendezvous */ static struct simplelock smp_rv_lock; @@ -1930,9 +1925,6 @@ init_locks(void) #ifdef USE_COMLOCK s_lock_init((struct simplelock*)&com_lock); #endif /* USE_COMLOCK */ -#ifdef USE_CLOCKLOCK - s_lock_init((struct simplelock*)&clock_lock); -#endif /* USE_CLOCKLOCK */ s_lock_init(&ap_boot_lock); } @@ -2425,7 +2417,6 @@ ap_init(void) * something unique to lock with. */ PCPU_SET(curproc,idleproc); - PCPU_SET(prevproc,idleproc); microuptime(&switchtime); switchticks = ticks; diff --git a/sys/i386/i386/mptable.c b/sys/i386/i386/mptable.c index ea9aee8..5ef95b3 100644 --- a/sys/i386/i386/mptable.c +++ b/sys/i386/i386/mptable.c @@ -1900,11 +1900,6 @@ struct simplelock mcount_lock; struct simplelock com_lock; #endif /* USE_COMLOCK */ -#ifdef USE_CLOCKLOCK -/* lock regions around the clock hardware */ -struct simplelock clock_lock; -#endif /* USE_CLOCKLOCK */ - /* lock around the MP rendezvous */ static struct simplelock smp_rv_lock; @@ -1930,9 +1925,6 @@ init_locks(void) #ifdef USE_COMLOCK s_lock_init((struct simplelock*)&com_lock); #endif /* USE_COMLOCK */ -#ifdef USE_CLOCKLOCK - s_lock_init((struct simplelock*)&clock_lock); -#endif /* USE_CLOCKLOCK */ s_lock_init(&ap_boot_lock); } @@ -2425,7 +2417,6 @@ ap_init(void) * something unique to lock with. */ PCPU_SET(curproc,idleproc); - PCPU_SET(prevproc,idleproc); microuptime(&switchtime); switchticks = ticks; diff --git a/sys/i386/i386/swtch.s b/sys/i386/i386/swtch.s index ac71f0c..32dbe56 100644 --- a/sys/i386/i386/swtch.s +++ b/sys/i386/i386/swtch.s @@ -82,7 +82,6 @@ ENTRY(cpu_switch) /* switch to new process. first, save context as needed */ movl _curproc,%ecx - movl %ecx,_prevproc /* if no process to save, don't bother */ testl %ecx,%ecx diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c index 1cbfcfa..b9ebb60 100644 --- a/sys/i386/i386/trap.c +++ b/sys/i386/i386/trap.c @@ -1244,6 +1244,18 @@ ast(frame) addupc_task(p, p->p_stats->p_prof.pr_addr, p->p_stats->p_prof.pr_ticks); } + if (p->p_flag & P_ALRMPEND) { + if (!mtx_owned(&Giant)) + mtx_enter(&Giant, MTX_DEF); + p->p_flag &= ~P_ALRMPEND; + psignal(p, SIGVTALRM); + } + if (p->p_flag & P_PROFPEND) { + if (!mtx_owned(&Giant)) + mtx_enter(&Giant, MTX_DEF); + p->p_flag &= ~P_PROFPEND; + psignal(p, SIGPROF); + } if (userret(p, &frame, sticks, mtx_owned(&Giant)) != 0) mtx_exit(&Giant, MTX_DEF); } diff --git a/sys/i386/i386/tsc.c b/sys/i386/i386/tsc.c index 0e630d9..a164288 100644 --- a/sys/i386/i386/tsc.c +++ b/sys/i386/i386/tsc.c @@ -72,6 +72,7 @@ #include <machine/ipl.h> #include <machine/limits.h> #include <machine/md_var.h> +#include <machine/mutex.h> #include <machine/psl.h> #ifdef APIC_IO #include <machine/segments.h> @@ -139,6 +140,7 @@ int timer0_max_count; u_int tsc_freq; int tsc_is_broken; int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */ +struct mtx clock_lock; static int beeping = 0; static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31}; @@ -198,12 +200,9 @@ SYSCTL_OPAQUE(_debug, OID_AUTO, i8254_timecounter, CTLFLAG_RD, static void clkintr(struct clockframe frame) { - int intrsave; if (timecounter->tc_get_timecount == i8254_get_timecount) { - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); if (i8254_ticked) i8254_ticked = 0; else { @@ -211,8 +210,7 @@ clkintr(struct clockframe frame) i8254_lastcount = 0; } clkintr_pending = 0; - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); } timer_func(&frame); switch (timer0_state) { @@ -231,17 +229,14 @@ clkintr(struct clockframe frame) break; case ACQUIRE_PENDING: - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); i8254_offset = i8254_get_timecount(NULL); i8254_lastcount = 0; timer0_max_count = TIMER_DIV(new_rate); outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); timer_func = new_function; timer0_state = ACQUIRED; setdelayed(); @@ -250,9 +245,7 @@ clkintr(struct clockframe frame) case RELEASE_PENDING: if ((timer0_prescaler_count += timer0_max_count) >= hardclock_max_count) { - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); i8254_offset = i8254_get_timecount(NULL); i8254_lastcount = 0; timer0_max_count = hardclock_max_count; @@ -260,8 +253,7 @@ clkintr(struct clockframe frame) TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); timer0_prescaler_count = 0; timer_func = hardclock; timer0_state = RELEASED; @@ -408,11 +400,9 @@ DB_SHOW_COMMAND(rtc, rtc) static int getit(void) { - int high, low, intrsave; + int high, low; - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); /* Select timer0 and latch counter value. */ outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); @@ -420,8 +410,7 @@ getit(void) low = inb(TIMER_CNTR0); high = inb(TIMER_CNTR0); - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); return ((high << 8) | low); } @@ -527,7 +516,6 @@ sysbeepstop(void *chan) int sysbeep(int pitch, int period) { - int intrsave; int x = splclock(); if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT)) @@ -536,13 +524,10 @@ sysbeep(int pitch, int period) splx(x); return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */ } - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); outb(TIMER_CNTR2, pitch); outb(TIMER_CNTR2, (pitch>>8)); - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); if (!beeping) { /* enable counter2 output to speaker */ outb(IO_PPI, inb(IO_PPI) | 3); @@ -691,12 +676,9 @@ fail: static void set_timer_freq(u_int freq, int intr_freq) { - int intrsave; int new_timer0_max_count; - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); timer_freq = freq; new_timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq); if (new_timer0_max_count != timer0_max_count) { @@ -705,8 +687,7 @@ set_timer_freq(u_int freq, int intr_freq) outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); } - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); } /* @@ -720,16 +701,12 @@ set_timer_freq(u_int freq, int intr_freq) void i8254_restore(void) { - int intrsave; - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); } /* @@ -989,8 +966,8 @@ cpu_initclocks() { int diag; #ifdef APIC_IO - int apic_8254_trial, num_8254_ticks; - struct intrec *clkdesc, *rtcdesc; + int apic_8254_trial; + struct intrec *clkdesc; #endif /* APIC_IO */ if (statclock_disable) { @@ -1023,6 +1000,11 @@ cpu_initclocks() } else panic("APIC_IO: Cannot route 8254 interrupt to CPU"); } + + clkdesc = inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, + NULL, PI_REALTIME, INTR_FAST); + INTREN(1 << apic_8254_intr); + #else /* APIC_IO */ /* @@ -1030,9 +1012,8 @@ cpu_initclocks() * couldn't find anything suitable in the BSD/OS code (grog, * 19 July 2000). */ - /* Setup the PIC clk handler. The APIC handler is setup later */ inthand_add("clk", 0, (driver_intr_t *)clkintr, NULL, PI_REALTIME, - INTR_EXCL); + INTR_FAST); INTREN(IRQ0); #endif /* APIC_IO */ @@ -1042,18 +1023,8 @@ cpu_initclocks() writertc(RTC_STATUSB, RTCSB_24HR); /* Don't bother enabling the statistics clock. */ - if (statclock_disable) { -#ifdef APIC_IO - /* - * XXX - if statclock is disabled, don't attempt the APIC - * trial. Not sure this is sane for APIC_IO. - */ - inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, - NULL, PI_REALTIME, INTR_EXCL); - INTREN(1 << apic_8254_intr); -#endif /* APIC_IO */ + if (statclock_disable) return; - } diag = rtcin(RTC_DIAG); if (diag != 0) printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS); @@ -1061,44 +1032,34 @@ cpu_initclocks() #ifdef APIC_IO if (isa_apic_irq(8) != 8) panic("APIC RTC != 8"); +#endif /* APIC_IO */ - if (apic_8254_trial) { - /* - * XXX - We use fast interrupts for clk and rtc long enough to - * perform the APIC probe and then revert to exclusive - * interrupts. - */ - clkdesc = inthand_add("clk", apic_8254_intr, - (driver_intr_t *)clkintr, NULL, PI_REALTIME, INTR_FAST); - INTREN(1 << apic_8254_intr); + inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, PI_REALTIME, + INTR_FAST); - rtcdesc = inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, - PI_REALTIME, INTR_FAST); /* XXX */ - INTREN(APIC_IRQ8); - writertc(RTC_STATUSB, rtc_statusb); +#ifdef APIC_IO + INTREN(APIC_IRQ8); +#else + INTREN(IRQ8); +#endif /* APIC_IO */ + + writertc(RTC_STATUSB, rtc_statusb); + +#ifdef APIC_IO + if (apic_8254_trial) { printf("APIC_IO: Testing 8254 interrupt delivery\n"); while (read_intr_count(8) < 6) ; /* nothing */ - num_8254_ticks = read_intr_count(apic_8254_intr); - - /* disable and remove our fake handlers */ - INTRDIS(1 << apic_8254_intr); - inthand_remove(clkdesc); - - writertc(RTC_STATUSA, rtc_statusa); - writertc(RTC_STATUSB, RTCSB_24HR); - - INTRDIS(APIC_IRQ8); - inthand_remove(rtcdesc); - - if (num_8254_ticks < 3) { + if (read_intr_count(apic_8254_intr) < 3) { /* * The MP table is broken. * The 8254 was not connected to the specified pin * on the IO APIC. * Workaround: Limited variant of mixed mode. */ + INTRDIS(1 << apic_8254_intr); + inthand_remove(clkdesc); printf("APIC_IO: Broken MP table detected: " "8254 is not connected to " "IOAPIC #%d intpin %d\n", @@ -1117,27 +1078,13 @@ cpu_initclocks() } apic_8254_intr = apic_irq(0, 0); setup_8254_mixed_mode(); + inthand_add("clk", apic_8254_intr, + (driver_intr_t *)clkintr, NULL, + PI_REALTIME, INTR_FAST); + INTREN(1 << apic_8254_intr); } } - - /* Finally, setup the real clock handlers */ - inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, NULL, - PI_REALTIME, INTR_EXCL); - INTREN(1 << apic_8254_intr); -#endif - - inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, PI_REALTIME, - INTR_EXCL); -#ifdef APIC_IO - INTREN(APIC_IRQ8); -#else - INTREN(IRQ8); -#endif - - writertc(RTC_STATUSB, rtc_statusb); - -#ifdef APIC_IO if (apic_int_type(0, 0) != 3 || int_to_apicintpin[apic_8254_intr].ioapic != 0 || int_to_apicintpin[apic_8254_intr].int_pin != 0) @@ -1242,12 +1189,11 @@ static unsigned i8254_get_timecount(struct timecounter *tc) { u_int count; - int intrsave; u_int high, low; + u_int eflags; - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + eflags = read_eflags(); + mtx_enter(&clock_lock, MTX_SPIN); /* Select timer0 and latch counter value. */ outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); @@ -1257,7 +1203,7 @@ i8254_get_timecount(struct timecounter *tc) count = timer0_max_count - ((high << 8) | low); if (count < i8254_lastcount || (!i8254_ticked && (clkintr_pending || - ((count < 20 || (!(intrsave & PSL_I) && count < timer0_max_count / 2u)) && + ((count < 20 || (!(eflags & PSL_I) && count < timer0_max_count / 2u)) && #ifdef APIC_IO #define lapic_irr1 ((volatile u_int *)&lapic)[0x210 / 4] /* XXX XXX */ /* XXX this assumes that apic_8254_intr is < 24. */ @@ -1271,8 +1217,7 @@ i8254_get_timecount(struct timecounter *tc) } i8254_lastcount = count; count += i8254_offset; - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); return (count); } diff --git a/sys/i386/include/asnames.h b/sys/i386/include/asnames.h index fe5d6ca..b99b9af 100644 --- a/sys/i386/include/asnames.h +++ b/sys/i386/include/asnames.h @@ -342,7 +342,6 @@ #define _cpu_lockid FS(cpu_lockid) #define _curpcb FS(curpcb) #define _curproc FS(curproc) -#define _prevproc FS(prevproc) #define _idleproc FS(idleproc) #define _astpending FS(astpending) #define _currentldt FS(currentldt) diff --git a/sys/i386/include/cpu.h b/sys/i386/include/cpu.h index 18822b8..d35b940 100644 --- a/sys/i386/include/cpu.h +++ b/sys/i386/include/cpu.h @@ -62,21 +62,6 @@ ((ISPL((framep)->cf_cs) == SEL_UPL) || (framep->cf_eflags & PSL_VM)) #define CLKF_INTR(framep) (intr_nesting_level >= 2) -#if 0 -/* - * XXX splsoftclock() is very broken and barely worth fixing. It doesn't - * turn off the clock bit in imen or in the icu. (This is not a serious - * problem at 100 Hz but it is serious at 16000 Hz for pcaudio. softclock() - * can take more than 62.5 usec so clock interrupts are lost.) It doesn't - * check for pending interrupts being unmasked. clkintr() and Xintr0() - * assume that the ipl is high when hardclock() returns. Our SWI_CLOCK - * handling is efficient enough that little is gained by calling - * softclock() directly. - */ -#define CLKF_BASEPRI(framep) ((framep)->cf_ppl == 0) -#else -#define CLKF_BASEPRI(framep) (0) -#endif #define CLKF_PC(framep) ((framep)->cf_eip) /* diff --git a/sys/i386/include/globaldata.h b/sys/i386/include/globaldata.h index ace3602..2788499 100644 --- a/sys/i386/include/globaldata.h +++ b/sys/i386/include/globaldata.h @@ -55,7 +55,6 @@ struct globaldata { struct privatespace *gd_prvspace; /* self-reference */ struct proc *gd_curproc; - struct proc *gd_prevproc; struct proc *gd_npxproc; struct pcb *gd_curpcb; struct proc *gd_idleproc; diff --git a/sys/i386/include/globals.h b/sys/i386/include/globals.h index 71bbbd5..d18c0ac 100644 --- a/sys/i386/include/globals.h +++ b/sys/i386/include/globals.h @@ -90,7 +90,6 @@ _global_globaldata(void) * portability between UP and SMP kernels. */ #define curproc GLOBAL_RVALUE_NV(curproc, struct proc *) -#define prevproc GLOBAL_RVALUE_NV(prevproc, struct proc *) #define curpcb GLOBAL_RVALUE_NV(curpcb, struct pcb *) #define npxproc GLOBAL_RVALUE_NV(npxproc, struct proc *) #define idleproc GLOBAL_RVALUE_NV(idleproc, struct proc *) @@ -126,7 +125,6 @@ _global_globaldata(void) #endif /*UP kernel*/ GLOBAL_FUNC(curproc) -GLOBAL_FUNC(prevproc) GLOBAL_FUNC(astpending) GLOBAL_FUNC(curpcb) GLOBAL_FUNC(npxproc) diff --git a/sys/i386/include/lock.h b/sys/i386/include/lock.h index 7871606..aa527ef 100644 --- a/sys/i386/include/lock.h +++ b/sys/i386/include/lock.h @@ -74,24 +74,10 @@ #define COM_UNLOCK() #endif /* USE_COMLOCK */ -/* - * Clock hardware/struct lock. - * XXX pcaudio and friends still need this lock installed. - */ -#ifdef USE_CLOCKLOCK -#define CLOCK_LOCK() s_lock(&clock_lock) -#define CLOCK_UNLOCK() s_unlock(&clock_lock) -#else -#define CLOCK_LOCK() -#define CLOCK_UNLOCK() -#endif /* USE_CLOCKLOCK */ - #else /* SMP */ #define COM_LOCK() #define COM_UNLOCK() -#define CLOCK_LOCK() -#define CLOCK_UNLOCK() #endif /* SMP */ @@ -124,7 +110,6 @@ extern struct simplelock imen_lock; extern struct simplelock cpl_lock; extern struct simplelock fast_intr_lock; extern struct simplelock intr_lock; -extern struct simplelock clock_lock; extern struct simplelock com_lock; extern struct simplelock mpintr_lock; extern struct simplelock mcount_lock; diff --git a/sys/i386/include/mptable.h b/sys/i386/include/mptable.h index ea9aee8..5ef95b3 100644 --- a/sys/i386/include/mptable.h +++ b/sys/i386/include/mptable.h @@ -1900,11 +1900,6 @@ struct simplelock mcount_lock; struct simplelock com_lock; #endif /* USE_COMLOCK */ -#ifdef USE_CLOCKLOCK -/* lock regions around the clock hardware */ -struct simplelock clock_lock; -#endif /* USE_CLOCKLOCK */ - /* lock around the MP rendezvous */ static struct simplelock smp_rv_lock; @@ -1930,9 +1925,6 @@ init_locks(void) #ifdef USE_COMLOCK s_lock_init((struct simplelock*)&com_lock); #endif /* USE_COMLOCK */ -#ifdef USE_CLOCKLOCK - s_lock_init((struct simplelock*)&clock_lock); -#endif /* USE_CLOCKLOCK */ s_lock_init(&ap_boot_lock); } @@ -2425,7 +2417,6 @@ ap_init(void) * something unique to lock with. */ PCPU_SET(curproc,idleproc); - PCPU_SET(prevproc,idleproc); microuptime(&switchtime); switchticks = ticks; diff --git a/sys/i386/include/mutex.h b/sys/i386/include/mutex.h index ca518d9..881cbfa 100644 --- a/sys/i386/include/mutex.h +++ b/sys/i386/include/mutex.h @@ -146,6 +146,7 @@ void _mtx_exit(struct mtx *mtxp, int type, const char *file, int line); /* Global locks */ extern struct mtx sched_lock; extern struct mtx Giant; +extern struct mtx clock_lock; /* * Used to replace return with an exit Giant and return. diff --git a/sys/i386/include/pcpu.h b/sys/i386/include/pcpu.h index ace3602..2788499 100644 --- a/sys/i386/include/pcpu.h +++ b/sys/i386/include/pcpu.h @@ -55,7 +55,6 @@ struct globaldata { struct privatespace *gd_prvspace; /* self-reference */ struct proc *gd_curproc; - struct proc *gd_prevproc; struct proc *gd_npxproc; struct pcb *gd_curpcb; struct proc *gd_idleproc; diff --git a/sys/i386/include/smptests.h b/sys/i386/include/smptests.h index 304e990..239f849 100644 --- a/sys/i386/include/smptests.h +++ b/sys/i386/include/smptests.h @@ -87,14 +87,12 @@ * protected via cli/sti in the UP kernel. * * COMLOCK protects the sio/cy drivers. - * CLOCKLOCK protects clock hardware and data * known to be incomplete: * joystick lkm * ? */ #ifdef PUSHDOWN_LEVEL_1 #define USE_COMLOCK -#define USE_CLOCKLOCK #endif diff --git a/sys/i386/isa/apic_vector.s b/sys/i386/isa/apic_vector.s index 11d9797..1f80224 100644 --- a/sys/i386/isa/apic_vector.s +++ b/sys/i386/isa/apic_vector.s @@ -15,6 +15,23 @@ /* make an index into the IO APIC from the IRQ# */ #define REDTBL_IDX(irq_num) (0x10 + ((irq_num) * 2)) +/* + * + */ +#define PUSH_FRAME \ + pushl $0 ; /* dummy error code */ \ + pushl $0 ; /* dummy trap type */ \ + pushal ; \ + pushl %ds ; /* save data and extra segments ... */ \ + pushl %es ; \ + pushl %fs + +#define POP_FRAME \ + popl %fs ; \ + popl %es ; \ + popl %ds ; \ + popal ; \ + addl $4+4,%esp /* * Macros for interrupt entry, call to handler, and exit. @@ -24,18 +41,14 @@ .text ; \ SUPERALIGN_TEXT ; \ IDTVEC(vec_name) ; \ - pushl %eax ; /* save only call-used registers */ \ - pushl %ecx ; \ - pushl %edx ; \ - pushl %ds ; \ - MAYBE_PUSHL_ES ; \ - pushl %fs ; \ + PUSH_FRAME ; \ movl $KDSEL,%eax ; \ mov %ax,%ds ; \ - MAYBE_MOVW_AX_ES ; \ + mov %ax,%es ; \ movl $KPSEL,%eax ; \ mov %ax,%fs ; \ - FAKE_MCOUNT((5+ACTUALLY_PUSHED)*4(%esp)) ; \ + FAKE_MCOUNT(13*4(%esp)) ; \ + incb _intr_nesting_level ; \ pushl _intr_unit + (irq_num) * 4 ; \ call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \ addl $4, %esp ; \ @@ -46,31 +59,7 @@ IDTVEC(vec_name) ; \ lock ; \ incl (%eax) ; \ MEXITCOUNT ; \ - popl %fs ; \ - MAYBE_POPL_ES ; \ - popl %ds ; \ - popl %edx ; \ - popl %ecx ; \ - popl %eax ; \ - iret - -/* - * - */ -#define PUSH_FRAME \ - pushl $0 ; /* dummy error code */ \ - pushl $0 ; /* dummy trap type */ \ - pushal ; \ - pushl %ds ; /* save data and extra segments ... */ \ - pushl %es ; \ - pushl %fs - -#define POP_FRAME \ - popl %fs ; \ - popl %es ; \ - popl %ds ; \ - popal ; \ - addl $4+4,%esp + jmp doreti_next #define IOAPICADDR(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 8 #define REDIRIDX(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 12 diff --git a/sys/i386/isa/atpic_vector.s b/sys/i386/isa/atpic_vector.s index 0a89492..7644c03 100644 --- a/sys/i386/isa/atpic_vector.s +++ b/sys/i386/isa/atpic_vector.s @@ -49,17 +49,18 @@ .text ; \ SUPERALIGN_TEXT ; \ IDTVEC(vec_name) ; \ - pushl %eax ; /* save only call-used registers */ \ - pushl %ecx ; \ - pushl %edx ; \ + pushl $0 ; /* dummy error code */ \ + pushl $0 ; /* dummy trap type */ \ + pushal ; \ pushl %ds ; \ + pushl %es ; \ pushl %fs ; \ - MAYBE_PUSHL_ES ; \ mov $KDSEL,%ax ; \ mov %ax,%ds ; \ + mov %ax,%es ; \ mov %ax,%fs ; \ - MAYBE_MOVW_AX_ES ; \ - FAKE_MCOUNT((4+ACTUALLY_PUSHED)*4(%esp)) ; \ + FAKE_MCOUNT((12+ACTUALLY_PUSHED)*4(%esp)) ; \ + incb _intr_nesting_level ; \ pushl _intr_unit + (irq_num) * 4 ; \ call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \ enable_icus ; /* (re)enable ASAP (helps edge trigger?) */ \ @@ -67,19 +68,8 @@ IDTVEC(vec_name) ; \ incl _cnt+V_INTR ; /* book-keeping can wait */ \ movl _intr_countp + (irq_num) * 4,%eax ; \ incl (%eax) ; \ -/* movl _cpl,%eax ; // are we unmasking pending SWIs? / \ - notl %eax ; \ - andl _spending,$SWI_MASK ; \ - jne 2f ; // yes, maybe handle them */ \ -1: ; \ MEXITCOUNT ; \ - MAYBE_POPL_ES ; \ - popl %fs ; \ - popl %ds ; \ - popl %edx ; \ - popl %ecx ; \ - popl %eax ; \ - iret ; \ + jmp doreti_next #if 0 ; \ @@ -141,7 +131,7 @@ IDTVEC(vec_name) ; \ movb %al,_imen + IRQ_BYTE(irq_num) ; \ outb %al,$icu+ICU_IMR_OFFSET ; \ enable_icus ; \ - incb _intr_nesting_level ; /* XXX do we need this? */ \ + incb _intr_nesting_level ; \ __CONCAT(Xresume,irq_num): ; \ FAKE_MCOUNT(13*4(%esp)) ; /* XXX late to avoid double count */ \ pushl $irq_num; /* pass the IRQ */ \ @@ -153,26 +143,6 @@ __CONCAT(Xresume,irq_num): ; \ /* _doreti, but it's probably better to use less cache. */ \ jmp doreti_next /* and catch up inside doreti */ -/* - * Reenable the interrupt mask after completing an interrupt. Called - * from ithd_loop. There are two separate functions, one for each - * ICU. - */ - .globl setimask0, setimask1 -setimask0: - cli - movb _imen,%al - outb %al,$IO_ICU1 + ICU_IMR_OFFSET - sti - ret - -setimask1: - cli - movb _imen + 1,%al - outb %al,$IO_ICU2 + ICU_IMR_OFFSET - sti - ret - MCOUNT_LABEL(bintr) FAST_INTR(0,fastintr0, ENABLE_ICU1) FAST_INTR(1,fastintr1, ENABLE_ICU1) diff --git a/sys/i386/isa/clock.c b/sys/i386/isa/clock.c index 0e630d9..a164288 100644 --- a/sys/i386/isa/clock.c +++ b/sys/i386/isa/clock.c @@ -72,6 +72,7 @@ #include <machine/ipl.h> #include <machine/limits.h> #include <machine/md_var.h> +#include <machine/mutex.h> #include <machine/psl.h> #ifdef APIC_IO #include <machine/segments.h> @@ -139,6 +140,7 @@ int timer0_max_count; u_int tsc_freq; int tsc_is_broken; int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */ +struct mtx clock_lock; static int beeping = 0; static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31}; @@ -198,12 +200,9 @@ SYSCTL_OPAQUE(_debug, OID_AUTO, i8254_timecounter, CTLFLAG_RD, static void clkintr(struct clockframe frame) { - int intrsave; if (timecounter->tc_get_timecount == i8254_get_timecount) { - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); if (i8254_ticked) i8254_ticked = 0; else { @@ -211,8 +210,7 @@ clkintr(struct clockframe frame) i8254_lastcount = 0; } clkintr_pending = 0; - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); } timer_func(&frame); switch (timer0_state) { @@ -231,17 +229,14 @@ clkintr(struct clockframe frame) break; case ACQUIRE_PENDING: - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); i8254_offset = i8254_get_timecount(NULL); i8254_lastcount = 0; timer0_max_count = TIMER_DIV(new_rate); outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); timer_func = new_function; timer0_state = ACQUIRED; setdelayed(); @@ -250,9 +245,7 @@ clkintr(struct clockframe frame) case RELEASE_PENDING: if ((timer0_prescaler_count += timer0_max_count) >= hardclock_max_count) { - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); i8254_offset = i8254_get_timecount(NULL); i8254_lastcount = 0; timer0_max_count = hardclock_max_count; @@ -260,8 +253,7 @@ clkintr(struct clockframe frame) TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); timer0_prescaler_count = 0; timer_func = hardclock; timer0_state = RELEASED; @@ -408,11 +400,9 @@ DB_SHOW_COMMAND(rtc, rtc) static int getit(void) { - int high, low, intrsave; + int high, low; - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); /* Select timer0 and latch counter value. */ outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); @@ -420,8 +410,7 @@ getit(void) low = inb(TIMER_CNTR0); high = inb(TIMER_CNTR0); - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); return ((high << 8) | low); } @@ -527,7 +516,6 @@ sysbeepstop(void *chan) int sysbeep(int pitch, int period) { - int intrsave; int x = splclock(); if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT)) @@ -536,13 +524,10 @@ sysbeep(int pitch, int period) splx(x); return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */ } - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); outb(TIMER_CNTR2, pitch); outb(TIMER_CNTR2, (pitch>>8)); - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); if (!beeping) { /* enable counter2 output to speaker */ outb(IO_PPI, inb(IO_PPI) | 3); @@ -691,12 +676,9 @@ fail: static void set_timer_freq(u_int freq, int intr_freq) { - int intrsave; int new_timer0_max_count; - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); timer_freq = freq; new_timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq); if (new_timer0_max_count != timer0_max_count) { @@ -705,8 +687,7 @@ set_timer_freq(u_int freq, int intr_freq) outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); } - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); } /* @@ -720,16 +701,12 @@ set_timer_freq(u_int freq, int intr_freq) void i8254_restore(void) { - int intrsave; - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); } /* @@ -989,8 +966,8 @@ cpu_initclocks() { int diag; #ifdef APIC_IO - int apic_8254_trial, num_8254_ticks; - struct intrec *clkdesc, *rtcdesc; + int apic_8254_trial; + struct intrec *clkdesc; #endif /* APIC_IO */ if (statclock_disable) { @@ -1023,6 +1000,11 @@ cpu_initclocks() } else panic("APIC_IO: Cannot route 8254 interrupt to CPU"); } + + clkdesc = inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, + NULL, PI_REALTIME, INTR_FAST); + INTREN(1 << apic_8254_intr); + #else /* APIC_IO */ /* @@ -1030,9 +1012,8 @@ cpu_initclocks() * couldn't find anything suitable in the BSD/OS code (grog, * 19 July 2000). */ - /* Setup the PIC clk handler. The APIC handler is setup later */ inthand_add("clk", 0, (driver_intr_t *)clkintr, NULL, PI_REALTIME, - INTR_EXCL); + INTR_FAST); INTREN(IRQ0); #endif /* APIC_IO */ @@ -1042,18 +1023,8 @@ cpu_initclocks() writertc(RTC_STATUSB, RTCSB_24HR); /* Don't bother enabling the statistics clock. */ - if (statclock_disable) { -#ifdef APIC_IO - /* - * XXX - if statclock is disabled, don't attempt the APIC - * trial. Not sure this is sane for APIC_IO. - */ - inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, - NULL, PI_REALTIME, INTR_EXCL); - INTREN(1 << apic_8254_intr); -#endif /* APIC_IO */ + if (statclock_disable) return; - } diag = rtcin(RTC_DIAG); if (diag != 0) printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS); @@ -1061,44 +1032,34 @@ cpu_initclocks() #ifdef APIC_IO if (isa_apic_irq(8) != 8) panic("APIC RTC != 8"); +#endif /* APIC_IO */ - if (apic_8254_trial) { - /* - * XXX - We use fast interrupts for clk and rtc long enough to - * perform the APIC probe and then revert to exclusive - * interrupts. - */ - clkdesc = inthand_add("clk", apic_8254_intr, - (driver_intr_t *)clkintr, NULL, PI_REALTIME, INTR_FAST); - INTREN(1 << apic_8254_intr); + inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, PI_REALTIME, + INTR_FAST); - rtcdesc = inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, - PI_REALTIME, INTR_FAST); /* XXX */ - INTREN(APIC_IRQ8); - writertc(RTC_STATUSB, rtc_statusb); +#ifdef APIC_IO + INTREN(APIC_IRQ8); +#else + INTREN(IRQ8); +#endif /* APIC_IO */ + + writertc(RTC_STATUSB, rtc_statusb); + +#ifdef APIC_IO + if (apic_8254_trial) { printf("APIC_IO: Testing 8254 interrupt delivery\n"); while (read_intr_count(8) < 6) ; /* nothing */ - num_8254_ticks = read_intr_count(apic_8254_intr); - - /* disable and remove our fake handlers */ - INTRDIS(1 << apic_8254_intr); - inthand_remove(clkdesc); - - writertc(RTC_STATUSA, rtc_statusa); - writertc(RTC_STATUSB, RTCSB_24HR); - - INTRDIS(APIC_IRQ8); - inthand_remove(rtcdesc); - - if (num_8254_ticks < 3) { + if (read_intr_count(apic_8254_intr) < 3) { /* * The MP table is broken. * The 8254 was not connected to the specified pin * on the IO APIC. * Workaround: Limited variant of mixed mode. */ + INTRDIS(1 << apic_8254_intr); + inthand_remove(clkdesc); printf("APIC_IO: Broken MP table detected: " "8254 is not connected to " "IOAPIC #%d intpin %d\n", @@ -1117,27 +1078,13 @@ cpu_initclocks() } apic_8254_intr = apic_irq(0, 0); setup_8254_mixed_mode(); + inthand_add("clk", apic_8254_intr, + (driver_intr_t *)clkintr, NULL, + PI_REALTIME, INTR_FAST); + INTREN(1 << apic_8254_intr); } } - - /* Finally, setup the real clock handlers */ - inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, NULL, - PI_REALTIME, INTR_EXCL); - INTREN(1 << apic_8254_intr); -#endif - - inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, PI_REALTIME, - INTR_EXCL); -#ifdef APIC_IO - INTREN(APIC_IRQ8); -#else - INTREN(IRQ8); -#endif - - writertc(RTC_STATUSB, rtc_statusb); - -#ifdef APIC_IO if (apic_int_type(0, 0) != 3 || int_to_apicintpin[apic_8254_intr].ioapic != 0 || int_to_apicintpin[apic_8254_intr].int_pin != 0) @@ -1242,12 +1189,11 @@ static unsigned i8254_get_timecount(struct timecounter *tc) { u_int count; - int intrsave; u_int high, low; + u_int eflags; - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + eflags = read_eflags(); + mtx_enter(&clock_lock, MTX_SPIN); /* Select timer0 and latch counter value. */ outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); @@ -1257,7 +1203,7 @@ i8254_get_timecount(struct timecounter *tc) count = timer0_max_count - ((high << 8) | low); if (count < i8254_lastcount || (!i8254_ticked && (clkintr_pending || - ((count < 20 || (!(intrsave & PSL_I) && count < timer0_max_count / 2u)) && + ((count < 20 || (!(eflags & PSL_I) && count < timer0_max_count / 2u)) && #ifdef APIC_IO #define lapic_irr1 ((volatile u_int *)&lapic)[0x210 / 4] /* XXX XXX */ /* XXX this assumes that apic_8254_intr is < 24. */ @@ -1271,8 +1217,7 @@ i8254_get_timecount(struct timecounter *tc) } i8254_lastcount = count; count += i8254_offset; - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); return (count); } diff --git a/sys/i386/isa/icu_vector.s b/sys/i386/isa/icu_vector.s index 0a89492..7644c03 100644 --- a/sys/i386/isa/icu_vector.s +++ b/sys/i386/isa/icu_vector.s @@ -49,17 +49,18 @@ .text ; \ SUPERALIGN_TEXT ; \ IDTVEC(vec_name) ; \ - pushl %eax ; /* save only call-used registers */ \ - pushl %ecx ; \ - pushl %edx ; \ + pushl $0 ; /* dummy error code */ \ + pushl $0 ; /* dummy trap type */ \ + pushal ; \ pushl %ds ; \ + pushl %es ; \ pushl %fs ; \ - MAYBE_PUSHL_ES ; \ mov $KDSEL,%ax ; \ mov %ax,%ds ; \ + mov %ax,%es ; \ mov %ax,%fs ; \ - MAYBE_MOVW_AX_ES ; \ - FAKE_MCOUNT((4+ACTUALLY_PUSHED)*4(%esp)) ; \ + FAKE_MCOUNT((12+ACTUALLY_PUSHED)*4(%esp)) ; \ + incb _intr_nesting_level ; \ pushl _intr_unit + (irq_num) * 4 ; \ call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \ enable_icus ; /* (re)enable ASAP (helps edge trigger?) */ \ @@ -67,19 +68,8 @@ IDTVEC(vec_name) ; \ incl _cnt+V_INTR ; /* book-keeping can wait */ \ movl _intr_countp + (irq_num) * 4,%eax ; \ incl (%eax) ; \ -/* movl _cpl,%eax ; // are we unmasking pending SWIs? / \ - notl %eax ; \ - andl _spending,$SWI_MASK ; \ - jne 2f ; // yes, maybe handle them */ \ -1: ; \ MEXITCOUNT ; \ - MAYBE_POPL_ES ; \ - popl %fs ; \ - popl %ds ; \ - popl %edx ; \ - popl %ecx ; \ - popl %eax ; \ - iret ; \ + jmp doreti_next #if 0 ; \ @@ -141,7 +131,7 @@ IDTVEC(vec_name) ; \ movb %al,_imen + IRQ_BYTE(irq_num) ; \ outb %al,$icu+ICU_IMR_OFFSET ; \ enable_icus ; \ - incb _intr_nesting_level ; /* XXX do we need this? */ \ + incb _intr_nesting_level ; \ __CONCAT(Xresume,irq_num): ; \ FAKE_MCOUNT(13*4(%esp)) ; /* XXX late to avoid double count */ \ pushl $irq_num; /* pass the IRQ */ \ @@ -153,26 +143,6 @@ __CONCAT(Xresume,irq_num): ; \ /* _doreti, but it's probably better to use less cache. */ \ jmp doreti_next /* and catch up inside doreti */ -/* - * Reenable the interrupt mask after completing an interrupt. Called - * from ithd_loop. There are two separate functions, one for each - * ICU. - */ - .globl setimask0, setimask1 -setimask0: - cli - movb _imen,%al - outb %al,$IO_ICU1 + ICU_IMR_OFFSET - sti - ret - -setimask1: - cli - movb _imen + 1,%al - outb %al,$IO_ICU2 + ICU_IMR_OFFSET - sti - ret - MCOUNT_LABEL(bintr) FAST_INTR(0,fastintr0, ENABLE_ICU1) FAST_INTR(1,fastintr1, ENABLE_ICU1) diff --git a/sys/isa/atrtc.c b/sys/isa/atrtc.c index 0e630d9..a164288 100644 --- a/sys/isa/atrtc.c +++ b/sys/isa/atrtc.c @@ -72,6 +72,7 @@ #include <machine/ipl.h> #include <machine/limits.h> #include <machine/md_var.h> +#include <machine/mutex.h> #include <machine/psl.h> #ifdef APIC_IO #include <machine/segments.h> @@ -139,6 +140,7 @@ int timer0_max_count; u_int tsc_freq; int tsc_is_broken; int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */ +struct mtx clock_lock; static int beeping = 0; static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31}; @@ -198,12 +200,9 @@ SYSCTL_OPAQUE(_debug, OID_AUTO, i8254_timecounter, CTLFLAG_RD, static void clkintr(struct clockframe frame) { - int intrsave; if (timecounter->tc_get_timecount == i8254_get_timecount) { - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); if (i8254_ticked) i8254_ticked = 0; else { @@ -211,8 +210,7 @@ clkintr(struct clockframe frame) i8254_lastcount = 0; } clkintr_pending = 0; - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); } timer_func(&frame); switch (timer0_state) { @@ -231,17 +229,14 @@ clkintr(struct clockframe frame) break; case ACQUIRE_PENDING: - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); i8254_offset = i8254_get_timecount(NULL); i8254_lastcount = 0; timer0_max_count = TIMER_DIV(new_rate); outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); timer_func = new_function; timer0_state = ACQUIRED; setdelayed(); @@ -250,9 +245,7 @@ clkintr(struct clockframe frame) case RELEASE_PENDING: if ((timer0_prescaler_count += timer0_max_count) >= hardclock_max_count) { - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); i8254_offset = i8254_get_timecount(NULL); i8254_lastcount = 0; timer0_max_count = hardclock_max_count; @@ -260,8 +253,7 @@ clkintr(struct clockframe frame) TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); timer0_prescaler_count = 0; timer_func = hardclock; timer0_state = RELEASED; @@ -408,11 +400,9 @@ DB_SHOW_COMMAND(rtc, rtc) static int getit(void) { - int high, low, intrsave; + int high, low; - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); /* Select timer0 and latch counter value. */ outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); @@ -420,8 +410,7 @@ getit(void) low = inb(TIMER_CNTR0); high = inb(TIMER_CNTR0); - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); return ((high << 8) | low); } @@ -527,7 +516,6 @@ sysbeepstop(void *chan) int sysbeep(int pitch, int period) { - int intrsave; int x = splclock(); if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT)) @@ -536,13 +524,10 @@ sysbeep(int pitch, int period) splx(x); return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */ } - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); outb(TIMER_CNTR2, pitch); outb(TIMER_CNTR2, (pitch>>8)); - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); if (!beeping) { /* enable counter2 output to speaker */ outb(IO_PPI, inb(IO_PPI) | 3); @@ -691,12 +676,9 @@ fail: static void set_timer_freq(u_int freq, int intr_freq) { - int intrsave; int new_timer0_max_count; - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); timer_freq = freq; new_timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq); if (new_timer0_max_count != timer0_max_count) { @@ -705,8 +687,7 @@ set_timer_freq(u_int freq, int intr_freq) outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); } - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); } /* @@ -720,16 +701,12 @@ set_timer_freq(u_int freq, int intr_freq) void i8254_restore(void) { - int intrsave; - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + mtx_enter(&clock_lock, MTX_SPIN); outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); } /* @@ -989,8 +966,8 @@ cpu_initclocks() { int diag; #ifdef APIC_IO - int apic_8254_trial, num_8254_ticks; - struct intrec *clkdesc, *rtcdesc; + int apic_8254_trial; + struct intrec *clkdesc; #endif /* APIC_IO */ if (statclock_disable) { @@ -1023,6 +1000,11 @@ cpu_initclocks() } else panic("APIC_IO: Cannot route 8254 interrupt to CPU"); } + + clkdesc = inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, + NULL, PI_REALTIME, INTR_FAST); + INTREN(1 << apic_8254_intr); + #else /* APIC_IO */ /* @@ -1030,9 +1012,8 @@ cpu_initclocks() * couldn't find anything suitable in the BSD/OS code (grog, * 19 July 2000). */ - /* Setup the PIC clk handler. The APIC handler is setup later */ inthand_add("clk", 0, (driver_intr_t *)clkintr, NULL, PI_REALTIME, - INTR_EXCL); + INTR_FAST); INTREN(IRQ0); #endif /* APIC_IO */ @@ -1042,18 +1023,8 @@ cpu_initclocks() writertc(RTC_STATUSB, RTCSB_24HR); /* Don't bother enabling the statistics clock. */ - if (statclock_disable) { -#ifdef APIC_IO - /* - * XXX - if statclock is disabled, don't attempt the APIC - * trial. Not sure this is sane for APIC_IO. - */ - inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, - NULL, PI_REALTIME, INTR_EXCL); - INTREN(1 << apic_8254_intr); -#endif /* APIC_IO */ + if (statclock_disable) return; - } diag = rtcin(RTC_DIAG); if (diag != 0) printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS); @@ -1061,44 +1032,34 @@ cpu_initclocks() #ifdef APIC_IO if (isa_apic_irq(8) != 8) panic("APIC RTC != 8"); +#endif /* APIC_IO */ - if (apic_8254_trial) { - /* - * XXX - We use fast interrupts for clk and rtc long enough to - * perform the APIC probe and then revert to exclusive - * interrupts. - */ - clkdesc = inthand_add("clk", apic_8254_intr, - (driver_intr_t *)clkintr, NULL, PI_REALTIME, INTR_FAST); - INTREN(1 << apic_8254_intr); + inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, PI_REALTIME, + INTR_FAST); - rtcdesc = inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, - PI_REALTIME, INTR_FAST); /* XXX */ - INTREN(APIC_IRQ8); - writertc(RTC_STATUSB, rtc_statusb); +#ifdef APIC_IO + INTREN(APIC_IRQ8); +#else + INTREN(IRQ8); +#endif /* APIC_IO */ + + writertc(RTC_STATUSB, rtc_statusb); + +#ifdef APIC_IO + if (apic_8254_trial) { printf("APIC_IO: Testing 8254 interrupt delivery\n"); while (read_intr_count(8) < 6) ; /* nothing */ - num_8254_ticks = read_intr_count(apic_8254_intr); - - /* disable and remove our fake handlers */ - INTRDIS(1 << apic_8254_intr); - inthand_remove(clkdesc); - - writertc(RTC_STATUSA, rtc_statusa); - writertc(RTC_STATUSB, RTCSB_24HR); - - INTRDIS(APIC_IRQ8); - inthand_remove(rtcdesc); - - if (num_8254_ticks < 3) { + if (read_intr_count(apic_8254_intr) < 3) { /* * The MP table is broken. * The 8254 was not connected to the specified pin * on the IO APIC. * Workaround: Limited variant of mixed mode. */ + INTRDIS(1 << apic_8254_intr); + inthand_remove(clkdesc); printf("APIC_IO: Broken MP table detected: " "8254 is not connected to " "IOAPIC #%d intpin %d\n", @@ -1117,27 +1078,13 @@ cpu_initclocks() } apic_8254_intr = apic_irq(0, 0); setup_8254_mixed_mode(); + inthand_add("clk", apic_8254_intr, + (driver_intr_t *)clkintr, NULL, + PI_REALTIME, INTR_FAST); + INTREN(1 << apic_8254_intr); } } - - /* Finally, setup the real clock handlers */ - inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, NULL, - PI_REALTIME, INTR_EXCL); - INTREN(1 << apic_8254_intr); -#endif - - inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, PI_REALTIME, - INTR_EXCL); -#ifdef APIC_IO - INTREN(APIC_IRQ8); -#else - INTREN(IRQ8); -#endif - - writertc(RTC_STATUSB, rtc_statusb); - -#ifdef APIC_IO if (apic_int_type(0, 0) != 3 || int_to_apicintpin[apic_8254_intr].ioapic != 0 || int_to_apicintpin[apic_8254_intr].int_pin != 0) @@ -1242,12 +1189,11 @@ static unsigned i8254_get_timecount(struct timecounter *tc) { u_int count; - int intrsave; u_int high, low; + u_int eflags; - intrsave = save_intr(); - disable_intr(); - CLOCK_LOCK(); + eflags = read_eflags(); + mtx_enter(&clock_lock, MTX_SPIN); /* Select timer0 and latch counter value. */ outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); @@ -1257,7 +1203,7 @@ i8254_get_timecount(struct timecounter *tc) count = timer0_max_count - ((high << 8) | low); if (count < i8254_lastcount || (!i8254_ticked && (clkintr_pending || - ((count < 20 || (!(intrsave & PSL_I) && count < timer0_max_count / 2u)) && + ((count < 20 || (!(eflags & PSL_I) && count < timer0_max_count / 2u)) && #ifdef APIC_IO #define lapic_irr1 ((volatile u_int *)&lapic)[0x210 / 4] /* XXX XXX */ /* XXX this assumes that apic_8254_intr is < 24. */ @@ -1271,8 +1217,7 @@ i8254_get_timecount(struct timecounter *tc) } i8254_lastcount = count; count += i8254_offset; - CLOCK_UNLOCK(); - restore_intr(intrsave); + mtx_exit(&clock_lock, MTX_SPIN); return (count); } diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c index bc6bf06..6b3153f 100644 --- a/sys/kern/kern_clock.c +++ b/sys/kern/kern_clock.c @@ -58,7 +58,9 @@ #include <sys/sysctl.h> #include <machine/cpu.h> +#include <machine/ipl.h> #include <machine/limits.h> +#include <machine/mutex.h> #include <machine/smp.h> #ifdef GPROF @@ -161,11 +163,15 @@ hardclock(frame) pstats = p->p_stats; if (CLKF_USERMODE(frame) && timevalisset(&pstats->p_timer[ITIMER_VIRTUAL].it_value) && - itimerdecr(&pstats->p_timer[ITIMER_VIRTUAL], tick) == 0) - psignal(p, SIGVTALRM); + itimerdecr(&pstats->p_timer[ITIMER_VIRTUAL], tick) == 0) { + p->p_flag |= P_ALRMPEND; + aston(); + } if (timevalisset(&pstats->p_timer[ITIMER_PROF].it_value) && - itimerdecr(&pstats->p_timer[ITIMER_PROF], tick) == 0) - psignal(p, SIGPROF); + itimerdecr(&pstats->p_timer[ITIMER_PROF], tick) == 0) { + p->p_flag |= P_PROFPEND; + aston(); + } } #if defined(SMP) && defined(BETTER_CLOCK) @@ -186,15 +192,7 @@ hardclock(frame) * relatively high clock interrupt priority any longer than necessary. */ if (TAILQ_FIRST(&callwheel[ticks & callwheelmask]) != NULL) { - if (CLKF_BASEPRI(frame)) { - /* - * Save the overhead of a software interrupt; - * it will happen as soon as we return, so do it now. - */ - (void)splsoftclock(); - softclock(); - } else - setsoftclock(); + setsoftclock(); } else if (softticks + 1 == ticks) ++softticks; } @@ -321,20 +319,24 @@ statclock(frame) struct rusage *ru; struct vmspace *vm; + mtx_enter(&sched_lock, MTX_SPIN); + if (CLKF_USERMODE(frame)) { /* * Came from user mode; CPU was in user state. * If this process is being profiled, record the tick. */ - p = prevproc; + p = curproc; if (p->p_flag & P_PROFIL) addupc_intr(p, CLKF_PC(frame), 1); #if defined(SMP) && defined(BETTER_CLOCK) if (stathz != 0) forward_statclock(pscnt); #endif - if (--pscnt > 0) + if (--pscnt > 0) { + mtx_exit(&sched_lock, MTX_SPIN); return; + } /* * Charge the time as appropriate. */ @@ -361,8 +363,10 @@ statclock(frame) if (stathz != 0) forward_statclock(pscnt); #endif - if (--pscnt > 0) + if (--pscnt > 0) { + mtx_exit(&sched_lock, MTX_SPIN); return; + } /* * Came from kernel mode, so we were: * - handling an interrupt, @@ -375,8 +379,8 @@ statclock(frame) * so that we know how much of its real time was spent * in ``non-process'' (i.e., interrupt) work. */ - p = prevproc; - if (p->p_ithd) { + p = curproc; + if ((p->p_ithd != NULL) || CLKF_INTR(frame)) { p->p_iticks++; cp_time[CP_INTR]++; } else { @@ -402,6 +406,8 @@ statclock(frame) if (ru->ru_maxrss < rss) ru->ru_maxrss = rss; } + + mtx_exit(&sched_lock, MTX_SPIN); } /* diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index eeddeb6..3031334 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -289,6 +289,7 @@ schedcpu(arg) if (p->p_stat == SWAIT) continue; */ + mtx_enter(&sched_lock, MTX_SPIN); p->p_swtime++; if (p->p_stat == SSLEEP || p->p_stat == SSTOP) p->p_slptime++; @@ -297,13 +298,15 @@ schedcpu(arg) * If the process has slept the entire second, * stop recalculating its priority until it wakes up. */ - if (p->p_slptime > 1) + if (p->p_slptime > 1) { + mtx_exit(&sched_lock, MTX_SPIN); continue; + } + /* * prevent state changes and protect run queue */ s = splhigh(); - mtx_enter(&sched_lock, MTX_SPIN); /* * p_pctcpu is only for ps. @@ -451,9 +454,6 @@ msleep(ident, mtx, priority, wmesg, timo) * in case this is the idle process and already asleep. */ mtx_exit(&sched_lock, MTX_SPIN); -#if 0 - splx(safepri); -#endif splx(s); return (0); } @@ -994,7 +994,6 @@ setrunnable(p) p->p_stat = SRUN; if (p->p_flag & P_INMEM) setrunqueue(p); - mtx_exit(&sched_lock, MTX_SPIN); splx(s); if (p->p_slptime > 1) updatepri(p); @@ -1005,6 +1004,7 @@ setrunnable(p) } else maybe_resched(p); + mtx_exit(&sched_lock, MTX_SPIN); } /* @@ -1018,6 +1018,7 @@ resetpriority(p) { register unsigned int newpriority; + mtx_enter(&sched_lock, MTX_SPIN); if (p->p_rtprio.type == RTP_PRIO_NORMAL) { newpriority = PUSER + p->p_estcpu / INVERSE_ESTCPU_WEIGHT + NICE_WEIGHT * (p->p_nice - PRIO_MIN); @@ -1025,6 +1026,7 @@ resetpriority(p) p->p_usrpri = newpriority; } maybe_resched(p); + mtx_exit(&sched_lock, MTX_SPIN); } /* ARGSUSED */ diff --git a/sys/kern/subr_smp.c b/sys/kern/subr_smp.c index ea9aee8..5ef95b3 100644 --- a/sys/kern/subr_smp.c +++ b/sys/kern/subr_smp.c @@ -1900,11 +1900,6 @@ struct simplelock mcount_lock; struct simplelock com_lock; #endif /* USE_COMLOCK */ -#ifdef USE_CLOCKLOCK -/* lock regions around the clock hardware */ -struct simplelock clock_lock; -#endif /* USE_CLOCKLOCK */ - /* lock around the MP rendezvous */ static struct simplelock smp_rv_lock; @@ -1930,9 +1925,6 @@ init_locks(void) #ifdef USE_COMLOCK s_lock_init((struct simplelock*)&com_lock); #endif /* USE_COMLOCK */ -#ifdef USE_CLOCKLOCK - s_lock_init((struct simplelock*)&clock_lock); -#endif /* USE_CLOCKLOCK */ s_lock_init(&ap_boot_lock); } @@ -2425,7 +2417,6 @@ ap_init(void) * something unique to lock with. */ PCPU_SET(curproc,idleproc); - PCPU_SET(prevproc,idleproc); microuptime(&switchtime); switchticks = ticks; diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c index 1cbfcfa..b9ebb60 100644 --- a/sys/kern/subr_trap.c +++ b/sys/kern/subr_trap.c @@ -1244,6 +1244,18 @@ ast(frame) addupc_task(p, p->p_stats->p_prof.pr_addr, p->p_stats->p_prof.pr_ticks); } + if (p->p_flag & P_ALRMPEND) { + if (!mtx_owned(&Giant)) + mtx_enter(&Giant, MTX_DEF); + p->p_flag &= ~P_ALRMPEND; + psignal(p, SIGVTALRM); + } + if (p->p_flag & P_PROFPEND) { + if (!mtx_owned(&Giant)) + mtx_enter(&Giant, MTX_DEF); + p->p_flag &= ~P_PROFPEND; + psignal(p, SIGPROF); + } if (userret(p, &frame, sticks, mtx_owned(&Giant)) != 0) mtx_exit(&Giant, MTX_DEF); } diff --git a/sys/powerpc/include/globals.h b/sys/powerpc/include/globals.h index 303efdf..f85a67c 100644 --- a/sys/powerpc/include/globals.h +++ b/sys/powerpc/include/globals.h @@ -56,7 +56,6 @@ register struct globaldata *globalp __asm__("$8"); #define switchtime PCPU_GET(switchtime) #define switchticks PCPU_GET(switchticks) #define cpuid PCPU_GET(cpuno) -#define prevproc PCPU_GET(curproc) /* XXX - until ithreads */ #endif /* _KERNEL */ diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 1f75150..3a14e34 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -273,6 +273,7 @@ struct proc { #define P_ADVLOCK 0x00001 /* Process may hold a POSIX advisory lock. */ #define P_CONTROLT 0x00002 /* Has a controlling terminal. */ #define P_INMEM 0x00004 /* Loaded into memory. */ +#define P_NOLOAD 0x00008 /* Ignore during load avg calculations. */ #define P_PPWAIT 0x00010 /* Parent is waiting for child to exec/exit. */ #define P_PROFIL 0x00020 /* Has started profiling. */ #define P_SELECT 0x00040 /* Selecting; wakeup/waiting danger. */ @@ -284,7 +285,8 @@ struct proc { #define P_WAITED 0x01000 /* Debugging process has waited for child. */ #define P_WEXIT 0x02000 /* Working on exiting. */ #define P_EXEC 0x04000 /* Process called exec. */ -#define P_NOLOAD 0x08000 /* Ignore during load avg calculations. */ +#define P_ALRMPEND 0x08000 /* Pending SIGVTALRM needs to be posted. */ +#define P_PROFPEND 0x08000 /* Pending SIGPROF needs to be posted. */ /* Should probably be changed into a hold count. */ /* was P_NOSWAP 0x08000 was: Do not swap upages; p->p_hold */ |