aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-01-15 15:24:45 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-15 15:24:45 -0500
commitb3c9dd182ed3bdcdaf0e42625a35924b0497afdc (patch)
treead48ad4d923fee147c736318d0fad35b3755f4f5 /block
parent83c2f912b43c3a7babbb6cb7ae2a5276c1ed2a3e (diff)
parent5d381efb3d1f1ef10535a31ca0dd9b22fe1e1922 (diff)
Merge branch 'for-3.3/core' of git://git.kernel.dk/linux-block
* 'for-3.3/core' of git://git.kernel.dk/linux-block: (37 commits) Revert "block: recursive merge requests" block: Stop using macro stubs for the bio data integrity calls blockdev: convert some macros to static inlines fs: remove unneeded plug in mpage_readpages() block: Add BLKROTATIONAL ioctl block: Introduce blk_set_stacking_limits function block: remove WARN_ON_ONCE() in exit_io_context() block: an exiting task should be allowed to create io_context block: ioc_cgroup_changed() needs to be exported block: recursive merge requests block, cfq: fix empty queue crash caused by request merge block, cfq: move icq creation and rq->elv.icq association to block core block, cfq: restructure io_cq creation path for io_context interface cleanup block, cfq: move io_cq exit/release to blk-ioc.c block, cfq: move icq cache management to block core block, cfq: move io_cq lookup to blk-ioc.c block, cfq: move cfqd->icq_list to request_queue and add request->elv.icq block, cfq: reorganize cfq_io_context into generic and cfq specific parts block: remove elevator_queue->ops block: reorder elevator switch sequence ... Fix up conflicts in: - block/blk-cgroup.c Switch from can_attach_task to can_attach - block/cfq-iosched.c conflict with now removed cic index changes (we now use q->id instead)
Diffstat (limited to 'block')
-rw-r--r--block/blk-cgroup.c11
-rw-r--r--block/blk-core.c203
-rw-r--r--block/blk-exec.c8
-rw-r--r--block/blk-ioc.c485
-rw-r--r--block/blk-settings.c32
-rw-r--r--block/blk-sysfs.c12
-rw-r--r--block/blk-throttle.c4
-rw-r--r--block/blk.h58
-rw-r--r--block/bsg.c4
-rw-r--r--block/cfq-iosched.c619
-rw-r--r--block/compat_ioctl.c3
-rw-r--r--block/deadline-iosched.c4
-rw-r--r--block/elevator.c217
-rw-r--r--block/genhd.c2
-rw-r--r--block/ioctl.c2
-rw-r--r--block/noop-iosched.c4
16 files changed, 847 insertions, 821 deletions
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index b8c143d68ee0..fa8f26309444 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -1655,11 +1655,12 @@ static void blkiocg_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
1655 struct io_context *ioc; 1655 struct io_context *ioc;
1656 1656
1657 cgroup_taskset_for_each(task, cgrp, tset) { 1657 cgroup_taskset_for_each(task, cgrp, tset) {
1658 task_lock(task); 1658 /* we don't lose anything even if ioc allocation fails */
1659 ioc = task->io_context; 1659 ioc = get_task_io_context(task, GFP_ATOMIC, NUMA_NO_NODE);
1660 if (ioc) 1660 if (ioc) {
1661 ioc->cgroup_changed = 1; 1661 ioc_cgroup_changed(ioc);
1662 task_unlock(task); 1662 put_io_context(ioc, NULL);
1663 }
1663 } 1664 }
1664} 1665}
1665 1666
diff --git a/block/blk-core.c b/block/blk-core.c
index 15de223c7f93..e6c05a97ee2b 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -39,6 +39,8 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_remap);
39EXPORT_TRACEPOINT_SYMBOL_GPL(block_rq_remap); 39EXPORT_TRACEPOINT_SYMBOL_GPL(block_rq_remap);
40EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_complete); 40EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_complete);
41 41
42DEFINE_IDA(blk_queue_ida);
43
42/* 44/*
43 * For the allocated request tables 45 * For the allocated request tables
44 */ 46 */
@@ -358,7 +360,8 @@ EXPORT_SYMBOL(blk_put_queue);
358void blk_drain_queue(struct request_queue *q, bool drain_all) 360void blk_drain_queue(struct request_queue *q, bool drain_all)
359{ 361{
360 while (true) { 362 while (true) {
361 int nr_rqs; 363 bool drain = false;
364 int i;
362 365
363 spin_lock_irq(q->queue_lock); 366 spin_lock_irq(q->queue_lock);
364 367
@@ -375,14 +378,25 @@ void blk_drain_queue(struct request_queue *q, bool drain_all)
375 if (!list_empty(&q->queue_head)) 378 if (!list_empty(&q->queue_head))
376 __blk_run_queue(q); 379 __blk_run_queue(q);
377 380
378 if (drain_all) 381 drain |= q->rq.elvpriv;
379 nr_rqs = q->rq.count[0] + q->rq.count[1]; 382
380 else 383 /*
381 nr_rqs = q->rq.elvpriv; 384 * Unfortunately, requests are queued at and tracked from
385 * multiple places and there's no single counter which can
386 * be drained. Check all the queues and counters.
387 */
388 if (drain_all) {
389 drain |= !list_empty(&q->queue_head);
390 for (i = 0; i < 2; i++) {
391 drain |= q->rq.count[i];
392 drain |= q->in_flight[i];
393 drain |= !list_empty(&q->flush_queue[i]);
394 }
395 }
382 396
383 spin_unlock_irq(q->queue_lock); 397 spin_unlock_irq(q->queue_lock);
384 398
385 if (!nr_rqs) 399 if (!drain)
386 break; 400 break;
387 msleep(10); 401 msleep(10);
388 } 402 }
@@ -469,6 +483,10 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
469 if (!q) 483 if (!q)
470 return NULL; 484 return NULL;
471 485
486 q->id = ida_simple_get(&blk_queue_ida, 0, 0, GFP_KERNEL);
487 if (q->id < 0)
488 goto fail_q;
489
472 q->backing_dev_info.ra_pages = 490 q->backing_dev_info.ra_pages =
473 (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; 491 (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE;
474 q->backing_dev_info.state = 0; 492 q->backing_dev_info.state = 0;
@@ -477,20 +495,17 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
477 q->node = node_id; 495 q->node = node_id;
478 496
479 err = bdi_init(&q->backing_dev_info); 497 err = bdi_init(&q->backing_dev_info);
480 if (err) { 498 if (err)
481 kmem_cache_free(blk_requestq_cachep, q); 499 goto fail_id;
482 return NULL;
483 }
484 500
485 if (blk_throtl_init(q)) { 501 if (blk_throtl_init(q))
486 kmem_cache_free(blk_requestq_cachep, q); 502 goto fail_id;
487 return NULL;
488 }
489 503
490 setup_timer(&q->backing_dev_info.laptop_mode_wb_timer, 504 setup_timer(&q->backing_dev_info.laptop_mode_wb_timer,
491 laptop_mode_timer_fn, (unsigned long) q); 505 laptop_mode_timer_fn, (unsigned long) q);
492 setup_timer(&q->timeout, blk_rq_timed_out_timer, (unsigned long) q); 506 setup_timer(&q->timeout, blk_rq_timed_out_timer, (unsigned long) q);
493 INIT_LIST_HEAD(&q->timeout_list); 507 INIT_LIST_HEAD(&q->timeout_list);
508 INIT_LIST_HEAD(&q->icq_list);
494 INIT_LIST_HEAD(&q->flush_queue[0]); 509 INIT_LIST_HEAD(&q->flush_queue[0]);
495 INIT_LIST_HEAD(&q->flush_queue[1]); 510 INIT_LIST_HEAD(&q->flush_queue[1]);
496 INIT_LIST_HEAD(&q->flush_data_in_flight); 511 INIT_LIST_HEAD(&q->flush_data_in_flight);
@@ -508,6 +523,12 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
508 q->queue_lock = &q->__queue_lock; 523 q->queue_lock = &q->__queue_lock;
509 524
510 return q; 525 return q;
526
527fail_id:
528 ida_simple_remove(&blk_queue_ida, q->id);
529fail_q:
530 kmem_cache_free(blk_requestq_cachep, q);
531 return NULL;
511} 532}
512EXPORT_SYMBOL(blk_alloc_queue_node); 533EXPORT_SYMBOL(blk_alloc_queue_node);
513 534
@@ -605,26 +626,31 @@ blk_init_allocated_queue(struct request_queue *q, request_fn_proc *rfn,
605} 626}
606EXPORT_SYMBOL(blk_init_allocated_queue); 627EXPORT_SYMBOL(blk_init_allocated_queue);
607 628
608int blk_get_queue(struct request_queue *q) 629bool blk_get_queue(struct request_queue *q)
609{ 630{
610 if (likely(!test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) { 631 if (likely(!blk_queue_dead(q))) {
611 kobject_get(&q->kobj); 632 __blk_get_queue(q);
612 return 0; 633 return true;
613 } 634 }
614 635
615 return 1; 636 return false;
616} 637}
617EXPORT_SYMBOL(blk_get_queue); 638EXPORT_SYMBOL(blk_get_queue);
618 639
619static inline void blk_free_request(struct request_queue *q, struct request *rq) 640static inline void blk_free_request(struct request_queue *q, struct request *rq)
620{ 641{
621 if (rq->cmd_flags & REQ_ELVPRIV) 642 if (rq->cmd_flags & REQ_ELVPRIV) {
622 elv_put_request(q, rq); 643 elv_put_request(q, rq);
644 if (rq->elv.icq)
645 put_io_context(rq->elv.icq->ioc, q);
646 }
647
623 mempool_free(rq, q->rq.rq_pool);