Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F145316751
D32866.1777637492.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D32866.1777637492.diff
View Options
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, ¶ms, 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
Details
Attached
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)
Attached To
Mode
D32866: xen/intr: merge CPU assignment during port binding together
Attached
Detach File
Event Timeline
Log In to Comment