Commit 62ee8c13e26cffe6483630f59932c3e936dfb586
Committed by
Jens Axboe
1 parent
3e54a3d1b8
Exists in
master
and in
6 other branches
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>
Showing 2 changed files with 65 additions and 40 deletions Side-by-side Diff
drivers/block/mtip32xx/mtip32xx.c
... | ... | @@ -87,6 +87,8 @@ |
87 | 87 | static DEFINE_SPINLOCK(rssd_index_lock); |
88 | 88 | static DEFINE_IDA(rssd_index_ida); |
89 | 89 | |
90 | +static int mtip_block_initialize(struct driver_data *dd); | |
91 | + | |
90 | 92 | #ifdef CONFIG_COMPAT |
91 | 93 | struct mtip_compat_ide_task_request_s { |
92 | 94 | __u8 io_ports[8]; |
... | ... | @@ -1031,7 +1033,8 @@ |
1031 | 1033 | |
1032 | 1034 | to = jiffies + msecs_to_jiffies(timeout); |
1033 | 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 | 1038 | msleep(20); |
1036 | 1039 | continue; /* svc thd is actively issuing commands */ |
1037 | 1040 | } |
... | ... | @@ -2410,6 +2413,7 @@ |
2410 | 2413 | "FTL rebuild complete (%d secs).\n", |
2411 | 2414 | jiffies_to_msecs(jiffies - start) / 1000); |
2412 | 2415 | dd->ftlrebuildflag = 0; |
2416 | + mtip_block_initialize(dd); | |
2413 | 2417 | break; |
2414 | 2418 | } |
2415 | 2419 | ssleep(10); |
2416 | 2420 | |
... | ... | @@ -2454,8 +2458,8 @@ |
2454 | 2458 | if (kthread_should_stop()) |
2455 | 2459 | break; |
2456 | 2460 | |
2461 | + set_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags); | |
2457 | 2462 | if (test_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags)) { |
2458 | - set_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags); | |
2459 | 2463 | slot = 1; |
2460 | 2464 | /* used to restrict the loop to one iteration */ |
2461 | 2465 | slot_start = num_cmd_slots; |
2462 | 2466 | |
... | ... | @@ -2488,8 +2492,14 @@ |
2488 | 2492 | } |
2489 | 2493 | |
2490 | 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 | 2504 | return 0; |
2495 | 2505 | } |
2496 | 2506 | |
2497 | 2507 | |
... | ... | @@ -2658,12 +2668,13 @@ |
2658 | 2668 | rv = -EFAULT; |
2659 | 2669 | goto out3; |
2660 | 2670 | } |
2661 | - mtip_dump_identify(dd->port); | |
2662 | 2671 | |
2663 | 2672 | if (*(dd->port->identify + MTIP_FTL_REBUILD_OFFSET) == |
2664 | 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 | 2678 | return rv; |
2668 | 2679 | |
2669 | 2680 | out3: |
2670 | 2681 | |
2671 | 2682 | |
2672 | 2683 | |
... | ... | @@ -3095,40 +3106,24 @@ |
3095 | 3106 | */ |
3096 | 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 | 3110 | sector_t capacity; |
3100 | 3111 | unsigned int index = 0; |
3101 | 3112 | struct kobject *kobj; |
3102 | 3113 | unsigned char thd_name[16]; |
3103 | 3114 | |
3115 | + if (dd->disk) | |
3116 | + goto skip_create_disk; /* hw init done, before rebuild */ | |
3117 | + | |
3104 | 3118 | /* Initialize the protocol layer. */ |
3105 | - rv = mtip_hw_init(dd); | |
3106 | - if (rv < 0) { | |
3119 | + wait_for_rebuild = mtip_hw_init(dd); | |
3120 | + if (wait_for_rebuild < 0) { | |
3107 | 3121 | dev_err(&dd->pdev->dev, |
3108 | 3122 | "Protocol layer initialization failed\n"); |
3109 | 3123 | rv = -EINVAL; |
3110 | 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 | 3127 | dd->disk = alloc_disk(MTIP_MAX_MINORS); |
3133 | 3128 | if (dd->disk == NULL) { |
3134 | 3129 | dev_err(&dd->pdev->dev, |
3135 | 3130 | |
3136 | 3131 | |
... | ... | @@ -3161,11 +3156,39 @@ |
3161 | 3156 | dd->disk->major = dd->major; |
3162 | 3157 | dd->disk->first_minor = dd->instance * MTIP_MAX_MINORS; |
3163 | 3158 | dd->disk->fops = &mtip_block_ops; |
3164 | - dd->disk->queue = dd->queue; | |
3165 | 3159 | dd->disk->private_data = dd; |
3166 | - dd->queue->queuedata = dd; | |
3167 | 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 | 3192 | /* Set the capacity of the device in 512 byte sectors. */ |
3170 | 3193 | if (!(mtip_hw_get_capacity(dd, &capacity))) { |
3171 | 3194 | dev_warn(&dd->pdev->dev, |
... | ... | @@ -3188,6 +3211,10 @@ |
3188 | 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 | 3218 | sprintf(thd_name, "mtip_svc_thd_%02d", index); |
3192 | 3219 | |
3193 | 3220 | dd->mtip_svc_handler = kthread_run(mtip_service_thread, |
3194 | 3221 | |
3195 | 3222 | |
... | ... | @@ -3197,18 +3224,19 @@ |
3197 | 3224 | printk(KERN_ERR "mtip32xx: service thread failed to start\n"); |
3198 | 3225 | dd->mtip_svc_handler = NULL; |
3199 | 3226 | rv = -EFAULT; |
3200 | - goto read_capacity_error; | |
3227 | + goto kthread_run_error; | |
3201 | 3228 | } |
3202 | 3229 | |
3203 | 3230 | return rv; |
3204 | 3231 | |
3205 | -read_capacity_error: | |
3206 | - /* | |
3207 | - * Delete our gendisk structure. This also removes the device | |
3208 | - * from /dev | |
3209 | - */ | |
3232 | +kthread_run_error: | |
3233 | + /* Delete our gendisk. This also removes the device from /dev */ | |
3210 | 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 | 3240 | disk_index_error: |
3213 | 3241 | spin_lock(&rssd_index_lock); |
3214 | 3242 | ida_remove(&rssd_index_ida, index); |
... | ... | @@ -3218,11 +3246,7 @@ |
3218 | 3246 | put_disk(dd->disk); |
3219 | 3247 | |
3220 | 3248 | alloc_disk_error: |
3221 | - blk_cleanup_queue(dd->queue); | |
3222 | - | |
3223 | -block_queue_alloc_init_error: | |
3224 | - /* De-initialize the protocol layer. */ | |
3225 | - mtip_hw_exit(dd); | |
3249 | + mtip_hw_exit(dd); /* De-initialize the protocol layer. */ | |
3226 | 3250 | |
3227 | 3251 | protocol_init_error: |
3228 | 3252 | return rv; |
drivers/block/mtip32xx/mtip32xx.h
... | ... | @@ -121,6 +121,7 @@ |
121 | 121 | #define MTIP_FLAG_EH_ACTIVE_BIT 1 |
122 | 122 | #define MTIP_FLAG_SVC_THD_ACTIVE_BIT 2 |
123 | 123 | #define MTIP_FLAG_ISSUE_CMDS_BIT 4 |
124 | +#define MTIP_FLAG_REBUILD_BIT 5 | |
124 | 125 | #define MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT 8 |
125 | 126 | |
126 | 127 | /* Register Frame Information Structure (FIS), host to device. */ |