diff options
-rw-r--r-- | block/blk-ioc.c | 5 | ||||
-rw-r--r-- | block/blk-settings.c | 39 | ||||
-rw-r--r-- | block/cfq-iosched.c | 6 | ||||
-rw-r--r-- | block/genhd.c | 2 | ||||
-rw-r--r-- | drivers/md/dm-table.c | 20 | ||||
-rw-r--r-- | include/linux/blkdev.h | 9 | ||||
-rw-r--r-- | include/linux/genhd.h | 6 | ||||
-rw-r--r-- | include/linux/iocontext.h | 27 |
8 files changed, 57 insertions, 57 deletions
diff --git a/block/blk-ioc.c b/block/blk-ioc.c index cbdabb0dd6d7..98e6bf61b0ac 100644 --- a/block/blk-ioc.c +++ b/block/blk-ioc.c | |||
@@ -39,8 +39,6 @@ int put_io_context(struct io_context *ioc) | |||
39 | 39 | ||
40 | if (atomic_long_dec_and_test(&ioc->refcount)) { | 40 | if (atomic_long_dec_and_test(&ioc->refcount)) { |
41 | rcu_read_lock(); | 41 | rcu_read_lock(); |
42 | if (ioc->aic && ioc->aic->dtor) | ||
43 | ioc->aic->dtor(ioc->aic); | ||
44 | cfq_dtor(ioc); | 42 | cfq_dtor(ioc); |
45 | rcu_read_unlock(); | 43 | rcu_read_unlock(); |
46 | 44 | ||
@@ -76,8 +74,6 @@ void exit_io_context(struct task_struct *task) | |||
76 | task_unlock(task); | 74 | task_unlock(task); |
77 | 75 | ||
78 | if (atomic_dec_and_test(&ioc->nr_tasks)) { | 76 | if (atomic_dec_and_test(&ioc->nr_tasks)) { |
79 | if (ioc->aic && ioc->aic->exit) | ||
80 | ioc->aic->exit(ioc->aic); | ||
81 | cfq_exit(ioc); | 77 | cfq_exit(ioc); |
82 | 78 | ||
83 | } | 79 | } |
@@ -97,7 +93,6 @@ struct io_context *alloc_io_context(gfp_t gfp_flags, int node) | |||
97 | ret->ioprio = 0; | 93 | ret->ioprio = 0; |
98 | ret->last_waited = jiffies; /* doesn't matter... */ | 94 | ret->last_waited = jiffies; /* doesn't matter... */ |
99 | ret->nr_batch_requests = 0; /* because this is 0 */ | 95 | ret->nr_batch_requests = 0; /* because this is 0 */ |
100 | ret->aic = NULL; | ||
101 | INIT_RADIX_TREE(&ret->radix_root, GFP_ATOMIC | __GFP_HIGH); | 96 | INIT_RADIX_TREE(&ret->radix_root, GFP_ATOMIC | __GFP_HIGH); |
102 | INIT_HLIST_HEAD(&ret->cic_list); | 97 | INIT_HLIST_HEAD(&ret->cic_list); |
103 | ret->ioc_data = NULL; | 98 | ret->ioc_data = NULL; |
diff --git a/block/blk-settings.c b/block/blk-settings.c index d52d4adc440b..5eeb9e0d256e 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c | |||
@@ -528,7 +528,7 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, | |||
528 | sector_t offset) | 528 | sector_t offset) |
529 | { | 529 | { |
530 | sector_t alignment; | 530 | sector_t alignment; |
531 | unsigned int top, bottom; | 531 | unsigned int top, bottom, ret = 0; |
532 | 532 | ||
533 | t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors); | 533 | t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors); |
534 | t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors); | 534 | t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors); |
@@ -546,6 +546,8 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, | |||
546 | t->max_segment_size = min_not_zero(t->max_segment_size, | 546 | t->max_segment_size = min_not_zero(t->max_segment_size, |
547 | b->max_segment_size); | 547 | b->max_segment_size); |
548 | 548 | ||
549 | t->misaligned |= b->misaligned; | ||
550 | |||
549 | alignment = queue_limit_alignment_offset(b, offset); | 551 | alignment = queue_limit_alignment_offset(b, offset); |
550 | 552 | ||
551 | /* Bottom device has different alignment. Check that it is | 553 | /* Bottom device has different alignment. Check that it is |
@@ -558,8 +560,10 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, | |||
558 | bottom = max(b->physical_block_size, b->io_min) + alignment; | 560 | bottom = max(b->physical_block_size, b->io_min) + alignment; |
559 | 561 | ||
560 | /* Verify that top and bottom intervals line up */ | 562 | /* Verify that top and bottom intervals line up */ |
561 | if (max(top, bottom) & (min(top, bottom) - 1)) | 563 | if (max(top, bottom) & (min(top, bottom) - 1)) { |
562 | t->misaligned = 1; | 564 | t->misaligned = 1; |
565 | ret = -1; | ||
566 | } | ||
563 | } | 567 | } |
564 | 568 | ||
565 | t->logical_block_size = max(t->logical_block_size, | 569 | t->logical_block_size = max(t->logical_block_size, |
@@ -578,18 +582,21 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, | |||
578 | if (t->physical_block_size & (t->logical_block_size - 1)) { | 582 | if (t->physical_block_size & (t->logical_block_size - 1)) { |
579 | t->physical_block_size = t->logical_block_size; | 583 | t->physical_block_size = t->logical_block_size; |
580 | t->misaligned = 1; | 584 | t->misaligned = 1; |
585 | ret = -1; | ||
581 | } | 586 | } |
582 | 587 | ||
583 | /* Minimum I/O a multiple of the physical block size? */ | 588 | /* Minimum I/O a multiple of the physical block size? */ |
584 | if (t->io_min & (t->physical_block_size - 1)) { | 589 | if (t->io_min & (t->physical_block_size - 1)) { |
585 | t->io_min = t->physical_block_size; | 590 | t->io_min = t->physical_block_size; |
586 | t->misaligned = 1; | 591 | t->misaligned = 1; |
592 | ret = -1; | ||
587 | } | 593 | } |
588 | 594 | ||
589 | /* Optimal I/O a multiple of the physical block size? */ | 595 | /* Optimal I/O a multiple of the physical block size? */ |
590 | if (t->io_opt & (t->physical_block_size - 1)) { | 596 | if (t->io_opt & (t->physical_block_size - 1)) { |
591 | t->io_opt = 0; | 597 | t->io_opt = 0; |
592 | t->misaligned = 1; | 598 | t->misaligned = 1; |
599 | ret = -1; | ||
593 | } | 600 | } |
594 | 601 | ||
595 | /* Find lowest common alignment_offset */ | 602 | /* Find lowest common alignment_offset */ |
@@ -597,8 +604,10 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, | |||
597 | & (max(t->physical_block_size, t->io_min) - 1); | 604 | & (max(t->physical_block_size, t->io_min) - 1); |
598 | 605 | ||
599 | /* Verify that new alignment_offset is on a logical block boundary */ | 606 | /* Verify that new alignment_offset is on a logical block boundary */ |
600 | if (t->alignment_offset & (t->logical_block_size - 1)) | 607 | if (t->alignment_offset & (t->logical_block_size - 1)) { |
601 | t->misaligned = 1; | 608 | t->misaligned = 1; |
609 | ret = -1; | ||
610 | } | ||
602 | 611 | ||
603 | /* Discard alignment and granularity */ | 612 | /* Discard alignment and granularity */ |
604 | if (b->discard_granularity) { | 613 | if (b->discard_granularity) { |
@@ -626,11 +635,33 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, | |||
626 | (t->discard_granularity - 1); | 635 | (t->discard_granularity - 1); |
627 | } | 636 | } |
628 | 637 | ||
629 | return t->misaligned ? -1 : 0; | 638 | return ret; |
630 | } | 639 | } |
631 | EXPORT_SYMBOL(blk_stack_limits); | 640 | EXPORT_SYMBOL(blk_stack_limits); |
632 | 641 | ||
633 | /** | 642 | /** |
643 | * bdev_stack_limits - adjust queue limits for stacked drivers | ||
644 | * @t: the stacking driver limits (top device) | ||
645 | * @bdev: the component block_device (bottom) | ||
646 | * @start: first data sector within component device | ||
647 | * | ||
648 | * Description: | ||
649 | * Merges queue limits for a top device and a block_device. Returns | ||
650 | * 0 if alignment didn't change. Returns -1 if adding the bottom | ||
651 | * device caused misalignment. | ||
652 | */ | ||
653 | int bdev_stack_limits(struct queue_limits *t, struct block_device *bdev, | ||
654 | sector_t start) | ||
655 | { | ||
656 | struct request_queue *bq = bdev_get_queue(bdev); | ||
657 | |||
658 | start += get_start_sect(bdev); | ||
659 | |||
660 | return blk_stack_limits(t, &bq->limits, start << 9); | ||
661 | } | ||
662 | EXPORT_SYMBOL(bdev_stack_limits); | ||
663 | |||
664 | /** | ||
634 | * disk_stack_limits - adjust queue limits for stacked drivers | 665 | * disk_stack_limits - adjust queue limits for stacked drivers |
635 | * @disk: MD/DM gendisk (top) | 666 | * @disk: MD/DM gendisk (top) |
636 | * @bdev: the underlying block device (bottom) | 667 | * @bdev: the underlying block device (bottom) |
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 918c7fd9aeb1..ee130f14d1fc 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
@@ -3077,6 +3077,12 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, | |||
3077 | return true; | 3077 | return true; |
3078 | 3078 | ||
3079 | /* | 3079 | /* |
3080 | * Don't allow a non-RT request to preempt an ongoing RT cfqq timeslice. | ||
3081 | */ | ||
3082 | if (cfq_class_rt(cfqq) && !cfq_class_rt(new_cfqq)) | ||
3083 | return false; | ||
3084 | |||
3085 | /* | ||
3080 | * if the new request is sync, but the currently running queue is | 3086 | * if the new request is sync, but the currently running queue is |
3081 | * not, let the sync request have priority. | 3087 | * not, let the sync request have priority. |
3082 | */ | 3088 | */ |
diff --git a/block/genhd.c b/block/genhd.c index b11a4ad7d571..d13ba76a169c 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
@@ -867,7 +867,7 @@ static ssize_t disk_discard_alignment_show(struct device *dev, | |||
867 | { | 867 | { |
868 | struct gendisk *disk = dev_to_disk(dev); | 868 | struct gendisk *disk = dev_to_disk(dev); |
869 | 869 | ||
870 | return sprintf(buf, "%u\n", queue_discard_alignment(disk->queue)); | 870 | return sprintf(buf, "%d\n", queue_discard_alignment(disk->queue)); |
871 | } | 871 | } |
872 | 872 | ||
873 | static DEVICE_ATTR(range, S_IRUGO, disk_range_show, NULL); | 873 | static DEVICE_ATTR(range, S_IRUGO, disk_range_show, NULL); |
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index be625475cf6d..4b22feb01a0c 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c | |||
@@ -503,16 +503,15 @@ int dm_set_device_limits(struct dm_target *ti, struct dm_dev *dev, | |||
503 | return 0; | 503 | return 0; |
504 | } | 504 | } |
505 | 505 | ||
506 | if (blk_stack_limits(limits, &q->limits, start << 9) < 0) | 506 | if (bdev_stack_limits(limits, bdev, start) < 0) |
507 | DMWARN("%s: target device %s is misaligned: " | 507 | DMWARN("%s: adding target device %s caused an alignment inconsistency: " |
508 | "physical_block_size=%u, logical_block_size=%u, " | 508 | "physical_block_size=%u, logical_block_size=%u, " |
509 | "alignment_offset=%u, start=%llu", | 509 | "alignment_offset=%u, start=%llu", |
510 | dm_device_name(ti->table->md), bdevname(bdev, b), | 510 | dm_device_name(ti->table->md), bdevname(bdev, b), |
511 | q->limits.physical_block_size, | 511 | q->limits.physical_block_size, |
512 | q->limits.logical_block_size, | 512 | q->limits.logical_block_size, |
513 | q->limits.alignment_offset, | 513 | q->limits.alignment_offset, |
514 | (unsigned long long) start << 9); | 514 | (unsigned long long) start << SECTOR_SHIFT); |
515 | |||
516 | 515 | ||
517 | /* | 516 | /* |
518 | * Check if merge fn is supported. | 517 | * Check if merge fn is supported. |
@@ -1026,9 +1025,9 @@ combine_limits: | |||
1026 | * for the table. | 1025 | * for the table. |
1027 | */ | 1026 | */ |
1028 | if (blk_stack_limits(limits, &ti_limits, 0) < 0) | 1027 | if (blk_stack_limits(limits, &ti_limits, 0) < 0) |
1029 | DMWARN("%s: target device " | 1028 | DMWARN("%s: adding target device " |
1030 | "(start sect %llu len %llu) " | 1029 | "(start sect %llu len %llu) " |
1031 | "is misaligned", | 1030 | "caused an alignment inconsistency", |
1032 | dm_device_name(table->md), | 1031 | dm_device_name(table->md), |
1033 | (unsigned long long) ti->begin, | 1032 | (unsigned long long) ti->begin, |
1034 | (unsigned long long) ti->len); | 1033 | (unsigned long long) ti->len); |
@@ -1080,15 +1079,6 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, | |||
1080 | struct queue_limits *limits) | 1079 | struct queue_limits *limits) |
1081 | { | 1080 | { |
1082 | /* | 1081 | /* |
1083 | * Each target device in the table has a data area that should normally | ||
1084 | * be aligned such that the DM device's alignment_offset is 0. | ||
1085 | * FIXME: Propagate alignment_offsets up the stack and warn of | ||
1086 | * sub-optimal or inconsistent settings. | ||
1087 | */ | ||
1088 | limits->alignment_offset = 0; | ||
1089 | limits->misaligned = 0; | ||
1090 | |||
1091 | /* | ||
1092 | * Copy table's limits to the DM device's request_queue | 1082 | * Copy table's limits to the DM device's request_queue |
1093 | */ | 1083 | */ |
1094 | q->limits = *limits; | 1084 | q->limits = *limits; |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 9b98173a8184..5c8018977efa 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -938,6 +938,8 @@ extern void blk_queue_io_opt(struct request_queue *q, unsigned int opt); | |||
938 | extern void blk_set_default_limits(struct queue_limits *lim); | 938 | extern void blk_set_default_limits(struct queue_limits *lim); |
939 | extern int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, | 939 | extern int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, |
940 | sector_t offset); | 940 | sector_t offset); |
941 | extern int bdev_stack_limits(struct queue_limits *t, struct block_device *bdev, | ||
942 | sector_t offset); | ||
941 | extern void disk_stack_limits(struct gendisk *disk, struct block_device *bdev, | 943 | extern void disk_stack_limits(struct gendisk *disk, struct block_device *bdev, |
942 | sector_t offset); | 944 | sector_t offset); |
943 | extern void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b); | 945 | extern void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b); |
@@ -1148,8 +1150,11 @@ static inline int queue_discard_alignment(struct request_queue *q) | |||
1148 | static inline int queue_sector_discard_alignment(struct request_queue *q, | 1150 | static inline int queue_sector_discard_alignment(struct request_queue *q, |
1149 | sector_t sector) | 1151 | sector_t sector) |
1150 | { | 1152 | { |
1151 | return ((sector << 9) - q->limits.discard_alignment) | 1153 | struct queue_limits *lim = &q->limits; |
1152 | & (q->limits.discard_granularity - 1); | 1154 | unsigned int alignment = (sector << 9) & (lim->discard_granularity - 1); |
1155 | |||
1156 | return (lim->discard_granularity + lim->discard_alignment - alignment) | ||
1157 | & (lim->discard_granularity - 1); | ||
1153 | } | 1158 | } |
1154 | 1159 | ||
1155 | static inline unsigned int queue_discard_zeroes_data(struct request_queue *q) | 1160 | static inline unsigned int queue_discard_zeroes_data(struct request_queue *q) |
diff --git a/include/linux/genhd.h b/include/linux/genhd.h index c6c0c41af35f..9717081c75ad 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h | |||
@@ -256,9 +256,9 @@ extern struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, | |||
256 | #define part_stat_read(part, field) \ | 256 | #define part_stat_read(part, field) \ |
257 | ({ \ | 257 | ({ \ |
258 | typeof((part)->dkstats->field) res = 0; \ | 258 | typeof((part)->dkstats->field) res = 0; \ |
259 | int i; \ | 259 | unsigned int _cpu; \ |
260 | for_each_possible_cpu(i) \ | 260 | for_each_possible_cpu(_cpu) \ |
261 | res += per_cpu_ptr((part)->dkstats, i)->field; \ | 261 | res += per_cpu_ptr((part)->dkstats, _cpu)->field; \ |
262 | res; \ | 262 | res; \ |
263 | }) | 263 | }) |
264 | 264 | ||
diff --git a/include/linux/iocontext.h b/include/linux/iocontext.h index a63235996309..78ef023227d4 100644 --- a/include/linux/iocontext.h +++ b/include/linux/iocontext.h | |||
@@ -4,32 +4,6 @@ | |||
4 | #include <linux/radix-tree.h> | 4 | #include <linux/radix-tree.h> |
5 | #include <linux/rcupdate.h> | 5 | #include <linux/rcupdate.h> |
6 | 6 | ||
7 | /* | ||
8 | * This is the per-process anticipatory I/O scheduler state. | ||
9 | */ | ||
10 | struct as_io_context { | ||
11 | spinlock_t lock; | ||
12 | |||
13 | void (*dtor)(struct as_io_context *aic); /* destructor */ | ||
14 | void (*exit)(struct as_io_context *aic); /* called on task exit */ | ||
15 | |||
16 | unsigned long state; | ||
17 | atomic_t nr_queued; /* queued reads & sync writes */ | ||
18 | atomic_t nr_dispatched; /* number of requests gone to the drivers */ | ||
19 | |||
20 | /* IO History tracking */ | ||
21 | /* Thinktime */ | ||
22 | unsigned long last_end_request; | ||
23 | unsigned long ttime_total; | ||
24 | unsigned long ttime_samples; | ||
25 | unsigned long ttime_mean; | ||
26 | /* Layout pattern */ | ||
27 | unsigned int seek_samples; | ||
28 | sector_t last_request_pos; | ||
29 | u64 seek_total; | ||
30 | sector_t seek_mean; | ||
31 | }; | ||
32 | |||
33 | struct cfq_queue; | 7 | struct cfq_queue; |
34 | struct cfq_io_context { | 8 | struct cfq_io_context { |
35 | void *key; | 9 | void *key; |
@@ -78,7 +52,6 @@ struct io_context { | |||
78 | unsigned long last_waited; /* Time last woken after wait for request */ | 52 | unsigned long last_waited; /* Time last woken after wait for request */ |
79 | int nr_batch_requests; /* Number of requests left in the batch */ | 53 | int nr_batch_requests; /* Number of requests left in the batch */ |
80 | 54 | ||
81 | struct as_io_context *aic; | ||
82 | struct radix_tree_root radix_root; | 55 | struct radix_tree_root radix_root; |
83 | struct hlist_head cic_list; | 56 | struct hlist_head cic_list; |
84 | void *ioc_data; | 57 | void *ioc_data; |