]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branch 'block/for-next'
authorStephen Rothwell <sfr@canb.auug.org.au>
Tue, 20 Dec 2011 02:51:16 +0000 (13:51 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Tue, 20 Dec 2011 02:51:16 +0000 (13:51 +1100)
1  2 
block/blk-core.c

index 15de223c7f9371a9da852825ea8857789d94ae70,1b4fd93af2c03d82cf767078fd8760b957b5041e..e6c05a97ee2ba94538222d76273d0d2fbae644cc
@@@ -366,19 -369,23 +369,30 @@@ void blk_drain_queue(struct request_que
                if (drain_all)
                        blk_throtl_drain(q);
  
 -              __blk_run_queue(q);
 +              /*
 +               * This function might be called on a queue which failed
 +               * driver init after queue creation.  Some drivers
 +               * (e.g. fd) get unhappy in such cases.  Kick queue iff
 +               * dispatch queue has something on it.
 +               */
 +              if (!list_empty(&q->queue_head))
 +                      __blk_run_queue(q);
  
-               if (drain_all)
-                       nr_rqs = q->rq.count[0] + q->rq.count[1];
-               else
-                       nr_rqs = q->rq.elvpriv;
+               drain |= q->rq.elvpriv;
+               /*
+                * Unfortunately, requests are queued at and tracked from
+                * multiple places and there's no single counter which can
+                * be drained.  Check all the queues and counters.
+                */
+               if (drain_all) {
+                       drain |= !list_empty(&q->queue_head);
+                       for (i = 0; i < 2; i++) {
+                               drain |= q->rq.count[i];
+                               drain |= q->in_flight[i];
+                               drain |= !list_empty(&q->flush_queue[i]);
+                       }
+               }
  
                spin_unlock_irq(q->queue_lock);