mirror of
https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux
synced 2025-09-14 16:46:19 +10:00
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: NeilBrown <neilb@suse.de> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
parent
d2f0ef1cbf
commit
6859d1f290
@ -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)
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user