Commit 6859d1f2 authored by NeilBrown's avatar NeilBrown Committed by Chuck Lever

SUNRPC: make rqst_should_sleep() idempotent()

Based on its name you would think that rqst_should_sleep() would be
read-only, not changing anything.  But in fact it will clear
SP_TASK_PENDING if that was set.  This is surprising, and it blurs the
line between "check for work to do" and "dequeue work to do".

So change the "test_and_clear" to simple "test" and clear the bit once
the thread has decided to wake up and return to the caller.

With this, it makes sense to *always* set SP_TASK_PENDING when asked,
rather than to set it only if no thread could be woken up.

[ cel: Previously TASK_PENDING indicated there is work waiting but no
idle threads were found to pick up that work. After this patch, it acts
as an XPT_BUSY flag for wake-ups that have no associated xprt. ]
Signed-off-by: default avatarNeilBrown <neilb@suse.de>
Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent d2f0ef1c
...@@ -581,8 +581,8 @@ void svc_wake_up(struct svc_serv *serv) ...@@ -581,8 +581,8 @@ void svc_wake_up(struct svc_serv *serv)
{ {
struct svc_pool *pool = &serv->sv_pools[0]; struct svc_pool *pool = &serv->sv_pools[0];
if (!svc_pool_wake_idle_thread(pool))
set_bit(SP_TASK_PENDING, &pool->sp_flags); set_bit(SP_TASK_PENDING, &pool->sp_flags);
svc_pool_wake_idle_thread(pool);
} }
EXPORT_SYMBOL_GPL(svc_wake_up); EXPORT_SYMBOL_GPL(svc_wake_up);
...@@ -704,7 +704,7 @@ rqst_should_sleep(struct svc_rqst *rqstp) ...@@ -704,7 +704,7 @@ rqst_should_sleep(struct svc_rqst *rqstp)
struct svc_pool *pool = rqstp->rq_pool; struct svc_pool *pool = rqstp->rq_pool;
/* did someone call svc_wake_up? */ /* did someone call svc_wake_up? */
if (test_and_clear_bit(SP_TASK_PENDING, &pool->sp_flags)) if (test_bit(SP_TASK_PENDING, &pool->sp_flags))
return false; return false;
/* was a socket queued? */ /* was a socket queued? */
...@@ -748,6 +748,7 @@ static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp) ...@@ -748,6 +748,7 @@ static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp)
set_bit(RQ_BUSY, &rqstp->rq_flags); set_bit(RQ_BUSY, &rqstp->rq_flags);
smp_mb__after_atomic(); smp_mb__after_atomic();
clear_bit(SP_TASK_PENDING, &pool->sp_flags);
rqstp->rq_xprt = svc_xprt_dequeue(pool); rqstp->rq_xprt = svc_xprt_dequeue(pool);
if (rqstp->rq_xprt) if (rqstp->rq_xprt)
goto out_found; goto out_found;
...@@ -756,6 +757,7 @@ static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp) ...@@ -756,6 +757,7 @@ static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp)
return NULL; return NULL;
return NULL; return NULL;
out_found: out_found:
clear_bit(SP_TASK_PENDING, &pool->sp_flags);
/* Normally we will wait up to 5 seconds for any required /* Normally we will wait up to 5 seconds for any required
* cache information to be provided. * cache information to be provided.
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment