Index: sys/xen/xen_intr.c =================================================================== --- sys/xen/xen_intr.c +++ sys/xen/xen_intr.c @@ -281,7 +281,7 @@ if (isrc != NULL) { mtx_unlock(&xen_intr_x86_lock); - return (isrc); + goto out; } if (xen_intr_auto_vector_count >= NR_EVENT_CHANNELS) { @@ -309,6 +309,18 @@ return (NULL); } +out: +#ifdef SMP + if (type == EVTCHN_TYPE_PORT) { + /* + * By default all interrupts are assigned to vCPU#0 + * unless specified otherwise, so shuffle them to balance + * the interrupt load. + */ + isrc->xi_cpu = intr_next_cpu(0); + } +#endif + return (isrc); } @@ -386,6 +398,7 @@ xen_intr_handle_t *port_handlep) { struct xenisrc *isrc; + u_int cpu; int error; *isrcp = NULL; @@ -398,11 +411,13 @@ if (isrc == NULL) return (ENOSPC); isrc->xi_port = local_port; + cpu = isrc->xi_cpu; mtx_lock(&xen_intr_isrc_lock); if (xen_intr_port_to_isrc[isrc->xi_port] != NULL) { xen_intr_port_to_isrc[isrc->xi_port]->xi_port = ~0U; isrc->xi_cpu = xen_intr_port_to_isrc[isrc->xi_port]->xi_cpu; - } + } else + isrc->xi_cpu = 0; xen_intr_port_to_isrc[isrc->xi_port] = isrc; refcount_init(&isrc->xi_refcount, 1); mtx_unlock(&xen_intr_isrc_lock); @@ -417,7 +432,7 @@ * unless specified otherwise, so shuffle them to balance * the interrupt load. */ - xen_intr_assign_cpu(isrc, intr_next_cpu(0)); + xen_intr_assign_cpu(isrc, cpu); } #endif