diff options
author | Ursula Braun <ubraun@linux.vnet.ibm.com> | 2018-01-25 05:15:34 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-01-25 16:10:42 -0500 |
commit | 610db66f377cf99aa07a2b1990727238f2e2d6d3 (patch) | |
tree | debd8dd0cdd136ceafd56b28be0919c785147e26 | |
parent | b4772b3a87b772401e2af1c894fef323fb5c6e7c (diff) |
net/smc: do not reuse a linkgroup with setup problems
Once a linkgroup is created successfully, it stays alive for a
certain time to service more connections potentially created.
If one of the initialization steps for a new linkgroup fails,
the linkgroup should not be reused by other connections following.
Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/smc/af_smc.c | 17 | ||||
-rw-r--r-- | net/smc/smc_core.c | 3 |
2 files changed, 20 insertions, 0 deletions
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index 05cbcd3a6f60..cf0e11978b66 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c | |||
@@ -377,6 +377,15 @@ static void smc_link_save_peer_info(struct smc_link *link, | |||
377 | link->peer_mtu = clc->qp_mtu; | 377 | link->peer_mtu = clc->qp_mtu; |
378 | } | 378 | } |
379 | 379 | ||
380 | static void smc_lgr_forget(struct smc_link_group *lgr) | ||
381 | { | ||
382 | spin_lock_bh(&smc_lgr_list.lock); | ||
383 | /* do not use this link group for new connections */ | ||
384 | if (!list_empty(&lgr->list)) | ||
385 | list_del_init(&lgr->list); | ||
386 | spin_unlock_bh(&smc_lgr_list.lock); | ||
387 | } | ||
388 | |||
380 | /* setup for RDMA connection of client */ | 389 | /* setup for RDMA connection of client */ |
381 | static int smc_connect_rdma(struct smc_sock *smc) | 390 | static int smc_connect_rdma(struct smc_sock *smc) |
382 | { | 391 | { |
@@ -513,6 +522,8 @@ out_connected: | |||
513 | return rc ? rc : local_contact; | 522 | return rc ? rc : local_contact; |
514 | 523 | ||
515 | decline_rdma_unlock: | 524 | decline_rdma_unlock: |
525 | if (local_contact == SMC_FIRST_CONTACT) | ||
526 | smc_lgr_forget(smc->conn.lgr); | ||
516 | mutex_unlock(&smc_create_lgr_pending); | 527 | mutex_unlock(&smc_create_lgr_pending); |
517 | smc_conn_free(&smc->conn); | 528 | smc_conn_free(&smc->conn); |
518 | decline_rdma: | 529 | decline_rdma: |
@@ -526,6 +537,8 @@ decline_rdma: | |||
526 | goto out_connected; | 537 | goto out_connected; |
527 | 538 | ||
528 | out_err_unlock: | 539 | out_err_unlock: |
540 | if (local_contact == SMC_FIRST_CONTACT) | ||
541 | smc_lgr_forget(smc->conn.lgr); | ||
529 | mutex_unlock(&smc_create_lgr_pending); | 542 | mutex_unlock(&smc_create_lgr_pending); |
530 | smc_conn_free(&smc->conn); | 543 | smc_conn_free(&smc->conn); |
531 | out_err: | 544 | out_err: |
@@ -906,6 +919,8 @@ enqueue: | |||
906 | return; | 919 | return; |
907 | 920 | ||
908 | decline_rdma_unlock: | 921 | decline_rdma_unlock: |
922 | if (local_contact == SMC_FIRST_CONTACT) | ||
923 | smc_lgr_forget(new_smc->conn.lgr); | ||
909 | mutex_unlock(&smc_create_lgr_pending); | 924 | mutex_unlock(&smc_create_lgr_pending); |
910 | decline_rdma: | 925 | decline_rdma: |
911 | /* RDMA setup failed, switch back to TCP */ | 926 | /* RDMA setup failed, switch back to TCP */ |
@@ -918,6 +933,8 @@ decline_rdma: | |||
918 | goto out_connected; | 933 | goto out_connected; |
919 | 934 | ||
920 | out_err_unlock: | 935 | out_err_unlock: |
936 | if (local_contact == SMC_FIRST_CONTACT) | ||
937 | smc_lgr_forget(new_smc->conn.lgr); | ||
921 | mutex_unlock(&smc_create_lgr_pending); | 938 | mutex_unlock(&smc_create_lgr_pending); |
922 | out_err: | 939 | out_err: |
923 | newsmcsk->sk_state = SMC_CLOSED; | 940 | newsmcsk->sk_state = SMC_CLOSED; |
diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c index 94f21116dac5..7406cbb41856 100644 --- a/net/smc/smc_core.c +++ b/net/smc/smc_core.c | |||
@@ -128,6 +128,8 @@ static void smc_lgr_free_work(struct work_struct *work) | |||
128 | bool conns; | 128 | bool conns; |
129 | 129 | ||
130 | spin_lock_bh(&smc_lgr_list.lock); | 130 | spin_lock_bh(&smc_lgr_list.lock); |
131 | if (list_empty(&lgr->list)) | ||
132 | goto free; | ||
131 | read_lock_bh(&lgr->conns_lock); | 133 | read_lock_bh(&lgr->conns_lock); |
132 | conns = RB_EMPTY_ROOT(&lgr->conns_all); | 134 | conns = RB_EMPTY_ROOT(&lgr->conns_all); |
133 | read_unlock_bh(&lgr->conns_lock); | 135 | read_unlock_bh(&lgr->conns_lock); |
@@ -136,6 +138,7 @@ static void smc_lgr_free_work(struct work_struct *work) | |||
136 | return; | 138 | return; |
137 | } | 139 | } |
138 | list_del_init(&lgr->list); /* remove from smc_lgr_list */ | 140 | list_del_init(&lgr->list); /* remove from smc_lgr_list */ |
141 | free: | ||
139 | spin_unlock_bh(&smc_lgr_list.lock); | 142 | spin_unlock_bh(&smc_lgr_list.lock); |
140 | smc_lgr_free(lgr); | 143 | smc_lgr_free(lgr); |
141 | } | 144 | } |