SUNRPC: Do not grab pool->sp_lock unnecessarily in svc_get_next_xprt
authorTrond Myklebust <trond.myklebust@primarydata.com>
Sun, 3 Aug 2014 17:03:09 +0000 (13:03 -0400)
committerJ. Bruce Fields <bfields@redhat.com>
Sun, 17 Aug 2014 16:00:10 +0000 (12:00 -0400)
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
net/sunrpc/svc_xprt.c

index 08e48cecfdcc7cfb7a8d119289418dc6e1616ea9..08e49d1e17b30fa324511178d33f7f99ab0773c6 100644 (file)
@@ -651,8 +651,8 @@ static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout)
        } else {
                if (pool->sp_task_pending) {
                        pool->sp_task_pending = 0;
-                       spin_unlock_bh(&pool->sp_lock);
-                       return ERR_PTR(-EAGAIN);
+                       xprt = ERR_PTR(-EAGAIN);
+                       goto out;
                }
                /* No data pending. Go to sleep */
                svc_thread_enqueue(pool, rqstp);
@@ -672,8 +672,8 @@ static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout)
                 */
                if (kthread_should_stop()) {
                        set_current_state(TASK_RUNNING);
-                       spin_unlock_bh(&pool->sp_lock);
-                       return ERR_PTR(-EINTR);
+                       xprt = ERR_PTR(-EINTR);
+                       goto out;
                }
 
                add_wait_queue(&rqstp->rq_wait, &wait);
@@ -683,8 +683,12 @@ static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout)
 
                try_to_freeze();
 
-               spin_lock_bh(&pool->sp_lock);
                remove_wait_queue(&rqstp->rq_wait, &wait);
+               xprt = rqstp->rq_xprt;
+               if (xprt != NULL)
+                       return xprt;
+
+               spin_lock_bh(&pool->sp_lock);
                if (!time_left)
                        pool->sp_stats.threads_timedout++;
 
@@ -699,6 +703,7 @@ static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout)
                                return ERR_PTR(-EAGAIN);
                }
        }
+out:
        spin_unlock_bh(&pool->sp_lock);
        return xprt;
 }