Re: [PATCH 02/05] svcrdma: Refactor RDMA_WRITE dma mapping logic

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 





On 5/20/08 9:52 PM, "J. Bruce Fields" <bfields@xxxxxxxxxxxx> wrote:

> On Tue, May 20, 2008 at 08:46:08PM -0400, J. Bruce Fields wrote:
>> On Sun, May 18, 2008 at 07:13:18PM -0500, Tom Tucker wrote:
>>> In order to make the dma mapping code easier to understand and reduce the
>>> number of I/O contexts required, move the DMA for RDMA_WRITE WR to the
>>> code that prepares the WR SGE.
>> 
>> This one makes my (32-bit) compiler whine:
>> 
>> CC      net/sunrpc/xprtrdma/svc_rdma_sendto.o
>> net/sunrpc/xprtrdma/svc_rdma_sendto.c: In function ?send_write¹:
>> net/sunrpc/xprtrdma/svc_rdma_sendto.c:180: warning: passing argument 2 of
>> ?ib_dma_map_single¹ makes pointer from integer without a cast
>> net/sunrpc/xprtrdma/svc_rdma_sendto.c: In function ?send_reply¹:
>> net/sunrpc/xprtrdma/svc_rdma_sendto.c:416: warning: passing argument 2 of
>> ?ib_dma_map_single¹ makes pointer from integer without a cast
> 
> Erm, sorry, that should have been:
> 
> unrpc/xprtrdma/svc_rdma_sendto.c: In function ?send_write¹:
> net/sunrpc/xprtrdma/svc_rdma_sendto.c:180: warning: cast to pointer from
> integer of different size
> net/sunrpc/xprtrdma/svc_rdma_sendto.c: In function ?send_reply¹:
> net/sunrpc/xprtrdma/svc_rdma_sendto.c:417: warning: cast to pointer from
> integer of different size
>

I have to jump on a plane, but I'll take a look tonight. Basically, the
ib_sge is sometimes being used to save pointers and other times dma_addr_t.
I need my own type there I guess.

Tom
 
> --b.
> 
>> And the types do seem weird:
>> 
>>> 
>>> Signed-off-by: Tom Tucker <tom@xxxxxxxxxxxxxxxxxxxxx>
>>> 
>>> ---
>>>  net/sunrpc/xprtrdma/svc_rdma_sendto.c    |   44
>>> +++++++++++++++---------------
>>>  net/sunrpc/xprtrdma/svc_rdma_transport.c |    5 +++-
>>>  2 files changed, 26 insertions(+), 23 deletions(-)
>>> 
>>> diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c
>>> b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
>>> index fb82b1b..85931c4 100644
>>> --- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c
>>> +++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
>>> @@ -84,10 +84,7 @@ static struct ib_sge *xdr_to_sge(struct svcxprt_rdma
>>> *xprt,
>>> sge_no = 1;
>>>  
>>> /* Head SGE */
>>> - sge[sge_no].addr = ib_dma_map_single(xprt->sc_cm_id->device,
>>> -          xdr->head[0].iov_base,
>>> -          xdr->head[0].iov_len,
>>> -          DMA_TO_DEVICE);
>>> + sge[sge_no].addr = (unsigned long)xdr->head[0].iov_base;
>> 
>> So before we called a function that took a void *, returned a u64; now
>> we're storing a void* directly into a u64.
>> 
>>> sge_bytes = min_t(u32, byte_count, xdr->head[0].iov_len);
>>> byte_count -= sge_bytes;
>>> sge[sge_no].length = sge_bytes;
>>> @@ -99,11 +96,9 @@ static struct ib_sge *xdr_to_sge(struct svcxprt_rdma
>>> *xprt,
>>> page_bytes = xdr->page_len;
>>> page_off = xdr->page_base;
>>> while (byte_count && page_bytes) {
>>> +  sge[sge_no].addr = (unsigned long)
>>> +   page_address(xdr->pages[page_no]) + page_off;
>>> sge_bytes = min_t(u32, byte_count, (PAGE_SIZE-page_off));
>>> -  sge[sge_no].addr =
>>> -   ib_dma_map_page(xprt->sc_cm_id->device,
>>> -     xdr->pages[page_no], page_off,
>>> -     sge_bytes, DMA_TO_DEVICE);
>>> sge_bytes = min(sge_bytes, page_bytes);
>>> byte_count -= sge_bytes;
>>> page_bytes -= sge_bytes;
>>> @@ -117,11 +112,7 @@ static struct ib_sge *xdr_to_sge(struct svcxprt_rdma
>>> *xprt,
>>>  
>>> /* Tail SGE */
>>> if (byte_count && xdr->tail[0].iov_len) {
>>> -  sge[sge_no].addr =
>>> -   ib_dma_map_single(xprt->sc_cm_id->device,
>>> -       xdr->tail[0].iov_base,
>>> -       xdr->tail[0].iov_len,
>>> -       DMA_TO_DEVICE);
>>> +  sge[sge_no].addr = (unsigned long)xdr->tail[0].iov_base;
>>> sge_bytes = min_t(u32, byte_count, xdr->tail[0].iov_len);
>>> byte_count -= sge_bytes;
>>> sge[sge_no].length = sge_bytes;
>>> @@ -145,7 +136,6 @@ static int send_write(struct svcxprt_rdma *xprt, struct
>>> svc_rqst *rqstp,
>>>      u32 xdr_off, int write_len,
>>>      struct ib_sge *xdr_sge, int sge_count)
>>>  {
>>> - struct svc_rdma_op_ctxt *tmp_sge_ctxt;
>>> struct ib_send_wr write_wr;
>>> struct ib_sge *sge;
>>> int xdr_sge_no;
>>> @@ -163,9 +153,8 @@ static int send_write(struct svcxprt_rdma *xprt, struct
>>> svc_rqst *rqstp,
>>> write_len, xdr_sge, sge_count);
>>>  
>>> ctxt = svc_rdma_get_context(xprt);
>>> - ctxt->count = 0;
>>> - tmp_sge_ctxt = svc_rdma_get_context(xprt);
>>> - sge = tmp_sge_ctxt->sge;
>>> + ctxt->direction = DMA_TO_DEVICE;
>>> + sge = ctxt->sge;
>>>  
>>> /* Find the SGE associated with xdr_off */
>>> for (bc = xdr_off, xdr_sge_no = 1; bc && xdr_sge_no < sge_count;
>>> @@ -181,14 +170,20 @@ static int send_write(struct svcxprt_rdma *xprt,
>>> struct svc_rqst *rqstp,
>>>  
>>> /* Copy the remaining SGE */
>>> while (bc != 0 && xdr_sge_no < sge_count) {
>>> -  sge[sge_no].addr = xdr_sge[xdr_sge_no].addr + sge_off;
>>> sge[sge_no].lkey = xdr_sge[xdr_sge_no].lkey;
>>> sge_bytes = min((size_t)bc,
>>> (size_t)(xdr_sge[xdr_sge_no].length-sge_off));
>>> sge[sge_no].length = sge_bytes;
>>> -
>>> +  sge[sge_no].addr =
>>> +   ib_dma_map_single(xprt->sc_cm_id->device,
>>> +       (void *)
>>> +       xdr_sge[xdr_sge_no].addr + sge_off,
>>> +       sge_bytes, DMA_TO_DEVICE);
>>> +  if (dma_mapping_error(sge[sge_no].addr))
>>> +   return -EINVAL;
>> 
>> And then here we're casting the u64 back to a void *.  Also, we're
>> adding sge_off to the input, instead of to the result.  Is it true that
>> that
>> 
>> ib_dma_map_single(., x + sge_off, ., .)
>> 
>> and
>> 
>> ib_dma_map_single(., x, ., .) + sge_off
>> 
>> always have the same result?
>> 
>> --b.
>> 
>>> sge_off = 0;
>>> sge_no++;
>>> +  ctxt->count++;
>>> xdr_sge_no++;
>>> bc -= sge_bytes;
>>> }
>>> @@ -210,11 +205,10 @@ static int send_write(struct svcxprt_rdma *xprt,
>>> struct svc_rqst *rqstp,
>>> /* Post It */
>>> atomic_inc(&rdma_stat_write);
>>> if (svc_rdma_send(xprt, &write_wr)) {
>>> -  svc_rdma_put_context(ctxt, 1);
>>> +  svc_rdma_put_context(ctxt, 0);
>>> /* Fatal error, close transport */
>>> ret = -EIO;
>>> }
>>> - svc_rdma_put_context(tmp_sge_ctxt, 0);
>>> return ret;
>>>  }
>>>  
>>> @@ -417,6 +411,11 @@ static int send_reply(struct svcxprt_rdma *rdma,
>>> sge_bytes = min((size_t)ctxt->sge[sge_no].length,
>>> (size_t)byte_count);
>>> byte_count -= sge_bytes;
>>> +  ctxt->sge[sge_no].addr =
>>> +   ib_dma_map_single(rdma->sc_cm_id->device,
>>> +       (void *)
>>> +       ctxt->sge[sge_no].addr,
>>> +       sge_bytes, DMA_TO_DEVICE);
>>> }
>>> BUG_ON(byte_count != 0);
>>>  
>>> @@ -428,8 +427,9 @@ static int send_reply(struct svcxprt_rdma *rdma,
>>> ctxt->pages[page_no+1] = rqstp->rq_respages[page_no];
>>> ctxt->count++;
>>> rqstp->rq_respages[page_no] = NULL;
>>> +  if (page_no+1 >= sge_no)
>>> +   ctxt->sge[page_no+1].length = 0;
>>> }
>>> -
>>> BUG_ON(sge_no > rdma->sc_max_sge);
>>> memset(&send_wr, 0, sizeof send_wr);
>>> ctxt->wr_op = IB_WR_SEND;
>>> diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c
>>> b/net/sunrpc/xprtrdma/svc_rdma_transport.c
>>> index e132509..9e9e244 100644
>>> --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
>>> +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
>>> @@ -361,10 +361,13 @@ static void sq_cq_reap(struct svcxprt_rdma *xprt)
>>>  
>>> switch (ctxt->wr_op) {
>>> case IB_WR_SEND:
>>> -  case IB_WR_RDMA_WRITE:
>>> svc_rdma_put_context(ctxt, 1);
>>> break;
>>>  
>>> +  case IB_WR_RDMA_WRITE:
>>> +   svc_rdma_put_context(ctxt, 0);
>>> +   break;
>>> +
>>> case IB_WR_RDMA_READ:
>>> if (test_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags)) {
>>> struct svc_rdma_op_ctxt *read_hdr = ctxt->read_hdr;
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
>> the body of a message to majordomo@xxxxxxxxxxxxxxx
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html


--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux