All of lore.kernel.org
 help / color / mirror / Atom feed
* rnfs: rq_respages pointer is bad
@ 2010-03-02  0:27 David J. Wilder
       [not found] ` <1267489621.9774.41.camel-XfwDJb4SXxnMbYB6QlFGEg@public.gmane.org>
  0 siblings, 1 reply; 8+ messages in thread
From: David J. Wilder @ 2010-03-02  0:27 UTC (permalink / raw)
  To: Tom Tucker, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	pradeep-r/Jw6+rmf7HQT0dZR+AlfA

Tom

I have been chasing an rnfs related Oops in svc_process().  I have found
the source of the Oops but I am not sure of my fix.  I am seeing the
problem on ppc64, kernel 2.6.32, I have not tried other arch yet.

The source of the problem is in rdma_read_complete(), I am finding that
rqstp->rq_respages is set to point past the end of the rqstp->rq_pages
page list.  This results in a NULL reference in svc_process() when
passing rq_respages[0] to page_address().

In rdma_read_complete() we are using rqstp->rq_arg.pages as the base of
the page list then indexing by page_no, however rq_arg.pages is not
pointing to the start of the list so rq_respages ends up pointing to:

rqstp->rq_pages[(head->count+1) + head->hdr_count]

In my case, it ends up pointing one past the end of the list by one.

Here is the change I made.

static int rdma_read_complete(struct svc_rqst *rqstp,
                              struct svc_rdma_op_ctxt *head)
{
        int page_no;
        int ret;

        BUG_ON(!head);

        /* Copy RPC pages */
        for (page_no = 0; page_no < head->count; page_no++) {
                put_page(rqstp->rq_pages[page_no]);
                rqstp->rq_pages[page_no] = head->pages[page_no];
        }
        /* Point rq_arg.pages past header */
        rqstp->rq_arg.pages = &rqstp->rq_pages[head->hdr_count];
        rqstp->rq_arg.page_len = head->arg.page_len;
        rqstp->rq_arg.page_base = head->arg.page_base;

        /* rq_respages starts after the last arg page */
-       rqstp->rq_respages = &rqstp->rq_arg.pages[page_no];
+	rqstp->rq_respages = &rqstp->rq_pages[page_no];
.
.
.

The change works for me, but I am not sure it is safe to assume the
rqstp->rq_pages[head->count] will always point to the last arg page.

Dave.

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

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: rnfs: rq_respages pointer is bad
       [not found] ` <1267489621.9774.41.camel-XfwDJb4SXxnMbYB6QlFGEg@public.gmane.org>
@ 2010-03-02  3:35   ` Tom Tucker
       [not found]     ` <4B8C8764.9080409-7bPotxP6k4+P2YhJcF5u+vpXobYPEAuW@public.gmane.org>
  2010-03-11 17:05   ` Tom Tucker
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ messages in thread
From: Tom Tucker @ 2010-03-02  3:35 UTC (permalink / raw)
  To: David J. Wilder
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, pradeep-r/Jw6+rmf7HQT0dZR+AlfA

Hi David:

That looks like a bug to me and it looks like what you propose is the 
correct fix. My only reservation is that if you are correct then how did 
this work at all without data corruption for large writes on x86_64?

I'm on the road right now, so I can't dig too deep until Wednesday, but 
at this point your analysis looks correct to me.

Tom


David J. Wilder wrote:
> Tom
>
> I have been chasing an rnfs related Oops in svc_process().  I have found
> the source of the Oops but I am not sure of my fix.  I am seeing the
> problem on ppc64, kernel 2.6.32, I have not tried other arch yet.
>
> The source of the problem is in rdma_read_complete(), I am finding that
> rqstp->rq_respages is set to point past the end of the rqstp->rq_pages
> page list.  This results in a NULL reference in svc_process() when
> passing rq_respages[0] to page_address().
>
> In rdma_read_complete() we are using rqstp->rq_arg.pages as the base of
> the page list then indexing by page_no, however rq_arg.pages is not
> pointing to the start of the list so rq_respages ends up pointing to:
>
> rqstp->rq_pages[(head->count+1) + head->hdr_count]
>
> In my case, it ends up pointing one past the end of the list by one.
>
> Here is the change I made.
>
> static int rdma_read_complete(struct svc_rqst *rqstp,
>                               struct svc_rdma_op_ctxt *head)
> {
>         int page_no;
>         int ret;
>
>         BUG_ON(!head);
>
>         /* Copy RPC pages */
>         for (page_no = 0; page_no < head->count; page_no++) {
>                 put_page(rqstp->rq_pages[page_no]);
>                 rqstp->rq_pages[page_no] = head->pages[page_no];
>         }
>         /* Point rq_arg.pages past header */
>         rqstp->rq_arg.pages = &rqstp->rq_pages[head->hdr_count];
>         rqstp->rq_arg.page_len = head->arg.page_len;
>         rqstp->rq_arg.page_base = head->arg.page_base;
>
>         /* rq_respages starts after the last arg page */
> -       rqstp->rq_respages = &rqstp->rq_arg.pages[page_no];
> +	rqstp->rq_respages = &rqstp->rq_pages[page_no];
> .
> .
> .
>
> The change works for me, but I am not sure it is safe to assume the
> rqstp->rq_pages[head->count] will always point to the last arg page.
>
> Dave.
>   

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

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: rnfs: rq_respages pointer is bad
       [not found]     ` <4B8C8764.9080409-7bPotxP6k4+P2YhJcF5u+vpXobYPEAuW@public.gmane.org>
@ 2010-03-03 16:20       ` David J. Wilder
  0 siblings, 0 replies; 8+ messages in thread
From: David J. Wilder @ 2010-03-03 16:20 UTC (permalink / raw)
  To: Tom Tucker
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, pradeep-r/Jw6+rmf7HQT0dZR+AlfA


On Mon, 2010-03-01 at 21:35 -0600, Tom Tucker wrote:
> Hi David:
> 
> That looks like a bug to me and it looks like what you propose is the 
> correct fix. My only reservation is that if you are correct then how did 
> this work at all without data corruption for large writes on x86_64?

The size of the page array is determined by page size (and some other
parameters).  I am using 64k pages, that may be the key.  I don't know
what page size was used on X86-64 but we may have been lucky and not
fallen off the end of the array thus avoided the problem.

> 
> I'm on the road right now, so I can't dig too deep until Wednesday, but 
> at this point your analysis looks correct to me.
> 
> Tom
> 
> 
> David J. Wilder wrote:
> > Tom
> >
> > I have been chasing an rnfs related Oops in svc_process().  I have found
> > the source of the Oops but I am not sure of my fix.  I am seeing the
> > problem on ppc64, kernel 2.6.32, I have not tried other arch yet.
> >
> > The source of the problem is in rdma_read_complete(), I am finding that
> > rqstp->rq_respages is set to point past the end of the rqstp->rq_pages
> > page list.  This results in a NULL reference in svc_process() when
> > passing rq_respages[0] to page_address().
> >
> > In rdma_read_complete() we are using rqstp->rq_arg.pages as the base of
> > the page list then indexing by page_no, however rq_arg.pages is not
> > pointing to the start of the list so rq_respages ends up pointing to:
> >
> > rqstp->rq_pages[(head->count+1) + head->hdr_count]
> >
> > In my case, it ends up pointing one past the end of the list by one.
> >
> > Here is the change I made.
> >
> > static int rdma_read_complete(struct svc_rqst *rqstp,
> >                               struct svc_rdma_op_ctxt *head)
> > {
> >         int page_no;
> >         int ret;
> >
> >         BUG_ON(!head);
> >
> >         /* Copy RPC pages */
> >         for (page_no = 0; page_no < head->count; page_no++) {
> >                 put_page(rqstp->rq_pages[page_no]);
> >                 rqstp->rq_pages[page_no] = head->pages[page_no];
> >         }
> >         /* Point rq_arg.pages past header */
> >         rqstp->rq_arg.pages = &rqstp->rq_pages[head->hdr_count];
> >         rqstp->rq_arg.page_len = head->arg.page_len;
> >         rqstp->rq_arg.page_base = head->arg.page_base;
> >
> >         /* rq_respages starts after the last arg page */
> > -       rqstp->rq_respages = &rqstp->rq_arg.pages[page_no];
> > +	rqstp->rq_respages = &rqstp->rq_pages[page_no];
> > .
> > .
> > .
> >
> > The change works for me, but I am not sure it is safe to assume the
> > rqstp->rq_pages[head->count] will always point to the last arg page.
> >
> > Dave.
> >   
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: rnfs: rq_respages pointer is bad
       [not found] ` <1267489621.9774.41.camel-XfwDJb4SXxnMbYB6QlFGEg@public.gmane.org>
  2010-03-02  3:35   ` Tom Tucker
@ 2010-03-11 17:05   ` Tom Tucker
  2010-03-11 21:32   ` Roland Dreier
  2010-05-05 22:58   ` Roland Dreier
  3 siblings, 0 replies; 8+ messages in thread
From: Tom Tucker @ 2010-03-11 17:05 UTC (permalink / raw)
  To: David J. Wilder
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, pradeep-r/Jw6+rmf7HQT0dZR+AlfA

David J. Wilder wrote:
> Tom
>
> I have been chasing an rnfs related Oops in svc_process().  I have found
> the source of the Oops but I am not sure of my fix.  I am seeing the
> problem on ppc64, kernel 2.6.32, I have not tried other arch yet.
>
> The source of the problem is in rdma_read_complete(), I am finding that
> rqstp->rq_respages is set to point past the end of the rqstp->rq_pages
> page list.  This results in a NULL reference in svc_process() when
> passing rq_respages[0] to page_address().
>
> In rdma_read_complete() we are using rqstp->rq_arg.pages as the base of
> the page list then indexing by page_no, however rq_arg.pages is not
> pointing to the start of the list so rq_respages ends up pointing to:
>
> rqstp->rq_pages[(head->count+1) + head->hdr_count]
>
> In my case, it ends up pointing one past the end of the list by one.
>
> Here is the change I made.
>
> static int rdma_read_complete(struct svc_rqst *rqstp,
>                               struct svc_rdma_op_ctxt *head)
> {
>         int page_no;
>         int ret;
>
>         BUG_ON(!head);
>
>         /* Copy RPC pages */
>         for (page_no = 0; page_no < head->count; page_no++) {
>                 put_page(rqstp->rq_pages[page_no]);
>                 rqstp->rq_pages[page_no] = head->pages[page_no];
>         }
>         /* Point rq_arg.pages past header */
>         rqstp->rq_arg.pages = &rqstp->rq_pages[head->hdr_count];
>         rqstp->rq_arg.page_len = head->arg.page_len;
>         rqstp->rq_arg.page_base = head->arg.page_base;
>
>         /* rq_respages starts after the last arg page */
> -       rqstp->rq_respages = &rqstp->rq_arg.pages[page_no];
> +	rqstp->rq_respages = &rqstp->rq_pages[page_no];
>   

This might be clearer as:

        rqstp->rq_respages = &rqstp->rq_pages[head->count];

> .
> .
> .
>
> The change works for me, but I am not sure it is safe to assume the
> rqstp->rq_pages[head->count] will always point to the last arg page.
>
> Dave.
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>   

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

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: rnfs: rq_respages pointer is bad
       [not found] ` <1267489621.9774.41.camel-XfwDJb4SXxnMbYB6QlFGEg@public.gmane.org>
  2010-03-02  3:35   ` Tom Tucker
  2010-03-11 17:05   ` Tom Tucker
@ 2010-03-11 21:32   ` Roland Dreier
       [not found]     ` <adar5nqczov.fsf-BjVyx320WGW9gfZ95n9DRSW4+XlvGpQz@public.gmane.org>
  2010-05-05 22:58   ` Roland Dreier
  3 siblings, 1 reply; 8+ messages in thread
From: Roland Dreier @ 2010-03-11 21:32 UTC (permalink / raw)
  To: David J. Wilder
  Cc: Tom Tucker, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	pradeep-r/Jw6+rmf7HQT0dZR+AlfA

Someone please make sure that a final patch with a full description gets
sent to the NFS guys for merging.  Tom, are you going to handle this?
-- 
Roland Dreier  <rolandd-FYB4Gu1CFyUAvxtiuMwx3w@public.gmane.org>
For corporate legal information go to:
http://www.cisco.com/web/about/doing_business/legal/cri/index.html
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: rnfs: rq_respages pointer is bad
       [not found]     ` <adar5nqczov.fsf-BjVyx320WGW9gfZ95n9DRSW4+XlvGpQz@public.gmane.org>
@ 2010-03-11 21:37       ` Tom Tucker
  0 siblings, 0 replies; 8+ messages in thread
From: Tom Tucker @ 2010-03-11 21:37 UTC (permalink / raw)
  To: Roland Dreier
  Cc: David J. Wilder, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	pradeep-r/Jw6+rmf7HQT0dZR+AlfA

Roland Dreier wrote:
> Someone please make sure that a final patch with a full description gets
> sent to the NFS guys for merging.  Tom, are you going to handle this?
>   
Yes, and I have several more in queue.

Tom

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

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: rnfs: rq_respages pointer is bad
       [not found] ` <1267489621.9774.41.camel-XfwDJb4SXxnMbYB6QlFGEg@public.gmane.org>
                     ` (2 preceding siblings ...)
  2010-03-11 21:32   ` Roland Dreier
@ 2010-05-05 22:58   ` Roland Dreier
       [not found]     ` <ada6332arcw.fsf-BjVyx320WGW9gfZ95n9DRSW4+XlvGpQz@public.gmane.org>
  3 siblings, 1 reply; 8+ messages in thread
From: Roland Dreier @ 2010-05-05 22:58 UTC (permalink / raw)
  To: David J. Wilder
  Cc: Tom Tucker, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	pradeep-r/Jw6+rmf7HQT0dZR+AlfA

 > The source of the problem is in rdma_read_complete(), I am finding that
 > rqstp->rq_respages is set to point past the end of the rqstp->rq_pages
 > page list.  This results in a NULL reference in svc_process() when
 > passing rq_respages[0] to page_address().

did this ever end up getting fixed upstream?
-- 
Roland Dreier <rolandd-FYB4Gu1CFyUAvxtiuMwx3w@public.gmane.org> || For corporate legal information go to:
http://www.cisco.com/web/about/doing_business/legal/cri/index.html
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: rnfs: rq_respages pointer is bad
       [not found]     ` <ada6332arcw.fsf-BjVyx320WGW9gfZ95n9DRSW4+XlvGpQz@public.gmane.org>
@ 2010-05-06  1:35       ` Tom Tucker
  0 siblings, 0 replies; 8+ messages in thread
From: Tom Tucker @ 2010-05-06  1:35 UTC (permalink / raw)
  To: Roland Dreier
  Cc: David J. Wilder, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	pradeep-r/Jw6+rmf7HQT0dZR+AlfA

On 5/5/10 5:58 PM, Roland Dreier wrote:
>   >  The source of the problem is in rdma_read_complete(), I am finding that
>   >  rqstp->rq_respages is set to point past the end of the rqstp->rq_pages
>   >  page list.  This results in a NULL reference in svc_process() when
>   >  passing rq_respages[0] to page_address().
>
> did this ever end up getting fixed upstream?
>    
I believe it did, but I'll check to be sure. It may be in Bruce's queue too.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2010-05-06  1:35 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-03-02  0:27 rnfs: rq_respages pointer is bad David J. Wilder
     [not found] ` <1267489621.9774.41.camel-XfwDJb4SXxnMbYB6QlFGEg@public.gmane.org>
2010-03-02  3:35   ` Tom Tucker
     [not found]     ` <4B8C8764.9080409-7bPotxP6k4+P2YhJcF5u+vpXobYPEAuW@public.gmane.org>
2010-03-03 16:20       ` David J. Wilder
2010-03-11 17:05   ` Tom Tucker
2010-03-11 21:32   ` Roland Dreier
     [not found]     ` <adar5nqczov.fsf-BjVyx320WGW9gfZ95n9DRSW4+XlvGpQz@public.gmane.org>
2010-03-11 21:37       ` Tom Tucker
2010-05-05 22:58   ` Roland Dreier
     [not found]     ` <ada6332arcw.fsf-BjVyx320WGW9gfZ95n9DRSW4+XlvGpQz@public.gmane.org>
2010-05-06  1:35       ` Tom Tucker

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.