--- a/sys/netbt/rfcomm_upper.c +++ b/sys/netbt/rfcomm_upper.c @@ -287,13 +287,13 @@ *handle = NULL; /* - * If callout is invoking we can't free the DLC so - * mark it and let the callout release it. + * Safe to free unconditionally: rfcomm_dlc_close() above invoked + * callout_stop(), which cancels any pending request and drains an + * in-progress callback before returning (kern_timeout.c). The old + * callout_active()/RFCOMM_DLC_DETACH dance was dead code -- + * callout_stop() always clears CALLOUT_ACTIVE first. */ - if (callout_active(&dlc->rd_timeout)) - dlc->rd_flags |= RFCOMM_DLC_DETACH; - else - kfree(dlc, M_BLUETOOTH); + kfree(dlc, M_BLUETOOTH); return 0; } --- a/sys/netbt/rfcomm_dlc.c +++ b/sys/netbt/rfcomm_dlc.c @@ -200,8 +200,6 @@ if (dlc->rd_state != RFCOMM_DLC_CLOSED) rfcomm_dlc_close(dlc, ETIMEDOUT); - else if (dlc->rd_flags & RFCOMM_DLC_DETACH) - kfree(dlc, M_BLUETOOTH); crit_exit(); }