Commit 62ee8c13 authored by Asai Thambi S P's avatar Asai Thambi S P Committed by Jens Axboe

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: default avatarAsai Thambi S P <asamymuthupa@micron.com>
Signed-off-by: default avatarSam Bradshaw <sbradshaw@micron.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 3e54a3d1
...@@ -87,6 +87,8 @@ static int mtip_major; ...@@ -87,6 +87,8 @@ static int mtip_major;
static DEFINE_SPINLOCK(rssd_index_lock); static DEFINE_SPINLOCK(rssd_index_lock);
static DEFINE_IDA(rssd_index_ida); static DEFINE_IDA(rssd_index_ida);
static int mtip_block_initialize(struct driver_data *dd);
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
struct mtip_compat_ide_task_request_s { struct mtip_compat_ide_task_request_s {
__u8 io_ports[8]; __u8 io_ports[8];
...@@ -1031,7 +1033,8 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout) ...@@ -1031,7 +1033,8 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout)
to = jiffies + msecs_to_jiffies(timeout); to = jiffies + msecs_to_jiffies(timeout);
do { do {
if (test_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags)) { if (test_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags) &&
test_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags)) {
msleep(20); msleep(20);
continue; /* svc thd is actively issuing commands */ continue; /* svc thd is actively issuing commands */
} }
...@@ -2410,6 +2413,7 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd) ...@@ -2410,6 +2413,7 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd)
"FTL rebuild complete (%d secs).\n", "FTL rebuild complete (%d secs).\n",
jiffies_to_msecs(jiffies - start) / 1000); jiffies_to_msecs(jiffies - start) / 1000);
dd->ftlrebuildflag = 0; dd->ftlrebuildflag = 0;
mtip_block_initialize(dd);
break; break;
} }
ssleep(10); ssleep(10);
...@@ -2454,8 +2458,8 @@ static int mtip_service_thread(void *data) ...@@ -2454,8 +2458,8 @@ static int mtip_service_thread(void *data)
if (kthread_should_stop()) if (kthread_should_stop())
break; break;
set_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags);
if (test_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags)) { if (test_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags)) {
set_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags);
slot = 1; slot = 1;
/* used to restrict the loop to one iteration */ /* used to restrict the loop to one iteration */
slot_start = num_cmd_slots; slot_start = num_cmd_slots;
...@@ -2488,8 +2492,14 @@ static int mtip_service_thread(void *data) ...@@ -2488,8 +2492,14 @@ static int mtip_service_thread(void *data)
} }
clear_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags); clear_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags);
clear_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags); } else if (test_bit(MTIP_FLAG_REBUILD_BIT, &port->flags)) {
mtip_ftl_rebuild_poll(dd);
clear_bit(MTIP_FLAG_REBUILD_BIT, &port->flags);
} }
clear_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags);
if (test_bit(MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT, &port->flags))
break;
} }
return 0; return 0;
} }
...@@ -2658,12 +2668,13 @@ static int mtip_hw_init(struct driver_data *dd) ...@@ -2658,12 +2668,13 @@ static int mtip_hw_init(struct driver_data *dd)
rv = -EFAULT; rv = -EFAULT;
goto out3; goto out3;
} }
mtip_dump_identify(dd->port);
if (*(dd->port->identify + MTIP_FTL_REBUILD_OFFSET) == if (*(dd->port->identify + MTIP_FTL_REBUILD_OFFSET) ==
MTIP_FTL_REBUILD_MAGIC) { MTIP_FTL_REBUILD_MAGIC) {
return mtip_ftl_rebuild_poll(dd); set_bit(MTIP_FLAG_REBUILD_BIT, &dd->port->flags);
return MTIP_FTL_REBUILD_MAGIC;
} }
mtip_dump_identify(dd->port);
return rv; return rv;
out3: out3:
...@@ -3095,40 +3106,24 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio) ...@@ -3095,40 +3106,24 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
*/ */
static int mtip_block_initialize(struct driver_data *dd) static int mtip_block_initialize(struct driver_data *dd)
{ {
int rv = 0; int rv = 0, wait_for_rebuild = 0;
sector_t capacity; sector_t capacity;
unsigned int index = 0; unsigned int index = 0;
struct kobject *kobj; struct kobject *kobj;
unsigned char thd_name[16]; unsigned char thd_name[16];
if (dd->disk)
goto skip_create_disk; /* hw init done, before rebuild */
/* Initialize the protocol layer. */ /* Initialize the protocol layer. */
rv = mtip_hw_init(dd); wait_for_rebuild = mtip_hw_init(dd);
if (rv < 0) { if (wait_for_rebuild < 0) {
dev_err(&dd->pdev->dev, dev_err(&dd->pdev->dev,
"Protocol layer initialization failed\n"); "Protocol layer initialization failed\n");
rv = -EINVAL; rv = -EINVAL;
goto protocol_init_error; goto protocol_init_error;
} }
/* Allocate the request queue. */
dd->queue = blk_alloc_queue(GFP_KERNEL);
if (dd->queue == NULL) {
dev_err(&dd->pdev->dev,
"Unable to allocate request queue\n");
rv = -ENOMEM;
goto block_queue_alloc_init_error;
}
/* Attach our request function to the request queue. */
blk_queue_make_request(dd->queue, mtip_make_request);
/* Set device limits. */
set_bit(QUEUE_FLAG_NONROT, &dd->queue->queue_flags);
blk_queue_max_segments(dd->queue, MTIP_MAX_SG);
blk_queue_physical_block_size(dd->queue, 4096);
blk_queue_io_min(dd->queue, 4096);
blk_queue_flush(dd->queue, 0);
dd->disk = alloc_disk(MTIP_MAX_MINORS); dd->disk = alloc_disk(MTIP_MAX_MINORS);
if (dd->disk == NULL) { if (dd->disk == NULL) {
dev_err(&dd->pdev->dev, dev_err(&dd->pdev->dev,
...@@ -3161,11 +3156,39 @@ static int mtip_block_initialize(struct driver_data *dd) ...@@ -3161,11 +3156,39 @@ static int mtip_block_initialize(struct driver_data *dd)
dd->disk->major = dd->major; dd->disk->major = dd->major;
dd->disk->first_minor = dd->instance * MTIP_MAX_MINORS; dd->disk->first_minor = dd->instance * MTIP_MAX_MINORS;
dd->disk->fops = &mtip_block_ops; dd->disk->fops = &mtip_block_ops;
dd->disk->queue = dd->queue;
dd->disk->private_data = dd; dd->disk->private_data = dd;
dd->queue->queuedata = dd;
dd->index = index; dd->index = index;
/*
* if rebuild pending, start the service thread, and delay the block
* queue creation and add_disk()
*/
if (wait_for_rebuild == MTIP_FTL_REBUILD_MAGIC)
goto start_service_thread;
skip_create_disk:
/* Allocate the request queue. */
dd->queue = blk_alloc_queue(GFP_KERNEL);
if (dd->queue == NULL) {
dev_err(&dd->pdev->dev,
"Unable to allocate request queue\n");
rv = -ENOMEM;
goto block_queue_alloc_init_error;
}
/* Attach our request function to the request queue. */
blk_queue_make_request(dd->queue, mtip_make_request);
dd->disk->queue = dd->queue;
dd->queue->queuedata = dd;
/* Set device limits. */
set_bit(QUEUE_FLAG_NONROT, &dd->queue->queue_flags);
blk_queue_max_segments(dd->queue, MTIP_MAX_SG);
blk_queue_physical_block_size(dd->queue, 4096);
blk_queue_io_min(dd->queue, 4096);
blk_queue_flush(dd->queue, 0);
/* Set the capacity of the device in 512 byte sectors. */ /* Set the capacity of the device in 512 byte sectors. */
if (!(mtip_hw_get_capacity(dd, &capacity))) { if (!(mtip_hw_get_capacity(dd, &capacity))) {
dev_warn(&dd->pdev->dev, dev_warn(&dd->pdev->dev,
...@@ -3188,6 +3211,10 @@ static int mtip_block_initialize(struct driver_data *dd) ...@@ -3188,6 +3211,10 @@ static int mtip_block_initialize(struct driver_data *dd)
kobject_put(kobj); kobject_put(kobj);
} }
if (dd->mtip_svc_handler)
return rv; /* service thread created for handling rebuild */
start_service_thread:
sprintf(thd_name, "mtip_svc_thd_%02d", index); sprintf(thd_name, "mtip_svc_thd_%02d", index);
dd->mtip_svc_handler = kthread_run(mtip_service_thread, dd->mtip_svc_handler = kthread_run(mtip_service_thread,
...@@ -3197,18 +3224,19 @@ static int mtip_block_initialize(struct driver_data *dd) ...@@ -3197,18 +3224,19 @@ static int mtip_block_initialize(struct driver_data *dd)
printk(KERN_ERR "mtip32xx: service thread failed to start\n"); printk(KERN_ERR "mtip32xx: service thread failed to start\n");
dd->mtip_svc_handler = NULL; dd->mtip_svc_handler = NULL;
rv = -EFAULT; rv = -EFAULT;
goto read_capacity_error; goto kthread_run_error;
} }
return rv; return rv;
read_capacity_error: kthread_run_error:
/* /* Delete our gendisk. This also removes the device from /dev */
* Delete our gendisk structure. This also removes the device
* from /dev
*/
del_gendisk(dd->disk); del_gendisk(dd->disk);
read_capacity_error:
blk_cleanup_queue(dd->queue);
block_queue_alloc_init_error:
disk_index_error: disk_index_error:
spin_lock(&rssd_index_lock); spin_lock(&rssd_index_lock);
ida_remove(&rssd_index_ida, index); ida_remove(&rssd_index_ida, index);
...@@ -3218,11 +3246,7 @@ static int mtip_block_initialize(struct driver_data *dd) ...@@ -3218,11 +3246,7 @@ static int mtip_block_initialize(struct driver_data *dd)
put_disk(dd->disk); put_disk(dd->disk);
alloc_disk_error: alloc_disk_error:
blk_cleanup_queue(dd->queue); mtip_hw_exit(dd); /* De-initialize the protocol layer. */
block_queue_alloc_init_error:
/* De-initialize the protocol layer. */
mtip_hw_exit(dd);
protocol_init_error: protocol_init_error:
return rv; return rv;
......
...@@ -121,6 +121,7 @@ ...@@ -121,6 +121,7 @@
#define MTIP_FLAG_EH_ACTIVE_BIT 1 #define MTIP_FLAG_EH_ACTIVE_BIT 1
#define MTIP_FLAG_SVC_THD_ACTIVE_BIT 2 #define MTIP_FLAG_SVC_THD_ACTIVE_BIT 2
#define MTIP_FLAG_ISSUE_CMDS_BIT 4 #define MTIP_FLAG_ISSUE_CMDS_BIT 4
#define MTIP_FLAG_REBUILD_BIT 5
#define MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT 8 #define MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT 8
/* Register Frame Information Structure (FIS), host to device. */ /* Register Frame Information Structure (FIS), host to device. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment