Index: sys/x86/xen/xen_arch_intr.c =================================================================== --- sys/x86/xen/xen_arch_intr.c +++ sys/x86/xen/xen_arch_intr.c @@ -219,6 +219,9 @@ struct xenisrc *isrc) { + if (isrc->xi_cookie != NULL) + return (EINVAL); + return (intr_add_handler(name, isrc->xi_arch.xai_vector, filter, handler, arg, flags, &isrc->xi_cookie, 0)); } Index: sys/xen/xen_intr.c =================================================================== --- sys/xen/xen_intr.c +++ sys/xen/xen_intr.c @@ -279,7 +279,7 @@ if (isrc != NULL) { mtx_unlock(&xen_intr_x86_lock); - return (isrc); + goto out; } if (xen_intr_auto_vector_count >= NR_EVENT_CHANNELS) { @@ -307,6 +307,12 @@ return (NULL); } +out: + KASSERT(!xen_arch_intr_has_handlers(isrc), + ("Allocator called, but xenisrc still in use")); + + isrc->xi_cookie = NULL; + return (isrc); } @@ -322,8 +328,6 @@ { mtx_lock(&xen_intr_isrc_lock); - KASSERT(xen_arch_intr_has_handlers(isrc), - ("Release called, but xenisrc still in use")); evtchn_mask_port(isrc->xi_port); evtchn_clear_port(isrc->xi_port); @@ -345,6 +349,9 @@ /* not reachable from xen_intr_port_to_isrc[], therefore unlock */ mtx_unlock(&xen_intr_isrc_lock); + if (isrc->xi_cookie != NULL) + xen_arch_intr_remove_handler(isrc); + isrc->xi_cpu = 0; isrc->xi_port = ~0U; isrc->xi_cookie = NULL; @@ -1169,8 +1176,6 @@ } mtx_unlock(&xen_intr_isrc_lock); - if (isrc->xi_cookie != NULL) - xen_arch_intr_remove_handler(isrc); xen_intr_release_isrc(isrc); } @@ -1210,7 +1215,7 @@ int error; isrc = xen_intr_isrc_from_handle(handle); - if (isrc == NULL || isrc->xi_cookie != NULL) + if (isrc == NULL) return (EINVAL); error = xen_arch_intr_add_handler(name, filter, handler, arg,