On 10/01/2022 10:26, Wen Gu wrote: > @@ -1226,15 +1245,23 @@ void smcr_link_clear(struct smc_link *lnk, bool log) > smc_wr_free_link(lnk); > smc_ib_destroy_queue_pair(lnk); > smc_ib_dealloc_protection_domain(lnk); > - smc_wr_free_link_mem(lnk); > - smc_lgr_put(lnk->lgr); /* lgr_hold in smcr_link_init() */ > smc_ibdev_cnt_dec(lnk); > put_device(&lnk->smcibdev->ibdev->dev); > smcibdev = lnk->smcibdev; > - memset(lnk, 0, sizeof(struct smc_link)); > - lnk->state = SMC_LNK_UNUSED; > if (!atomic_dec_return(&smcibdev->lnk_cnt)) > wake_up(&smcibdev->lnks_deleted); Same here, waiter should not be woken up until the link memory is actually freed. > + smcr_link_put(lnk); /* theoretically last link_put */ > +} > + > +void smcr_link_hold(struct smc_link *lnk) > +{ > + refcount_inc(&lnk->refcnt); > +} > + > +void smcr_link_put(struct smc_link *lnk) > +{ > + if (refcount_dec_and_test(&lnk->refcnt)) > + __smcr_link_clear(lnk); > }