lkml.org 
[lkml]   [2012]   [Sep]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[ 21/46] svcrpc: fix svc_xprt_enqueue/svc_recv busy-looping
    Date
    From: Greg KH <gregkh@linuxfoundation.org>

    3.0-stable review patch. If anyone has any objections, please let me know.

    ------------------

    From: "J. Bruce Fields" <bfields@redhat.com>

    commit d10f27a750312ed5638c876e4bd6aa83664cccd8 upstream.

    The rpc server tries to ensure that there will be room to send a reply
    before it receives a request.

    It does this by tracking, in xpt_reserved, an upper bound on the total
    size of the replies that is has already committed to for the socket.

    Currently it is adding in the estimate for a new reply *before* it
    checks whether there is space available. If it finds that there is not
    space, it then subtracts the estimate back out.

    This may lead the subsequent svc_xprt_enqueue to decide that there is
    space after all.

    The results is a svc_recv() that will repeatedly return -EAGAIN, causing
    server threads to loop without doing any actual work.

    Reported-by: Michael Tokarev <mjt@tls.msk.ru>
    Tested-by: Michael Tokarev <mjt@tls.msk.ru>
    Signed-off-by: J. Bruce Fields <bfields@redhat.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    net/sunrpc/svc_xprt.c | 7 ++-----
    1 file changed, 2 insertions(+), 5 deletions(-)

    --- a/net/sunrpc/svc_xprt.c
    +++ b/net/sunrpc/svc_xprt.c
    @@ -323,7 +323,6 @@ static bool svc_xprt_has_something_to_do
    */
    void svc_xprt_enqueue(struct svc_xprt *xprt)
    {
    - struct svc_serv *serv = xprt->xpt_server;
    struct svc_pool *pool;
    struct svc_rqst *rqstp;
    int cpu;
    @@ -369,8 +368,6 @@ void svc_xprt_enqueue(struct svc_xprt *x
    rqstp, rqstp->rq_xprt);
    rqstp->rq_xprt = xprt;
    svc_xprt_get(xprt);
    - rqstp->rq_reserved = serv->sv_max_mesg;
    - atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);
    pool->sp_stats.threads_woken++;
    wake_up(&rqstp->rq_wait);
    } else {
    @@ -650,8 +647,6 @@ int svc_recv(struct svc_rqst *rqstp, lon
    if (xprt) {
    rqstp->rq_xprt = xprt;
    svc_xprt_get(xprt);
    - rqstp->rq_reserved = serv->sv_max_mesg;
    - atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);

    /* As there is a shortage of threads and this request
    * had to be queued, don't allow the thread to wait so
    @@ -748,6 +743,8 @@ int svc_recv(struct svc_rqst *rqstp, lon
    else
    len = xprt->xpt_ops->xpo_recvfrom(rqstp);
    dprintk("svc: got len=%d\n", len);
    + rqstp->rq_reserved = serv->sv_max_mesg;
    + atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);
    }
    svc_xprt_received(xprt);




    \
     
     \ /
      Last update: 2012-09-13 04:41    [W:4.160 / U:0.924 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site