Skip to content

Commit d550066

Browse files
karstengrdavem330
authored andcommitted
net/smc: mutex to protect the lgr against parallel reconfigurations
Introduce llc_conf_mutex in the link group which is used to protect the buffers and lgr states against parallel link reconfiguration. This ensures that new connections do not start to register buffers with the links of a link group when link creation or termination is running. Signed-off-by: Karsten Graul <kgraul@linux.ibm.com> Reviewed-by: Ursula Braun <ubraun@linux.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent fbed3b3 commit d550066

File tree

4 files changed

+34
-12
lines changed

4 files changed

+34
-12
lines changed

net/smc/af_smc.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,13 @@ static int smcr_lgr_reg_rmbs(struct smc_link *link,
344344
struct smc_link_group *lgr = link->lgr;
345345
int i, rc = 0;
346346

347+
rc = smc_llc_flow_initiate(lgr, SMC_LLC_FLOW_RKEY);
348+
if (rc)
349+
return rc;
350+
/* protect against parallel smc_llc_cli_rkey_exchange() and
351+
* parallel smcr_link_reg_rmb()
352+
*/
353+
mutex_lock(&lgr->llc_conf_mutex);
347354
for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) {
348355
if (lgr->lnk[i].state != SMC_LNK_ACTIVE)
349356
continue;
@@ -360,6 +367,8 @@ static int smcr_lgr_reg_rmbs(struct smc_link *link,
360367
}
361368
rmb_desc->is_conf_rkey = true;
362369
out:
370+
mutex_unlock(&lgr->llc_conf_mutex);
371+
smc_llc_flow_stop(lgr, &lgr->llc_flow_lcl);
363372
return rc;
364373
}
365374

net/smc/smc_core.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -448,11 +448,21 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)
448448
static void smcr_buf_unuse(struct smc_buf_desc *rmb_desc,
449449
struct smc_link_group *lgr)
450450
{
451+
int rc;
452+
451453
if (rmb_desc->is_conf_rkey && !list_empty(&lgr->list)) {
452454
/* unregister rmb with peer */
453-
smc_llc_do_delete_rkey(lgr, rmb_desc);
454-
rmb_desc->is_conf_rkey = false;
455+
rc = smc_llc_flow_initiate(lgr, SMC_LLC_FLOW_RKEY);
456+
if (!rc) {
457+
/* protect against smc_llc_cli_rkey_exchange() */
458+
mutex_lock(&lgr->llc_conf_mutex);
459+
smc_llc_do_delete_rkey(lgr, rmb_desc);
460+
rmb_desc->is_conf_rkey = false;
461+
mutex_unlock(&lgr->llc_conf_mutex);
462+
smc_llc_flow_stop(lgr, &lgr->llc_flow_lcl);
463+
}
455464
}
465+
456466
if (rmb_desc->is_reg_err) {
457467
/* buf registration failed, reuse not possible */
458468
mutex_lock(&lgr->rmbs_lock);
@@ -552,6 +562,7 @@ static void smcr_rtoken_clear_link(struct smc_link *lnk)
552562
}
553563
}
554564

565+
/* must be called under lgr->llc_conf_mutex lock */
555566
void smcr_link_clear(struct smc_link *lnk)
556567
{
557568
struct smc_ib_device *smcibdev;
@@ -1170,7 +1181,9 @@ static int smcr_buf_map_link(struct smc_buf_desc *buf_desc, bool is_rmb,
11701181
return rc;
11711182
}
11721183

1173-
/* register a new rmb on IB device */
1184+
/* register a new rmb on IB device,
1185+
* must be called under lgr->llc_conf_mutex lock
1186+
*/
11741187
int smcr_link_reg_rmb(struct smc_link *link, struct smc_buf_desc *rmb_desc)
11751188
{
11761189
if (list_empty(&link->lgr->list))
@@ -1224,7 +1237,9 @@ int smcr_buf_map_lgr(struct smc_link *lnk)
12241237
return 0;
12251238
}
12261239

1227-
/* register all used buffers of lgr for a new link */
1240+
/* register all used buffers of lgr for a new link,
1241+
* must be called under lgr->llc_conf_mutex lock
1242+
*/
12281243
int smcr_buf_reg_lgr(struct smc_link *lnk)
12291244
{
12301245
struct smc_link_group *lgr = lnk->lgr;
@@ -1278,6 +1293,8 @@ static int smcr_buf_map_usable_links(struct smc_link_group *lgr,
12781293
{
12791294
int i, rc = 0;
12801295

1296+
/* protect against parallel link reconfiguration */
1297+
mutex_lock(&lgr->llc_conf_mutex);
12811298
for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) {
12821299
struct smc_link *lnk = &lgr->lnk[i];
12831300

@@ -1289,6 +1306,7 @@ static int smcr_buf_map_usable_links(struct smc_link_group *lgr,
12891306
}
12901307
}
12911308
out:
1309+
mutex_unlock(&lgr->llc_conf_mutex);
12921310
return rc;
12931311
}
12941312

net/smc/smc_core.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,8 @@ struct smc_link_group {
248248
/* queue for llc events */
249249
spinlock_t llc_event_q_lock;
250250
/* protects llc_event_q */
251+
struct mutex llc_conf_mutex;
252+
/* protects lgr reconfig. */
251253
struct work_struct llc_event_work;
252254
/* llc event worker */
253255
wait_queue_head_t llc_waiter;

net/smc/smc_llc.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -848,6 +848,7 @@ void smc_llc_lgr_init(struct smc_link_group *lgr, struct smc_sock *smc)
848848
spin_lock_init(&lgr->llc_event_q_lock);
849849
spin_lock_init(&lgr->llc_flow_lock);
850850
init_waitqueue_head(&lgr->llc_waiter);
851+
mutex_init(&lgr->llc_conf_mutex);
851852
lgr->llc_testlink_time = net->ipv4.sysctl_tcp_keepalive_time;
852853
}
853854

@@ -897,9 +898,6 @@ int smc_llc_do_confirm_rkey(struct smc_link *send_link,
897898
struct smc_llc_qentry *qentry = NULL;
898899
int rc = 0;
899900

900-
rc = smc_llc_flow_initiate(lgr, SMC_LLC_FLOW_RKEY);
901-
if (rc)
902-
return rc;
903901
rc = smc_llc_send_confirm_rkey(send_link, rmb_desc);
904902
if (rc)
905903
goto out;
@@ -911,7 +909,6 @@ int smc_llc_do_confirm_rkey(struct smc_link *send_link,
911909
out:
912910
if (qentry)
913911
smc_llc_flow_qentry_del(&lgr->llc_flow_lcl);
914-
smc_llc_flow_stop(lgr, &lgr->llc_flow_lcl);
915912
return rc;
916913
}
917914

@@ -927,9 +924,6 @@ int smc_llc_do_delete_rkey(struct smc_link_group *lgr,
927924
if (!send_link)
928925
return -ENOLINK;
929926

930-
rc = smc_llc_flow_initiate(lgr, SMC_LLC_FLOW_RKEY);
931-
if (rc)
932-
return rc;
933927
/* protected by llc_flow control */
934928
rc = smc_llc_send_delete_rkey(send_link, rmb_desc);
935929
if (rc)
@@ -942,7 +936,6 @@ int smc_llc_do_delete_rkey(struct smc_link_group *lgr,
942936
out:
943937
if (qentry)
944938
smc_llc_flow_qentry_del(&lgr->llc_flow_lcl);
945-
smc_llc_flow_stop(lgr, &lgr->llc_flow_lcl);
946939
return rc;
947940
}
948941

0 commit comments

Comments
 (0)