diff options
| -rw-r--r-- | drivers/block/ll_rw_blk.c | 35 | ||||
| -rw-r--r-- | include/linux/blkdev.h | 1 | 
2 files changed, 10 insertions, 26 deletions
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index 808390c74200..896d17c28f42 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c  | |||
| @@ -717,7 +717,7 @@ struct request *blk_queue_find_tag(request_queue_t *q, int tag) | |||
| 717 | { | 717 | { | 
| 718 | struct blk_queue_tag *bqt = q->queue_tags; | 718 | struct blk_queue_tag *bqt = q->queue_tags; | 
| 719 | 719 | ||
| 720 | if (unlikely(bqt == NULL || tag >= bqt->real_max_depth)) | 720 | if (unlikely(bqt == NULL || tag >= bqt->max_depth)) | 
| 721 | return NULL; | 721 | return NULL; | 
| 722 | 722 | ||
| 723 | return bqt->tag_index[tag]; | 723 | return bqt->tag_index[tag]; | 
| @@ -775,9 +775,9 @@ EXPORT_SYMBOL(blk_queue_free_tags); | |||
| 775 | static int | 775 | static int | 
| 776 | init_tag_map(request_queue_t *q, struct blk_queue_tag *tags, int depth) | 776 | init_tag_map(request_queue_t *q, struct blk_queue_tag *tags, int depth) | 
| 777 | { | 777 | { | 
| 778 | int bits, i; | ||
| 779 | struct request **tag_index; | 778 | struct request **tag_index; | 
| 780 | unsigned long *tag_map; | 779 | unsigned long *tag_map; | 
| 780 | int nr_ulongs; | ||
| 781 | 781 | ||
| 782 | if (depth > q->nr_requests * 2) { | 782 | if (depth > q->nr_requests * 2) { | 
| 783 | depth = q->nr_requests * 2; | 783 | depth = q->nr_requests * 2; | 
| @@ -789,24 +789,17 @@ init_tag_map(request_queue_t *q, struct blk_queue_tag *tags, int depth) | |||
| 789 | if (!tag_index) | 789 | if (!tag_index) | 
| 790 | goto fail; | 790 | goto fail; | 
| 791 | 791 | ||
| 792 | bits = (depth / BLK_TAGS_PER_LONG) + 1; | 792 | nr_ulongs = ALIGN(depth, BLK_TAGS_PER_LONG) / BLK_TAGS_PER_LONG; | 
| 793 | tag_map = kmalloc(bits * sizeof(unsigned long), GFP_ATOMIC); | 793 | tag_map = kmalloc(nr_ulongs * sizeof(unsigned long), GFP_ATOMIC); | 
| 794 | if (!tag_map) | 794 | if (!tag_map) | 
| 795 | goto fail; | 795 | goto fail; | 
| 796 | 796 | ||
| 797 | memset(tag_index, 0, depth * sizeof(struct request *)); | 797 | memset(tag_index, 0, depth * sizeof(struct request *)); | 
| 798 | memset(tag_map, 0, bits * sizeof(unsigned long)); | 798 | memset(tag_map, 0, nr_ulongs * sizeof(unsigned long)); | 
| 799 | tags->max_depth = depth; | 799 | tags->max_depth = depth; | 
| 800 | tags->real_max_depth = bits * BITS_PER_LONG; | ||
| 801 | tags->tag_index = tag_index; | 800 | tags->tag_index = tag_index; | 
| 802 | tags->tag_map = tag_map; | 801 | tags->tag_map = tag_map; | 
| 803 | 802 | ||
| 804 | /* | ||
| 805 | * set the upper bits if the depth isn't a multiple of the word size | ||
| 806 | */ | ||
| 807 | for (i = depth; i < bits * BLK_TAGS_PER_LONG; i++) | ||
| 808 | __set_bit(i, tag_map); | ||
| 809 | |||
| 810 | return 0; | 803 | return 0; | 
| 811 | fail: | 804 | fail: | 
| 812 | kfree(tag_index); | 805 | kfree(tag_index); | 
| @@ -871,32 +864,24 @@ int blk_queue_resize_tags(request_queue_t *q, int new_depth) | |||
| 871 | struct blk_queue_tag *bqt = q->queue_tags; | 864 | struct blk_queue_tag *bqt = q->queue_tags; | 
| 872 | struct request **tag_index; | 865 | struct request **tag_index; | 
| 873 | unsigned long *tag_map; | 866 | unsigned long *tag_map; | 
| 874 | int bits, max_depth; | 867 | int max_depth, nr_ulongs; | 
| 875 | 868 | ||
| 876 | if (!bqt) | 869 | if (!bqt) | 
| 877 | return -ENXIO; | 870 | return -ENXIO; | 
| 878 | 871 | ||
| 879 | /* | 872 | /* | 
| 880 | * don't bother sizing down | ||
| 881 | */ | ||
| 882 | if (new_depth <= bqt->real_max_depth) { | ||
| 883 | bqt->max_depth = new_depth; | ||
| 884 | return 0; | ||
| 885 | } | ||
| 886 | |||
| 887 | /* | ||
| 888 | * save the old state info, so we can copy it back | 873 | * save the old state info, so we can copy it back | 
| 889 | */ | 874 | */ | 
| 890 | tag_index = bqt->tag_index; | 875 | tag_index = bqt->tag_index; | 
| 891 | tag_map = bqt->tag_map; | 876 | tag_map = bqt->tag_map; | 
| 892 | max_depth = bqt->real_max_depth; | 877 | max_depth = bqt->max_depth; | 
| 893 | 878 | ||
| 894 | if (init_tag_map(q, bqt, new_depth)) | 879 | if (init_tag_map(q, bqt, new_depth)) | 
| 895 | return -ENOMEM; | 880 | return -ENOMEM; | 
| 896 | 881 | ||
| 897 | memcpy(bqt->tag_index, tag_index, max_depth * sizeof(struct request *)); | 882 | memcpy(bqt->tag_index, tag_index, max_depth * sizeof(struct request *)); | 
| 898 | bits = max_depth / BLK_TAGS_PER_LONG; | 883 | nr_ulongs = ALIGN(max_depth, BLK_TAGS_PER_LONG) / BLK_TAGS_PER_LONG; | 
| 899 | memcpy(bqt->tag_map, tag_map, bits * sizeof(unsigned long)); | 884 | memcpy(bqt->tag_map, tag_map, nr_ulongs * sizeof(unsigned long)); | 
| 900 | 885 | ||
| 901 | kfree(tag_index); | 886 | kfree(tag_index); | 
| 902 | kfree(tag_map); | 887 | kfree(tag_map); | 
| @@ -926,7 +911,7 @@ void blk_queue_end_tag(request_queue_t *q, struct request *rq) | |||
| 926 | 911 | ||
| 927 | BUG_ON(tag == -1); | 912 | BUG_ON(tag == -1); | 
| 928 | 913 | ||
| 929 | if (unlikely(tag >= bqt->real_max_depth)) | 914 | if (unlikely(tag >= bqt->max_depth)) | 
| 930 | return; | 915 | return; | 
| 931 | 916 | ||
| 932 | if (unlikely(!__test_and_clear_bit(tag, bqt->tag_map))) { | 917 | if (unlikely(!__test_and_clear_bit(tag, bqt->tag_map))) { | 
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 235c3414d268..8d7e2f4151d0 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h  | |||
| @@ -294,7 +294,6 @@ struct blk_queue_tag { | |||
| 294 | struct list_head busy_list; /* fifo list of busy tags */ | 294 | struct list_head busy_list; /* fifo list of busy tags */ | 
| 295 | int busy; /* current depth */ | 295 | int busy; /* current depth */ | 
| 296 | int max_depth; /* what we will send to device */ | 296 | int max_depth; /* what we will send to device */ | 
| 297 | int real_max_depth; /* what the array can hold */ | ||
| 298 | atomic_t refcnt; /* map can be shared */ | 297 | atomic_t refcnt; /* map can be shared */ | 
| 299 | }; | 298 | }; | 
| 300 | 299 | ||
