Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F140025306
D32866.id104983.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D32866.id104983.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
@@ -319,7 +319,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);
@@ -348,9 +347,10 @@
*
* \returns 0 on success, otherwise an errno.
*/
-#define BIND_PARAMS(type, ...) \
+#define BIND_PARAMS(type, cpu, ...) \
{ \
.xi_type = (type), \
+ .xi_cpu = (cpu), \
.xi_cookie = NULL, \
__VA_ARGS__ \
}
@@ -361,6 +361,9 @@
{
struct xenisrc *isrc;
int error;
+#ifdef SMP
+ u_int cpu;
+#endif
*isrcp = NULL;
if (port_handlep == NULL) {
@@ -372,6 +375,10 @@
if (isrc == NULL)
return (ENOSPC);
refcount_init(&isrc->xi_refcount, 1);
+#ifdef SMP
+ cpu = isrc->xi_cpu;
+#endif
+ isrc->xi_cpu = 0; /* initialize to the likely correct value */
mtx_lock(&xen_intr_isrc_lock);
xen_intr_port_to_isrc[isrc->xi_port] = isrc;
mtx_unlock(&xen_intr_isrc_lock);
@@ -382,13 +389,29 @@
/* ->xi_cookie is cleared in 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, intr_next_cpu(0));
+ cpu = intr_next_cpu(0);
+ }
+
+ 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
@@ -848,7 +871,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,
.xi_port = local_port,
/*
* The Event Channel API didn't open this port, so it is not
@@ -867,7 +890,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;
@@ -903,7 +926,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;
@@ -944,7 +967,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 };
@@ -964,11 +987,6 @@
error = xen_intr_bind_isrc(&isrc, ¶ms, device_get_nameunit(dev),
filter, handler, arg, flags, port_handlep);
-#ifdef SMP
- if (error == 0)
- error = xen_arch_intr_event_bind(isrc, cpu);
-#endif
-
if (error != 0) {
evtchn_close_t close = { .port = params.xi_port };
@@ -978,18 +996,6 @@
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.
@@ -1006,7 +1012,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];
@@ -1036,16 +1042,6 @@
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
Details
Attached
Mime Type
text/plain
Expires
Sat, Dec 20, 5:17 AM (7 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27092362
Default Alt Text
D32866.id104983.diff (4 KB)
Attached To
Mode
D32866: xen/intr: merge CPU assignment during port binding together
Attached
Detach File
Event Timeline
Log In to Comment