@@ -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. */
279309int 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
556586void 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 );
630669no_mem_wr_tx_mask :
631670 kfree (link -> wr_tx_mask );
632671no_mem_wr_rx_sges :
0 commit comments