Skip to content

Commit 08ae27d

Browse files
karstengrdavem330
authored andcommitted
net/smc: delete link processing as SMC server
Add smc_llc_process_srv_delete_link() to process a DELETE_LINK request as SMC server. When the request is to delete ALL links then terminate the whole link group. If not, find the link to delete by its link_id, send the DELETE_LINK request LLC message and wait for the response. No matter if a response was received, clear the deleted link and update the link group state. Signed-off-by: Karsten Graul <[email protected]> Reviewed-by: Ursula Braun <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 9c41687 commit 08ae27d

File tree

1 file changed

+72
-0
lines changed

1 file changed

+72
-0
lines changed

net/smc/smc_llc.c

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,6 +1187,76 @@ static void smc_llc_process_cli_delete_link(struct smc_link_group *lgr)
11871187
kfree(qentry);
11881188
}
11891189

1190+
static void smc_llc_process_srv_delete_link(struct smc_link_group *lgr)
1191+
{
1192+
struct smc_llc_msg_del_link *del_llc;
1193+
struct smc_link *lnk, *lnk_del;
1194+
struct smc_llc_qentry *qentry;
1195+
int active_links;
1196+
int i;
1197+
1198+
mutex_lock(&lgr->llc_conf_mutex);
1199+
qentry = smc_llc_flow_qentry_clr(&lgr->llc_flow_lcl);
1200+
lnk = qentry->link;
1201+
del_llc = &qentry->msg.delete_link;
1202+
1203+
if (qentry->msg.delete_link.hd.flags & SMC_LLC_FLAG_DEL_LINK_ALL) {
1204+
/* delete entire lgr */
1205+
smc_lgr_terminate_sched(lgr);
1206+
goto out;
1207+
}
1208+
/* delete single link */
1209+
lnk_del = NULL;
1210+
for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) {
1211+
if (lgr->lnk[i].link_id == del_llc->link_num) {
1212+
lnk_del = &lgr->lnk[i];
1213+
break;
1214+
}
1215+
}
1216+
if (!lnk_del)
1217+
goto out; /* asymmetric link already deleted */
1218+
1219+
if (smc_link_downing(&lnk_del->state)) {
1220+
/* tbd: call smc_switch_conns(lgr, lnk_del, false); */
1221+
smc_wr_tx_wait_no_pending_sends(lnk_del);
1222+
}
1223+
if (!list_empty(&lgr->list)) {
1224+
/* qentry is either a request from peer (send it back to
1225+
* initiate the DELETE_LINK processing), or a locally
1226+
* enqueued DELETE_LINK request (forward it)
1227+
*/
1228+
if (!smc_llc_send_message(lnk, &qentry->msg)) {
1229+
struct smc_llc_msg_del_link *del_llc_resp;
1230+
struct smc_llc_qentry *qentry2;
1231+
1232+
qentry2 = smc_llc_wait(lgr, lnk, SMC_LLC_WAIT_TIME,
1233+
SMC_LLC_DELETE_LINK);
1234+
if (!qentry2) {
1235+
} else {
1236+
del_llc_resp = &qentry2->msg.delete_link;
1237+
smc_llc_flow_qentry_del(&lgr->llc_flow_lcl);
1238+
}
1239+
}
1240+
}
1241+
smcr_link_clear(lnk_del);
1242+
1243+
active_links = smc_llc_active_link_count(lgr);
1244+
if (active_links == 1) {
1245+
lgr->type = SMC_LGR_SINGLE;
1246+
} else if (!active_links) {
1247+
lgr->type = SMC_LGR_NONE;
1248+
smc_lgr_terminate_sched(lgr);
1249+
}
1250+
1251+
if (lgr->type == SMC_LGR_SINGLE && !list_empty(&lgr->list)) {
1252+
/* trigger setup of asymm alt link */
1253+
/* tbd: call smc_llc_srv_add_link_local(lnk); */
1254+
}
1255+
out:
1256+
mutex_unlock(&lgr->llc_conf_mutex);
1257+
kfree(qentry);
1258+
}
1259+
11901260
static void smc_llc_delete_link_work(struct work_struct *work)
11911261
{
11921262
struct smc_link_group *lgr = container_of(work, struct smc_link_group,
@@ -1200,6 +1270,8 @@ static void smc_llc_delete_link_work(struct work_struct *work)
12001270

12011271
if (lgr->role == SMC_CLNT)
12021272
smc_llc_process_cli_delete_link(lgr);
1273+
else
1274+
smc_llc_process_srv_delete_link(lgr);
12031275
out:
12041276
smc_llc_flow_stop(lgr, &lgr->llc_flow_lcl);
12051277
}

0 commit comments

Comments
 (0)