Page MenuHomeFreeBSD

D32866.1777637492.diff
No OneTemporary

Size
5 KB
Referenced Files
None
Subscribers
None

D32866.1777637492.diff

Index: sys/dev/xen/bus/xen_intr.c
===================================================================
--- sys/dev/xen/bus/xen_intr.c
+++ sys/dev/xen/bus/xen_intr.c
@@ -382,7 +382,6 @@
xen_intr_port_to_isrc[isrc->xi_port] = NULL;
}
- isrc->xi_cpu = 0;
isrc->xi_type = EVTCHN_TYPE_UNBOUND;
isrc->xi_port = INVALID_EVTCHN;
mtx_unlock(&xen_intr_isrc_lock);
@@ -411,10 +410,11 @@
*
* \returns 0 on success, otherwise an errno.
*/
-#define BIND_PARAMS(type, ...) \
+#define BIND_PARAMS(type, cpu, ...) \
{ \
.xi_cookie = NULL, \
.xi_type = (type), \
+ .xi_cpu = (cpu), \
__VA_ARGS__ \
}
static int
@@ -424,6 +424,9 @@
{
struct xenisrc *isrc;
int error;
+#ifdef SMP
+ u_int cpu;
+#endif
KASSERT(params != NULL, ("%s: NULL params passed in", __func__));
@@ -443,6 +446,10 @@
if (isrc == NULL)
return (ENOSPC);
refcount_init(&isrc->xi_refcount, 1);
+#ifdef SMP
+ cpu = isrc->xi_cpu;
+ isrc->xi_cpu = 0; /* initialize to the likely correct value */
+#endif
mtx_lock(&xen_intr_isrc_lock);
xen_intr_port_to_isrc[isrc->xi_port] = isrc;
mtx_unlock(&xen_intr_isrc_lock);
@@ -450,13 +457,29 @@
/* ->xi_cookie is cleared by BIND_PARAMS() */
#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->xi_intsrc, intr_next_cpu(0));
+ cpu = intr_next_cpu(0);
+ }
+
+ error = intr_event_bind(isrc->xi_intsrc.is_event, 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->xi_intsrc, cpu);
}
#endif
@@ -1015,7 +1038,7 @@
* The Event Channel API didn't open this port, so it is not
* responsible for closing it automatically on unbind.
*/
- struct xenisrc params = BIND_PARAMS(EVTCHN_TYPE_PORT,
+ struct xenisrc params = BIND_PARAMS(EVTCHN_TYPE_PORT, ~0U,
.xi_close = 0,
.xi_port = local_port,
);
@@ -1030,7 +1053,7 @@
enum intr_type flags, xen_intr_handle_t *port_handlep)
{
struct xenisrc *isrc;
- struct xenisrc params = BIND_PARAMS(EVTCHN_TYPE_PORT);
+ struct xenisrc params = BIND_PARAMS(EVTCHN_TYPE_PORT, ~0U);
struct evtchn_alloc_unbound alloc_unbound;
int error;
@@ -1066,7 +1089,7 @@
void *arg, enum intr_type flags, xen_intr_handle_t *port_handlep)
{
struct xenisrc *isrc;
- struct xenisrc params = BIND_PARAMS(EVTCHN_TYPE_PORT);
+ struct xenisrc params = BIND_PARAMS(EVTCHN_TYPE_PORT, ~0U);
struct evtchn_bind_interdomain bind_interdomain;
int error;
@@ -1107,7 +1130,7 @@
{
u_int vcpu_id = XEN_CPUID_TO_VCPUID(cpu);
struct xenisrc *isrc;
- struct xenisrc params = BIND_PARAMS(EVTCHN_TYPE_VIRQ,
+ struct xenisrc params = BIND_PARAMS(EVTCHN_TYPE_VIRQ, cpu,
.xi_virq = virq,
);
struct evtchn_bind_virq bind_virq = { .virq = virq, .vcpu = vcpu_id };
@@ -1127,33 +1150,14 @@
error = xen_intr_bind_isrc(&isrc, &params, device_get_nameunit(dev),
filter, handler, arg, flags, port_handlep);
-#ifdef SMP
- if (error == 0)
- error = intr_event_bind(isrc->xi_intsrc.is_event, cpu);
-#endif
-
if (error != 0) {
evtchn_close_t close = { .port = bind_virq.port };
- if (isrc != NULL)
- xen_intr_release_isrc(isrc);
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->xi_intsrc, cpu);
- }
-#endif
-
/*
* The Event Channel API opened this port, so it is
* responsible for closing it automatically on unbind.
@@ -1170,7 +1174,7 @@
#ifdef SMP
u_int vcpu_id = XEN_CPUID_TO_VCPUID(cpu);
struct xenisrc *isrc;
- struct xenisrc params = BIND_PARAMS(EVTCHN_TYPE_IPI);
+ struct xenisrc params = BIND_PARAMS(EVTCHN_TYPE_IPI, cpu);
struct evtchn_bind_ipi bind_ipi = { .vcpu = vcpu_id };
/* Same size as the one used by intr_handler->ih_name. */
char name[MAXCOMLEN + 1];
@@ -1194,23 +1198,11 @@
if (error != 0) {
evtchn_close_t close = { .port = bind_ipi.port };
- if (isrc != NULL)
- xen_intr_release_isrc(isrc);
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->xi_intsrc, 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, May 1, 12:11 PM (3 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28524851
Default Alt Text
D32866.1777637492.diff (5 KB)

Event Timeline