Package: linux-2.6
Version: 2.6.26-21
Severity: important
Tags: patch

Oops happens "while doing preparation for vzt-ss test
(just creating/starting
VEs, with continuous ps axf running in background if it matters): "
http://bugzilla.openvz.org/show_bug.cgi?id=1240




>From 1a6d795abc130bd356b10abbd91ef63ef23f01c4 Mon Sep 17 00:00:00 2001
From: Konstantin Khlebnikov <[email protected]>
Date: Thu, 24 Dec 2009 20:58:15 +0300
Subject: [PATCH 88/90] cfq: unlink queues at bc destroy

Unlink cfq-queues from cfq-io-contexts at cfq-bc-data destroy and
always revalidate cached cfq-queues from cfq-io-context.

Should fix pdflush oops in cfq_set_request after container stop.

http://bugzilla.openvz.org/show_bug.cgi?id=1240

Signed-off-by: Konstantin Khlebnikov <[email protected]>
Signed-off-by: Pavel Emelyanov <[email protected]>
---
 block/cfq-iosched.c |   20 +++++---------------
 kernel/bc/io_prio.c |   11 +++++++++++
 2 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index b25b442..3a9992a 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -2014,32 +2014,22 @@ cfq_set_request(struct request_queue *q, struct request 
*rq, gfp_t gfp_mask)
        struct cfq_queue *cfqq;
        unsigned long flags;
        struct ub_iopriv *iopriv;
-       struct cfq_bc_data *cfq_bc = NULL;
 
        might_sleep_if(gfp_mask & __GFP_WAIT);
 
        cic = cfq_get_io_context(cfqd, gfp_mask);
        iopriv = cfqq_ub_iopriv(cfqd, is_sync);
-       if (!is_sync)
-               cfq_bc = bc_findcreate_cfq_bc(iopriv, cfqd, gfp_mask);
 
        spin_lock_irqsave(q->queue_lock, flags);
 
-       if (!cic || (!is_sync && cfq_bc == NULL))
+       if (!cic)
                goto queue_fail;
 
        cfqq = cic_to_cfqq(cic, is_sync);
-       if (!cfqq) {
-               cfqq = cfq_get_queue(cfqd, is_sync, cic->ioc, gfp_mask);
-
-               if (!cfqq)
-                       goto queue_fail;
-
-               cic_set_cfqq(cic, cfqq, is_sync);
-       }
-
-       if (!is_sync && cfqq->cfq_bc != cfq_bc) {
-               cfq_put_queue(cfqq);
+       if (!cfqq || cfqq->cfq_bc->ub_iopriv != iopriv) {
+               if (cfqq)
+                       cfq_put_queue(cfqq);
+               cic_set_cfqq(cic, NULL, is_sync);
                cfqq = cfq_get_queue(cfqd, is_sync, cic->ioc, gfp_mask);
                cic_set_cfqq(cic, cfqq, is_sync);
                if (!cfqq)
diff --git a/kernel/bc/io_prio.c b/kernel/bc/io_prio.c
index 5bb22e5..4a1ee2e 100644
--- a/kernel/bc/io_prio.c
+++ b/kernel/bc/io_prio.c
@@ -88,6 +88,7 @@ static void inline bc_cfq_bc_check_empty(struct cfq_bc_data 
*cfq_bc)
 
 static void bc_release_cfq_bc(struct cfq_bc_data *cfq_bc)
 {
+       struct cfq_io_context *cic;
        struct cfq_data *cfqd;
        elevator_t *eq;
        int i;
@@ -109,6 +110,16 @@ static void bc_release_cfq_bc(struct cfq_bc_data *cfq_bc)
                eq->ops->put_queue(cfq_bc->async_idle_cfqq);
                cfq_bc->async_idle_cfqq = NULL;
        }
+       list_for_each_entry(cic, &cfqd->cic_list, queue_list) {
+               if (cic->cfqq[0] && cic->cfqq[0]->cfq_bc == cfq_bc) {
+                       eq->ops->put_queue(cic->cfqq[0]);
+                       cic->cfqq[0] = NULL;
+               }
+               if (cic->cfqq[1] && cic->cfqq[1]->cfq_bc == cfq_bc) {
+                       eq->ops->put_queue(cic->cfqq[1]);
+                       cic->cfqq[1] = NULL;
+               }
+       }
        /* 
         * Note: this cfq_bc is already not in active list,
         * but can be still pointed from cfqd as active.
-- 
1.6.5.7


-- System Information:
Debian Release: squeeze/sid
  APT prefers testing
  APT policy: (900, 'testing'), (500, 'unstable'), (1, 'experimental')
Architecture: amd64 (x86_64)

Kernel: Linux 2.6.30-2-amd64 (SMP w/2 CPU cores)
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash



-- 
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]

Reply via email to