diff options
author | Andriy Skulysh <andriy_skulysh@xyratex.com> | 2013-01-06 17:12:15 -0500 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2013-01-23 18:17:39 -0500 |
commit | 35525b79786b2ba58ef13822198ce22c497bc7a2 (patch) | |
tree | 2aaefaf2b21a3b3b133b29b711c811be0e335c11 /net | |
parent | 624ab4644819948e9dc87c114201e98f2e52490f (diff) |
sunrpc: Fix lockd sleeping until timeout
There is a race in enqueueing thread to a pool and
waking up a thread.
lockd doesn't wake up on reception of lock granted callback
if svc_wake_up() is called before lockd's thread is added
to a pool.
Signed-off-by: Andriy Skulysh <Andriy_Skulysh@xyratex.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/sunrpc/svc_xprt.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index b8e47fac7315..5a9d40c5a9f3 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c | |||
@@ -499,7 +499,8 @@ void svc_wake_up(struct svc_serv *serv) | |||
499 | rqstp->rq_xprt = NULL; | 499 | rqstp->rq_xprt = NULL; |
500 | */ | 500 | */ |
501 | wake_up(&rqstp->rq_wait); | 501 | wake_up(&rqstp->rq_wait); |
502 | } | 502 | } else |
503 | pool->sp_task_pending = 1; | ||
503 | spin_unlock_bh(&pool->sp_lock); | 504 | spin_unlock_bh(&pool->sp_lock); |
504 | } | 505 | } |
505 | } | 506 | } |
@@ -634,7 +635,13 @@ struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout) | |||
634 | * long for cache updates. | 635 | * long for cache updates. |
635 | */ | 636 | */ |
636 | rqstp->rq_chandle.thread_wait = 1*HZ; | 637 | rqstp->rq_chandle.thread_wait = 1*HZ; |
638 | pool->sp_task_pending = 0; | ||
637 | } else { | 639 | } else { |
640 | if (pool->sp_task_pending) { | ||
641 | pool->sp_task_pending = 0; | ||
642 | spin_unlock_bh(&pool->sp_lock); | ||
643 | return ERR_PTR(-EAGAIN); | ||
644 | } | ||
638 | /* No data pending. Go to sleep */ | 645 | /* No data pending. Go to sleep */ |
639 | svc_thread_enqueue(pool, rqstp); | 646 | svc_thread_enqueue(pool, rqstp); |
640 | 647 | ||