aboutsummaryrefslogtreecommitdiffstats
path: root/block/blk-flush.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2011-03-04 13:09:02 -0500
committerTejun Heo <tj@kernel.org>2011-03-04 13:09:02 -0500
commite83a46bbb1d4c03defd733a64b727632a40059ad (patch)
treec4bc4822b2d3af1bf38095f531adc0a2aac054a5 /block/blk-flush.c
parentda527770007fce8e4541947d47918248286da875 (diff)
parentfd51469fb68b987032e46297e0a4fe9020063c20 (diff)
Merge branch 'for-linus' of ../linux-2.6-block into block-for-2.6.39/core
This merge creates two set of conflicts. One is simple context conflicts caused by removal of throtl_scheduled_delayed_work() in for-linus and removal of throtl_shutdown_timer_wq() in for-2.6.39/core. The other is caused by commit 255bb490c8 (block: blk-flush shouldn't call directly into q->request_fn() __blk_run_queue()) in for-linus crashing with FLUSH reimplementation in for-2.6.39/core. The conflict isn't trivial but the resolution is straight-forward. * __blk_run_queue() calls in flush_end_io() and flush_data_end_io() should be called with @force_kblockd set to %true. * elv_insert() in blk_kick_flush() should use %ELEVATOR_INSERT_REQUEUE. Both changes are to avoid invoking ->request_fn() directly from request completion path and closely match the changes in the commit 255bb490c8. Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'block/blk-flush.c')
-rw-r--r--block/blk-flush.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/block/blk-flush.c b/block/blk-flush.c
index a867e3f524f..0bd8c9c5d6e 100644
--- a/block/blk-flush.c
+++ b/block/blk-flush.c
@@ -212,9 +212,14 @@ static void flush_end_io(struct request *flush_rq, int error)
212 queued |= blk_flush_complete_seq(rq, seq, error); 212 queued |= blk_flush_complete_seq(rq, seq, error);
213 } 213 }
214 214
215 /* after populating an empty queue, kick it to avoid stall */ 215 /*
216 * Moving a request silently to empty queue_head may stall the
217 * queue. Kick the queue in those cases. This function is called
218 * from request completion path and calling directly into
219 * request_fn may confuse the driver. Always use kblockd.
220 */
216 if (queued && was_empty) 221 if (queued && was_empty)
217 __blk_run_queue(q); 222 __blk_run_queue(q, true);
218} 223}
219 224
220/** 225/**
@@ -257,7 +262,7 @@ static bool blk_kick_flush(struct request_queue *q)
257 q->flush_rq.end_io = flush_end_io; 262 q->flush_rq.end_io = flush_end_io;
258 263
259 q->flush_pending_idx ^= 1; 264 q->flush_pending_idx ^= 1;
260 elv_insert(q, &q->flush_rq, ELEVATOR_INSERT_FRONT); 265 elv_insert(q, &q->flush_rq, ELEVATOR_INSERT_REQUEUE);
261 return true; 266 return true;
262} 267}
263 268
@@ -266,9 +271,12 @@ static void flush_data_end_io(struct request *rq, int error)
266 struct request_queue *q = rq->q; 271 struct request_queue *q = rq->q;
267 bool was_empty = elv_queue_empty(q); 272 bool was_empty = elv_queue_empty(q);
268 273
269 /* after populating an empty queue, kick it to avoid stall */ 274 /*
275 * After populating an empty queue, kick it to avoid stall. Read
276 * the comment in flush_end_io().
277 */
270 if (blk_flush_complete_seq(rq, REQ_FSEQ_DATA, error) && was_empty) 278 if (blk_flush_complete_seq(rq, REQ_FSEQ_DATA, error) && was_empty)
271 __blk_run_queue(q); 279 __blk_run_queue(q, true);
272} 280}
273 281
274/** 282/**