From owner-p4-projects@FreeBSD.ORG Sun Dec 12 23:41:30 2004 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id D29CC16A4D0; Sun, 12 Dec 2004 23:41:29 +0000 (GMT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 9371216A4CE for ; Sun, 12 Dec 2004 23:41:29 +0000 (GMT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 592CC43D55 for ; Sun, 12 Dec 2004 23:41:29 +0000 (GMT) (envelope-from peter@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id iBCNfTqb084942 for ; Sun, 12 Dec 2004 23:41:29 GMT (envelope-from peter@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id iBCNfS7d084939 for perforce@freebsd.org; Sun, 12 Dec 2004 23:41:28 GMT (envelope-from peter@freebsd.org) Date: Sun, 12 Dec 2004 23:41:28 GMT Message-Id: <200412122341.iBCNfS7d084939@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to peter@freebsd.org using -f From: Peter Wemm To: Perforce Change Reviews Subject: PERFORCE change 66921 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 12 Dec 2004 23:41:30 -0000 http://perforce.freebsd.org/chv.cgi?CH=66921 Change 66921 by peter@peter_daintree on 2004/12/12 23:41:13 integrate i386 changes into amd64 Affected files ... .. //depot/projects/hammer/sys/amd64/amd64/apic_vector.S#23 integrate .. //depot/projects/hammer/sys/amd64/amd64/identcpu.c#36 integrate .. //depot/projects/hammer/sys/amd64/amd64/legacy.c#16 integrate .. //depot/projects/hammer/sys/amd64/amd64/mp_machdep.c#78 integrate .. //depot/projects/hammer/sys/amd64/amd64/vm_machdep.c#58 integrate .. //depot/projects/hammer/sys/amd64/conf/NOTES#51 integrate .. //depot/projects/hammer/sys/amd64/include/apicvar.h#26 integrate .. //depot/projects/hammer/sys/amd64/include/smp.h#18 integrate .. //depot/projects/hammer/sys/amd64/pci/pci_cfgreg.c#16 integrate Differences ... ==== //depot/projects/hammer/sys/amd64/amd64/apic_vector.S#23 (text+ko) ==== @@ -210,31 +210,16 @@ */ .text SUPERALIGN_TEXT -IDTVEC(hardclock) +IDTVEC(ipi_intr_bitmap_handler) + PUSH_FRAME movq lapic, %rdx movl $0, LA_EOI(%rdx) /* End Of Interrupt to APIC */ - - call forwarded_hardclock - MEXITCOUNT - jmp doreti - -/* - * Forward statclock to another CPU. Pushes a clockframe and calls - * forwarded_statclock(). - */ - .text - SUPERALIGN_TEXT -IDTVEC(statclock) - PUSH_FRAME - - movq lapic, %rdx - movl $0, LA_EOI(%rdx) /* End Of Interrupt to APIC */ - + FAKE_MCOUNT(TF_RIP(%rsp)) - call forwarded_statclock + call ipi_bitmap_handler MEXITCOUNT jmp doreti ==== //depot/projects/hammer/sys/amd64/amd64/identcpu.c#36 (text+ko) ==== @@ -2,8 +2,6 @@ * Copyright (c) 1992 Terrence R. Lambert. * Copyright (c) 1982, 1987, 1990 The Regents of the University of California. * Copyright (c) 1997 KATO Takenori. - * Copyright (c) 2001 Tamotsu Hattori. - * Copyright (c) 2001 Mitsuru IWASAKI. * All rights reserved. * * This code is derived from software contributed to Berkeley by ==== //depot/projects/hammer/sys/amd64/amd64/legacy.c#16 (text+ko) ==== ==== //depot/projects/hammer/sys/amd64/amd64/mp_machdep.c#78 (text+ko) ==== @@ -131,6 +131,9 @@ } static cpu_info[MAXCPU]; static int cpu_apic_ids[MAXCPU]; +/* Holds pending bitmap based IPIs per CPU */ +static volatile u_int cpu_ipi_pending[MAXCPU]; + static u_int boot_address; static void set_logical_apic_ids(void); @@ -296,25 +299,22 @@ int i; /* Initialize the logical ID to APIC ID table. */ - for (i = 0; i < MAXCPU; i++) + for (i = 0; i < MAXCPU; i++) { cpu_apic_ids[i] = -1; + cpu_ipi_pending[i] = 0; + } /* Install an inter-CPU IPI for TLB invalidation */ setidt(IPI_INVLTLB, IDTVEC(invltlb), SDT_SYSIGT, SEL_KPL, 0); setidt(IPI_INVLPG, IDTVEC(invlpg), SDT_SYSIGT, SEL_KPL, 0); setidt(IPI_INVLRNG, IDTVEC(invlrng), SDT_SYSIGT, SEL_KPL, 0); - - /* Install an inter-CPU IPI for forwarding hardclock() */ - setidt(IPI_HARDCLOCK, IDTVEC(hardclock), SDT_SYSIGT, SEL_KPL, 0); - - /* Install an inter-CPU IPI for forwarding statclock() */ - setidt(IPI_STATCLOCK, IDTVEC(statclock), SDT_SYSIGT, SEL_KPL, 0); /* Install an inter-CPU IPI for all-CPU rendezvous */ setidt(IPI_RENDEZVOUS, IDTVEC(rendezvous), SDT_SYSIGT, SEL_KPL, 0); - /* Install an inter-CPU IPI for forcing an additional software trap */ - setidt(IPI_AST, IDTVEC(cpuast), SDT_SYSIGT, SEL_KPL, 0); + /* Install generic inter-CPU IPI handler */ + setidt(IPI_BITMAP_VECTOR, IDTVEC(ipi_intr_bitmap_handler), + SDT_SYSIGT, SEL_KPL, 0); /* Install an inter-CPU IPI for CPU stop/restart */ setidt(IPI_STOP, IDTVEC(cpustop), SDT_SYSIGT, SEL_KPL, 0); @@ -876,21 +876,7 @@ * For statclock, we send an IPI to all CPU's to have them call this * function. */ -void -forwarded_statclock(struct clockframe frame) -{ - struct thread *td; - CTR0(KTR_SMP, "forwarded_statclock"); - td = curthread; - td->td_intr_nesting_level++; - if (profprocs != 0) - profclock(&frame); - if (pscnt == psdiv) - statclock(&frame); - td->td_intr_nesting_level--; -} - void forward_statclock(void) { @@ -913,18 +899,7 @@ * state and call hardclock_process() on the CPU receiving the clock interrupt * and then just use a simple IPI to handle any ast's if needed. */ -void -forwarded_hardclock(struct clockframe frame) -{ - struct thread *td; - CTR0(KTR_SMP, "forwarded_hardclock"); - td = curthread; - td->td_intr_nesting_level++; - hardclock_process(&frame); - td->td_intr_nesting_level--; -} - void forward_hardclock(void) { @@ -940,6 +915,42 @@ ipi_selected(map, IPI_HARDCLOCK); } + +void ipi_bitmap_handler(struct clockframe frame) +{ + int cpu = PCPU_GET(cpuid); + u_int ipi_bitmap; + struct thread *td; + + ipi_bitmap = atomic_readandclear_int(&cpu_ipi_pending[cpu]); + + critical_enter(); + + /* Nothing to do for AST */ + + if (ipi_bitmap & (1 << IPI_HARDCLOCK)) { + td = curthread; + td->td_intr_nesting_level++; + hardclock_process(&frame); + td->td_intr_nesting_level--; + } + + if (ipi_bitmap & (1 << IPI_STATCLOCK)) { + CTR0(KTR_SMP, "forwarded_statclock"); + + td = curthread; + td->td_intr_nesting_level++; + if (profprocs != 0) + profclock(&frame); + if (pscnt == psdiv) + statclock(&frame); + td->td_intr_nesting_level--; + } + + critical_exit(); +} + + /* * send an IPI to a set of cpus. */ @@ -947,15 +958,36 @@ ipi_selected(u_int32_t cpus, u_int ipi) { int cpu; + u_int bitmap = 0; + u_int old_pending; + u_int new_pending; + if (IPI_IS_BITMAPED(ipi)) { + bitmap = 1 << ipi; + ipi = IPI_BITMAP_VECTOR; + } + CTR3(KTR_SMP, "%s: cpus: %x ipi: %x", __func__, cpus, ipi); while ((cpu = ffs(cpus)) != 0) { cpu--; + cpus &= ~(1 << cpu); + KASSERT(cpu_apic_ids[cpu] != -1, ("IPI to non-existent CPU %d", cpu)); + + if (bitmap) { + do { + old_pending = cpu_ipi_pending[cpu]; + new_pending = old_pending | bitmap; + } while (!atomic_cmpset_int(&cpu_ipi_pending[cpu],old_pending, new_pending)); + + if (old_pending) + continue; + } + lapic_ipi_vectored(ipi, cpu_apic_ids[cpu]); - cpus &= ~(1 << cpu); } + } /* ==== //depot/projects/hammer/sys/amd64/amd64/vm_machdep.c#58 (text+ko) ==== @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -128,6 +129,17 @@ td2->td_frame->tf_rdx = 1; /* + * If the parent process has the trap bit set (i.e. a debugger had + * single stepped the process to the system call), we need to clear + * the trap flag from the new frame unless the debugger had set PF_FORK + * on the parent. Otherwise, the child will receive a (likely + * unexpected) SIGTRAP when it executes the first instruction after + * returning to userland. + */ + if ((p1->p_pfsflags & PF_FORK) == 0) + td2->td_frame->tf_eflags &= ~PSL_T; + + /* * Set registers for trampoline to user mode. Leave space for the * return address on stack. These are the kernel mode register values. */ ==== //depot/projects/hammer/sys/amd64/conf/NOTES#51 (text+ko) ==== @@ -4,7 +4,7 @@ # This file contains machine dependent kernel configuration notes. For # machine independent notes, look in /sys/conf/NOTES. # -# (XXX from i386:NOTES,v 1.1176) +# (XXX from i386:NOTES,v 1.1177) # $FreeBSD: src/sys/amd64/conf/NOTES,v 1.20 2004/09/22 01:04:54 peter Exp $ # @@ -240,8 +240,10 @@ #XXX#device ed #XXX#device lnc -#XXX#device ath -#XXX#device ath_hal # Atheros HAL (includes binary component) +device ath +device ath_hal # Atheros HAL (includes binary component) +device ath_rate_onoe # Onoe rate control for ath driver +#device ath_rate_amrr # AMRR rate control for ath driver device wlan # 802.11 layer # ==== //depot/projects/hammer/sys/amd64/include/apicvar.h#26 (text+ko) ==== @@ -83,21 +83,54 @@ #define APIC_IO_INTS (IDT_IO_INTS + 16) #define APIC_NUM_IOINTS 192 +/* + ********************* !!! WARNING !!! ****************************** + * Each local apic has an interrupt receive fifo that is two entries deep + * for each interrupt priority class (higher 4 bits of interrupt vector). + * Once the fifo is full the APIC can no longer receive interrupts for this + * class and sending IPIs from other CPUs will be blocked. + * To avoid deadlocks there should be no more than two IPI interrupts + * pending at the same time. + * Currently this is guaranteed by dividing the IPIs in two groups that have + * each at most one IPI interrupt pending. The first group is protected by the + * smp_ipi_mtx and waits for the completion of the IPI (Only one IPI user + * at a time) The second group uses a single interrupt and a bitmap to avoid + * redundant IPI interrupts. + * + * Right now IPI_STOP used by kdb shares the interrupt priority class with + * the two IPI groups mentioned above. As such IPI_STOP may cause a deadlock. + * Eventually IPI_STOP should use NMI IPIs - this would eliminate this and + * other deadlocks caused by IPI_STOP. + */ + #define APIC_LOCAL_INTS 240 -#define APIC_TIMER_INT APIC_LOCAL_INTS -#define APIC_ERROR_INT (APIC_LOCAL_INTS + 1) -#define APIC_THERMAL_INT (APIC_LOCAL_INTS + 2) + +#if 0 +#define APIC_TIMER_INT (APIC_LOCAL_INTS + X) +#define APIC_ERROR_INT (APIC_LOCAL_INTS + X) +#define APIC_THERMAL_INT (APIC_LOCAL_INTS + X) +#endif -#define APIC_IPI_INTS (APIC_LOCAL_INTS + 3) -#define IPI_AST APIC_IPI_INTS /* Generate software trap. */ +#define APIC_IPI_INTS (APIC_LOCAL_INTS + 0) +#define IPI_RENDEZVOUS (APIC_IPI_INTS) /* Inter-CPU rendezvous. */ #define IPI_INVLTLB (APIC_IPI_INTS + 1) /* TLB Shootdown IPIs */ #define IPI_INVLPG (APIC_IPI_INTS + 2) #define IPI_INVLRNG (APIC_IPI_INTS + 3) -#define IPI_HARDCLOCK (APIC_IPI_INTS + 8) /* Inter-CPU clock handling. */ -#define IPI_STATCLOCK (APIC_IPI_INTS + 9) -#define IPI_RENDEZVOUS (APIC_IPI_INTS + 10) /* Inter-CPU rendezvous. */ -#define IPI_STOP (APIC_IPI_INTS + 11) /* Stop CPU until restarted. */ +/* Vector to handle bitmap based IPIs */ +#define IPI_BITMAP_VECTOR (APIC_IPI_INTS + 5) + +/* IPIs handled by IPI_BITMAPED_VECTOR (XXX ups is there a better place?) */ +#define IPI_AST 0 /* Generate software trap. */ +#define IPI_HARDCLOCK 1 /* Inter-CPU clock handling. */ +#define IPI_STATCLOCK 2 +#define IPI_BITMAP_LAST IPI_STATCLOCK +#define IPI_IS_BITMAPED(x) ((x) <= IPI_BITMAP_LAST) + +#define IPI_STOP (APIC_IPI_INTS + 6) /* Stop CPU until restarted. */ +/* The spurious interrupt can share the priority class with the IPIs since + * it is not a normal interrupt. (Does not use the APIC's interrupt fifo) + */ #define APIC_SPURIOUS_INT 255 #define LVT_LINT0 0 ==== //depot/projects/hammer/sys/amd64/include/smp.h#18 (text+ko) ==== @@ -40,9 +40,7 @@ IDTVEC(invltlb), /* TLB shootdowns - global */ IDTVEC(invlpg), /* TLB shootdowns - 1 page */ IDTVEC(invlrng), /* TLB shootdowns - page range */ - IDTVEC(hardclock), /* Forward hardclock() */ - IDTVEC(statclock), /* Forward statclock() */ - IDTVEC(cpuast), /* Additional software trap on other cpu */ + IDTVEC(ipi_intr_bitmap_handler), /* Bitmap based IPIs */ IDTVEC(cpustop), /* CPU stops & waits to be restarted */ IDTVEC(rendezvous); /* handle CPU rendezvous */ @@ -54,9 +52,8 @@ void ipi_all_but_self(u_int ipi); void ipi_self(u_int ipi); void forward_statclock(void); -void forwarded_statclock(struct clockframe frame); void forward_hardclock(void); -void forwarded_hardclock(struct clockframe frame); +void ipi_bitmap_handler(struct clockframe frame); u_int mp_bootaddress(u_int); int mp_grab_cpu_hlt(void); void mp_topology(void); ==== //depot/projects/hammer/sys/amd64/pci/pci_cfgreg.c#16 (text+ko) ====