--- a/sys/kern/kern_mutex.c +++ b/sys/kern/kern_mutex.c @@ -911,8 +911,16 @@ */ nlock = MTX_LINKSPIN; /* to clear */ + /* + * DF-2786: terminate the LINKED state BEFORE unlinking and + * dropping LINKSPIN. Previously the stale MTX_LINK_LINKED_EX/SH + * state survived until mtx_wait_link() reset it to MTX_LINK_IDLE + * outside LINKSPIN, letting a racing mtx_abort_link() execute the + * de-link writes through the victim's dangling next/prev. + */ switch(link->state) { case MTX_LINK_LINKED_EX: + link->state = MTX_LINK_IDLE; if (link->next == link) { mtx->mtx_exlink = NULL; nlock |= MTX_EXWANTED; /* to clear */ @@ -923,6 +931,7 @@ } break; case MTX_LINK_LINKED_SH: + link->state = MTX_LINK_IDLE; if (link->next == link) { mtx->mtx_shlink = NULL; nlock |= MTX_SHWANTED; /* to clear */