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