mtip32xx: fix crash on surprise removal of the drive
PATCH 5/9 mtip32xx: fix crash on surprise removal of the drive
pci and block layers have changed a lot compared to when SRSI support was added. Given the current state of pci and block layers, this driver do not have to do any specific handling.
Signed-off-by Asai Thambi S P <[email protected]>
Signed-off-by Selvan Mani <[email protected]>
--- drivers/block/mtip32xx/mtip32xx.c | 143 ++++++++++++------------------------- 1 files changed, 45 insertions(+), 98 deletions(-)
drivers/block/mtip32xx/mtip32xx.c +45 -98
@@ -895,6 +895,10 @@ static inline irqreturn_t mtip_handle_irq(struct driver_data *data)/* Acknowledge the interrupt status on the port.*/ port_stat =readl (port->mmio +PORT_IRQ_STAT ); +if (unlikely (port_stat ==0xFFFFFFFF )) { +mtip_check_surprise_removal (dd->pdev); +return IRQ_HANDLED ; + }writel (port_stat, port->mmio +PORT_IRQ_STAT );/* Demux port status */
@@ -2765,49 +2769,6 @@ static void mtip_hw_debugfs_exit(struct driver_data *dd)debugfs_remove_recursive (dd->dfs_node); } -static int mtip_free_orphan (struct driver_data *dd) -{ -struct kobject *kobj; - -if (dd->bdev) { -if (dd->bdev->bd_holders >=1 ) -return -2 ; - -bdput (dd->bdev); - dd->bdev =NULL ; - } - -mtip_hw_debugfs_exit (dd); - -spin_lock (&rssd_index_lock); -ida_remove (&rssd_index_ida, dd->index); -spin_unlock (&rssd_index_lock); - -if (!test_bit (MTIP_DDF_INIT_DONE_BIT , &dd->dd_flag) && -test_bit (MTIP_DDF_REBUILD_FAILED_BIT , &dd->dd_flag)) { -put_disk (dd->disk); - }else { -if (dd->disk) { - kobj =kobject_get (&disk_to_dev (dd->disk)->kobj); -if (kobj) { -mtip_hw_sysfs_exit (dd, kobj); -kobject_put (kobj); - } -del_gendisk (dd->disk); -put_disk (dd->disk); - dd->disk =NULL ; - } -if (dd->queue) { - dd->queue->queuedata =NULL ; -blk_cleanup_queue (dd->queue); -blk_mq_free_tag_set (&dd->tags); - dd->queue =NULL ; - } - } -kfree (dd); -return 0 ; -} -/* * Perform any init/resume time hardware setup *
@@ -2955,7 +2916,6 @@ static int mtip_service_thread(void *data)unsigned long slot, slot_start, slot_wrap;unsigned int num_cmd_slots = dd->slot_groups *32 ;struct mtip_port *port = dd->port; -int ret;while (1 ) { if (kthread_should_stop() ||
@@ -3041,18 +3001,6 @@ restart_eh:if (kthread_should_stop ()) goto st_out; } - -while (1 ) { - ret =mtip_free_orphan (dd); -if (!ret) { -/* NOTE: All data structures are invalid, do not -* access any here */ -return 0 ; - } -msleep_interruptible (1000 ); -if (kthread_should_stop ()) - goto st_out; - } st_out:return 0 ; }
@@ -3380,6 +3328,7 @@ static int mtip_hw_exit(struct driver_data *dd)/* Release the IRQ. */ irq_set_affinity_hint (dd->pdev->irq,NULL );devm_free_irq (&dd->pdev->dev, dd->pdev->irq, dd); +msleep (1000 );/* Free dma regions */ mtip_dma_free (dd);
@@ -4075,52 +4024,51 @@ static int mtip_block_remove(struct driver_data *dd) {struct kobject *kobj; -if (!dd->sr) { -mtip_hw_debugfs_exit (dd); +mtip_hw_debugfs_exit (dd); -if (dd->mtip_svc_handler) { -set_bit (MTIP_PF_SVC_THD_STOP_BIT , &dd->port->flags); -wake_up_interruptible (&dd->port->svc_wait); -kthread_stop (dd->mtip_svc_handler); - } +if (dd->mtip_svc_handler) { +set_bit (MTIP_PF_SVC_THD_STOP_BIT , &dd->port->flags); +wake_up_interruptible (&dd->port->svc_wait); +kthread_stop (dd->mtip_svc_handler); + } -/* Clean up the sysfs attributes, if created */ -if (test_bit (MTIP_DDF_INIT_DONE_BIT , &dd->dd_flag)) { - kobj =kobject_get (&disk_to_dev (dd->disk)->kobj); -if (kobj) { -mtip_hw_sysfs_exit (dd, kobj); -kobject_put (kobj); - } +/* Clean up the sysfs attributes, if created */ +if (test_bit (MTIP_DDF_INIT_DONE_BIT , &dd->dd_flag)) { + kobj =kobject_get (&disk_to_dev (dd->disk)->kobj); +if (kobj) { +mtip_hw_sysfs_exit (dd, kobj); +kobject_put (kobj); } + } +if (!dd->sr)mtip_standby_drive (dd); - -/* -* Delete our gendisk structure. This also removes the device -* from /dev -*/ -if (dd->bdev) { -bdput (dd->bdev); - dd->bdev =NULL ; - } -if (dd->disk) { -del_gendisk (dd->disk); -if (dd->disk->queue) { -blk_cleanup_queue (dd->queue); -blk_mq_free_tag_set (&dd->tags); - dd->queue =NULL ; - } -put_disk (dd->disk); - } - dd->disk =NULL ; - -spin_lock (&rssd_index_lock); -ida_remove (&rssd_index_ida, dd->index); -spin_unlock (&rssd_index_lock); - }else { +else dev_info (&dd->pdev->dev,"device %s surprise removal\n" , dd->disk->disk_name); + +/* +* Delete our gendisk structure. This also removes the device +* from /dev +*/ +if (dd->bdev) { +bdput (dd->bdev); + dd->bdev =NULL ; + } +if (dd->disk) { +del_gendisk (dd->disk); +if (dd->disk->queue) { +blk_cleanup_queue (dd->queue); +blk_mq_free_tag_set (&dd->tags); + dd->queue =NULL ; + } +put_disk (dd->disk); } + dd->disk =NULL ; + +spin_lock (&rssd_index_lock); +ida_remove (&rssd_index_ida, dd->index); +spin_unlock (&rssd_index_lock);/* De-initialize the protocol layer. */ mtip_hw_exit (dd);
@@ -4516,6 +4464,7 @@ static void mtip_pci_remove(struct pci_dev *pdev) "Completion workers still active!\n"); } +blk_mq_stop_hw_queues (dd->queue);/* Clean up the block layer. */ mtip_block_remove (dd);
@@ -4533,10 +4482,8 @@ static void mtip_pci_remove(struct pci_dev *pdev)list_del_init (&dd->remove_list);spin_unlock_irqrestore (&dev_lock, flags); -if (!dd->sr) -kfree (dd); -else -set_bit (MTIP_DDF_REMOVE_DONE_BIT , &dd->dd_flag); +kfree (dd); +set_bit (MTIP_DDF_REMOVE_DONE_BIT , &dd->dd_flag);pcim_iounmap_regions (pdev,1 <<MTIP_ABAR );pci_set_drvdata (pdev,NULL );
Signature · 1 line
1.7.1