Skip to content

Commit 0b29ec6

Browse files
Ursula Braundavem330
authored andcommitted
net/smc: immediate termination for SMCR link groups
If the SMC module is unloaded or an IB device is thrown away, the immediate link group freeing introduced for SMCD is exploited for SMCR as well. That means SMCR-specifics are added to smc_conn_kill(). Signed-off-by: Ursula Braun <[email protected]> Signed-off-by: Karsten Graul <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 6a37ad3 commit 0b29ec6

File tree

4 files changed

+46
-22
lines changed

4 files changed

+46
-22
lines changed

net/smc/smc_core.c

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,10 @@ static void smc_lgr_cleanup(struct smc_link_group *lgr)
566566
struct smc_link *lnk = &lgr->lnk[SMC_SINGLE_LINK];
567567

568568
wake_up(&lnk->wr_reg_wait);
569+
if (lnk->state != SMC_LNK_INACTIVE) {
570+
smc_link_send_delete(lnk, false);
571+
smc_llc_link_inactive(lnk);
572+
}
569573
}
570574
}
571575

@@ -638,14 +642,16 @@ void smc_port_terminate(struct smc_ib_device *smcibdev, u8 ibport)
638642
list_for_each_entry_safe(lgr, l, &smc_lgr_list.list, list) {
639643
if (!lgr->is_smcd &&
640644
lgr->lnk[SMC_SINGLE_LINK].smcibdev == smcibdev &&
641-
lgr->lnk[SMC_SINGLE_LINK].ibport == ibport)
645+
lgr->lnk[SMC_SINGLE_LINK].ibport == ibport) {
642646
list_move(&lgr->list, &lgr_free_list);
647+
lgr->freeing = 1;
648+
}
643649
}
644650
spin_unlock_bh(&smc_lgr_list.lock);
645651

646652
list_for_each_entry_safe(lgr, l, &lgr_free_list, list) {
647653
list_del_init(&lgr->list);
648-
__smc_lgr_terminate(lgr, true);
654+
__smc_lgr_terminate(lgr, false);
649655
}
650656
}
651657

@@ -695,6 +701,36 @@ void smc_smcd_terminate_all(struct smcd_dev *smcd)
695701
wait_event(smcd->lgrs_deleted, !atomic_read(&smcd->lgr_cnt));
696702
}
697703

704+
/* Called when an SMCR device is removed or the smc module is unloaded.
705+
* If smcibdev is given, all SMCR link groups using this device are terminated.
706+
* If smcibdev is NULL, all SMCR link groups are terminated.
707+
*/
708+
void smc_smcr_terminate_all(struct smc_ib_device *smcibdev)
709+
{
710+
struct smc_link_group *lgr, *lg;
711+
LIST_HEAD(lgr_free_list);
712+
713+
spin_lock_bh(&smc_lgr_list.lock);
714+
if (!smcibdev) {
715+
list_splice_init(&smc_lgr_list.list, &lgr_free_list);
716+
list_for_each_entry(lgr, &lgr_free_list, list)
717+
lgr->freeing = 1;
718+
} else {
719+
list_for_each_entry_safe(lgr, lg, &smc_lgr_list.list, list) {
720+
if (lgr->lnk[SMC_SINGLE_LINK].smcibdev == smcibdev) {
721+
list_move(&lgr->list, &lgr_free_list);
722+
lgr->freeing = 1;
723+
}
724+
}
725+
}
726+
spin_unlock_bh(&smc_lgr_list.lock);
727+
728+
list_for_each_entry_safe(lgr, lg, &lgr_free_list, list) {
729+
list_del_init(&lgr->list);
730+
__smc_lgr_terminate(lgr, false);
731+
}
732+
}
733+
698734
/* Determine vlan of internal TCP socket.
699735
* @vlan_id: address to store the determined vlan id into
700736
*/
@@ -1215,32 +1251,16 @@ static void smc_core_going_away(void)
12151251
/* Clean up all SMC link groups */
12161252
static void smc_lgrs_shutdown(void)
12171253
{
1218-
struct smc_link_group *lgr, *lg;
1219-
LIST_HEAD(lgr_freeing_list);
12201254
struct smcd_dev *smcd;
12211255

12221256
smc_core_going_away();
12231257

1224-
spin_lock_bh(&smc_lgr_list.lock);
1225-
list_splice_init(&smc_lgr_list.list, &lgr_freeing_list);
1226-
spin_unlock_bh(&smc_lgr_list.lock);
1258+
smc_smcr_terminate_all(NULL);
12271259

12281260
spin_lock(&smcd_dev_list.lock);
12291261
list_for_each_entry(smcd, &smcd_dev_list.list, list)
12301262
smc_smcd_terminate_all(smcd);
12311263
spin_unlock(&smcd_dev_list.lock);
1232-
1233-
list_for_each_entry_safe(lgr, lg, &lgr_freeing_list, list) {
1234-
list_del_init(&lgr->list);
1235-
if (!lgr->is_smcd) {
1236-
struct smc_link *lnk = &lgr->lnk[SMC_SINGLE_LINK];
1237-
1238-
smc_link_send_delete(&lgr->lnk[SMC_SINGLE_LINK], false);
1239-
smc_llc_link_inactive(lnk);
1240-
}
1241-
cancel_delayed_work_sync(&lgr->free_work);
1242-
smc_lgr_free(lgr); /* free link group */
1243-
}
12441264
}
12451265

12461266
/* Called (from smc_exit) when module is removed */

net/smc/smc_core.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ static inline struct smc_connection *smc_lgr_find_conn(
287287

288288
static inline void smc_lgr_terminate_sched(struct smc_link_group *lgr)
289289
{
290-
if (!lgr->terminating)
290+
if (!lgr->terminating && !lgr->freeing)
291291
schedule_work(&lgr->terminate_work);
292292
}
293293

@@ -301,6 +301,7 @@ void smc_port_terminate(struct smc_ib_device *smcibdev, u8 ibport);
301301
void smc_smcd_terminate(struct smcd_dev *dev, u64 peer_gid,
302302
unsigned short vlan);
303303
void smc_smcd_terminate_all(struct smcd_dev *dev);
304+
void smc_smcr_terminate_all(struct smc_ib_device *smcibdev);
304305
int smc_buf_create(struct smc_sock *smc, bool is_smcd);
305306
int smc_uncompress_bufsize(u8 compressed);
306307
int smc_rmb_rtoken_handling(struct smc_connection *conn,

net/smc/smc_ib.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,7 @@ static void smc_ib_add_dev(struct ib_device *ibdev)
565565
schedule_work(&smcibdev->port_event_work);
566566
}
567567

568-
/* callback function for ib_register_client() */
568+
/* callback function for ib_unregister_client() */
569569
static void smc_ib_remove_dev(struct ib_device *ibdev, void *client_data)
570570
{
571571
struct smc_ib_device *smcibdev;
@@ -575,6 +575,7 @@ static void smc_ib_remove_dev(struct ib_device *ibdev, void *client_data)
575575
spin_lock(&smc_ib_devices.lock);
576576
list_del_init(&smcibdev->list); /* remove from smc_ib_devices */
577577
spin_unlock(&smc_ib_devices.lock);
578+
smc_smcr_terminate_all(smcibdev);
578579
smc_ib_cleanup_per_ibdev(smcibdev);
579580
ib_unregister_event_handler(&smcibdev->event_handler);
580581
kfree(smcibdev);

net/smc/smc_llc.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -698,9 +698,11 @@ int smc_llc_do_confirm_rkey(struct smc_link *link,
698698
int smc_llc_do_delete_rkey(struct smc_link *link,
699699
struct smc_buf_desc *rmb_desc)
700700
{
701-
int rc;
701+
int rc = 0;
702702

703703
mutex_lock(&link->llc_delete_rkey_mutex);
704+
if (link->state != SMC_LNK_ACTIVE)
705+
goto out;
704706
reinit_completion(&link->llc_delete_rkey);
705707
rc = smc_llc_send_delete_rkey(link, rmb_desc);
706708
if (rc)

0 commit comments

Comments
 (0)