From: Trond Myklebust <Trond.Myklebust@netapp.com>
To: Ian Campbell <ijc-KcIKpvwj1kUDXYZnReoRVg@public.gmane.org>
Cc: linux-nfs@vger.kernel.org,
Max Kellermann <mk-xMchvyqCc6DQT0dZR+AlfA@public.gmane.org>,
linux-kernel@vger.kernel.org, gcosta@redhat.com,
Grant Coady <grant_lkml-rGYn+TmxqGy6c6uEtOJ/EA@public.gmane.org>,
"J. Bruce Fields" <bfields@fieldses.org>,
Tom Tucker <tom@opengridcomputing.com>
Subject: Re: [PATCH 3/3] SUNRPC: svc_xprt_enqueue should not refuse to enqueue 'XPT_DEAD' transports
Date: Sun, 30 Nov 2008 19:20:15 -0500 [thread overview]
Message-ID: <1228090815.7112.15.camel@heimdal.trondhjem.org> (raw)
In-Reply-To: <1228090631.7112.11.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
Aside from being racy (there is nothing preventing someone setting XPT_DEAD
after the test in svc_xprt_enqueue, and before XPT_BUSY is set), it is
wrong to assume that transports which have called svc_delete_xprt() might
not need to be re-enqueued.
See the list of deferred requests, which is currently never going to
be cleared if the revisit call happens after svc_delete_xprt(). In this
case, the deferred request will currently keep a reference to the transport
forever.
The fix should be to allow dead transports to be enqueued in order to clear
the deferred requests, then change the order of processing in svc_recv() so
that we pick up deferred requests before we do the XPT_CLOSE processing.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
---
net/sunrpc/svc_xprt.c | 124 +++++++++++++++++++++++++++----------------------
1 files changed, 69 insertions(+), 55 deletions(-)
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index a417064..b54cf84 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -297,10 +297,15 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
struct svc_serv *serv = xprt->xpt_server;
struct svc_pool *pool;
struct svc_rqst *rqstp;
+ unsigned long flags;
int cpu;
- if (!(xprt->xpt_flags &
- ((1<<XPT_CONN)|(1<<XPT_DATA)|(1<<XPT_CLOSE)|(1<<XPT_DEFERRED))))
+ flags = xprt->xpt_flags &
+ (1UL<<XPT_CONN | 1UL<<XPT_DATA | 1UL<<XPT_CLOSE |
+ 1UL<<XPT_DEAD | 1UL<<XPT_DEFERRED);
+ if (flags == 0)
+ return;
+ if ((flags & 1UL<<XPT_DEAD) != 0 && (flags & 1UL<<XPT_DEFERRED) == 0)
return;
cpu = get_cpu();
@@ -315,12 +320,6 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
"svc_xprt_enqueue: "
"threads and transports both waiting??\n");
- if (test_bit(XPT_DEAD, &xprt->xpt_flags)) {
- /* Don't enqueue dead transports */
- dprintk("svc: transport %p is dead, not enqueued\n", xprt);
- goto out_unlock;
- }
-
/* Mark transport as busy. It will remain in this state until
* the provider calls svc_xprt_received. We update XPT_BUSY
* atomically because it also guards against trying to enqueue
@@ -566,6 +565,7 @@ static void svc_check_conn_limits(struct svc_serv *serv)
int svc_recv(struct svc_rqst *rqstp, long timeout)
{
struct svc_xprt *xprt = NULL;
+ struct svc_xprt *newxpt;
struct svc_serv *serv = rqstp->rq_server;
struct svc_pool *pool = rqstp->rq_pool;
int len, i;
@@ -673,62 +673,76 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
spin_unlock_bh(&pool->sp_lock);
len = 0;
+
+ /*
+ * Deal with deferred requests first, since they need to be
+ * dequeued and dropped if the transport has been closed.
+ */
+ rqstp->rq_deferred = svc_deferred_dequeue(xprt);
+ if (rqstp->rq_deferred) {
+ svc_xprt_received(xprt);
+ len = svc_deferred_recv(rqstp);
+ }
+
if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) {
dprintk("svc_recv: found XPT_CLOSE\n");
svc_delete_xprt(xprt);
- } else if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) {
- struct svc_xprt *newxpt;
- newxpt = xprt->xpt_ops->xpo_accept(xprt);
- if (newxpt) {
- /*
- * We know this module_get will succeed because the
- * listener holds a reference too
- */
- __module_get(newxpt->xpt_class->xcl_owner);
- svc_check_conn_limits(xprt->xpt_server);
- spin_lock_bh(&serv->sv_lock);
- set_bit(XPT_TEMP, &newxpt->xpt_flags);
- list_add(&newxpt->xpt_list, &serv->sv_tempsocks);
- serv->sv_tmpcnt++;
- if (serv->sv_temptimer.function == NULL) {
- /* setup timer to age temp transports */
- setup_timer(&serv->sv_temptimer,
- svc_age_temp_xprts,
- (unsigned long)serv);
- mod_timer(&serv->sv_temptimer,
- jiffies + svc_conn_age_period * HZ);
- }
- spin_unlock_bh(&serv->sv_lock);
- svc_xprt_received(newxpt);
- }
- svc_xprt_received(xprt);
- } else {
- dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n",
- rqstp, pool->sp_id, xprt,
- atomic_read(&xprt->xpt_ref.refcount));
- rqstp->rq_deferred = svc_deferred_dequeue(xprt);
- if (rqstp->rq_deferred) {
- svc_xprt_received(xprt);
- len = svc_deferred_recv(rqstp);
- } else
+ goto drop_request;
+ }
+
+ if (!test_bit(XPT_LISTENER, &xprt->xpt_flags)) {
+ if (len == 0) {
+ dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n",
+ rqstp, pool->sp_id, xprt,
+ atomic_read(&xprt->xpt_ref.refcount));
len = xprt->xpt_ops->xpo_recvfrom(rqstp);
+
+ /* No data, incomplete (TCP) read, or accept() */
+ if (len == 0 || len == -EAGAIN)
+ goto drop_request;
+ }
+
dprintk("svc: got len=%d\n", len);
- }
- /* No data, incomplete (TCP) read, or accept() */
- if (len == 0 || len == -EAGAIN) {
- rqstp->rq_res.len = 0;
- svc_xprt_release(rqstp);
- return -EAGAIN;
+ clear_bit(XPT_OLD, &xprt->xpt_flags);
+
+ rqstp->rq_secure = svc_port_is_privileged(svc_addr(rqstp));
+ rqstp->rq_chandle.defer = svc_defer;
+
+ if (serv->sv_stats)
+ serv->sv_stats->netcnt++;
+ return len;
}
- clear_bit(XPT_OLD, &xprt->xpt_flags);
- rqstp->rq_secure = svc_port_is_privileged(svc_addr(rqstp));
- rqstp->rq_chandle.defer = svc_defer;
+ newxpt = xprt->xpt_ops->xpo_accept(xprt);
+ if (newxpt) {
+ /*
+ * We know this module_get will succeed because the
+ * listener holds a reference too
+ */
+ __module_get(newxpt->xpt_class->xcl_owner);
+ svc_check_conn_limits(xprt->xpt_server);
+ spin_lock_bh(&serv->sv_lock);
+ set_bit(XPT_TEMP, &newxpt->xpt_flags);
+ list_add(&newxpt->xpt_list, &serv->sv_tempsocks);
+ serv->sv_tmpcnt++;
+ if (serv->sv_temptimer.function == NULL) {
+ /* setup timer to age temp transports */
+ setup_timer(&serv->sv_temptimer,
+ svc_age_temp_xprts,
+ (unsigned long)serv);
+ mod_timer(&serv->sv_temptimer,
+ jiffies + svc_conn_age_period * HZ);
+ }
+ spin_unlock_bh(&serv->sv_lock);
+ svc_xprt_received(newxpt);
+ }
+ svc_xprt_received(xprt);
- if (serv->sv_stats)
- serv->sv_stats->netcnt++;
- return len;
+drop_request:
+ rqstp->rq_res.len = 0;
+ svc_xprt_release(rqstp);
+ return -EAGAIN;
}
EXPORT_SYMBOL(svc_recv);
--
Trond Myklebust
Linux NFS client maintainer
NetApp
Trond.Myklebust@netapp.com
www.netapp.com
next prev parent reply other threads:[~2008-12-01 0:20 UTC|newest]
Thread overview: 79+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20081017123207.GA14979@rabbit.intern.cm-ag>
[not found] ` <1224484046.23068.14.camel@localhost.localdomain>
[not found] ` <1225539927.2221.3.camel@localhost.localdomain>
[not found] ` <1225546878.4390.3.camel@heimdal.trondhjem.org>
2008-11-25 7:09 ` [PATCH] NFS regression in 2.6.26?, "task blocked for more than 120 seconds" Ian Campbell
[not found] ` <1227596962.16868.22.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2008-11-25 13:28 ` Trond Myklebust
[not found] ` <1227619696.7057.19.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2008-11-25 13:38 ` Ian Campbell
[not found] ` <1227620339.9425.99.camel-o4Be2W7LfRlXesXXhkcM7miJhflN2719@public.gmane.org>
2008-11-25 13:57 ` Trond Myklebust
[not found] ` <1227621434.7057.33.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2008-11-25 14:04 ` Ian Campbell
[not found] ` <1227621877.9425.102.camel-o4Be2W7LfRlXesXXhkcM7miJhflN2719@public.gmane.org>
2008-11-26 22:12 ` Ian Campbell
[not found] ` <1227737539.31008.2.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2008-12-01 0:17 ` [PATCH 0/3] " Trond Myklebust
2008-12-01 0:19 ` [PATCH 2/3] SUNRPC: We only need to call svc_delete_xprt() once Trond Myklebust
[not found] ` <1228090631.7112.11.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2008-12-01 0:18 ` [PATCH 1/3] SUNRPC: Ensure the server closes sockets in a timely fashion Trond Myklebust
[not found] ` <1228090719.7112.13.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2008-12-17 15:27 ` Tom Tucker
2008-12-17 18:08 ` Trond Myklebust
[not found] ` <1229537296.7257.37.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2008-12-17 18:59 ` Tom Tucker
2008-12-01 0:20 ` Trond Myklebust [this message]
2008-12-17 15:35 ` [PATCH 3/3] SUNRPC: svc_xprt_enqueue should not refuse to enqueue 'XPT_DEAD' transports Tom Tucker
2008-12-17 19:07 ` Trond Myklebust
[not found] ` <1229540877.7257.97.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2008-12-23 14:49 ` Tom Tucker
2008-12-23 23:39 ` Tom Tucker
2009-01-02 21:44 ` Tom Tucker
2009-01-04 19:12 ` Trond Myklebust
[not found] ` <1231096358.7363.6.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2009-01-04 19:25 ` Trond Myklebust
2009-01-05 3:33 ` Tom Tucker
[not found] ` <1231097131.7 363.11.camel@heimdal.trondhjem.org>
[not found] ` <1231097131.7363.11.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2009-01-05 3:33 ` Tom Tucker
2009-01-05 17:04 ` Tom Tucker
2009-01-05 17:13 ` Trond Myklebust
[not found] ` <1231175613.7127.6.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2009-01-05 19:33 ` Tom Tucker
2009-01-05 19:51 ` Trond Myklebust
[not found] ` <1231185115.7127.28.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2009-01-05 20:13 ` Tom Tucker
2009-01-05 20:41 ` Tom Tucker
2009-01-05 20:48 ` Trond Myklebust
[not found] ` <1231188518.7127.30.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2009-01-05 21:10 ` Tom Tucker
2008-12-01 0:29 ` [PATCH 0/3] NFS regression in 2.6.26?, "task blocked for more than 120 seconds" Trond Myklebust
[not found] ` <1228091380.7112.17.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2008-12-02 15:22 ` Kasparek Tomas
2008-12-02 15:37 ` Trond Myklebust
[not found] ` <1228232222.3090.5.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2008-12-02 16:26 ` Kasparek Tomas
2008-12-02 18:10 ` Trond Myklebust
[not found] ` <1228241407.3090.7.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2008-12-04 10:23 ` Kasparek Tomas
[not found] ` <1229284201.6463.98.camel@heimdal.trondhjem.org>
[not found] ` <1229284201.6463.98.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2008-12-16 12:05 ` Kasparek Tomas
2008-12-16 12:10 ` Kasparek Tomas
2008-12-16 12:59 ` Trond Myklebust
2008-12-23 22:34 ` Trond Myklebust
[not found] ` <1230071647.17701.27.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2009-01-05 12:18 ` Kasparek Tomas
2009-01-09 14:56 ` Kasparek Tomas
2009-01-09 17:59 ` Trond Myklebust
[not found] ` <1231523966.7179.67.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2009-01-10 10:24 ` Kasparek Tomas
2009-01-10 16:00 ` Trond Myklebust
[not found] ` <20090112090404.GL47559@fit.vutbr.cz>
[not found] ` <1231782009.7322.12.camel@heimdal.trondhjem.org>
[not found] ` <1231809446.7322.17.camel@heimdal.trondhjem.org>
[not found] ` <1231809446.7322.17.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2009-01-13 15:22 ` Kasparek Tomas
2009-01-16 10:48 ` Kasparek Tomas
2009-01-18 13:08 ` Kasparek Tomas
2009-01-20 15:03 ` Kasparek Tomas
2009-01-20 15:32 ` Trond Myklebust
[not found] ` <1232465547.7055.3.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2009-01-28 8:18 ` Kasparek Tomas
2009-02-06 6:35 ` Kasparek Tomas
2009-02-10 7:55 ` Kasparek Tomas
2009-03-03 12:08 ` Kasparek Tomas
2009-03-03 14:16 ` Trond Myklebust
[not found] ` <1236089767.9631.4.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2009-03-25 8:46 ` Kasparek Tomas
2009-04-18 5:17 ` Kasparek Tomas
2009-04-22 17:27 ` NFS client packet storm on 2.6.27.x Kasparek Tomas
2009-04-29 12:12 ` Steve Dickson
[not found] ` <49F84436.5090007-AfCzQyP5zfLQT0dZR+AlfA@public.gmane.org>
2009-04-29 14:57 ` Kasparek Tomas
2009-06-25 5:55 ` Kasparek Tomas
2009-07-13 11:12 ` Kasparek Tomas
2009-07-13 17:20 ` [stable] " Greg KH
2009-07-13 17:40 ` Trond Myklebust
[not found] ` <1247506817.14524.25.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2009-07-24 8:54 ` Kasparek Tomas
2009-07-28 18:31 ` Greg KH
2008-12-01 22:09 ` [PATCH 0/3] NFS regression in 2.6.26?, "task blocked for more than 120 seconds" Ian Campbell
[not found] ` <1228169383.20370.3.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2008-12-06 12:16 ` Ian Campbell
[not found] ` <1228565812.10856.30.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2008-12-14 18:24 ` Ian Campbell
[not found] ` <1229279045.3721.1.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2008-12-16 17:55 ` J. Bruce Fields
2008-12-16 18:39 ` Ian Campbell
[not found] ` <1229452775.3721.25.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2009-01-07 22:21 ` J. Bruce Fields
2009-01-08 18:20 ` J. Bruce Fields
2009-01-08 21:22 ` Ian Campbell
[not found] ` <1231449753.21688.12.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2009-01-08 21:26 ` J. Bruce Fields
2009-01-12 9:46 ` Ian Campbell
2009-01-22 8:27 ` Ian Campbell
[not found] ` <1232612860.29604.57.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2009-01-22 16:44 ` J. Bruce Fields
2008-11-26 9:16 ` [PATCH] NFS regression in 2.6.26?, Tomas Kasparek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1228090815.7112.15.camel@heimdal.trondhjem.org \
--to=trond.myklebust@netapp.com \
--cc=bfields@fieldses.org \
--cc=gcosta@redhat.com \
--cc=grant_lkml-rGYn+TmxqGy6c6uEtOJ/EA@public.gmane.org \
--cc=ijc-KcIKpvwj1kUDXYZnReoRVg@public.gmane.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=mk-xMchvyqCc6DQT0dZR+AlfA@public.gmane.org \
--cc=tom@opengridcomputing.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox