Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 12 Dec 2004 23:41:28 GMT
From:      Peter Wemm <peter@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 66921 for review
Message-ID:  <200412122341.iBCNfS7d084939@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <sys/malloc.h>
 #include <sys/mbuf.h>
 #include <sys/mutex.h>
+#include <sys/pioctl.h>
 #include <sys/proc.h>
 #include <sys/sf_buf.h>
 #include <sys/smp.h>
@@ -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) ====



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200412122341.iBCNfS7d084939>