diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-08 14:51:05 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-08 14:51:05 -0400 |
commit | ebb37277796269da36a8bc5d72ed1e8e1fb7d34b (patch) | |
tree | 0ded627a62a5cec70b18d12825dd858855c135d3 /drivers/block/mtip32xx | |
parent | 4de13d7aa8f4d02f4dc99d4609575659f92b3c5a (diff) | |
parent | f50efd2fdbd9b35b11f5778ed85beb764184bda9 (diff) |
Merge branch 'for-3.10/drivers' of git://git.kernel.dk/linux-block
Pull block driver updates from Jens Axboe:
"It might look big in volume, but when categorized, not a lot of
drivers are touched. The pull request contains:
- mtip32xx fixes from Micron.
- A slew of drbd updates, this time in a nicer series.
- bcache, a flash/ssd caching framework from Kent.
- Fixes for cciss"
* 'for-3.10/drivers' of git://git.kernel.dk/linux-block: (66 commits)
bcache: Use bd_link_disk_holder()
bcache: Allocator cleanup/fixes
cciss: bug fix to prevent cciss from loading in kdump crash kernel
cciss: add cciss_allow_hpsa module parameter
drivers/block/mg_disk.c: add CONFIG_PM_SLEEP to suspend/resume functions
mtip32xx: Workaround for unaligned writes
bcache: Make sure blocksize isn't smaller than device blocksize
bcache: Fix merge_bvec_fn usage for when it modifies the bvm
bcache: Correctly check against BIO_MAX_PAGES
bcache: Hack around stuff that clones up to bi_max_vecs
bcache: Set ra_pages based on backing device's ra_pages
bcache: Take data offset from the bdev superblock.
mtip32xx: mtip32xx: Disable TRIM support
mtip32xx: fix a smatch warning
bcache: Disable broken btree fuzz tester
bcache: Fix a format string overflow
bcache: Fix a minor memory leak on device teardown
bcache: Documentation updates
bcache: Use WARN_ONCE() instead of __WARN()
bcache: Add missing #include <linux/prefetch.h>
...
Diffstat (limited to 'drivers/block/mtip32xx')
-rw-r--r-- | drivers/block/mtip32xx/mtip32xx.c | 79 | ||||
-rw-r--r-- | drivers/block/mtip32xx/mtip32xx.h | 11 |
2 files changed, 68 insertions, 22 deletions
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 32c678028e53..847107ef0cce 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c | |||
@@ -728,7 +728,10 @@ static void mtip_async_complete(struct mtip_port *port, | |||
728 | atomic_set(&port->commands[tag].active, 0); | 728 | atomic_set(&port->commands[tag].active, 0); |
729 | release_slot(port, tag); | 729 | release_slot(port, tag); |
730 | 730 | ||
731 | up(&port->cmd_slot); | 731 | if (unlikely(command->unaligned)) |
732 | up(&port->cmd_slot_unal); | ||
733 | else | ||
734 | up(&port->cmd_slot); | ||
732 | } | 735 | } |
733 | 736 | ||
734 | /* | 737 | /* |
@@ -1560,10 +1563,12 @@ static int mtip_get_identify(struct mtip_port *port, void __user *user_buffer) | |||
1560 | } | 1563 | } |
1561 | #endif | 1564 | #endif |
1562 | 1565 | ||
1566 | #ifdef MTIP_TRIM /* Disabling TRIM support temporarily */ | ||
1563 | /* Demux ID.DRAT & ID.RZAT to determine trim support */ | 1567 | /* Demux ID.DRAT & ID.RZAT to determine trim support */ |
1564 | if (port->identify[69] & (1 << 14) && port->identify[69] & (1 << 5)) | 1568 | if (port->identify[69] & (1 << 14) && port->identify[69] & (1 << 5)) |
1565 | port->dd->trim_supp = true; | 1569 | port->dd->trim_supp = true; |
1566 | else | 1570 | else |
1571 | #endif | ||
1567 | port->dd->trim_supp = false; | 1572 | port->dd->trim_supp = false; |
1568 | 1573 | ||
1569 | /* Set the identify buffer as valid. */ | 1574 | /* Set the identify buffer as valid. */ |
@@ -2557,7 +2562,7 @@ static int mtip_hw_ioctl(struct driver_data *dd, unsigned int cmd, | |||
2557 | */ | 2562 | */ |
2558 | static void mtip_hw_submit_io(struct driver_data *dd, sector_t sector, | 2563 | static void mtip_hw_submit_io(struct driver_data *dd, sector_t sector, |
2559 | int nsect, int nents, int tag, void *callback, | 2564 | int nsect, int nents, int tag, void *callback, |
2560 | void *data, int dir) | 2565 | void *data, int dir, int unaligned) |
2561 | { | 2566 | { |
2562 | struct host_to_dev_fis *fis; | 2567 | struct host_to_dev_fis *fis; |
2563 | struct mtip_port *port = dd->port; | 2568 | struct mtip_port *port = dd->port; |
@@ -2570,6 +2575,7 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t sector, | |||
2570 | 2575 | ||
2571 | command->scatter_ents = nents; | 2576 | command->scatter_ents = nents; |
2572 | 2577 | ||
2578 | command->unaligned = unaligned; | ||
2573 | /* | 2579 | /* |
2574 | * The number of retries for this command before it is | 2580 | * The number of retries for this command before it is |
2575 | * reported as a failure to the upper layers. | 2581 | * reported as a failure to the upper layers. |
@@ -2598,6 +2604,9 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t sector, | |||
2598 | fis->res3 = 0; | 2604 | fis->res3 = 0; |
2599 | fill_command_sg(dd, command, nents); | 2605 | fill_command_sg(dd, command, nents); |
2600 | 2606 | ||
2607 | if (unaligned) | ||
2608 | fis->device |= 1 << 7; | ||
2609 | |||
2601 | /* Populate the command header */ | 2610 | /* Populate the command header */ |
2602 | command->command_header->opts = | 2611 | command->command_header->opts = |
2603 | __force_bit2int cpu_to_le32( | 2612 | __force_bit2int cpu_to_le32( |
@@ -2644,9 +2653,13 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t sector, | |||
2644 | * return value | 2653 | * return value |
2645 | * None | 2654 | * None |
2646 | */ | 2655 | */ |
2647 | static void mtip_hw_release_scatterlist(struct driver_data *dd, int tag) | 2656 | static void mtip_hw_release_scatterlist(struct driver_data *dd, int tag, |
2657 | int unaligned) | ||
2648 | { | 2658 | { |
2659 | struct semaphore *sem = unaligned ? &dd->port->cmd_slot_unal : | ||
2660 | &dd->port->cmd_slot; | ||
2649 | release_slot(dd->port, tag); | 2661 | release_slot(dd->port, tag); |
2662 | up(sem); | ||
2650 | } | 2663 | } |
2651 | 2664 | ||
2652 | /* | 2665 | /* |
@@ -2661,22 +2674,25 @@ static void mtip_hw_release_scatterlist(struct driver_data *dd, int tag) | |||
2661 | * or NULL if no command slots are available. | 2674 | * or NULL if no command slots are available. |
2662 | */ | 2675 | */ |
2663 | static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd, | 2676 | static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd, |
2664 | int *tag) | 2677 | int *tag, int unaligned) |
2665 | { | 2678 | { |
2679 | struct semaphore *sem = unaligned ? &dd->port->cmd_slot_unal : | ||
2680 | &dd->port->cmd_slot; | ||
2681 | |||
2666 | /* | 2682 | /* |
2667 | * It is possible that, even with this semaphore, a thread | 2683 | * It is possible that, even with this semaphore, a thread |
2668 | * may think that no command slots are available. Therefore, we | 2684 | * may think that no command slots are available. Therefore, we |
2669 | * need to make an attempt to get_slot(). | 2685 | * need to make an attempt to get_slot(). |
2670 | */ | 2686 | */ |
2671 | down(&dd->port->cmd_slot); | 2687 | down(sem); |
2672 | *tag = get_slot(dd->port); | 2688 | *tag = get_slot(dd->port); |
2673 | 2689 | ||
2674 | if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))) { | 2690 | if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))) { |
2675 | up(&dd->port->cmd_slot); | 2691 | up(sem); |
2676 | return NULL; | 2692 | return NULL; |
2677 | } | 2693 | } |
2678 | if (unlikely(*tag < 0)) { | 2694 | if (unlikely(*tag < 0)) { |
2679 | up(&dd->port->cmd_slot); | 2695 | up(sem); |
2680 | return NULL; | 2696 | return NULL; |
2681 | } | 2697 | } |
2682 | 2698 | ||
@@ -3010,6 +3026,11 @@ static inline void hba_setup(struct driver_data *dd) | |||
3010 | dd->mmio + HOST_HSORG); | 3026 | dd->mmio + HOST_HSORG); |
3011 | } | 3027 | } |
3012 | 3028 | ||
3029 | static int mtip_device_unaligned_constrained(struct driver_data *dd) | ||
3030 | { | ||
3031 | return (dd->pdev->device == P420M_DEVICE_ID ? 1 : 0); | ||
3032 | } | ||
3033 | |||
3013 | /* | 3034 | /* |
3014 | * Detect the details of the product, and store anything needed | 3035 | * Detect the details of the product, and store anything needed |
3015 | * into the driver data structure. This includes product type and | 3036 | * into the driver data structure. This includes product type and |
@@ -3232,8 +3253,15 @@ static int mtip_hw_init(struct driver_data *dd) | |||
3232 | for (i = 0; i < MTIP_MAX_SLOT_GROUPS; i++) | 3253 | for (i = 0; i < MTIP_MAX_SLOT_GROUPS; i++) |
3233 | dd->work[i].port = dd->port; | 3254 | dd->work[i].port = dd->port; |
3234 | 3255 | ||
3256 | /* Enable unaligned IO constraints for some devices */ | ||
3257 | if (mtip_device_unaligned_constrained(dd)) | ||
3258 | dd->unal_qdepth = MTIP_MAX_UNALIGNED_SLOTS; | ||
3259 | else | ||
3260 | dd->unal_qdepth = 0; | ||
3261 | |||
3235 | /* Counting semaphore to track command slot usage */ | 3262 | /* Counting semaphore to track command slot usage */ |
3236 | sema_init(&dd->port->cmd_slot, num_command_slots - 1); | 3263 | sema_init(&dd->port->cmd_slot, num_command_slots - 1 - dd->unal_qdepth); |
3264 | sema_init(&dd->port->cmd_slot_unal, dd->unal_qdepth); | ||
3237 | 3265 | ||
3238 | /* Spinlock to prevent concurrent issue */ | 3266 | /* Spinlock to prevent concurrent issue */ |
3239 | for (i = 0; i < MTIP_MAX_SLOT_GROUPS; i++) | 3267 | for (i = 0; i < MTIP_MAX_SLOT_GROUPS; i++) |
@@ -3836,7 +3864,7 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio) | |||
3836 | struct scatterlist *sg; | 3864 | struct scatterlist *sg; |
3837 | struct bio_vec *bvec; | 3865 | struct bio_vec *bvec; |
3838 | int nents = 0; | 3866 | int nents = 0; |
3839 | int tag = 0; | 3867 | int tag = 0, unaligned = 0; |
3840 | 3868 | ||
3841 | if (unlikely(dd->dd_flag & MTIP_DDF_STOP_IO)) { | 3869 | if (unlikely(dd->dd_flag & MTIP_DDF_STOP_IO)) { |
3842 | if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, | 3870 | if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, |
@@ -3872,7 +3900,15 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio) | |||
3872 | return; | 3900 | return; |
3873 | } | 3901 | } |
3874 | 3902 | ||
3875 | sg = mtip_hw_get_scatterlist(dd, &tag); | 3903 | if (bio_data_dir(bio) == WRITE && bio_sectors(bio) <= 64 && |
3904 | dd->unal_qdepth) { | ||
3905 | if (bio->bi_sector % 8 != 0) /* Unaligned on 4k boundaries */ | ||
3906 | unaligned = 1; | ||
3907 | else if (bio_sectors(bio) % 8 != 0) /* Aligned but not 4k/8k */ | ||
3908 | unaligned = 1; | ||
3909 | } | ||
3910 | |||
3911 | sg = mtip_hw_get_scatterlist(dd, &tag, unaligned); | ||
3876 | if (likely(sg != NULL)) { | 3912 | if (likely(sg != NULL)) { |
3877 | blk_queue_bounce(queue, &bio); | 3913 | blk_queue_bounce(queue, &bio); |
3878 | 3914 | ||
@@ -3880,7 +3916,7 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio) | |||
3880 | dev_warn(&dd->pdev->dev, | 3916 | dev_warn(&dd->pdev->dev, |
3881 | "Maximum number of SGL entries exceeded\n"); | 3917 | "Maximum number of SGL entries exceeded\n"); |
3882 | bio_io_error(bio); | 3918 | bio_io_error(bio); |
3883 | mtip_hw_release_scatterlist(dd, tag); | 3919 | mtip_hw_release_scatterlist(dd, tag, unaligned); |
3884 | return; | 3920 | return; |
3885 | } | 3921 | } |
3886 | 3922 | ||
@@ -3900,7 +3936,8 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio) | |||
3900 | tag, | 3936 | tag, |
3901 | bio_endio, | 3937 | bio_endio, |
3902 | bio, | 3938 | bio, |
3903 | bio_data_dir(bio)); | 3939 | bio_data_dir(bio), |
3940 | unaligned); | ||
3904 | } else | 3941 | } else |
3905 | bio_io_error(bio); | 3942 | bio_io_error(bio); |
3906 | } | 3943 | } |
@@ -4156,26 +4193,24 @@ static int mtip_block_remove(struct driver_data *dd) | |||
4156 | */ | 4193 | */ |
4157 | static int mtip_block_shutdown(struct driver_data *dd) | 4194 | static int mtip_block_shutdown(struct driver_data *dd) |
4158 | { | 4195 | { |
4159 | dev_info(&dd->pdev->dev, | ||
4160 | "Shutting down %s ...\n", dd->disk->disk_name); | ||
4161 | |||
4162 | /* Delete our gendisk structure, and cleanup the blk queue. */ | 4196 | /* Delete our gendisk structure, and cleanup the blk queue. */ |
4163 | if (dd->disk) { | 4197 | if (dd->disk) { |
4164 | if (dd->disk->queue) | 4198 | dev_info(&dd->pdev->dev, |
4199 | "Shutting down %s ...\n", dd->disk->disk_name); | ||
4200 | |||
4201 | if (dd->disk->queue) { | ||
4165 | del_gendisk(dd->disk); | 4202 | del_gendisk(dd->disk); |
4166 | else | 4203 | blk_cleanup_queue(dd->queue); |
4204 | } else | ||
4167 | put_disk(dd->disk); | 4205 | put_disk(dd->disk); |
4206 | dd->disk = NULL; | ||
4207 | dd->queue = NULL; | ||
4168 | } | 4208 | } |
4169 | 4209 | ||
4170 | |||
4171 | spin_lock(&rssd_index_lock); | 4210 | spin_lock(&rssd_index_lock); |
4172 | ida_remove(&rssd_index_ida, dd->index); | 4211 | ida_remove(&rssd_index_ida, dd->index); |
4173 | spin_unlock(&rssd_index_lock); | 4212 | spin_unlock(&rssd_index_lock); |
4174 | 4213 | ||
4175 | blk_cleanup_queue(dd->queue); | ||
4176 | dd->disk = NULL; | ||
4177 | dd->queue = NULL; | ||
4178 | |||
4179 | mtip_hw_shutdown(dd); | 4214 | mtip_hw_shutdown(dd); |
4180 | return 0; | 4215 | return 0; |
4181 | } | 4216 | } |
diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index 8e8334c9dd0f..3bb8a295fbe4 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h | |||
@@ -52,6 +52,9 @@ | |||
52 | #define MTIP_FTL_REBUILD_MAGIC 0xED51 | 52 | #define MTIP_FTL_REBUILD_MAGIC 0xED51 |
53 | #define MTIP_FTL_REBUILD_TIMEOUT_MS 2400000 | 53 | #define MTIP_FTL_REBUILD_TIMEOUT_MS 2400000 |
54 | 54 | ||
55 | /* unaligned IO handling */ | ||
56 | #define MTIP_MAX_UNALIGNED_SLOTS 8 | ||
57 | |||
55 | /* Macro to extract the tag bit number from a tag value. */ | 58 | /* Macro to extract the tag bit number from a tag value. */ |
56 | #define MTIP_TAG_BIT(tag) (tag & 0x1F) | 59 | #define MTIP_TAG_BIT(tag) (tag & 0x1F) |
57 | 60 | ||
@@ -333,6 +336,8 @@ struct mtip_cmd { | |||
333 | 336 | ||
334 | int scatter_ents; /* Number of scatter list entries used */ | 337 | int scatter_ents; /* Number of scatter list entries used */ |
335 | 338 | ||
339 | int unaligned; /* command is unaligned on 4k boundary */ | ||
340 | |||
336 | struct scatterlist sg[MTIP_MAX_SG]; /* Scatter list entries */ | 341 | struct scatterlist sg[MTIP_MAX_SG]; /* Scatter list entries */ |
337 | 342 | ||
338 | int retries; /* The number of retries left for this command. */ | 343 | int retries; /* The number of retries left for this command. */ |
@@ -452,6 +457,10 @@ struct mtip_port { | |||
452 | * command slots available. | 457 | * command slots available. |
453 | */ | 458 | */ |
454 | struct semaphore cmd_slot; | 459 | struct semaphore cmd_slot; |
460 | |||
461 | /* Semaphore to control queue depth of unaligned IOs */ | ||
462 | struct semaphore cmd_slot_unal; | ||
463 | |||
455 | /* Spinlock for working around command-issue bug. */ | 464 | /* Spinlock for working around command-issue bug. */ |
456 | spinlock_t cmd_issue_lock[MTIP_MAX_SLOT_GROUPS]; | 465 | spinlock_t cmd_issue_lock[MTIP_MAX_SLOT_GROUPS]; |
457 | }; | 466 | }; |
@@ -502,6 +511,8 @@ struct driver_data { | |||
502 | 511 | ||
503 | int isr_binding; | 512 | int isr_binding; |
504 | 513 | ||
514 | int unal_qdepth; /* qdepth of unaligned IO queue */ | ||
515 | |||
505 | struct list_head online_list; /* linkage for online list */ | 516 | struct list_head online_list; /* linkage for online list */ |
506 | 517 | ||
507 | struct list_head remove_list; /* linkage for removing list */ | 518 | struct list_head remove_list; /* linkage for removing list */ |