Skip to content

Commit 09c61d2

Browse files
karstengrdavem330
authored andcommitted
net/smc: wait for departure of an IB message
Introduce smc_wr_tx_send_wait() to send an IB message and wait for the tx completion event of the message. This makes sure that the message is no longer in-flight when the function returns. 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 b286a06 commit 09c61d2

File tree

3 files changed

+42
-0
lines changed

3 files changed

+42
-0
lines changed

net/smc/smc_core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ struct smc_link {
8585
struct smc_rdma_sges *wr_tx_rdma_sges;/*RDMA WRITE gather meta data*/
8686
struct smc_rdma_wr *wr_tx_rdmas; /* WR RDMA WRITE */
8787
struct smc_wr_tx_pend *wr_tx_pends; /* WR send waiting for CQE */
88+
struct completion *wr_tx_compl; /* WR send CQE completion */
8889
/* above four vectors have wr_tx_cnt elements and use the same index */
8990
dma_addr_t wr_tx_dma_addr; /* DMA address of wr_tx_bufs */
9091
atomic_long_t wr_tx_id; /* seq # of last sent WR */

net/smc/smc_wr.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ struct smc_wr_tx_pend { /* control data for a pending send request */
4444
struct smc_link *link;
4545
u32 idx;
4646
struct smc_wr_tx_pend_priv priv;
47+
u8 compl_requested;
4748
};
4849

4950
/******************************** send queue *********************************/
@@ -103,6 +104,8 @@ static inline void smc_wr_tx_process_cqe(struct ib_wc *wc)
103104
if (pnd_snd_idx == link->wr_tx_cnt)
104105
return;
105106
link->wr_tx_pends[pnd_snd_idx].wc_status = wc->status;
107+
if (link->wr_tx_pends[pnd_snd_idx].compl_requested)
108+
complete(&link->wr_tx_compl[pnd_snd_idx]);
106109
memcpy(&pnd_snd, &link->wr_tx_pends[pnd_snd_idx], sizeof(pnd_snd));
107110
/* clear the full struct smc_wr_tx_pend including .priv */
108111
memset(&link->wr_tx_pends[pnd_snd_idx], 0,
@@ -275,6 +278,33 @@ int smc_wr_tx_send(struct smc_link *link, struct smc_wr_tx_pend_priv *priv)
275278
return rc;
276279
}
277280

281+
/* Send prepared WR slot via ib_post_send and wait for send completion
282+
* notification.
283+
* @priv: pointer to smc_wr_tx_pend_priv identifying prepared message buffer
284+
*/
285+
int smc_wr_tx_send_wait(struct smc_link *link, struct smc_wr_tx_pend_priv *priv,
286+
unsigned long timeout)
287+
{
288+
struct smc_wr_tx_pend *pend;
289+
int rc;
290+
291+
pend = container_of(priv, struct smc_wr_tx_pend, priv);
292+
pend->compl_requested = 1;
293+
init_completion(&link->wr_tx_compl[pend->idx]);
294+
295+
rc = smc_wr_tx_send(link, priv);
296+
if (rc)
297+
return rc;
298+
/* wait for completion by smc_wr_tx_process_cqe() */
299+
rc = wait_for_completion_interruptible_timeout(
300+
&link->wr_tx_compl[pend->idx], timeout);
301+
if (rc <= 0)
302+
rc = -ENODATA;
303+
if (rc > 0)
304+
rc = 0;
305+
return rc;
306+
}
307+
278308
/* Register a memory region and wait for result. */
279309
int smc_wr_reg_send(struct smc_link *link, struct ib_mr *mr)
280310
{
@@ -555,6 +585,8 @@ void smc_wr_free_link(struct smc_link *lnk)
555585

556586
void smc_wr_free_link_mem(struct smc_link *lnk)
557587
{
588+
kfree(lnk->wr_tx_compl);
589+
lnk->wr_tx_compl = NULL;
558590
kfree(lnk->wr_tx_pends);
559591
lnk->wr_tx_pends = NULL;
560592
kfree(lnk->wr_tx_mask);
@@ -625,8 +657,15 @@ int smc_wr_alloc_link_mem(struct smc_link *link)
625657
GFP_KERNEL);
626658
if (!link->wr_tx_pends)
627659
goto no_mem_wr_tx_mask;
660+
link->wr_tx_compl = kcalloc(SMC_WR_BUF_CNT,
661+
sizeof(link->wr_tx_compl[0]),
662+
GFP_KERNEL);
663+
if (!link->wr_tx_compl)
664+
goto no_mem_wr_tx_pends;
628665
return 0;
629666

667+
no_mem_wr_tx_pends:
668+
kfree(link->wr_tx_pends);
630669
no_mem_wr_tx_mask:
631670
kfree(link->wr_tx_mask);
632671
no_mem_wr_rx_sges:

net/smc/smc_wr.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ int smc_wr_tx_put_slot(struct smc_link *link,
101101
struct smc_wr_tx_pend_priv *wr_pend_priv);
102102
int smc_wr_tx_send(struct smc_link *link,
103103
struct smc_wr_tx_pend_priv *wr_pend_priv);
104+
int smc_wr_tx_send_wait(struct smc_link *link, struct smc_wr_tx_pend_priv *priv,
105+
unsigned long timeout);
104106
void smc_wr_tx_cq_handler(struct ib_cq *ib_cq, void *cq_context);
105107
void smc_wr_tx_dismiss_slots(struct smc_link *lnk, u8 wr_rx_hdr_type,
106108
smc_wr_tx_filter filter,

0 commit comments

Comments
 (0)