Skip to content

Commit f3811fd

Browse files
karstengrdavem330
authored andcommitted
net/smc: send DELETE_LINK, ALL message and wait for send to complete
Add smc_llc_send_message_wait() which uses smc_wr_tx_send_wait() to send an LLC message and waits for the message send to complete. smc_llc_send_link_delete_all() calls the new function to send an DELETE_LINK,ALL LLC message. The RFC states that the sender of this type of message needs to wait for the completion event of the message transmission and can terminate the link afterwards. 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 09c61d2 commit f3811fd

File tree

3 files changed

+51
-0
lines changed

3 files changed

+51
-0
lines changed

net/smc/smc_core.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,9 @@ static void smc_lgr_free_work(struct work_struct *work)
238238
spin_unlock_bh(lgr_lock);
239239
cancel_delayed_work(&lgr->free_work);
240240

241+
if (!lgr->is_smcd && !lgr->terminating)
242+
smc_llc_send_link_delete_all(lgr, true,
243+
SMC_LLC_DEL_PROG_INIT_TERM);
241244
if (lgr->is_smcd && !lgr->terminating)
242245
smc_ism_signal_shutdown(lgr);
243246
if (!lgr->is_smcd) {
@@ -847,6 +850,8 @@ static void smc_lgr_cleanup(struct smc_link_group *lgr)
847850
smc_ism_put_vlan(lgr->smcd, lgr->vlan_id);
848851
put_device(&lgr->smcd->dev);
849852
} else {
853+
smc_llc_send_link_delete_all(lgr, false,
854+
SMC_LLC_DEL_OP_INIT_TERM);
850855
for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) {
851856
struct smc_link *lnk = &lgr->lnk[i];
852857

net/smc/smc_llc.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,25 @@ static int smc_llc_send_message(struct smc_link *link, void *llcbuf)
560560
return smc_wr_tx_send(link, pend);
561561
}
562562

563+
/* schedule an llc send on link, may wait for buffers,
564+
* and wait for send completion notification.
565+
* @return 0 on success
566+
*/
567+
static int smc_llc_send_message_wait(struct smc_link *link, void *llcbuf)
568+
{
569+
struct smc_wr_tx_pend_priv *pend;
570+
struct smc_wr_buf *wr_buf;
571+
int rc;
572+
573+
if (!smc_link_usable(link))
574+
return -ENOLINK;
575+
rc = smc_llc_add_pending_send(link, &wr_buf, &pend);
576+
if (rc)
577+
return rc;
578+
memcpy(wr_buf, llcbuf, sizeof(union smc_llc_msg));
579+
return smc_wr_tx_send_wait(link, pend, SMC_LLC_WAIT_TIME);
580+
}
581+
563582
/********************************* receive ***********************************/
564583

565584
static int smc_llc_alloc_alt_link(struct smc_link_group *lgr,
@@ -1215,6 +1234,29 @@ static void smc_llc_process_cli_delete_link(struct smc_link_group *lgr)
12151234
kfree(qentry);
12161235
}
12171236

1237+
/* try to send a DELETE LINK ALL request on any active link,
1238+
* waiting for send completion
1239+
*/
1240+
void smc_llc_send_link_delete_all(struct smc_link_group *lgr, bool ord, u32 rsn)
1241+
{
1242+
struct smc_llc_msg_del_link delllc = {0};
1243+
int i;
1244+
1245+
delllc.hd.common.type = SMC_LLC_DELETE_LINK;
1246+
delllc.hd.length = sizeof(delllc);
1247+
if (ord)
1248+
delllc.hd.flags |= SMC_LLC_FLAG_DEL_LINK_ORDERLY;
1249+
delllc.hd.flags |= SMC_LLC_FLAG_DEL_LINK_ALL;
1250+
delllc.reason = htonl(rsn);
1251+
1252+
for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) {
1253+
if (!smc_link_usable(&lgr->lnk[i]))
1254+
continue;
1255+
if (!smc_llc_send_message_wait(&lgr->lnk[i], &delllc))
1256+
break;
1257+
}
1258+
}
1259+
12181260
static void smc_llc_process_srv_delete_link(struct smc_link_group *lgr)
12191261
{
12201262
struct smc_llc_msg_del_link *del_llc;
@@ -1230,6 +1272,8 @@ static void smc_llc_process_srv_delete_link(struct smc_link_group *lgr)
12301272

12311273
if (qentry->msg.delete_link.hd.flags & SMC_LLC_FLAG_DEL_LINK_ALL) {
12321274
/* delete entire lgr */
1275+
smc_llc_send_link_delete_all(lgr, true, ntohl(
1276+
qentry->msg.delete_link.reason));
12331277
smc_lgr_terminate_sched(lgr);
12341278
goto out;
12351279
}

net/smc/smc_llc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ struct smc_llc_qentry *smc_llc_wait(struct smc_link_group *lgr,
8989
int time_out, u8 exp_msg);
9090
struct smc_llc_qentry *smc_llc_flow_qentry_clr(struct smc_llc_flow *flow);
9191
void smc_llc_flow_qentry_del(struct smc_llc_flow *flow);
92+
void smc_llc_send_link_delete_all(struct smc_link_group *lgr, bool ord,
93+
u32 rsn);
9294
int smc_llc_cli_add_link(struct smc_link *link, struct smc_llc_qentry *qentry);
9395
int smc_llc_srv_add_link(struct smc_link *link);
9496
void smc_llc_srv_add_link_local(struct smc_link *link);

0 commit comments

Comments
 (0)