diff options
author | Asai Thambi S P <asamymuthupa@micron.com> | 2012-01-04 16:01:32 -0500 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2012-01-04 16:01:32 -0500 |
commit | 62ee8c13e26cffe6483630f59932c3e936dfb586 (patch) | |
tree | 7f92cc63e2413b19466255133f1198319dd4ae4f /drivers/block/mtip32xx | |
parent | 3e54a3d1b83220d748f1a27c8999634be7a83949 (diff) |
mtip32xx: do rebuild monitoring asynchronously
Earlier, rebuild monitoring was done in the context of probe. Now the service
thread takes the responsibility of rebuild monitoring, and probe returns good
status.
Signed-off-by: Asai Thambi S P <asamymuthupa@micron.com>
Signed-off-by: Sam Bradshaw <sbradshaw@micron.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/block/mtip32xx')
-rw-r--r-- | drivers/block/mtip32xx/mtip32xx.c | 104 | ||||
-rw-r--r-- | drivers/block/mtip32xx/mtip32xx.h | 1 |
2 files changed, 65 insertions, 40 deletions
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 9bc10e31a143..b74eab70c3d0 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c | |||
@@ -87,6 +87,8 @@ static int mtip_major; | |||
87 | static DEFINE_SPINLOCK(rssd_index_lock); | 87 | static DEFINE_SPINLOCK(rssd_index_lock); |
88 | static DEFINE_IDA(rssd_index_ida); | 88 | static DEFINE_IDA(rssd_index_ida); |
89 | 89 | ||
90 | static int mtip_block_initialize(struct driver_data *dd); | ||
91 | |||
90 | #ifdef CONFIG_COMPAT | 92 | #ifdef CONFIG_COMPAT |
91 | struct mtip_compat_ide_task_request_s { | 93 | struct mtip_compat_ide_task_request_s { |
92 | __u8 io_ports[8]; | 94 | __u8 io_ports[8]; |
@@ -1031,7 +1033,8 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout) | |||
1031 | 1033 | ||
1032 | to = jiffies + msecs_to_jiffies(timeout); | 1034 | to = jiffies + msecs_to_jiffies(timeout); |
1033 | do { | 1035 | do { |
1034 | if (test_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags)) { | 1036 | if (test_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags) && |
1037 | test_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags)) { | ||
1035 | msleep(20); | 1038 | msleep(20); |
1036 | continue; /* svc thd is actively issuing commands */ | 1039 | continue; /* svc thd is actively issuing commands */ |
1037 | } | 1040 | } |
@@ -2410,6 +2413,7 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd) | |||
2410 | "FTL rebuild complete (%d secs).\n", | 2413 | "FTL rebuild complete (%d secs).\n", |
2411 | jiffies_to_msecs(jiffies - start) / 1000); | 2414 | jiffies_to_msecs(jiffies - start) / 1000); |
2412 | dd->ftlrebuildflag = 0; | 2415 | dd->ftlrebuildflag = 0; |
2416 | mtip_block_initialize(dd); | ||
2413 | break; | 2417 | break; |
2414 | } | 2418 | } |
2415 | ssleep(10); | 2419 | ssleep(10); |
@@ -2454,8 +2458,8 @@ static int mtip_service_thread(void *data) | |||
2454 | if (kthread_should_stop()) | 2458 | if (kthread_should_stop()) |
2455 | break; | 2459 | break; |
2456 | 2460 | ||
2461 | set_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags); | ||
2457 | if (test_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags)) { | 2462 | if (test_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags)) { |
2458 | set_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags); | ||
2459 | slot = 1; | 2463 | slot = 1; |
2460 | /* used to restrict the loop to one iteration */ | 2464 | /* used to restrict the loop to one iteration */ |
2461 | slot_start = num_cmd_slots; | 2465 | slot_start = num_cmd_slots; |
@@ -2488,8 +2492,14 @@ static int mtip_service_thread(void *data) | |||
2488 | } | 2492 | } |
2489 | 2493 | ||
2490 | clear_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags); | 2494 | clear_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags); |
2491 | clear_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags); | 2495 | } else if (test_bit(MTIP_FLAG_REBUILD_BIT, &port->flags)) { |
2496 | mtip_ftl_rebuild_poll(dd); | ||
2497 | clear_bit(MTIP_FLAG_REBUILD_BIT, &port->flags); | ||
2492 | } | 2498 | } |
2499 | clear_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags); | ||
2500 | |||
2501 | if (test_bit(MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT, &port->flags)) | ||
2502 | break; | ||
2493 | } | 2503 | } |
2494 | return 0; | 2504 | return 0; |
2495 | } | 2505 | } |
@@ -2658,12 +2668,13 @@ static int mtip_hw_init(struct driver_data *dd) | |||
2658 | rv = -EFAULT; | 2668 | rv = -EFAULT; |
2659 | goto out3; | 2669 | goto out3; |
2660 | } | 2670 | } |
2661 | mtip_dump_identify(dd->port); | ||
2662 | 2671 | ||
2663 | if (*(dd->port->identify + MTIP_FTL_REBUILD_OFFSET) == | 2672 | if (*(dd->port->identify + MTIP_FTL_REBUILD_OFFSET) == |
2664 | MTIP_FTL_REBUILD_MAGIC) { | 2673 | MTIP_FTL_REBUILD_MAGIC) { |
2665 | return mtip_ftl_rebuild_poll(dd); | 2674 | set_bit(MTIP_FLAG_REBUILD_BIT, &dd->port->flags); |
2675 | return MTIP_FTL_REBUILD_MAGIC; | ||
2666 | } | 2676 | } |
2677 | mtip_dump_identify(dd->port); | ||
2667 | return rv; | 2678 | return rv; |
2668 | 2679 | ||
2669 | out3: | 2680 | out3: |
@@ -3095,40 +3106,24 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio) | |||
3095 | */ | 3106 | */ |
3096 | static int mtip_block_initialize(struct driver_data *dd) | 3107 | static int mtip_block_initialize(struct driver_data *dd) |
3097 | { | 3108 | { |
3098 | int rv = 0; | 3109 | int rv = 0, wait_for_rebuild = 0; |
3099 | sector_t capacity; | 3110 | sector_t capacity; |
3100 | unsigned int index = 0; | 3111 | unsigned int index = 0; |
3101 | struct kobject *kobj; | 3112 | struct kobject *kobj; |
3102 | unsigned char thd_name[16]; | 3113 | unsigned char thd_name[16]; |
3103 | 3114 | ||
3115 | if (dd->disk) | ||
3116 | goto skip_create_disk; /* hw init done, before rebuild */ | ||
3117 | |||
3104 | /* Initialize the protocol layer. */ | 3118 | /* Initialize the protocol layer. */ |
3105 | rv = mtip_hw_init(dd); | 3119 | wait_for_rebuild = mtip_hw_init(dd); |
3106 | if (rv < 0) { | 3120 | if (wait_for_rebuild < 0) { |
3107 | dev_err(&dd->pdev->dev, | 3121 | dev_err(&dd->pdev->dev, |
3108 | "Protocol layer initialization failed\n"); | 3122 | "Protocol layer initialization failed\n"); |
3109 | rv = -EINVAL; | 3123 | rv = -EINVAL; |
3110 | goto protocol_init_error; | 3124 | goto protocol_init_error; |
3111 | } | 3125 | } |
3112 | 3126 | ||
3113 | /* Allocate the request queue. */ | ||
3114 | dd->queue = blk_alloc_queue(GFP_KERNEL); | ||
3115 | if (dd->queue == NULL) { | ||
3116 | dev_err(&dd->pdev->dev, | ||
3117 | "Unable to allocate request queue\n"); | ||
3118 | rv = -ENOMEM; | ||
3119 | goto block_queue_alloc_init_error; | ||
3120 | } | ||
3121 | |||
3122 | /* Attach our request function to the request queue. */ | ||
3123 | blk_queue_make_request(dd->queue, mtip_make_request); | ||
3124 | |||
3125 | /* Set device limits. */ | ||
3126 | set_bit(QUEUE_FLAG_NONROT, &dd->queue->queue_flags); | ||
3127 | blk_queue_max_segments(dd->queue, MTIP_MAX_SG); | ||
3128 | blk_queue_physical_block_size(dd->queue, 4096); | ||
3129 | blk_queue_io_min(dd->queue, 4096); | ||
3130 | blk_queue_flush(dd->queue, 0); | ||
3131 | |||
3132 | dd->disk = alloc_disk(MTIP_MAX_MINORS); | 3127 | dd->disk = alloc_disk(MTIP_MAX_MINORS); |
3133 | if (dd->disk == NULL) { | 3128 | if (dd->disk == NULL) { |
3134 | dev_err(&dd->pdev->dev, | 3129 | dev_err(&dd->pdev->dev, |
@@ -3161,11 +3156,39 @@ static int mtip_block_initialize(struct driver_data *dd) | |||
3161 | dd->disk->major = dd->major; | 3156 | dd->disk->major = dd->major; |
3162 | dd->disk->first_minor = dd->instance * MTIP_MAX_MINORS; | 3157 | dd->disk->first_minor = dd->instance * MTIP_MAX_MINORS; |
3163 | dd->disk->fops = &mtip_block_ops; | 3158 | dd->disk->fops = &mtip_block_ops; |
3164 | dd->disk->queue = dd->queue; | ||
3165 | dd->disk->private_data = dd; | 3159 | dd->disk->private_data = dd; |
3166 | dd->queue->queuedata = dd; | ||
3167 | dd->index = index; | 3160 | dd->index = index; |
3168 | 3161 | ||
3162 | /* | ||
3163 | * if rebuild pending, start the service thread, and delay the block | ||
3164 | * queue creation and add_disk() | ||
3165 | */ | ||
3166 | if (wait_for_rebuild == MTIP_FTL_REBUILD_MAGIC) | ||
3167 | goto start_service_thread; | ||
3168 | |||
3169 | skip_create_disk: | ||
3170 | /* Allocate the request queue. */ | ||
3171 | dd->queue = blk_alloc_queue(GFP_KERNEL); | ||
3172 | if (dd->queue == NULL) { | ||
3173 | dev_err(&dd->pdev->dev, | ||
3174 | "Unable to allocate request queue\n"); | ||
3175 | rv = -ENOMEM; | ||
3176 | goto block_queue_alloc_init_error; | ||
3177 | } | ||
3178 | |||
3179 | /* Attach our request function to the request queue. */ | ||
3180 | blk_queue_make_request(dd->queue, mtip_make_request); | ||
3181 | |||
3182 | dd->disk->queue = dd->queue; | ||
3183 | dd->queue->queuedata = dd; | ||
3184 | |||
3185 | /* Set device limits. */ | ||
3186 | set_bit(QUEUE_FLAG_NONROT, &dd->queue->queue_flags); | ||
3187 | blk_queue_max_segments(dd->queue, MTIP_MAX_SG); | ||
3188 | blk_queue_physical_block_size(dd->queue, 4096); | ||
3189 | blk_queue_io_min(dd->queue, 4096); | ||
3190 | blk_queue_flush(dd->queue, 0); | ||
3191 | |||
3169 | /* Set the capacity of the device in 512 byte sectors. */ | 3192 | /* Set the capacity of the device in 512 byte sectors. */ |
3170 | if (!(mtip_hw_get_capacity(dd, &capacity))) { | 3193 | if (!(mtip_hw_get_capacity(dd, &capacity))) { |
3171 | dev_warn(&dd->pdev->dev, | 3194 | dev_warn(&dd->pdev->dev, |
@@ -3188,6 +3211,10 @@ static int mtip_block_initialize(struct driver_data *dd) | |||
3188 | kobject_put(kobj); | 3211 | kobject_put(kobj); |
3189 | } | 3212 | } |
3190 | 3213 | ||
3214 | if (dd->mtip_svc_handler) | ||
3215 | return rv; /* service thread created for handling rebuild */ | ||
3216 | |||
3217 | start_service_thread: | ||
3191 | sprintf(thd_name, "mtip_svc_thd_%02d", index); | 3218 | sprintf(thd_name, "mtip_svc_thd_%02d", index); |
3192 | 3219 | ||
3193 | dd->mtip_svc_handler = kthread_run(mtip_service_thread, | 3220 | dd->mtip_svc_handler = kthread_run(mtip_service_thread, |
@@ -3197,18 +3224,19 @@ static int mtip_block_initialize(struct driver_data *dd) | |||
3197 | printk(KERN_ERR "mtip32xx: service thread failed to start\n"); | 3224 | printk(KERN_ERR "mtip32xx: service thread failed to start\n"); |
3198 | dd->mtip_svc_handler = NULL; | 3225 | dd->mtip_svc_handler = NULL; |
3199 | rv = -EFAULT; | 3226 | rv = -EFAULT; |
3200 | goto read_capacity_error; | 3227 | goto kthread_run_error; |
3201 | } | 3228 | } |
3202 | 3229 | ||
3203 | return rv; | 3230 | return rv; |
3204 | 3231 | ||
3205 | read_capacity_error: | 3232 | kthread_run_error: |
3206 | /* | 3233 | /* Delete our gendisk. This also removes the device from /dev */ |
3207 | * Delete our gendisk structure. This also removes the device | ||
3208 | * from /dev | ||
3209 | */ | ||
3210 | del_gendisk(dd->disk); | 3234 | del_gendisk(dd->disk); |
3211 | 3235 | ||
3236 | read_capacity_error: | ||
3237 | blk_cleanup_queue(dd->queue); | ||
3238 | |||
3239 | block_queue_alloc_init_error: | ||
3212 | disk_index_error: | 3240 | disk_index_error: |
3213 | spin_lock(&rssd_index_lock); | 3241 | spin_lock(&rssd_index_lock); |
3214 | ida_remove(&rssd_index_ida, index); | 3242 | ida_remove(&rssd_index_ida, index); |
@@ -3218,11 +3246,7 @@ ida_get_error: | |||
3218 | put_disk(dd->disk); | 3246 | put_disk(dd->disk); |
3219 | 3247 | ||
3220 | alloc_disk_error: | 3248 | alloc_disk_error: |
3221 | blk_cleanup_queue(dd->queue); | 3249 | mtip_hw_exit(dd); /* De-initialize the protocol layer. */ |
3222 | |||
3223 | block_queue_alloc_init_error: | ||
3224 | /* De-initialize the protocol layer. */ | ||
3225 | mtip_hw_exit(dd); | ||
3226 | 3250 | ||
3227 | protocol_init_error: | 3251 | protocol_init_error: |
3228 | return rv; | 3252 | return rv; |
diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index 933192abe178..723d7c4946dc 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h | |||
@@ -121,6 +121,7 @@ | |||
121 | #define MTIP_FLAG_EH_ACTIVE_BIT 1 | 121 | #define MTIP_FLAG_EH_ACTIVE_BIT 1 |
122 | #define MTIP_FLAG_SVC_THD_ACTIVE_BIT 2 | 122 | #define MTIP_FLAG_SVC_THD_ACTIVE_BIT 2 |
123 | #define MTIP_FLAG_ISSUE_CMDS_BIT 4 | 123 | #define MTIP_FLAG_ISSUE_CMDS_BIT 4 |
124 | #define MTIP_FLAG_REBUILD_BIT 5 | ||
124 | #define MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT 8 | 125 | #define MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT 8 |
125 | 126 | ||
126 | /* Register Frame Information Structure (FIS), host to device. */ | 127 | /* Register Frame Information Structure (FIS), host to device. */ |