diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-24 10:48:24 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-24 10:48:24 -0400 |
commit | 97c68d00dbb2decda4b3dce79ce55df04246a834 (patch) | |
tree | f7c2f3185e4dfb073f6d268b4aa0a4d9a0015ece | |
parent | 596a5c4e43b08e90c0cd788861f859bf7ed6eddc (diff) | |
parent | f2d1f0ae7851be5ebd9613a80dac139270938809 (diff) |
Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block
* 'for-linus' of git://git.kernel.dk/linux-2.6-block:
cfq-iosched: cache prio_tree root in cfqq->p_root
cfq-iosched: fix bug with aliased request and cooperation detection
cfq-iosched: clear ->prio_trees[] on cfqd alloc
block: fix intermittent dm timeout based oops
umem: fix request_queue lock warning
block: simplify I/O stat accounting
pktcdvd.h should include mempool.h
cfq-iosched: use the default seek distance when there aren't enough seek samples
cfq-iosched: make seek_mean converge more quickly
block: make blk_abort_queue() ignore non-request based devices
block: include empty disks in /proc/diskstats
bio: use bio_kmalloc() in copy/map functions
bio: fix bio_kmalloc()
block: fix queue bounce limit setting
block: fix SG_IO vector request data length handling
scatterlist: make sure sg_miter_next() doesn't return 0 sized mappings
-rw-r--r-- | block/blk-core.c | 6 | ||||
-rw-r--r-- | block/blk-merge.c | 5 | ||||
-rw-r--r-- | block/blk-settings.c | 20 | ||||
-rw-r--r-- | block/blk-sysfs.c | 4 | ||||
-rw-r--r-- | block/blk-timeout.c | 13 | ||||
-rw-r--r-- | block/blk.h | 7 | ||||
-rw-r--r-- | block/cfq-iosched.c | 66 | ||||
-rw-r--r-- | block/genhd.c | 12 | ||||
-rw-r--r-- | block/scsi_ioctl.c | 13 | ||||
-rw-r--r-- | drivers/block/umem.c | 1 | ||||
-rw-r--r-- | fs/bio.c | 124 | ||||
-rw-r--r-- | include/linux/bio.h | 1 | ||||
-rw-r--r-- | include/linux/blkdev.h | 3 | ||||
-rw-r--r-- | include/linux/genhd.h | 1 | ||||
-rw-r--r-- | include/linux/pktcdvd.h | 1 | ||||
-rw-r--r-- | lib/scatterlist.c | 9 |
16 files changed, 166 insertions, 120 deletions
diff --git a/block/blk-core.c b/block/blk-core.c index 07ab75403e1a..2998fe3a2377 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
@@ -643,7 +643,7 @@ static inline void blk_free_request(struct request_queue *q, struct request *rq) | |||
643 | } | 643 | } |
644 | 644 | ||
645 | static struct request * | 645 | static struct request * |
646 | blk_alloc_request(struct request_queue *q, int rw, int priv, gfp_t gfp_mask) | 646 | blk_alloc_request(struct request_queue *q, int flags, int priv, gfp_t gfp_mask) |
647 | { | 647 | { |
648 | struct request *rq = mempool_alloc(q->rq.rq_pool, gfp_mask); | 648 | struct request *rq = mempool_alloc(q->rq.rq_pool, gfp_mask); |
649 | 649 | ||
@@ -652,7 +652,7 @@ blk_alloc_request(struct request_queue *q, int rw, int priv, gfp_t gfp_mask) | |||
652 | 652 | ||
653 | blk_rq_init(q, rq); | 653 | blk_rq_init(q, rq); |
654 | 654 | ||
655 | rq->cmd_flags = rw | REQ_ALLOCED; | 655 | rq->cmd_flags = flags | REQ_ALLOCED; |
656 | 656 | ||
657 | if (priv) { | 657 | if (priv) { |
658 | if (unlikely(elv_set_request(q, rq, gfp_mask))) { | 658 | if (unlikely(elv_set_request(q, rq, gfp_mask))) { |
@@ -792,6 +792,8 @@ static struct request *get_request(struct request_queue *q, int rw_flags, | |||
792 | if (priv) | 792 | if (priv) |
793 | rl->elvpriv++; | 793 | rl->elvpriv++; |
794 | 794 | ||
795 | if (blk_queue_io_stat(q)) | ||
796 | rw_flags |= REQ_IO_STAT; | ||
795 | spin_unlock_irq(q->queue_lock); | 797 | spin_unlock_irq(q->queue_lock); |
796 | 798 | ||
797 | rq = blk_alloc_request(q, rw_flags, priv, gfp_mask); | 799 | rq = blk_alloc_request(q, rw_flags, priv, gfp_mask); |
diff --git a/block/blk-merge.c b/block/blk-merge.c index 63760ca3da0f..23d2a6fe34a3 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c | |||
@@ -402,7 +402,10 @@ static int attempt_merge(struct request_queue *q, struct request *req, | |||
402 | 402 | ||
403 | elv_merge_requests(q, req, next); | 403 | elv_merge_requests(q, req, next); |
404 | 404 | ||
405 | blk_account_io_merge(req); | 405 | /* |
406 | * 'next' is going away, so update stats accordingly | ||
407 | */ | ||
408 | blk_account_io_merge(next); | ||
406 | 409 | ||
407 | req->ioprio = ioprio_best(req->ioprio, next->ioprio); | 410 | req->ioprio = ioprio_best(req->ioprio, next->ioprio); |
408 | if (blk_rq_cpu_valid(next)) | 411 | if (blk_rq_cpu_valid(next)) |
diff --git a/block/blk-settings.c b/block/blk-settings.c index 69c42adde52b..57af728d94bb 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c | |||
@@ -156,26 +156,28 @@ EXPORT_SYMBOL(blk_queue_make_request); | |||
156 | 156 | ||
157 | /** | 157 | /** |
158 | * blk_queue_bounce_limit - set bounce buffer limit for queue | 158 | * blk_queue_bounce_limit - set bounce buffer limit for queue |
159 | * @q: the request queue for the device | 159 | * @q: the request queue for the device |
160 | * @dma_addr: bus address limit | 160 | * @dma_mask: the maximum address the device can handle |
161 | * | 161 | * |
162 | * Description: | 162 | * Description: |
163 | * Different hardware can have different requirements as to what pages | 163 | * Different hardware can have different requirements as to what pages |
164 | * it can do I/O directly to. A low level driver can call | 164 | * it can do I/O directly to. A low level driver can call |
165 | * blk_queue_bounce_limit to have lower memory pages allocated as bounce | 165 | * blk_queue_bounce_limit to have lower memory pages allocated as bounce |
166 | * buffers for doing I/O to pages residing above @dma_addr. | 166 | * buffers for doing I/O to pages residing above @dma_mask. |
167 | **/ | 167 | **/ |
168 | void blk_queue_bounce_limit(struct request_queue *q, u64 dma_addr) | 168 | void blk_queue_bounce_limit(struct request_queue *q, u64 dma_mask) |
169 | { | 169 | { |
170 | unsigned long b_pfn = dma_addr >> PAGE_SHIFT; | 170 | unsigned long b_pfn = dma_mask >> PAGE_SHIFT; |
171 | int dma = 0; | 171 | int dma = 0; |
172 | 172 | ||
173 | q->bounce_gfp = GFP_NOIO; | 173 | q->bounce_gfp = GFP_NOIO; |
174 | #if BITS_PER_LONG == 64 | 174 | #if BITS_PER_LONG == 64 |
175 | /* Assume anything <= 4GB can be handled by IOMMU. | 175 | /* |
176 | Actually some IOMMUs can handle everything, but I don't | 176 | * Assume anything <= 4GB can be handled by IOMMU. Actually |
177 | know of a way to test this here. */ | 177 | * some IOMMUs can handle everything, but I don't know of a |
178 | if (b_pfn < (min_t(u64, 0x100000000UL, BLK_BOUNCE_HIGH) >> PAGE_SHIFT)) | 178 | * way to test this here. |
179 | */ | ||
180 | if (b_pfn < (min_t(u64, 0xffffffffUL, BLK_BOUNCE_HIGH) >> PAGE_SHIFT)) | ||
179 | dma = 1; | 181 | dma = 1; |
180 | q->bounce_pfn = max_low_pfn; | 182 | q->bounce_pfn = max_low_pfn; |
181 | #else | 183 | #else |
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index cac4e9febe6a..3ff9bba3379a 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c | |||
@@ -209,14 +209,10 @@ static ssize_t queue_iostats_store(struct request_queue *q, const char *page, | |||
209 | ssize_t ret = queue_var_store(&stats, page, count); | 209 | ssize_t ret = queue_var_store(&stats, page, count); |
210 | 210 | ||
211 | spin_lock_irq(q->queue_lock); | 211 | spin_lock_irq(q->queue_lock); |
212 | elv_quiesce_start(q); | ||
213 | |||
214 | if (stats) | 212 | if (stats) |
215 | queue_flag_set(QUEUE_FLAG_IO_STAT, q); | 213 | queue_flag_set(QUEUE_FLAG_IO_STAT, q); |
216 | else | 214 | else |
217 | queue_flag_clear(QUEUE_FLAG_IO_STAT, q); | 215 | queue_flag_clear(QUEUE_FLAG_IO_STAT, q); |
218 | |||
219 | elv_quiesce_end(q); | ||
220 | spin_unlock_irq(q->queue_lock); | 216 | spin_unlock_irq(q->queue_lock); |
221 | 217 | ||
222 | return ret; | 218 | return ret; |
diff --git a/block/blk-timeout.c b/block/blk-timeout.c index bbbdc4b8ccf2..1ec0d503cacd 100644 --- a/block/blk-timeout.c +++ b/block/blk-timeout.c | |||
@@ -211,6 +211,12 @@ void blk_abort_queue(struct request_queue *q) | |||
211 | struct request *rq, *tmp; | 211 | struct request *rq, *tmp; |
212 | LIST_HEAD(list); | 212 | LIST_HEAD(list); |
213 | 213 | ||
214 | /* | ||
215 | * Not a request based block device, nothing to abort | ||
216 | */ | ||
217 | if (!q->request_fn) | ||
218 | return; | ||
219 | |||
214 | spin_lock_irqsave(q->queue_lock, flags); | 220 | spin_lock_irqsave(q->queue_lock, flags); |
215 | 221 | ||
216 | elv_abort_queue(q); | 222 | elv_abort_queue(q); |
@@ -224,6 +230,13 @@ void blk_abort_queue(struct request_queue *q) | |||
224 | list_for_each_entry_safe(rq, tmp, &list, timeout_list) | 230 | list_for_each_entry_safe(rq, tmp, &list, timeout_list) |
225 | blk_abort_request(rq); | 231 | blk_abort_request(rq); |
226 | 232 | ||
233 | /* | ||
234 | * Occasionally, blk_abort_request() will return without | ||
235 | * deleting the element from the list. Make sure we add those back | ||
236 | * instead of leaving them on the local stack list. | ||
237 | */ | ||
238 | list_splice(&list, &q->timeout_list); | ||
239 | |||
227 | spin_unlock_irqrestore(q->queue_lock, flags); | 240 | spin_unlock_irqrestore(q->queue_lock, flags); |
228 | 241 | ||
229 | } | 242 | } |
diff --git a/block/blk.h b/block/blk.h index 5dfc41267a08..79c85f7c9ff5 100644 --- a/block/blk.h +++ b/block/blk.h | |||
@@ -114,12 +114,7 @@ static inline int blk_cpu_to_group(int cpu) | |||
114 | 114 | ||
115 | static inline int blk_do_io_stat(struct request *rq) | 115 | static inline int blk_do_io_stat(struct request *rq) |
116 | { | 116 | { |
117 | struct gendisk *disk = rq->rq_disk; | 117 | return rq->rq_disk && blk_rq_io_stat(rq); |
118 | |||
119 | if (!disk || !disk->queue) | ||
120 | return 0; | ||
121 | |||
122 | return blk_queue_io_stat(disk->queue) && (rq->cmd_flags & REQ_ELVPRIV); | ||
123 | } | 118 | } |
124 | 119 | ||
125 | #endif | 120 | #endif |
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 0d3b70de3d80..a55a9bd75bd1 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
@@ -154,6 +154,8 @@ struct cfq_queue { | |||
154 | unsigned long rb_key; | 154 | unsigned long rb_key; |
155 | /* prio tree member */ | 155 | /* prio tree member */ |
156 | struct rb_node p_node; | 156 | struct rb_node p_node; |
157 | /* prio tree root we belong to, if any */ | ||
158 | struct rb_root *p_root; | ||
157 | /* sorted list of pending requests */ | 159 | /* sorted list of pending requests */ |
158 | struct rb_root sort_list; | 160 | struct rb_root sort_list; |
159 | /* if fifo isn't expired, next request to serve */ | 161 | /* if fifo isn't expired, next request to serve */ |
@@ -558,10 +560,10 @@ static void cfq_service_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq, | |||
558 | } | 560 | } |
559 | 561 | ||
560 | static struct cfq_queue * | 562 | static struct cfq_queue * |
561 | cfq_prio_tree_lookup(struct cfq_data *cfqd, int ioprio, sector_t sector, | 563 | cfq_prio_tree_lookup(struct cfq_data *cfqd, struct rb_root *root, |
562 | struct rb_node **ret_parent, struct rb_node ***rb_link) | 564 | sector_t sector, struct rb_node **ret_parent, |
565 | struct rb_node ***rb_link) | ||
563 | { | 566 | { |
564 | struct rb_root *root = &cfqd->prio_trees[ioprio]; | ||
565 | struct rb_node **p, *parent; | 567 | struct rb_node **p, *parent; |
566 | struct cfq_queue *cfqq = NULL; | 568 | struct cfq_queue *cfqq = NULL; |
567 | 569 | ||
@@ -584,34 +586,38 @@ cfq_prio_tree_lookup(struct cfq_data *cfqd, int ioprio, sector_t sector, | |||
584 | else | 586 | else |
585 | break; | 587 | break; |
586 | p = n; | 588 | p = n; |
589 | cfqq = NULL; | ||
587 | } | 590 | } |
588 | 591 | ||
589 | *ret_parent = parent; | 592 | *ret_parent = parent; |
590 | if (rb_link) | 593 | if (rb_link) |
591 | *rb_link = p; | 594 | *rb_link = p; |
592 | return NULL; | 595 | return cfqq; |
593 | } | 596 | } |
594 | 597 | ||
595 | static void cfq_prio_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq) | 598 | static void cfq_prio_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq) |
596 | { | 599 | { |
597 | struct rb_root *root = &cfqd->prio_trees[cfqq->ioprio]; | ||
598 | struct rb_node **p, *parent; | 600 | struct rb_node **p, *parent; |
599 | struct cfq_queue *__cfqq; | 601 | struct cfq_queue *__cfqq; |
600 | 602 | ||
601 | if (!RB_EMPTY_NODE(&cfqq->p_node)) | 603 | if (cfqq->p_root) { |
602 | rb_erase_init(&cfqq->p_node, root); | 604 | rb_erase(&cfqq->p_node, cfqq->p_root); |
605 | cfqq->p_root = NULL; | ||
606 | } | ||
603 | 607 | ||
604 | if (cfq_class_idle(cfqq)) | 608 | if (cfq_class_idle(cfqq)) |
605 | return; | 609 | return; |
606 | if (!cfqq->next_rq) | 610 | if (!cfqq->next_rq) |
607 | return; | 611 | return; |
608 | 612 | ||
609 | __cfqq = cfq_prio_tree_lookup(cfqd, cfqq->ioprio, cfqq->next_rq->sector, | 613 | cfqq->p_root = &cfqd->prio_trees[cfqq->org_ioprio]; |
614 | __cfqq = cfq_prio_tree_lookup(cfqd, cfqq->p_root, cfqq->next_rq->sector, | ||
610 | &parent, &p); | 615 | &parent, &p); |
611 | BUG_ON(__cfqq); | 616 | if (!__cfqq) { |
612 | 617 | rb_link_node(&cfqq->p_node, parent, p); | |
613 | rb_link_node(&cfqq->p_node, parent, p); | 618 | rb_insert_color(&cfqq->p_node, cfqq->p_root); |
614 | rb_insert_color(&cfqq->p_node, root); | 619 | } else |
620 | cfqq->p_root = NULL; | ||
615 | } | 621 | } |
616 | 622 | ||
617 | /* | 623 | /* |
@@ -656,8 +662,10 @@ static void cfq_del_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq) | |||
656 | 662 | ||
657 | if (!RB_EMPTY_NODE(&cfqq->rb_node)) | 663 | if (!RB_EMPTY_NODE(&cfqq->rb_node)) |
658 | cfq_rb_erase(&cfqq->rb_node, &cfqd->service_tree); | 664 | cfq_rb_erase(&cfqq->rb_node, &cfqd->service_tree); |
659 | if (!RB_EMPTY_NODE(&cfqq->p_node)) | 665 | if (cfqq->p_root) { |
660 | rb_erase_init(&cfqq->p_node, &cfqd->prio_trees[cfqq->ioprio]); | 666 | rb_erase(&cfqq->p_node, cfqq->p_root); |
667 | cfqq->p_root = NULL; | ||
668 | } | ||
661 | 669 | ||
662 | BUG_ON(!cfqd->busy_queues); | 670 | BUG_ON(!cfqd->busy_queues); |
663 | cfqd->busy_queues--; | 671 | cfqd->busy_queues--; |
@@ -947,20 +955,24 @@ static inline sector_t cfq_dist_from_last(struct cfq_data *cfqd, | |||
947 | return cfqd->last_position - rq->sector; | 955 | return cfqd->last_position - rq->sector; |
948 | } | 956 | } |
949 | 957 | ||
958 | #define CIC_SEEK_THR 8 * 1024 | ||
959 | #define CIC_SEEKY(cic) ((cic)->seek_mean > CIC_SEEK_THR) | ||
960 | |||
950 | static inline int cfq_rq_close(struct cfq_data *cfqd, struct request *rq) | 961 | static inline int cfq_rq_close(struct cfq_data *cfqd, struct request *rq) |
951 | { | 962 | { |
952 | struct cfq_io_context *cic = cfqd->active_cic; | 963 | struct cfq_io_context *cic = cfqd->active_cic; |
964 | sector_t sdist = cic->seek_mean; | ||
953 | 965 | ||
954 | if (!sample_valid(cic->seek_samples)) | 966 | if (!sample_valid(cic->seek_samples)) |
955 | return 0; | 967 | sdist = CIC_SEEK_THR; |
956 | 968 | ||
957 | return cfq_dist_from_last(cfqd, rq) <= cic->seek_mean; | 969 | return cfq_dist_from_last(cfqd, rq) <= sdist; |
958 | } | 970 | } |
959 | 971 | ||
960 | static struct cfq_queue *cfqq_close(struct cfq_data *cfqd, | 972 | static struct cfq_queue *cfqq_close(struct cfq_data *cfqd, |
961 | struct cfq_queue *cur_cfqq) | 973 | struct cfq_queue *cur_cfqq) |
962 | { | 974 | { |
963 | struct rb_root *root = &cfqd->prio_trees[cur_cfqq->ioprio]; | 975 | struct rb_root *root = &cfqd->prio_trees[cur_cfqq->org_ioprio]; |
964 | struct rb_node *parent, *node; | 976 | struct rb_node *parent, *node; |
965 | struct cfq_queue *__cfqq; | 977 | struct cfq_queue *__cfqq; |
966 | sector_t sector = cfqd->last_position; | 978 | sector_t sector = cfqd->last_position; |
@@ -972,8 +984,7 @@ static struct cfq_queue *cfqq_close(struct cfq_data *cfqd, | |||
972 | * First, if we find a request starting at the end of the last | 984 | * First, if we find a request starting at the end of the last |
973 | * request, choose it. | 985 | * request, choose it. |
974 | */ | 986 | */ |
975 | __cfqq = cfq_prio_tree_lookup(cfqd, cur_cfqq->ioprio, | 987 | __cfqq = cfq_prio_tree_lookup(cfqd, root, sector, &parent, NULL); |
976 | sector, &parent, NULL); | ||
977 | if (__cfqq) | 988 | if (__cfqq) |
978 | return __cfqq; | 989 | return __cfqq; |
979 | 990 | ||
@@ -1039,9 +1050,6 @@ static struct cfq_queue *cfq_close_cooperator(struct cfq_data *cfqd, | |||
1039 | return cfqq; | 1050 | return cfqq; |
1040 | } | 1051 | } |
1041 | 1052 | ||
1042 | |||
1043 | #define CIC_SEEKY(cic) ((cic)->seek_mean > (8 * 1024)) | ||
1044 | |||
1045 | static void cfq_arm_slice_timer(struct cfq_data *cfqd) | 1053 | static void cfq_arm_slice_timer(struct cfq_data *cfqd) |
1046 | { | 1054 | { |
1047 | struct cfq_queue *cfqq = cfqd->active_queue; | 1055 | struct cfq_queue *cfqq = cfqd->active_queue; |
@@ -1908,7 +1916,9 @@ cfq_update_io_seektime(struct cfq_data *cfqd, struct cfq_io_context *cic, | |||
1908 | sector_t sdist; | 1916 | sector_t sdist; |
1909 | u64 total; | 1917 | u64 total; |
1910 | 1918 | ||
1911 | if (cic->last_request_pos < rq->sector) | 1919 | if (!cic->last_request_pos) |
1920 | sdist = 0; | ||
1921 | else if (cic->last_request_pos < rq->sector) | ||
1912 | sdist = rq->sector - cic->last_request_pos; | 1922 | sdist = rq->sector - cic->last_request_pos; |
1913 | else | 1923 | else |
1914 | sdist = cic->last_request_pos - rq->sector; | 1924 | sdist = cic->last_request_pos - rq->sector; |
@@ -2443,12 +2453,22 @@ static void cfq_exit_queue(struct elevator_queue *e) | |||
2443 | static void *cfq_init_queue(struct request_queue *q) | 2453 | static void *cfq_init_queue(struct request_queue *q) |
2444 | { | 2454 | { |
2445 | struct cfq_data *cfqd; | 2455 | struct cfq_data *cfqd; |
2456 | int i; | ||
2446 | 2457 | ||
2447 | cfqd = kmalloc_node(sizeof(*cfqd), GFP_KERNEL | __GFP_ZERO, q->node); | 2458 | cfqd = kmalloc_node(sizeof(*cfqd), GFP_KERNEL | __GFP_ZERO, q->node); |
2448 | if (!cfqd) | 2459 | if (!cfqd) |
2449 | return NULL; | 2460 | return NULL; |
2450 | 2461 | ||
2451 | cfqd->service_tree = CFQ_RB_ROOT; | 2462 | cfqd->service_tree = CFQ_RB_ROOT; |
2463 | |||
2464 | /* | ||
2465 | * Not strictly needed (since RB_ROOT just clears the node and we | ||
2466 | * zeroed cfqd on alloc), but better be safe in case someone decides | ||
2467 | * to add magic to the rb code | ||
2468 | */ | ||
2469 | for (i = 0; i < CFQ_PRIO_LISTS; i++) | ||
2470 | cfqd->prio_trees[i] = RB_ROOT; | ||
2471 | |||
2452 | INIT_LIST_HEAD(&cfqd->cic_list); | 2472 | INIT_LIST_HEAD(&cfqd->cic_list); |
2453 | 2473 | ||
2454 | cfqd->queue = q; | 2474 | cfqd->queue = q; |
diff --git a/block/genhd.c b/block/genhd.c index a9ec910974c1..1a4916e01732 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
@@ -98,7 +98,7 @@ void disk_part_iter_init(struct disk_part_iter *piter, struct gendisk *disk, | |||
98 | 98 | ||
99 | if (flags & DISK_PITER_REVERSE) | 99 | if (flags & DISK_PITER_REVERSE) |
100 | piter->idx = ptbl->len - 1; | 100 | piter->idx = ptbl->len - 1; |
101 | else if (flags & DISK_PITER_INCL_PART0) | 101 | else if (flags & (DISK_PITER_INCL_PART0 | DISK_PITER_INCL_EMPTY_PART0)) |
102 | piter->idx = 0; | 102 | piter->idx = 0; |
103 | else | 103 | else |
104 | piter->idx = 1; | 104 | piter->idx = 1; |
@@ -134,7 +134,8 @@ struct hd_struct *disk_part_iter_next(struct disk_part_iter *piter) | |||
134 | /* determine iteration parameters */ | 134 | /* determine iteration parameters */ |
135 | if (piter->flags & DISK_PITER_REVERSE) { | 135 | if (piter->flags & DISK_PITER_REVERSE) { |
136 | inc = -1; | 136 | inc = -1; |
137 | if (piter->flags & DISK_PITER_INCL_PART0) | 137 | if (piter->flags & (DISK_PITER_INCL_PART0 | |
138 | DISK_PITER_INCL_EMPTY_PART0)) | ||
138 | end = -1; | 139 | end = -1; |
139 | else | 140 | else |
140 | end = 0; | 141 | end = 0; |
@@ -150,7 +151,10 @@ struct hd_struct *disk_part_iter_next(struct disk_part_iter *piter) | |||
150 | part = rcu_dereference(ptbl->part[piter->idx]); | 151 | part = rcu_dereference(ptbl->part[piter->idx]); |
151 | if (!part) | 152 | if (!part) |
152 | continue; | 153 | continue; |
153 | if (!(piter->flags & DISK_PITER_INCL_EMPTY) && !part->nr_sects) | 154 | if (!part->nr_sects && |
155 | !(piter->flags & DISK_PITER_INCL_EMPTY) && | ||
156 | !(piter->flags & DISK_PITER_INCL_EMPTY_PART0 && | ||
157 | piter->idx == 0)) | ||
154 | continue; | 158 | continue; |
155 | 159 | ||
156 | get_device(part_to_dev(part)); | 160 | get_device(part_to_dev(part)); |
@@ -1011,7 +1015,7 @@ static int diskstats_show(struct seq_file *seqf, void *v) | |||
1011 | "\n\n"); | 1015 | "\n\n"); |
1012 | */ | 1016 | */ |
1013 | 1017 | ||
1014 | disk_part_iter_init(&piter, gp, DISK_PITER_INCL_PART0); | 1018 | disk_part_iter_init(&piter, gp, DISK_PITER_INCL_EMPTY_PART0); |
1015 | while ((hd = disk_part_iter_next(&piter))) { | 1019 | while ((hd = disk_part_iter_next(&piter))) { |
1016 | cpu = part_stat_lock(); | 1020 | cpu = part_stat_lock(); |
1017 | part_round_stats(cpu, hd); | 1021 | part_round_stats(cpu, hd); |
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index 84b7f8709f41..82a0ca2f6729 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c | |||
@@ -290,6 +290,7 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk, | |||
290 | 290 | ||
291 | if (hdr->iovec_count) { | 291 | if (hdr->iovec_count) { |
292 | const int size = sizeof(struct sg_iovec) * hdr->iovec_count; | 292 | const int size = sizeof(struct sg_iovec) * hdr->iovec_count; |
293 | size_t iov_data_len; | ||
293 | struct sg_iovec *iov; | 294 | struct sg_iovec *iov; |
294 | 295 | ||
295 | iov = kmalloc(size, GFP_KERNEL); | 296 | iov = kmalloc(size, GFP_KERNEL); |
@@ -304,8 +305,18 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk, | |||
304 | goto out; | 305 | goto out; |
305 | } | 306 | } |
306 | 307 | ||
308 | /* SG_IO howto says that the shorter of the two wins */ | ||
309 | iov_data_len = iov_length((struct iovec *)iov, | ||
310 | hdr->iovec_count); | ||
311 | if (hdr->dxfer_len < iov_data_len) { | ||
312 | hdr->iovec_count = iov_shorten((struct iovec *)iov, | ||
313 | hdr->iovec_count, | ||
314 | hdr->dxfer_len); | ||
315 | iov_data_len = hdr->dxfer_len; | ||
316 | } | ||
317 | |||
307 | ret = blk_rq_map_user_iov(q, rq, NULL, iov, hdr->iovec_count, | 318 | ret = blk_rq_map_user_iov(q, rq, NULL, iov, hdr->iovec_count, |
308 | hdr->dxfer_len, GFP_KERNEL); | 319 | iov_data_len, GFP_KERNEL); |
309 | kfree(iov); | 320 | kfree(iov); |
310 | } else if (hdr->dxfer_len) | 321 | } else if (hdr->dxfer_len) |
311 | ret = blk_rq_map_user(q, rq, NULL, hdr->dxferp, hdr->dxfer_len, | 322 | ret = blk_rq_map_user(q, rq, NULL, hdr->dxferp, hdr->dxfer_len, |
diff --git a/drivers/block/umem.c b/drivers/block/umem.c index 9744d59a69f2..858c34dd032d 100644 --- a/drivers/block/umem.c +++ b/drivers/block/umem.c | |||
@@ -906,6 +906,7 @@ static int __devinit mm_pci_probe(struct pci_dev *dev, | |||
906 | goto failed_alloc; | 906 | goto failed_alloc; |
907 | 907 | ||
908 | blk_queue_make_request(card->queue, mm_make_request); | 908 | blk_queue_make_request(card->queue, mm_make_request); |
909 | card->queue->queue_lock = &card->lock; | ||
909 | card->queue->queuedata = card; | 910 | card->queue->queuedata = card; |
910 | card->queue->unplug_fn = mm_unplug_device; | 911 | card->queue->unplug_fn = mm_unplug_device; |
911 | 912 | ||
@@ -175,14 +175,6 @@ struct bio_vec *bvec_alloc_bs(gfp_t gfp_mask, int nr, unsigned long *idx, | |||
175 | struct bio_vec *bvl; | 175 | struct bio_vec *bvl; |
176 | 176 | ||
177 | /* | 177 | /* |
178 | * If 'bs' is given, lookup the pool and do the mempool alloc. | ||
179 | * If not, this is a bio_kmalloc() allocation and just do a | ||
180 | * kzalloc() for the exact number of vecs right away. | ||
181 | */ | ||
182 | if (!bs) | ||
183 | bvl = kmalloc(nr * sizeof(struct bio_vec), gfp_mask); | ||
184 | |||
185 | /* | ||
186 | * see comment near bvec_array define! | 178 | * see comment near bvec_array define! |
187 | */ | 179 | */ |
188 | switch (nr) { | 180 | switch (nr) { |
@@ -260,21 +252,6 @@ void bio_free(struct bio *bio, struct bio_set *bs) | |||
260 | mempool_free(p, bs->bio_pool); | 252 | mempool_free(p, bs->bio_pool); |
261 | } | 253 | } |
262 | 254 | ||
263 | /* | ||
264 | * default destructor for a bio allocated with bio_alloc_bioset() | ||
265 | */ | ||
266 | static void bio_fs_destructor(struct bio *bio) | ||
267 | { | ||
268 | bio_free(bio, fs_bio_set); | ||
269 | } | ||
270 | |||
271 | static void bio_kmalloc_destructor(struct bio *bio) | ||
272 | { | ||
273 | if (bio_has_allocated_vec(bio)) | ||
274 | kfree(bio->bi_io_vec); | ||
275 | kfree(bio); | ||
276 | } | ||
277 | |||
278 | void bio_init(struct bio *bio) | 255 | void bio_init(struct bio *bio) |
279 | { | 256 | { |
280 | memset(bio, 0, sizeof(*bio)); | 257 | memset(bio, 0, sizeof(*bio)); |
@@ -301,21 +278,15 @@ void bio_init(struct bio *bio) | |||
301 | **/ | 278 | **/ |
302 | struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs) | 279 | struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs) |
303 | { | 280 | { |
281 | unsigned long idx = BIO_POOL_NONE; | ||
304 | struct bio_vec *bvl = NULL; | 282 | struct bio_vec *bvl = NULL; |
305 | struct bio *bio = NULL; | 283 | struct bio *bio; |
306 | unsigned long idx = 0; | 284 | void *p; |
307 | void *p = NULL; | 285 | |
308 | 286 | p = mempool_alloc(bs->bio_pool, gfp_mask); | |
309 | if (bs) { | 287 | if (unlikely(!p)) |
310 | p = mempool_alloc(bs->bio_pool, gfp_mask); | 288 | return NULL; |
311 | if (!p) | 289 | bio = p + bs->front_pad; |
312 | goto err; | ||
313 | bio = p + bs->front_pad; | ||
314 | } else { | ||
315 | bio = kmalloc(sizeof(*bio), gfp_mask); | ||
316 | if (!bio) | ||
317 | goto err; | ||
318 | } | ||
319 | 290 | ||
320 | bio_init(bio); | 291 | bio_init(bio); |
321 | 292 | ||
@@ -332,22 +303,50 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs) | |||
332 | 303 | ||
333 | nr_iovecs = bvec_nr_vecs(idx); | 304 | nr_iovecs = bvec_nr_vecs(idx); |
334 | } | 305 | } |
306 | out_set: | ||
335 | bio->bi_flags |= idx << BIO_POOL_OFFSET; | 307 | bio->bi_flags |= idx << BIO_POOL_OFFSET; |
336 | bio->bi_max_vecs = nr_iovecs; | 308 | bio->bi_max_vecs = nr_iovecs; |
337 | out_set: | ||
338 | bio->bi_io_vec = bvl; | 309 | bio->bi_io_vec = bvl; |
339 | |||
340 | return bio; | 310 | return bio; |
341 | 311 | ||
342 | err_free: | 312 | err_free: |
343 | if (bs) | 313 | mempool_free(p, bs->bio_pool); |
344 | mempool_free(p, bs->bio_pool); | ||
345 | else | ||
346 | kfree(bio); | ||
347 | err: | ||
348 | return NULL; | 314 | return NULL; |
349 | } | 315 | } |
350 | 316 | ||
317 | static void bio_fs_destructor(struct bio *bio) | ||
318 | { | ||
319 | bio_free(bio, fs_bio_set); | ||
320 | } | ||
321 | |||
322 | /** | ||
323 | * bio_alloc - allocate a new bio, memory pool backed | ||
324 | * @gfp_mask: allocation mask to use | ||
325 | * @nr_iovecs: number of iovecs | ||
326 | * | ||
327 | * Allocate a new bio with @nr_iovecs bvecs. If @gfp_mask | ||
328 | * contains __GFP_WAIT, the allocation is guaranteed to succeed. | ||
329 | * | ||
330 | * RETURNS: | ||
331 | * Pointer to new bio on success, NULL on failure. | ||
332 | */ | ||
333 | struct bio *bio_alloc(gfp_t gfp_mask, int nr_iovecs) | ||
334 | { | ||
335 | struct bio *bio = bio_alloc_bioset(gfp_mask, nr_iovecs, fs_bio_set); | ||
336 | |||
337 | if (bio) | ||
338 | bio->bi_destructor = bio_fs_destructor; | ||
339 | |||
340 | return bio; | ||
341 | } | ||
342 | |||
343 | static void bio_kmalloc_destructor(struct bio *bio) | ||
344 | { | ||
345 | if (bio_integrity(bio)) | ||
346 | bio_integrity_free(bio); | ||
347 | kfree(bio); | ||
348 | } | ||
349 | |||
351 | /** | 350 | /** |
352 | * bio_alloc - allocate a bio for I/O | 351 | * bio_alloc - allocate a bio for I/O |
353 | * @gfp_mask: the GFP_ mask given to the slab allocator | 352 | * @gfp_mask: the GFP_ mask given to the slab allocator |
@@ -366,29 +365,20 @@ err: | |||
366 | * do so can cause livelocks under memory pressure. | 365 | * do so can cause livelocks under memory pressure. |
367 | * | 366 | * |
368 | **/ | 367 | **/ |
369 | struct bio *bio_alloc(gfp_t gfp_mask, int nr_iovecs) | ||
370 | { | ||
371 | struct bio *bio = bio_alloc_bioset(gfp_mask, nr_iovecs, fs_bio_set); | ||
372 | |||
373 | if (bio) | ||
374 | bio->bi_destructor = bio_fs_destructor; | ||
375 | |||
376 | return bio; | ||
377 | } | ||
378 | |||
379 | /* | ||
380 | * Like bio_alloc(), but doesn't use a mempool backing. This means that | ||
381 | * it CAN fail, but while bio_alloc() can only be used for allocations | ||
382 | * that have a short (finite) life span, bio_kmalloc() should be used | ||
383 | * for more permanent bio allocations (like allocating some bio's for | ||
384 | * initalization or setup purposes). | ||
385 | */ | ||
386 | struct bio *bio_kmalloc(gfp_t gfp_mask, int nr_iovecs) | 368 | struct bio *bio_kmalloc(gfp_t gfp_mask, int nr_iovecs) |
387 | { | 369 | { |
388 | struct bio *bio = bio_alloc_bioset(gfp_mask, nr_iovecs, NULL); | 370 | struct bio *bio; |
389 | 371 | ||
390 | if (bio) | 372 | bio = kmalloc(sizeof(struct bio) + nr_iovecs * sizeof(struct bio_vec), |
391 | bio->bi_destructor = bio_kmalloc_destructor; | 373 | gfp_mask); |
374 | if (unlikely(!bio)) | ||
375 | return NULL; | ||
376 | |||
377 | bio_init(bio); | ||
378 | bio->bi_flags |= BIO_POOL_NONE << BIO_POOL_OFFSET; | ||
379 | bio->bi_max_vecs = nr_iovecs; | ||
380 | bio->bi_io_vec = bio->bi_inline_vecs; | ||
381 | bio->bi_destructor = bio_kmalloc_destructor; | ||
392 | 382 | ||
393 | return bio; | 383 | return bio; |
394 | } | 384 | } |
@@ -832,7 +822,7 @@ struct bio *bio_copy_user_iov(struct request_queue *q, | |||
832 | return ERR_PTR(-ENOMEM); | 822 | return ERR_PTR(-ENOMEM); |
833 | 823 | ||
834 | ret = -ENOMEM; | 824 | ret = -ENOMEM; |
835 | bio = bio_alloc(gfp_mask, nr_pages); | 825 | bio = bio_kmalloc(gfp_mask, nr_pages); |
836 | if (!bio) | 826 | if (!bio) |
837 | goto out_bmd; | 827 | goto out_bmd; |
838 | 828 | ||
@@ -956,7 +946,7 @@ static struct bio *__bio_map_user_iov(struct request_queue *q, | |||
956 | if (!nr_pages) | 946 | if (!nr_pages) |
957 | return ERR_PTR(-EINVAL); | 947 | return ERR_PTR(-EINVAL); |
958 | 948 | ||
959 | bio = bio_alloc(gfp_mask, nr_pages); | 949 | bio = bio_kmalloc(gfp_mask, nr_pages); |
960 | if (!bio) | 950 | if (!bio) |
961 | return ERR_PTR(-ENOMEM); | 951 | return ERR_PTR(-ENOMEM); |
962 | 952 | ||
@@ -1140,7 +1130,7 @@ static struct bio *__bio_map_kern(struct request_queue *q, void *data, | |||
1140 | int offset, i; | 1130 | int offset, i; |
1141 | struct bio *bio; | 1131 | struct bio *bio; |
1142 | 1132 | ||
1143 | bio = bio_alloc(gfp_mask, nr_pages); | 1133 | bio = bio_kmalloc(gfp_mask, nr_pages); |
1144 | if (!bio) | 1134 | if (!bio) |
1145 | return ERR_PTR(-ENOMEM); | 1135 | return ERR_PTR(-ENOMEM); |
1146 | 1136 | ||
diff --git a/include/linux/bio.h b/include/linux/bio.h index b89cf2d82898..7b214fd672a2 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h | |||
@@ -132,6 +132,7 @@ struct bio { | |||
132 | * top 4 bits of bio flags indicate the pool this bio came from | 132 | * top 4 bits of bio flags indicate the pool this bio came from |
133 | */ | 133 | */ |
134 | #define BIO_POOL_BITS (4) | 134 | #define BIO_POOL_BITS (4) |
135 | #define BIO_POOL_NONE ((1UL << BIO_POOL_BITS) - 1) | ||
135 | #define BIO_POOL_OFFSET (BITS_PER_LONG - BIO_POOL_BITS) | 136 | #define BIO_POOL_OFFSET (BITS_PER_LONG - BIO_POOL_BITS) |
136 | #define BIO_POOL_MASK (1UL << BIO_POOL_OFFSET) | 137 | #define BIO_POOL_MASK (1UL << BIO_POOL_OFFSET) |
137 | #define BIO_POOL_IDX(bio) ((bio)->bi_flags >> BIO_POOL_OFFSET) | 138 | #define BIO_POOL_IDX(bio) ((bio)->bi_flags >> BIO_POOL_OFFSET) |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index ba54c834a590..2755d5c6da22 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -118,6 +118,7 @@ enum rq_flag_bits { | |||
118 | __REQ_COPY_USER, /* contains copies of user pages */ | 118 | __REQ_COPY_USER, /* contains copies of user pages */ |
119 | __REQ_INTEGRITY, /* integrity metadata has been remapped */ | 119 | __REQ_INTEGRITY, /* integrity metadata has been remapped */ |
120 | __REQ_NOIDLE, /* Don't anticipate more IO after this one */ | 120 | __REQ_NOIDLE, /* Don't anticipate more IO after this one */ |
121 | __REQ_IO_STAT, /* account I/O stat */ | ||
121 | __REQ_NR_BITS, /* stops here */ | 122 | __REQ_NR_BITS, /* stops here */ |
122 | }; | 123 | }; |
123 | 124 | ||
@@ -145,6 +146,7 @@ enum rq_flag_bits { | |||
145 | #define REQ_COPY_USER (1 << __REQ_COPY_USER) | 146 | #define REQ_COPY_USER (1 << __REQ_COPY_USER) |
146 | #define REQ_INTEGRITY (1 << __REQ_INTEGRITY) | 147 | #define REQ_INTEGRITY (1 << __REQ_INTEGRITY) |
147 | #define REQ_NOIDLE (1 << __REQ_NOIDLE) | 148 | #define REQ_NOIDLE (1 << __REQ_NOIDLE) |
149 | #define REQ_IO_STAT (1 << __REQ_IO_STAT) | ||
148 | 150 | ||
149 | #define BLK_MAX_CDB 16 | 151 | #define BLK_MAX_CDB 16 |
150 | 152 | ||
@@ -598,6 +600,7 @@ enum { | |||
598 | blk_failfast_transport(rq) || \ | 600 | blk_failfast_transport(rq) || \ |
599 | blk_failfast_driver(rq)) | 601 | blk_failfast_driver(rq)) |
600 | #define blk_rq_started(rq) ((rq)->cmd_flags & REQ_STARTED) | 602 | #define blk_rq_started(rq) ((rq)->cmd_flags & REQ_STARTED) |
603 | #define blk_rq_io_stat(rq) ((rq)->cmd_flags & REQ_IO_STAT) | ||
601 | 604 | ||
602 | #define blk_account_rq(rq) (blk_rq_started(rq) && (blk_fs_request(rq) || blk_discard_rq(rq))) | 605 | #define blk_account_rq(rq) (blk_rq_started(rq) && (blk_fs_request(rq) || blk_discard_rq(rq))) |
603 | 606 | ||
diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 634c53028fb8..a1a28caed23d 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h | |||
@@ -214,6 +214,7 @@ static inline void disk_put_part(struct hd_struct *part) | |||
214 | #define DISK_PITER_REVERSE (1 << 0) /* iterate in the reverse direction */ | 214 | #define DISK_PITER_REVERSE (1 << 0) /* iterate in the reverse direction */ |
215 | #define DISK_PITER_INCL_EMPTY (1 << 1) /* include 0-sized parts */ | 215 | #define DISK_PITER_INCL_EMPTY (1 << 1) /* include 0-sized parts */ |
216 | #define DISK_PITER_INCL_PART0 (1 << 2) /* include partition 0 */ | 216 | #define DISK_PITER_INCL_PART0 (1 << 2) /* include partition 0 */ |
217 | #define DISK_PITER_INCL_EMPTY_PART0 (1 << 3) /* include empty partition 0 */ | ||
217 | 218 | ||
218 | struct disk_part_iter { | 219 | struct disk_part_iter { |
219 | struct gendisk *disk; | 220 | struct gendisk *disk; |
diff --git a/include/linux/pktcdvd.h b/include/linux/pktcdvd.h index 04b4d7330e6d..d745f5b6c7b0 100644 --- a/include/linux/pktcdvd.h +++ b/include/linux/pktcdvd.h | |||
@@ -113,6 +113,7 @@ struct pkt_ctrl_command { | |||
113 | #include <linux/cdrom.h> | 113 | #include <linux/cdrom.h> |
114 | #include <linux/kobject.h> | 114 | #include <linux/kobject.h> |
115 | #include <linux/sysfs.h> | 115 | #include <linux/sysfs.h> |
116 | #include <linux/mempool.h> | ||
116 | 117 | ||
117 | /* default bio write queue congestion marks */ | 118 | /* default bio write queue congestion marks */ |
118 | #define PKT_WRITE_CONGESTION_ON 10000 | 119 | #define PKT_WRITE_CONGESTION_ON 10000 |
diff --git a/lib/scatterlist.c b/lib/scatterlist.c index b7b449dafbe5..a295e404e908 100644 --- a/lib/scatterlist.c +++ b/lib/scatterlist.c | |||
@@ -347,9 +347,12 @@ bool sg_miter_next(struct sg_mapping_iter *miter) | |||
347 | sg_miter_stop(miter); | 347 | sg_miter_stop(miter); |
348 | 348 | ||
349 | /* get to the next sg if necessary. __offset is adjusted by stop */ | 349 | /* get to the next sg if necessary. __offset is adjusted by stop */ |
350 | if (miter->__offset == miter->__sg->length && --miter->__nents) { | 350 | while (miter->__offset == miter->__sg->length) { |
351 | miter->__sg = sg_next(miter->__sg); | 351 | if (--miter->__nents) { |
352 | miter->__offset = 0; | 352 | miter->__sg = sg_next(miter->__sg); |
353 | miter->__offset = 0; | ||
354 | } else | ||
355 | return false; | ||
353 | } | 356 | } |
354 | 357 | ||
355 | /* map the next page */ | 358 | /* map the next page */ |