Page MenuHomeFreeBSD

D32866.diff
No OneTemporary

D32866.diff

diff --git a/sys/dev/xen/bus/xen_intr.c b/sys/dev/xen/bus/xen_intr.c
--- a/sys/dev/xen/bus/xen_intr.c
+++ b/sys/dev/xen/bus/xen_intr.c
@@ -270,6 +270,10 @@
xen_intr_bind_isrc(struct xenisrc *isrc, const char *intr_owner,
xen_intr_handle_t *const port_handlep)
{
+#ifdef SMP
+ int error;
+ u_int cpu;
+#endif
KASSERT(port_handlep != NULL, ("%s: %s: Bad event handle\n", intr_owner,
__func__));
@@ -288,18 +292,43 @@
KASSERT(isrc->xi_cookie == NULL,
("%s: Called with uninitialized cookie", __func__));
+#ifdef SMP
+ cpu = isrc->xi_cpu;
+ isrc->xi_cpu = 0; /* initialize what is initially needed */
+#endif
+
mtx_lock(&xen_intr_isrc_lock);
xen_intr_port_to_isrc[isrc->xi_port] = isrc;
mtx_unlock(&xen_intr_isrc_lock);
#ifdef SMP
- if (isrc->xi_type == EVTCHN_TYPE_PORT) {
+ if (cpu > mp_maxid) {
/*
* By default all interrupts are assigned to vCPU#0
* unless specified otherwise, so shuffle them to balance
* the interrupt load.
*/
- xen_intr_assign_cpu(isrc, xen_arch_intr_next_cpu(isrc));
+ cpu = xen_arch_intr_next_cpu(isrc);
+ }
+
+ /* IPI interrupts are bound before the APs are started and CPU_ABSENT()
+ * will return false. Hence intr_event_bind() would return EINVAL. */
+ if (isrc->xi_type != EVTCHN_TYPE_IPI) {
+ error = xen_arch_intr_event_bind(isrc, cpu);
+ if (error != 0) { /* *very* unlikely */
+ xen_intr_release_isrc(isrc);
+ return (error);
+ }
+ }
+
+ if (isrc->xi_cpu != cpu) {
+ /*
+ * Too early in the boot process for the generic interrupt
+ * code to perform the binding. Update our event channel
+ * masks manually so events can't fire on the wrong cpu
+ * during AP startup.
+ */
+ xen_intr_assign_cpu(isrc, cpu);
}
#endif
@@ -861,6 +890,7 @@
return (ENOSPC);
isrc->xi_type = EVTCHN_TYPE_VIRQ;
+ isrc->xi_cpu = cpu;
isrc->xi_virq = virq;
error = HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq, &bind_virq);
@@ -876,32 +906,14 @@
isrc->xi_port = bind_virq.port;
error = xen_intr_bind_isrc(isrc, name, port_handlep);
-#ifdef SMP
- if (error == 0)
- error = xen_arch_intr_event_bind(isrc, cpu);
-#endif
-
if (error != 0) {
evtchn_close_t close = { .port = bind_virq.port };
- xen_intr_unbind(*port_handlep);
if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close))
panic("EVTCHNOP_close failed");
return (error);
}
-#ifdef SMP
- if (isrc->xi_cpu != cpu) {
- /*
- * Too early in the boot process for the generic interrupt
- * code to perform the binding. Update our event channel
- * masks manually so events can't fire on the wrong cpu
- * during AP startup.
- */
- xen_intr_assign_cpu(isrc, cpu);
- }
-#endif
-
/*
* The Event Channel API opened this port, so it is
* responsible for closing it automatically on unbind.
@@ -931,6 +943,7 @@
return (ENOSPC);
isrc->xi_type = EVTCHN_TYPE_IPI;
+ isrc->xi_cpu = cpu;
error = HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi, &bind_ipi);
if (error != 0) {
@@ -947,22 +960,11 @@
if (error != 0) {
evtchn_close_t close = { .port = bind_ipi.port };
- xen_intr_unbind(*port_handlep);
if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close))
panic("EVTCHNOP_close failed");
return (error);
}
- if (isrc->xi_cpu != cpu) {
- /*
- * Too early in the boot process for the generic interrupt
- * code to perform the binding. Update our event channel
- * masks manually so events can't fire on the wrong cpu
- * during AP startup.
- */
- xen_intr_assign_cpu(isrc, cpu);
- }
-
/*
* The Event Channel API opened this port, so it is
* responsible for closing it automatically on unbind.

File Metadata

Mime Type
text/plain
Expires
Fri, Nov 15, 3:38 PM (17 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14644750
Default Alt Text
D32866.diff (3 KB)

Event Timeline