svn commit: r184224 - in head/sys/i386: include xen

Kip Macy kmacy at FreeBSD.org
Fri Oct 24 07:58:39 UTC 2008


Author: kmacy
Date: Fri Oct 24 07:58:38 2008
New Revision: 184224
URL: http://svn.freebsd.org/changeset/base/184224

Log:
  Fix general issues with IPI support

Modified:
  head/sys/i386/include/apicvar.h
  head/sys/i386/include/smp.h
  head/sys/i386/xen/mp_machdep.c

Modified: head/sys/i386/include/apicvar.h
==============================================================================
--- head/sys/i386/include/apicvar.h	Fri Oct 24 07:57:48 2008	(r184223)
+++ head/sys/i386/include/apicvar.h	Fri Oct 24 07:58:38 2008	(r184224)
@@ -114,14 +114,14 @@
 
 #define	APIC_IPI_INTS	(APIC_LOCAL_INTS + 2)
 #ifdef XEN
-#define	IPI_RENDEZVOUS		(0)	/* Inter-CPU rendezvous. */
-#define	IPI_INVLTLB		(1)	/* TLB Shootdown IPIs */
-#define	IPI_INVLPG		(2)
-#define	IPI_INVLRNG		(3)
-#define	IPI_INVLCACHE		(4)
-#define	IPI_LAZYPMAP		(5)	/* Lazy pmap release. */
+#define	IPI_RENDEZVOUS		(2)	/* Inter-CPU rendezvous. */
+#define	IPI_INVLTLB		(3)	/* TLB Shootdown IPIs */
+#define	IPI_INVLPG		(4)
+#define	IPI_INVLRNG		(5)
+#define	IPI_INVLCACHE		(6)
+#define	IPI_LAZYPMAP		(7)	/* Lazy pmap release. */
 /* Vector to handle bitmap based IPIs */
-#define	IPI_BITMAP_VECTOR	(6)
+#define	IPI_BITMAP_VECTOR	(8)
 
 #else
 #define	IPI_RENDEZVOUS	(APIC_IPI_INTS)		/* Inter-CPU rendezvous. */

Modified: head/sys/i386/include/smp.h
==============================================================================
--- head/sys/i386/include/smp.h	Fri Oct 24 07:57:48 2008	(r184223)
+++ head/sys/i386/include/smp.h	Fri Oct 24 07:58:38 2008	(r184224)
@@ -86,8 +86,8 @@ int	ipi_nmi_handler(void);
 #ifdef XEN
 void ipi_to_irq_init(void);
 
-#define CALL_FUNCTION_VECTOR	0
-#define RESCHEDULE_VECTOR	1
+#define RESCHEDULE_VECTOR	0
+#define CALL_FUNCTION_VECTOR	1
 #define NR_IPIS			2
 
 #endif

Modified: head/sys/i386/xen/mp_machdep.c
==============================================================================
--- head/sys/i386/xen/mp_machdep.c	Fri Oct 24 07:57:48 2008	(r184223)
+++ head/sys/i386/xen/mp_machdep.c	Fri Oct 24 07:58:38 2008	(r184224)
@@ -309,14 +309,12 @@ static void
 iv_invltlb(uintptr_t a, uintptr_t b)
 {
 	xen_tlb_flush();
-	atomic_add_int(&smp_tlb_wait, 1);
 }
 
 static void
 iv_invlpg(uintptr_t a, uintptr_t b)
 {
 	xen_invlpg(a);
-	atomic_add_int(&smp_tlb_wait, 1);
 }
 
 static void
@@ -329,7 +327,6 @@ iv_invlrng(uintptr_t a, uintptr_t b)
 		xen_invlpg(start);
 		start += PAGE_SIZE;
 	}
-	atomic_add_int(&smp_tlb_wait, 1);
 }
 
 
@@ -345,12 +342,36 @@ static void
 iv_lazypmap(uintptr_t a, uintptr_t b)
 {
 	pmap_lazyfix_action();
+	atomic_add_int(&smp_tlb_wait, 1);
 }
 
+
 static void
-iv_bitmap_vector(uintptr_t a, uintptr_t b)
+iv_noop(uintptr_t a, uintptr_t b)
 {
+	atomic_add_int(&smp_tlb_wait, 1);
+}
 
+static call_data_func_t *ipi_vectors[IPI_BITMAP_VECTOR] = 
+{
+  iv_noop,
+  iv_noop,
+  iv_rendezvous,
+  iv_invltlb,
+  iv_invlpg,
+  iv_invlrng,
+  iv_invlcache,
+  iv_lazypmap,
+};
+
+/*
+ * Reschedule call back. Nothing to do,
+ * all the work is done automatically when
+ * we return from the interrupt.
+ */
+static int
+smp_reschedule_interrupt(void *unused)
+{
 	int cpu = PCPU_GET(cpuid);
 	u_int ipi_bitmap;
 
@@ -369,37 +390,16 @@ iv_bitmap_vector(uintptr_t a, uintptr_t 
 #endif
 		/* Nothing to do for AST */
 	}	
-}
-
-
-static call_data_func_t *ipi_vectors[IPI_BITMAP_VECTOR + 1] = 
-{ iv_rendezvous,
-  iv_invltlb,
-  iv_invlpg,
-  iv_invlrng,
-  iv_invlcache,
-  iv_lazypmap,
-  iv_bitmap_vector
-};
-
-/*
- * Reschedule call back. Nothing to do,
- * all the work is done automatically when
- * we return from the interrupt.
- */
-static int
-smp_reschedule_interrupt(void *unused)
-{
 	return (FILTER_HANDLED);
 }
 
 struct _call_data {
-	call_data_func_t *func;
+	uint16_t func_id;
+	uint16_t wait;
 	uintptr_t arg1;
 	uintptr_t arg2;
 	atomic_t started;
 	atomic_t finished;
-	int wait;
 };
 
 static struct _call_data *call_data;
@@ -407,17 +407,23 @@ static struct _call_data *call_data;
 static int
 smp_call_function_interrupt(void *unused)
 {	
-	call_data_func_t *func = call_data->func;
+	call_data_func_t *func;
 	uintptr_t arg1 = call_data->arg1;
 	uintptr_t arg2 = call_data->arg2;
 	int wait = call_data->wait;
+	atomic_t *started = &call_data->started;
+	atomic_t *finished = &call_data->finished;
 
+	if (call_data->func_id > IPI_BITMAP_VECTOR)
+		panic("invalid function id %u", call_data->func_id);
+	
+	func = ipi_vectors[call_data->func_id];
 	/*
 	 * Notify initiating CPU that I've grabbed the data and am
 	 * about to execute the function
 	 */
 	mb();
-	atomic_inc(&call_data->started);
+	atomic_inc(started);
 	/*
 	 * At this point the info structure may be out of scope unless wait==1
 	 */
@@ -425,8 +431,9 @@ smp_call_function_interrupt(void *unused
 
 	if (wait) {
 		mb();
-		atomic_inc(&call_data->finished);
+		atomic_inc(finished);
 	}
+	atomic_add_int(&smp_tlb_wait, 1);
 	return (FILTER_HANDLED);
 }
 
@@ -967,12 +974,14 @@ smp_tlb_shootdown(u_int vector, vm_offse
 	if (!(read_eflags() & PSL_I))
 		panic("%s: interrupts disabled", __func__);
 	mtx_lock_spin(&smp_ipi_mtx);
+	call_data->func_id = vector;
 	call_data->arg1 = addr1;
 	call_data->arg2 = addr2;
 	atomic_store_rel_int(&smp_tlb_wait, 0);
 	ipi_all_but_self(vector);
 	while (smp_tlb_wait < ncpu)
 		ia32_pause();
+	call_data = NULL;
 	mtx_unlock_spin(&smp_ipi_mtx);
 }
 
@@ -980,6 +989,7 @@ static void
 smp_targeted_tlb_shootdown(u_int mask, u_int vector, vm_offset_t addr1, vm_offset_t addr2)
 {
 	int ncpu, othercpus;
+	struct _call_data data;
 
 	othercpus = mp_ncpus - 1;
 	if (mask == (u_int)-1) {
@@ -1004,8 +1014,10 @@ smp_targeted_tlb_shootdown(u_int mask, u
 	if (!(read_eflags() & PSL_I))
 		panic("%s: interrupts disabled", __func__);
 	mtx_lock_spin(&smp_ipi_mtx);
-	smp_tlb_addr1 = addr1;
-	smp_tlb_addr2 = addr2;
+	call_data = &data;		
+	call_data->func_id = vector;
+	call_data->arg1 = addr1;
+	call_data->arg2 = addr2;
 	atomic_store_rel_int(&smp_tlb_wait, 0);
 	if (mask == (u_int)-1)
 		ipi_all_but_self(vector);
@@ -1013,6 +1025,7 @@ smp_targeted_tlb_shootdown(u_int mask, u
 		ipi_selected(mask, vector);
 	while (smp_tlb_wait < ncpu)
 		ia32_pause();
+	call_data = NULL;
 	mtx_unlock_spin(&smp_ipi_mtx);
 }
 
@@ -1082,20 +1095,17 @@ smp_masked_invlpg_range(u_int mask, vm_o
  * send an IPI to a set of cpus.
  */
 void
-ipi_selected(u_int32_t cpus, u_int ipi)
+ipi_selected(uint32_t cpus, u_int ipi)
 {
 	int cpu;
 	u_int bitmap = 0;
 	u_int old_pending;
 	u_int new_pending;
-	struct _call_data data;
-
-	call_data = &data;
 	
 	if (IPI_IS_BITMAPED(ipi)) { 
 		bitmap = 1 << ipi;
 		ipi = IPI_BITMAP_VECTOR;
-	}
+	} 
 
 #ifdef STOP_NMI
 	if (ipi == IPI_STOP && stop_cpus_with_nmi) {
@@ -1117,10 +1127,13 @@ ipi_selected(u_int32_t cpus, u_int ipi)
 				new_pending = old_pending | bitmap;
 			} while  (!atomic_cmpset_int(&cpu_ipi_pending[cpu],old_pending, new_pending));	
 
-			if (old_pending)
-				continue;
+			if (!old_pending)
+				ipi_pcpu(cpu, RESCHEDULE_VECTOR);
+			continue;
+			
 		}
-		call_data->func = ipi_vectors[ipi];
+		
+		KASSERT(call_data != NULL, ("call_data not set"));
 		ipi_pcpu(cpu, CALL_FUNCTION_VECTOR);
 	}
 }
@@ -1137,7 +1150,7 @@ ipi_all_but_self(u_int ipi)
 		return;
 	}
 	CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi);
-	ipi_selected((all_cpus & ~(1 << curcpu)), ipi);
+	ipi_selected(PCPU_GET(other_cpus), ipi);
 }
 
 #ifdef STOP_NMI


More information about the svn-src-all mailing list