--- a/sys/vfs/hammer2/hammer2_admin.c +++ b/sys/vfs/hammer2/hammer2_admin.c @@ -431,9 +431,21 @@ lockmgr(&pmp->lock, LK_EXCLUSIVE); pmp->has_xop_threads = 1; - pmp->xop_groups = kmalloc(hammer2_xop_nthreads * - sizeof(hammer2_xop_group_t), - M_HAMMER2, M_WAITOK | M_ZERO); + /* + * DF-2621: only allocate the group array once. This function can + * be called multiple times on the same pmp (hammer2_pfsalloc() + * merging another same-clid device into a mounted pmp, the mount + * helper, and xop_start's lazy setup). Unconditionally assigning + * a fresh kmalloc() here loses the old array pointer, leaking it + * and orphaning its kernel threads (they are only ever signalled + * through the array stored in pmp->xop_groups). Keep the existing + * array and just create any missing threads below. + */ + if (pmp->xop_groups == NULL) { + pmp->xop_groups = kmalloc(hammer2_xop_nthreads * + sizeof(hammer2_xop_group_t), + M_HAMMER2, M_WAITOK | M_ZERO); + } for (i = 0; i < pmp->iroot->cluster.nchains; ++i) { for (j = 0; j < hammer2_xop_nthreads; ++j) { if (pmp->xop_groups[j].thrs[i].td)