* [PATCH] SVC: Guard call to xpo_release_rqst in svc_send
@ 2008-02-27 19:58 Tom Tucker
[not found] ` <1204142339.24762.94.camel-SMNkleLxa3ZimH42XvhXlA@public.gmane.org>
0 siblings, 1 reply; 5+ messages in thread
From: Tom Tucker @ 2008-02-27 19:58 UTC (permalink / raw)
To: bfields; +Cc: linux-nfs, jaschut, swise
The svc_send path is calling xpo_release_rqst without checking
the XPT_DEAD bit. It is illegal to call transport methods on a dead
transport. In practice, if the transport gets an error and shuts down
while there are still RPC in svc_process the resulting svc_send could
crash calling into a transport that is being shut down.
Signed-off-by: Tom Tucker <tom@opengridcomputing.com>
---
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index ea377e0..467c1c0 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -729,9 +729,6 @@ int svc_send(struct svc_rqst *rqstp)
if (!xprt)
return -EFAULT;
- /* release the receive skb before sending the reply */
- rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp);
-
/* calculate over-all length */
xb = &rqstp->rq_res;
xb->len = xb->head[0].iov_len +
@@ -742,8 +739,11 @@ int svc_send(struct svc_rqst *rqstp)
mutex_lock(&xprt->xpt_mutex);
if (test_bit(XPT_DEAD, &xprt->xpt_flags))
len = -ENOTCONN;
- else
+ else {
+ /* release the receive skb before sending the reply */
+ rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp);
len = xprt->xpt_ops->xpo_sendto(rqstp);
+ }
mutex_unlock(&xprt->xpt_mutex);
svc_xprt_release(rqstp);
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] SVC: Guard call to xpo_release_rqst in svc_send
[not found] ` <1204142339.24762.94.camel-SMNkleLxa3ZimH42XvhXlA@public.gmane.org>
@ 2008-02-29 20:40 ` J. Bruce Fields
2008-03-01 3:20 ` Tom Tucker
0 siblings, 1 reply; 5+ messages in thread
From: J. Bruce Fields @ 2008-02-29 20:40 UTC (permalink / raw)
To: Tom Tucker; +Cc: bfields, linux-nfs, jaschut, swise
On Wed, Feb 27, 2008 at 01:58:59PM -0600, Tom Tucker wrote:
>
> The svc_send path is calling xpo_release_rqst without checking
> the XPT_DEAD bit. It is illegal to call transport methods on a dead
> transport. In practice, if the transport gets an error and shuts down
> while there are still RPC in svc_process the resulting svc_send could
> crash calling into a transport that is being shut down.
As long as we have a pointer to an xprt (say in rqstp->rq_xprt), we
should have a reference on the corresponding xprt class, shouldn't we?
Anything else seems like a problem.
>
> Signed-off-by: Tom Tucker <tom@opengridcomputing.com>
> ---
> diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
> index ea377e0..467c1c0 100644
> --- a/net/sunrpc/svc_xprt.c
> +++ b/net/sunrpc/svc_xprt.c
> @@ -729,9 +729,6 @@ int svc_send(struct svc_rqst *rqstp)
> if (!xprt)
> return -EFAULT;
>
> - /* release the receive skb before sending the reply */
> - rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp);
> -
> /* calculate over-all length */
> xb = &rqstp->rq_res;
> xb->len = xb->head[0].iov_len +
> @@ -742,8 +739,11 @@ int svc_send(struct svc_rqst *rqstp)
> mutex_lock(&xprt->xpt_mutex);
> if (test_bit(XPT_DEAD, &xprt->xpt_flags))
> len = -ENOTCONN;
> - else
> + else {
> + /* release the receive skb before sending the reply */
> + rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp);
> len = xprt->xpt_ops->xpo_sendto(rqstp);
> + }
So in the case where XPT_DEAD is set, doesn't the receive skb also need
to be freed, or does somebody else do that?
> mutex_unlock(&xprt->xpt_mutex);
> svc_xprt_release(rqstp);
Also something else is odd here: svc_xprt_release(rqstp) already calls
rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp) itself, so we seem to
have two calls to that method.
--b.
>
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] SVC: Guard call to xpo_release_rqst in svc_send
2008-02-29 20:40 ` J. Bruce Fields
@ 2008-03-01 3:20 ` Tom Tucker
2008-03-01 16:24 ` J. Bruce Fields
0 siblings, 1 reply; 5+ messages in thread
From: Tom Tucker @ 2008-03-01 3:20 UTC (permalink / raw)
To: J. Bruce Fields; +Cc: linux-nfs, jaschut, Steve Wise
Bruce:
Summary response: Mia culpa....please revert this patch. Although it made
the test failure go away, this patch just moves the problem, it doesn't fix
anything.
More below inline....
On 2/29/08 2:40 PM, "J. Bruce Fields" <bfields@fieldses.org> wrote:
> On Wed, Feb 27, 2008 at 01:58:59PM -0600, Tom Tucker wrote:
>>
>> The svc_send path is calling xpo_release_rqst without checking
>> the XPT_DEAD bit. It is illegal to call transport methods on a dead
>> transport. In practice, if the transport gets an error and shuts down
>> while there are still RPC in svc_process the resulting svc_send could
>> crash calling into a transport that is being shut down.
>
> As long as we have a pointer to an xprt (say in rqstp->rq_xprt), we
> should have a reference on the corresponding xprt class, shouldn't we?
> Anything else seems like a problem.
>
Generally yes. In particular, at entry to svc_recv, we should have a minimum
of two references. svc_xprt_enqueue gets you one, and there is a one ref
bias that comes from svc_xprt_init. The bias gets removed on close.
>>
>> Signed-off-by: Tom Tucker <tom@opengridcomputing.com>
>> ---
>> diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
>> index ea377e0..467c1c0 100644
>> --- a/net/sunrpc/svc_xprt.c
>> +++ b/net/sunrpc/svc_xprt.c
>> @@ -729,9 +729,6 @@ int svc_send(struct svc_rqst *rqstp)
>> if (!xprt)
>> return -EFAULT;
>>
>> - /* release the receive skb before sending the reply */
>> - rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp);
>> -
>> /* calculate over-all length */
>> xb = &rqstp->rq_res;
>> xb->len = xb->head[0].iov_len +
>> @@ -742,8 +739,11 @@ int svc_send(struct svc_rqst *rqstp)
>> mutex_lock(&xprt->xpt_mutex);
>> if (test_bit(XPT_DEAD, &xprt->xpt_flags))
>> len = -ENOTCONN;
>> - else
>> + else {
>> + /* release the receive skb before sending the reply */
>> + rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp);
>> len = xprt->xpt_ops->xpo_sendto(rqstp);
>> + }
>
> So in the case where XPT_DEAD is set, doesn't the receive skb also need
> to be freed, or does somebody else do that?
>
Only reboot does that :-\. I need to think this through more carefully. On
RDMA transports this function is used to return send credits to the user,
and that involves talking to the transport. Sorry for this hasty
patch...it's not right.
>> mutex_unlock(&xprt->xpt_mutex);
>> svc_xprt_release(rqstp);
>
> Also something else is odd here: svc_xprt_release(rqstp) already calls
> rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp) itself, so we seem to
> have two calls to that method.
>
Hmm. Busted. This patch is broken in three dimensions. Is that a record?
Tom
> --b.
>
>>
>>
>> -
>> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
>> the body of a message to majordomo@vger.kernel.org
>> 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@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] SVC: Guard call to xpo_release_rqst in svc_send
2008-03-01 3:20 ` Tom Tucker
@ 2008-03-01 16:24 ` J. Bruce Fields
2008-03-01 18:53 ` Tom Tucker
0 siblings, 1 reply; 5+ messages in thread
From: J. Bruce Fields @ 2008-03-01 16:24 UTC (permalink / raw)
To: Tom Tucker; +Cc: linux-nfs, jaschut, Steve Wise
On Fri, Feb 29, 2008 at 09:20:34PM -0600, Tom Tucker wrote:
> Bruce:
>
> Summary response: Mia culpa....please revert this patch.
OK! I hadn't gotten around to applying it, so no need to revert.
> Although it made the test failure go away, this patch just moves the
> problem, it doesn't fix anything.
Remind me what the test failure was? (You saw that the problem Torsten
Kaiser reported turned out to be a bug in the memory allocator, right?:
http://bugzilla.kernel.org/show_bug.cgi?id=9973)
--b.
>
> More below inline....
>
> On 2/29/08 2:40 PM, "J. Bruce Fields" <bfields@fieldses.org> wrote:
>
>
> > On Wed, Feb 27, 2008 at 01:58:59PM -0600, Tom Tucker wrote:
> >>
> >> The svc_send path is calling xpo_release_rqst without checking
> >> the XPT_DEAD bit. It is illegal to call transport methods on a dead
> >> transport. In practice, if the transport gets an error and shuts down
> >> while there are still RPC in svc_process the resulting svc_send could
> >> crash calling into a transport that is being shut down.
> >
> > As long as we have a pointer to an xprt (say in rqstp->rq_xprt), we
> > should have a reference on the corresponding xprt class, shouldn't we?
> > Anything else seems like a problem.
> >
>
> Generally yes. In particular, at entry to svc_recv, we should have a minimum
> of two references. svc_xprt_enqueue gets you one, and there is a one ref
> bias that comes from svc_xprt_init. The bias gets removed on close.
>
> >>
> >> Signed-off-by: Tom Tucker <tom@opengridcomputing.com>
> >> ---
> >> diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
> >> index ea377e0..467c1c0 100644
> >> --- a/net/sunrpc/svc_xprt.c
> >> +++ b/net/sunrpc/svc_xprt.c
> >> @@ -729,9 +729,6 @@ int svc_send(struct svc_rqst *rqstp)
> >> if (!xprt)
> >> return -EFAULT;
> >>
> >> - /* release the receive skb before sending the reply */
> >> - rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp);
> >> -
> >> /* calculate over-all length */
> >> xb = &rqstp->rq_res;
> >> xb->len = xb->head[0].iov_len +
> >> @@ -742,8 +739,11 @@ int svc_send(struct svc_rqst *rqstp)
> >> mutex_lock(&xprt->xpt_mutex);
> >> if (test_bit(XPT_DEAD, &xprt->xpt_flags))
> >> len = -ENOTCONN;
> >> - else
> >> + else {
> >> + /* release the receive skb before sending the reply */
> >> + rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp);
> >> len = xprt->xpt_ops->xpo_sendto(rqstp);
> >> + }
> >
> > So in the case where XPT_DEAD is set, doesn't the receive skb also need
> > to be freed, or does somebody else do that?
> >
>
> Only reboot does that :-\. I need to think this through more carefully. On
> RDMA transports this function is used to return send credits to the user,
> and that involves talking to the transport. Sorry for this hasty
> patch...it's not right.
>
> >> mutex_unlock(&xprt->xpt_mutex);
> >> svc_xprt_release(rqstp);
> >
> > Also something else is odd here: svc_xprt_release(rqstp) already calls
> > rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp) itself, so we seem to
> > have two calls to that method.
> >
>
> Hmm. Busted. This patch is broken in three dimensions. Is that a record?
>
> Tom
>
> > --b.
> >
> >>
> >>
> >> -
> >> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> >> the body of a message to majordomo@vger.kernel.org
> >> 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@vger.kernel.org
> > 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@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] SVC: Guard call to xpo_release_rqst in svc_send
2008-03-01 16:24 ` J. Bruce Fields
@ 2008-03-01 18:53 ` Tom Tucker
0 siblings, 0 replies; 5+ messages in thread
From: Tom Tucker @ 2008-03-01 18:53 UTC (permalink / raw)
To: J. Bruce Fields; +Cc: linux-nfs, jaschut, Steve Wise
On 3/1/08 10:24 AM, "J. Bruce Fields" <bfields@fieldses.org> wrote:
> On Fri, Feb 29, 2008 at 09:20:34PM -0600, Tom Tucker wrote:
>> Bruce:
>>
>> Summary response: Mia culpa....please revert this patch.
>
> OK! I hadn't gotten around to applying it, so no need to revert.
>
Awesome.
>> Although it made the test failure go away, this patch just moves the
>> problem, it doesn't fix anything.
>
> Remind me what the test failure was? (You saw that the problem Torsten
> Kaiser reported turned out to be a bug in the memory allocator, right?:
> http://bugzilla.kernel.org/show_bug.cgi?id=9973)
>
The real problem was found by Sandia labs. But it is easily reproducible
here. Something seems to have changed in the Infiniband verbs core that
exposed a latent bug in the RDMA transport driver. The initial "fix" fixed
the original crash, but in addition to being incorrect, additional testing
revealed that it still crashed in other ways -- that's why I sent this note.
So the problem is that there is a race between the I/O event callbacks from
the RDMA core and the close path in the transport driver. The incorrect
assumption made in the code is that after the call to rdma_destroy_id
returns, you will receive no more events from lower level. Well .... that's
not true. You won't receive any more CM events, but you may still receive CQ
and QP events.
I have a fix and am thoroughly testing it now. I'll send it to you after
I've had 24 hrs on it ;-).
Tom
> --b.
>
>>
>> More below inline....
>>
>> On 2/29/08 2:40 PM, "J. Bruce Fields" <bfields@fieldses.org> wrote:
>>
>>
>>> On Wed, Feb 27, 2008 at 01:58:59PM -0600, Tom Tucker wrote:
>>>>
>>>> The svc_send path is calling xpo_release_rqst without checking
>>>> the XPT_DEAD bit. It is illegal to call transport methods on a dead
>>>> transport. In practice, if the transport gets an error and shuts down
>>>> while there are still RPC in svc_process the resulting svc_send could
>>>> crash calling into a transport that is being shut down.
>>>
>>> As long as we have a pointer to an xprt (say in rqstp->rq_xprt), we
>>> should have a reference on the corresponding xprt class, shouldn't we?
>>> Anything else seems like a problem.
>>>
>>
>> Generally yes. In particular, at entry to svc_recv, we should have a minimum
>> of two references. svc_xprt_enqueue gets you one, and there is a one ref
>> bias that comes from svc_xprt_init. The bias gets removed on close.
>>
>>>>
>>>> Signed-off-by: Tom Tucker <tom@opengridcomputing.com>
>>>> ---
>>>> diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
>>>> index ea377e0..467c1c0 100644
>>>> --- a/net/sunrpc/svc_xprt.c
>>>> +++ b/net/sunrpc/svc_xprt.c
>>>> @@ -729,9 +729,6 @@ int svc_send(struct svc_rqst *rqstp)
>>>> if (!xprt)
>>>> return -EFAULT;
>>>>
>>>> - /* release the receive skb before sending the reply */
>>>> - rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp);
>>>> -
>>>> /* calculate over-all length */
>>>> xb = &rqstp->rq_res;
>>>> xb->len = xb->head[0].iov_len +
>>>> @@ -742,8 +739,11 @@ int svc_send(struct svc_rqst *rqstp)
>>>> mutex_lock(&xprt->xpt_mutex);
>>>> if (test_bit(XPT_DEAD, &xprt->xpt_flags))
>>>> len = -ENOTCONN;
>>>> - else
>>>> + else {
>>>> + /* release the receive skb before sending the reply */
>>>> + rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp);
>>>> len = xprt->xpt_ops->xpo_sendto(rqstp);
>>>> + }
>>>
>>> So in the case where XPT_DEAD is set, doesn't the receive skb also need
>>> to be freed, or does somebody else do that?
>>>
>>
>> Only reboot does that :-\. I need to think this through more carefully. On
>> RDMA transports this function is used to return send credits to the user,
>> and that involves talking to the transport. Sorry for this hasty
>> patch...it's not right.
>>
>>>> mutex_unlock(&xprt->xpt_mutex);
>>>> svc_xprt_release(rqstp);
>>>
>>> Also something else is odd here: svc_xprt_release(rqstp) already calls
>>> rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp) itself, so we seem to
>>> have two calls to that method.
>>>
>>
>> Hmm. Busted. This patch is broken in three dimensions. Is that a record?
>>
>> Tom
>>
>>> --b.
>>>
>>>>
>>>>
>>>> -
>>>> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
>>>> the body of a message to majordomo@vger.kernel.org
>>>> 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@vger.kernel.org
>>> 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@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2008-03-01 18:54 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-02-27 19:58 [PATCH] SVC: Guard call to xpo_release_rqst in svc_send Tom Tucker
[not found] ` <1204142339.24762.94.camel-SMNkleLxa3ZimH42XvhXlA@public.gmane.org>
2008-02-29 20:40 ` J. Bruce Fields
2008-03-01 3:20 ` Tom Tucker
2008-03-01 16:24 ` J. Bruce Fields
2008-03-01 18:53 ` Tom Tucker
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox