Index: sys/xen/xen_intr.c =================================================================== --- sys/xen/xen_intr.c +++ sys/xen/xen_intr.c @@ -281,7 +281,7 @@ isrc = xen_intr_find_unused_isrc(type); if (isrc != NULL) { mtx_unlock(&xen_intr_x86_lock); - return (isrc); + goto out; } if (xen_intr_auto_vector_count >= NR_EVENT_CHANNELS) { @@ -311,6 +311,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); } @@ -390,6 +402,9 @@ { struct xenisrc *isrc; int error; +#ifdef SMP + u_int cpu; +#endif *isrcp = NULL; if (port_handlep == NULL) { @@ -402,6 +417,9 @@ return (ENOSPC); isrc->xi_port = local_port; 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); if (__predict_false(xen_intr_port_to_isrc[isrc->xi_port] != NULL)) { @@ -421,7 +439,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