The commit is pushed to "branch-rh7-3.10.0-123.1.2-ovz" and will appear at 
https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-123.1.2.vz7.5.1
------>
commit a5678140dd8f793272b5e562e81e27e2a249e4fd
Author: Andrey Smetanin <asmeta...@virtuozzo.com>
Date:   Tue May 19 08:27:11 2015 +0400

    ploop: fix busyloop on secondary discard bio
    
    After diff-ploop-add-a-separate-queue-for-discard-bio-s, ploop_thread()
    skips processing previously queued discard bio-s if any discard bio is
    already under processing (fbd->fbd_dbl is not empty).
    
    ploop_wait() must take care about such a case, otherwise a busyloop may
    happen: ploop_thread() believes that it has to go to sleep because all
    incoming queues are empty excepting plo->bio_discard_list which cannot be
    processed by now and calls ploop_wait(); the latter returns immediately
    because plo->bio_discard_list is not empty and hence needs for processing.
    
    The patch also fixes a trivial bug in discard bio accounting:
    
    ploop_bio_queue() is called for all bio-s including discard bio-s and
    it decrements bio_qlen unconditionally. This is incorrect: it has to
    decrement either bio_qlen or discard_bio_qlen dependently on the type of 
bio.
    
    https://jira.sw.ru/browse/PSBM-30451
    https://bugzilla.openvz.org/show_bug.cgi?id=3124
    
    Signed-off-by: Maxim Patlasov <mpatla...@parallels.com>
    
    Acked-by: Andrew Vagin <ava...@parallels.com>
---
 drivers/block/ploop/dev.c      |  9 +++++++--
 drivers/block/ploop/freeblks.c | 12 ++++++++----
 2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c
index e2ff0aa..ac0f28f 100644
--- a/drivers/block/ploop/dev.c
+++ b/drivers/block/ploop/dev.c
@@ -551,7 +551,11 @@ ploop_bio_queue(struct ploop_device * plo, struct bio * 
bio,
 
        __TRACE("A %p %u\n", preq, preq->req_cluster);
 
-       plo->bio_qlen--;
+       if (unlikely(bio->bi_rw & REQ_DISCARD))
+               plo->bio_discard_qlen--;
+       else
+               plo->bio_qlen--;
+
        ploop_entry_add(plo, preq);
 
        if (bio->bi_size && !(bio->bi_rw & REQ_DISCARD))
@@ -2563,7 +2567,8 @@ static void ploop_wait(struct ploop_device * plo, int 
once, struct blk_plug *plu
                             !plo->active_reqs))
                                break;
                } else if (plo->bio_head ||
-                               !bio_list_empty(&plo->bio_discard_list)) {
+                               (!bio_list_empty(&plo->bio_discard_list) &&
+                                !ploop_discard_is_inprogress(plo->fbd))) {
                        /* ready_queue and entry_queue are empty, but
                         * bio list not. Obviously, we'd like to process
                         * bio_list instead of sleeping */
diff --git a/drivers/block/ploop/freeblks.c b/drivers/block/ploop/freeblks.c
index cf48d3a..89108c7 100644
--- a/drivers/block/ploop/freeblks.c
+++ b/drivers/block/ploop/freeblks.c
@@ -696,20 +696,24 @@ int ploop_fb_get_free_block(struct ploop_freeblks_desc 
*fbd,
 
 static void fbd_complete_bio(struct ploop_freeblks_desc *fbd, int err)
 {
+       struct ploop_device *plo = fbd->plo;
        unsigned int nr_completed = 0;
 
        while (fbd->fbd_dbl.head) {
                struct bio * bio = fbd->fbd_dbl.head;
                fbd->fbd_dbl.head = bio->bi_next;
                bio->bi_next = NULL;
-               BIO_ENDIO(fbd->plo->queue, bio, err);
+               BIO_ENDIO(plo->queue, bio, err);
                nr_completed++;
        }
        fbd->fbd_dbl.tail = NULL;
 
-       spin_lock_irq(&fbd->plo->lock);
-       fbd->plo->bio_total -= nr_completed;
-       spin_unlock_irq(&fbd->plo->lock);
+       spin_lock_irq(&plo->lock);
+       plo->bio_total -= nr_completed;
+       if (!bio_list_empty(&plo->bio_discard_list) &&
+           waitqueue_active(&plo->waitq))
+               wake_up_interruptible(&plo->waitq);
+       spin_unlock_irq(&plo->lock);
 }
 
 void ploop_fb_reinit(struct ploop_freeblks_desc *fbd, int err)
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to