Whamcloud - gitweb
LU-3274 osc: allow to call brw_commit() multiple times 15/8215/2
authorJinshan Xiong <jinshan.xiong@intel.com>
Fri, 8 Nov 2013 03:58:19 +0000 (19:58 -0800)
committerOleg Drokin <oleg.drokin@intel.com>
Mon, 10 Mar 2014 23:48:33 +0000 (23:48 +0000)
Sometimes the rq_commit_cb of BRW RPC can be called twice if that RPC
has already committed at reply time. This will cause inaccuracy of
unstable pages accounting and then assertion.

Signed-off-by: Jinshan Xiong <jinshan.xiong@intel.com>
Change-Id: Ic596e1d44e2c27bf13701d2c6c9691562beb7e58
Reviewed-on: http://review.whamcloud.com/8215
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Prakash Surya <surya1@llnl.gov>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/osc/osc_cache.c
lustre/osc/osc_request.c

index 6887309..5885c59 100644 (file)
@@ -1811,11 +1811,6 @@ void osc_dec_unstable_pages(struct ptlrpc_request *req)
        atomic_sub(page_count, &obd_unstable_pages);
        LASSERT(atomic_read(&obd_unstable_pages) >= 0);
 
-       spin_lock(&req->rq_lock);
-       req->rq_committed = 1;
-       req->rq_unstable  = 0;
-       spin_unlock(&req->rq_lock);
-
        wake_up_all(&cli->cl_cache->ccc_unstable_waitq);
 }
 
@@ -1845,25 +1840,19 @@ void osc_inc_unstable_pages(struct ptlrpc_request *req)
        LASSERT(atomic_read(&obd_unstable_pages) >= 0);
        atomic_add(page_count, &obd_unstable_pages);
 
-       spin_lock(&req->rq_lock);
-
        /* If the request has already been committed (i.e. brw_commit
         * called via rq_commit_cb), we need to undo the unstable page
         * increments we just performed because rq_commit_cb wont be
-        * called again. Otherwise, just set the commit callback so the
-        * unstable page accounting is properly updated when the request
-        * is committed */
-       if (req->rq_committed) {
-               /* Drop lock before calling osc_dec_unstable_pages */
+        * called again. */
+       spin_lock(&req->rq_lock);
+       if (unlikely(req->rq_committed)) {
                spin_unlock(&req->rq_lock);
+
                osc_dec_unstable_pages(req);
-               spin_lock(&req->rq_lock);
        } else {
-               req->rq_unstable  = 1;
-               req->rq_commit_cb = osc_dec_unstable_pages;
+               req->rq_unstable = 1;
+               spin_unlock(&req->rq_lock);
        }
-
-       spin_unlock(&req->rq_lock);
 }
 
 /* this must be called holding the loi list lock to give coverage to exit_cache,
index ed8b962..d1d793a 100644 (file)
@@ -2072,19 +2072,20 @@ static int brw_interpret(const struct lu_env *env,
 
 static void brw_commit(struct ptlrpc_request *req)
 {
-       spin_lock(&req->rq_lock);
        /* If osc_inc_unstable_pages (via osc_extent_finish) races with
         * this called via the rq_commit_cb, I need to ensure
         * osc_dec_unstable_pages is still called. Otherwise unstable
         * pages may be leaked. */
-       if (req->rq_unstable) {
+       spin_lock(&req->rq_lock);
+       if (likely(req->rq_unstable)) {
+               req->rq_unstable = 0;
                spin_unlock(&req->rq_lock);
+
                osc_dec_unstable_pages(req);
-               spin_lock(&req->rq_lock);
        } else {
                req->rq_committed = 1;
+               spin_unlock(&req->rq_lock);
        }
-       spin_unlock(&req->rq_lock);
 }
 
 /**