summaryrefslogtreecommitdiff
path: root/net/smc/smc_ism.c
diff options
context:
space:
mode:
authorUrsula Braun <ubraun@linux.ibm.com>2019-11-14 13:02:40 +0100
committerDavid S. Miller <davem@davemloft.net>2019-11-15 12:28:28 -0800
commit50c6b20eff8e10cb91f06262d8003a5d9be3dfab (patch)
tree8dcdfe1e3be31ee93946f19d3c710bffb97b17be /net/smc/smc_ism.c
parent43da44c87678612f301d6ef6314064a6b52aad60 (diff)
downloadlinux-50c6b20eff8e10cb91f06262d8003a5d9be3dfab.tar.gz
net/smc: fix final cleanup sequence for SMCD devices
If peer announces shutdown, use the link group terminate worker for local cleanup of link groups and connections to terminate link group in proper context. Make sure link groups are cleaned up first before destroying the event queue of the SMCD device, because link group cleanup may raise events. Send signal shutdown only if peer has not done it already. Send socket abort or close only, if peer has not already announced shutdown. Signed-off-by: Ursula Braun <ubraun@linux.ibm.com> Signed-off-by: Karsten Graul <kgraul@linux.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/smc/smc_ism.c')
-rw-r--r--net/smc/smc_ism.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/net/smc/smc_ism.c b/net/smc/smc_ism.c
index ee7340898cb4..18946e95a3be 100644
--- a/net/smc/smc_ism.c
+++ b/net/smc/smc_ism.c
@@ -226,6 +226,9 @@ int smc_ism_signal_shutdown(struct smc_link_group *lgr)
int rc;
union smcd_sw_event_info ev_info;
+ if (lgr->peer_shutdown)
+ return 0;
+
memcpy(ev_info.uid, lgr->id, SMC_LGR_ID_SIZE);
ev_info.vlan_id = lgr->vlan_id;
ev_info.code = ISM_EVENT_REQUEST;
@@ -313,12 +316,12 @@ EXPORT_SYMBOL_GPL(smcd_register_dev);
void smcd_unregister_dev(struct smcd_dev *smcd)
{
spin_lock(&smcd_dev_list.lock);
- list_del(&smcd->list);
+ list_del_init(&smcd->list);
spin_unlock(&smcd_dev_list.lock);
smcd->going_away = 1;
+ smc_smcd_terminate(smcd, 0, VLAN_VID_MASK);
flush_workqueue(smcd->event_wq);
destroy_workqueue(smcd->event_wq);
- smc_smcd_terminate(smcd, 0, VLAN_VID_MASK);
device_del(&smcd->dev);
}