diff options
Diffstat (limited to 'net/smc/smc_wr.c')
| -rw-r--r-- | net/smc/smc_wr.c | 46 | 
1 files changed, 41 insertions, 5 deletions
diff --git a/net/smc/smc_wr.c b/net/smc/smc_wr.c index c2694750a6a8..253aa75dc2b6 100644 --- a/net/smc/smc_wr.c +++ b/net/smc/smc_wr.c @@ -160,6 +160,7 @@ static inline int smc_wr_tx_get_free_slot_index(struct smc_link *link, u32 *idx)   * @link:		Pointer to smc_link used to later send the message.   * @handler:		Send completion handler function pointer.   * @wr_buf:		Out value returns pointer to message buffer. + * @wr_rdma_buf:	Out value returns pointer to rdma work request.   * @wr_pend_priv:	Out value returns pointer serving as handler context.   *   * Return: 0 on success, or -errno on error. @@ -167,6 +168,7 @@ static inline int smc_wr_tx_get_free_slot_index(struct smc_link *link, u32 *idx)  int smc_wr_tx_get_free_slot(struct smc_link *link,  			    smc_wr_tx_handler handler,  			    struct smc_wr_buf **wr_buf, +			    struct smc_rdma_wr **wr_rdma_buf,  			    struct smc_wr_tx_pend_priv **wr_pend_priv)  {  	struct smc_wr_tx_pend *wr_pend; @@ -204,6 +206,8 @@ int smc_wr_tx_get_free_slot(struct smc_link *link,  	wr_ib = &link->wr_tx_ibs[idx];  	wr_ib->wr_id = wr_id;  	*wr_buf = &link->wr_tx_bufs[idx]; +	if (wr_rdma_buf) +		*wr_rdma_buf = &link->wr_tx_rdmas[idx];  	*wr_pend_priv = &wr_pend->priv;  	return 0;  } @@ -218,10 +222,10 @@ int smc_wr_tx_put_slot(struct smc_link *link,  		u32 idx = pend->idx;  		/* clear the full struct smc_wr_tx_pend including .priv */ -		memset(&link->wr_tx_pends[pend->idx], 0, -		       sizeof(link->wr_tx_pends[pend->idx])); -		memset(&link->wr_tx_bufs[pend->idx], 0, -		       sizeof(link->wr_tx_bufs[pend->idx])); +		memset(&link->wr_tx_pends[idx], 0, +		       sizeof(link->wr_tx_pends[idx])); +		memset(&link->wr_tx_bufs[idx], 0, +		       sizeof(link->wr_tx_bufs[idx]));  		test_and_clear_bit(idx, link->wr_tx_mask);  		return 1;  	} @@ -465,12 +469,26 @@ static void smc_wr_init_sge(struct smc_link *lnk)  			lnk->wr_tx_dma_addr + i * SMC_WR_BUF_SIZE;  		lnk->wr_tx_sges[i].length = SMC_WR_TX_SIZE;  		lnk->wr_tx_sges[i].lkey = lnk->roce_pd->local_dma_lkey; +		lnk->wr_tx_rdma_sges[i].tx_rdma_sge[0].wr_tx_rdma_sge[0].lkey = +			lnk->roce_pd->local_dma_lkey; +		lnk->wr_tx_rdma_sges[i].tx_rdma_sge[0].wr_tx_rdma_sge[1].lkey = +			lnk->roce_pd->local_dma_lkey; +		lnk->wr_tx_rdma_sges[i].tx_rdma_sge[1].wr_tx_rdma_sge[0].lkey = +			lnk->roce_pd->local_dma_lkey; +		lnk->wr_tx_rdma_sges[i].tx_rdma_sge[1].wr_tx_rdma_sge[1].lkey = +			lnk->roce_pd->local_dma_lkey;  		lnk->wr_tx_ibs[i].next = NULL;  		lnk->wr_tx_ibs[i].sg_list = &lnk->wr_tx_sges[i];  		lnk->wr_tx_ibs[i].num_sge = 1;  		lnk->wr_tx_ibs[i].opcode = IB_WR_SEND;  		lnk->wr_tx_ibs[i].send_flags =  			IB_SEND_SIGNALED | IB_SEND_SOLICITED; +		lnk->wr_tx_rdmas[i].wr_tx_rdma[0].wr.opcode = IB_WR_RDMA_WRITE; +		lnk->wr_tx_rdmas[i].wr_tx_rdma[1].wr.opcode = IB_WR_RDMA_WRITE; +		lnk->wr_tx_rdmas[i].wr_tx_rdma[0].wr.sg_list = +			lnk->wr_tx_rdma_sges[i].tx_rdma_sge[0].wr_tx_rdma_sge; +		lnk->wr_tx_rdmas[i].wr_tx_rdma[1].wr.sg_list = +			lnk->wr_tx_rdma_sges[i].tx_rdma_sge[1].wr_tx_rdma_sge;  	}  	for (i = 0; i < lnk->wr_rx_cnt; i++) {  		lnk->wr_rx_sges[i].addr = @@ -521,8 +539,12 @@ void smc_wr_free_link_mem(struct smc_link *lnk)  	lnk->wr_tx_mask = NULL;  	kfree(lnk->wr_tx_sges);  	lnk->wr_tx_sges = NULL; +	kfree(lnk->wr_tx_rdma_sges); +	lnk->wr_tx_rdma_sges = NULL;  	kfree(lnk->wr_rx_sges);  	lnk->wr_rx_sges = NULL; +	kfree(lnk->wr_tx_rdmas); +	lnk->wr_tx_rdmas = NULL;  	kfree(lnk->wr_rx_ibs);  	lnk->wr_rx_ibs = NULL;  	kfree(lnk->wr_tx_ibs); @@ -552,10 +574,20 @@ int smc_wr_alloc_link_mem(struct smc_link *link)  				  GFP_KERNEL);  	if (!link->wr_rx_ibs)  		goto no_mem_wr_tx_ibs; +	link->wr_tx_rdmas = kcalloc(SMC_WR_BUF_CNT, +				    sizeof(link->wr_tx_rdmas[0]), +				    GFP_KERNEL); +	if (!link->wr_tx_rdmas) +		goto no_mem_wr_rx_ibs; +	link->wr_tx_rdma_sges = kcalloc(SMC_WR_BUF_CNT, +					sizeof(link->wr_tx_rdma_sges[0]), +					GFP_KERNEL); +	if (!link->wr_tx_rdma_sges) +		goto no_mem_wr_tx_rdmas;  	link->wr_tx_sges = kcalloc(SMC_WR_BUF_CNT, sizeof(link->wr_tx_sges[0]),  				   GFP_KERNEL);  	if (!link->wr_tx_sges) -		goto no_mem_wr_rx_ibs; +		goto no_mem_wr_tx_rdma_sges;  	link->wr_rx_sges = kcalloc(SMC_WR_BUF_CNT * 3,  				   sizeof(link->wr_rx_sges[0]),  				   GFP_KERNEL); @@ -579,6 +611,10 @@ no_mem_wr_rx_sges:  	kfree(link->wr_rx_sges);  no_mem_wr_tx_sges:  	kfree(link->wr_tx_sges); +no_mem_wr_tx_rdma_sges: +	kfree(link->wr_tx_rdma_sges); +no_mem_wr_tx_rdmas: +	kfree(link->wr_tx_rdmas);  no_mem_wr_rx_ibs:  	kfree(link->wr_rx_ibs);  no_mem_wr_tx_ibs:  |