diff options
Diffstat (limited to 'net/smc/smc_core.c')
-rw-r--r-- | net/smc/smc_core.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c index 1382ddae591e..35c1cdc93e1c 100644 --- a/net/smc/smc_core.c +++ b/net/smc/smc_core.c | |||
@@ -189,6 +189,8 @@ free: | |||
189 | 189 | ||
190 | if (!lgr->is_smcd && lnk->state != SMC_LNK_INACTIVE) | 190 | if (!lgr->is_smcd && lnk->state != SMC_LNK_INACTIVE) |
191 | smc_llc_link_inactive(lnk); | 191 | smc_llc_link_inactive(lnk); |
192 | if (lgr->is_smcd) | ||
193 | smc_ism_signal_shutdown(lgr); | ||
192 | smc_lgr_free(lgr); | 194 | smc_lgr_free(lgr); |
193 | } | 195 | } |
194 | } | 196 | } |
@@ -495,7 +497,7 @@ void smc_port_terminate(struct smc_ib_device *smcibdev, u8 ibport) | |||
495 | } | 497 | } |
496 | 498 | ||
497 | /* Called when SMC-D device is terminated or peer is lost */ | 499 | /* Called when SMC-D device is terminated or peer is lost */ |
498 | void smc_smcd_terminate(struct smcd_dev *dev, u64 peer_gid) | 500 | void smc_smcd_terminate(struct smcd_dev *dev, u64 peer_gid, unsigned short vlan) |
499 | { | 501 | { |
500 | struct smc_link_group *lgr, *l; | 502 | struct smc_link_group *lgr, *l; |
501 | LIST_HEAD(lgr_free_list); | 503 | LIST_HEAD(lgr_free_list); |
@@ -505,7 +507,7 @@ void smc_smcd_terminate(struct smcd_dev *dev, u64 peer_gid) | |||
505 | list_for_each_entry_safe(lgr, l, &smc_lgr_list.list, list) { | 507 | list_for_each_entry_safe(lgr, l, &smc_lgr_list.list, list) { |
506 | if (lgr->is_smcd && lgr->smcd == dev && | 508 | if (lgr->is_smcd && lgr->smcd == dev && |
507 | (!peer_gid || lgr->peer_gid == peer_gid) && | 509 | (!peer_gid || lgr->peer_gid == peer_gid) && |
508 | !list_empty(&lgr->list)) { | 510 | (vlan == VLAN_VID_MASK || lgr->vlan_id == vlan)) { |
509 | __smc_lgr_terminate(lgr); | 511 | __smc_lgr_terminate(lgr); |
510 | list_move(&lgr->list, &lgr_free_list); | 512 | list_move(&lgr->list, &lgr_free_list); |
511 | } | 513 | } |
@@ -516,6 +518,8 @@ void smc_smcd_terminate(struct smcd_dev *dev, u64 peer_gid) | |||
516 | list_for_each_entry_safe(lgr, l, &lgr_free_list, list) { | 518 | list_for_each_entry_safe(lgr, l, &lgr_free_list, list) { |
517 | list_del_init(&lgr->list); | 519 | list_del_init(&lgr->list); |
518 | cancel_delayed_work_sync(&lgr->free_work); | 520 | cancel_delayed_work_sync(&lgr->free_work); |
521 | if (!peer_gid && vlan == VLAN_VID_MASK) /* dev terminated? */ | ||
522 | smc_ism_signal_shutdown(lgr); | ||
519 | smc_lgr_free(lgr); | 523 | smc_lgr_free(lgr); |
520 | } | 524 | } |
521 | } | 525 | } |
@@ -569,7 +573,7 @@ out: | |||
569 | 573 | ||
570 | static bool smcr_lgr_match(struct smc_link_group *lgr, | 574 | static bool smcr_lgr_match(struct smc_link_group *lgr, |
571 | struct smc_clc_msg_local *lcl, | 575 | struct smc_clc_msg_local *lcl, |
572 | enum smc_lgr_role role) | 576 | enum smc_lgr_role role, u32 clcqpn) |
573 | { | 577 | { |
574 | return !memcmp(lgr->peer_systemid, lcl->id_for_peer, | 578 | return !memcmp(lgr->peer_systemid, lcl->id_for_peer, |
575 | SMC_SYSTEMID_LEN) && | 579 | SMC_SYSTEMID_LEN) && |
@@ -577,7 +581,9 @@ static bool smcr_lgr_match(struct smc_link_group *lgr, | |||
577 | SMC_GID_SIZE) && | 581 | SMC_GID_SIZE) && |
578 | !memcmp(lgr->lnk[SMC_SINGLE_LINK].peer_mac, lcl->mac, | 582 | !memcmp(lgr->lnk[SMC_SINGLE_LINK].peer_mac, lcl->mac, |
579 | sizeof(lcl->mac)) && | 583 | sizeof(lcl->mac)) && |
580 | lgr->role == role; | 584 | lgr->role == role && |
585 | (lgr->role == SMC_SERV || | ||
586 | lgr->lnk[SMC_SINGLE_LINK].peer_qpn == clcqpn); | ||
581 | } | 587 | } |
582 | 588 | ||
583 | static bool smcd_lgr_match(struct smc_link_group *lgr, | 589 | static bool smcd_lgr_match(struct smc_link_group *lgr, |
@@ -588,7 +594,7 @@ static bool smcd_lgr_match(struct smc_link_group *lgr, | |||
588 | 594 | ||
589 | /* create a new SMC connection (and a new link group if necessary) */ | 595 | /* create a new SMC connection (and a new link group if necessary) */ |
590 | int smc_conn_create(struct smc_sock *smc, bool is_smcd, int srv_first_contact, | 596 | int smc_conn_create(struct smc_sock *smc, bool is_smcd, int srv_first_contact, |
591 | struct smc_ib_device *smcibdev, u8 ibport, | 597 | struct smc_ib_device *smcibdev, u8 ibport, u32 clcqpn, |
592 | struct smc_clc_msg_local *lcl, struct smcd_dev *smcd, | 598 | struct smc_clc_msg_local *lcl, struct smcd_dev *smcd, |
593 | u64 peer_gid) | 599 | u64 peer_gid) |
594 | { | 600 | { |
@@ -613,7 +619,7 @@ int smc_conn_create(struct smc_sock *smc, bool is_smcd, int srv_first_contact, | |||
613 | list_for_each_entry(lgr, &smc_lgr_list.list, list) { | 619 | list_for_each_entry(lgr, &smc_lgr_list.list, list) { |
614 | write_lock_bh(&lgr->conns_lock); | 620 | write_lock_bh(&lgr->conns_lock); |
615 | if ((is_smcd ? smcd_lgr_match(lgr, smcd, peer_gid) : | 621 | if ((is_smcd ? smcd_lgr_match(lgr, smcd, peer_gid) : |
616 | smcr_lgr_match(lgr, lcl, role)) && | 622 | smcr_lgr_match(lgr, lcl, role, clcqpn)) && |
617 | !lgr->sync_err && | 623 | !lgr->sync_err && |
618 | lgr->vlan_id == vlan_id && | 624 | lgr->vlan_id == vlan_id && |
619 | (role == SMC_CLNT || | 625 | (role == SMC_CLNT || |
@@ -1034,6 +1040,8 @@ void smc_core_exit(void) | |||
1034 | smc_llc_link_inactive(lnk); | 1040 | smc_llc_link_inactive(lnk); |
1035 | } | 1041 | } |
1036 | cancel_delayed_work_sync(&lgr->free_work); | 1042 | cancel_delayed_work_sync(&lgr->free_work); |
1043 | if (lgr->is_smcd) | ||
1044 | smc_ism_signal_shutdown(lgr); | ||
1037 | smc_lgr_free(lgr); /* free link group */ | 1045 | smc_lgr_free(lgr); /* free link group */ |
1038 | } | 1046 | } |
1039 | } | 1047 | } |