From: Bryam Vargas dibs_lo_unregister_dmb() resets the DMB's dmb_clientid_arr[] entry only on the last put. If an attacher still holds the DMB, as when an SMC link group is freed while a peer is still attached, the entry stays set after the attacher's dibs_lo_detach_dmb() frees the DMB. dibs_unregister_client() then warns at rmmod smc and returns -EBUSY, which smc_ism_exit() ignores: smc stays in clients[] and dibs->subs[], and a later dibs_dev_add() or dibs_dev_del() (rmmod dibs, ISM hotplug) calls into the unloaded module. Reset the entry when the owner unregisters, before its put, as ism_unregister_dmb() does. The index stays allocated until the last put, and the attacher's writes no longer raise an interrupt for a client that gave the DMB up. Fixes: cc21191b584c ("dibs: Move data path to dibs layer") Cc: stable@vger.kernel.org Signed-off-by: Bryam Vargas --- drivers/dibs/dibs_loopback.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/dibs/dibs_loopback.c b/drivers/dibs/dibs_loopback.c index 44a2e74c2efc..566e61a013d0 100644 --- a/drivers/dibs/dibs_loopback.c +++ b/drivers/dibs/dibs_loopback.c @@ -138,6 +138,13 @@ static int dibs_lo_unregister_dmb(struct dibs_dev *dibs, struct dibs_dmb *dmb) ldev = dibs->drv_priv; + /* Reset before the owner's put: after it, an attacher's detach can + * free the index for a new DMB. + */ + spin_lock_irqsave(&dibs->lock, flags); + dibs->dmb_clientid_arr[dmb->idx] = NO_DIBS_CLIENT; + spin_unlock_irqrestore(&dibs->lock, flags); + /* find dmb from hash table */ write_lock_bh(&ldev->dmb_ht_lock); hash_for_each_possible(ldev->dmb_ht, tmp_node, list, dmb->dmb_tok) { @@ -155,13 +162,8 @@ static int dibs_lo_unregister_dmb(struct dibs_dev *dibs, struct dibs_dmb *dmb) hash_del(&dmb_node->list); write_unlock_bh(&ldev->dmb_ht_lock); - if (last) { - spin_lock_irqsave(&dibs->lock, flags); - dibs->dmb_clientid_arr[dmb_node->sba_idx] = NO_DIBS_CLIENT; - spin_unlock_irqrestore(&dibs->lock, flags); - + if (last) dibs_lo_free_dmb(ldev, dmb_node); - } return 0; } -- 2.56.0