diff options
author | Asai Thambi S P <asamymuthupa@micron.com> | 2014-05-20 13:48:56 -0400 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2014-05-20 13:51:30 -0400 |
commit | 9b204fbf0987748ec6cc4a3cde0064ecf42accd0 (patch) | |
tree | 58c669aefeaef7ac581617e712ca6ecc768f5e20 /drivers/block/mtip32xx | |
parent | 0c29e93eae8a7f703e463c7b38ebc85d8718cae2 (diff) |
mtip32xx: move error handling to service thread
Move error handling to service thread, and use mtip_set_timeout()
to set timeouts for HDIO_DRIVE_TASK and HDIO_DRIVE_CMD IOCTL commands.
Signed-off-by: Selvan Mani <smani@micron.com>
Signed-off-by: Asai Thambi S P <asamymuthupa@micron.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'drivers/block/mtip32xx')
-rw-r--r-- | drivers/block/mtip32xx/mtip32xx.c | 71 | ||||
-rw-r--r-- | drivers/block/mtip32xx/mtip32xx.h | 8 |
2 files changed, 53 insertions, 26 deletions
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 4efc676aa5f4..ae331ab4a451 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c | |||
@@ -620,7 +620,6 @@ static void mtip_handle_tfe(struct driver_data *dd) | |||
620 | 620 | ||
621 | port = dd->port; | 621 | port = dd->port; |
622 | 622 | ||
623 | /* Stop the timer to prevent command timeouts. */ | ||
624 | set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); | 623 | set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); |
625 | 624 | ||
626 | if (test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags) && | 625 | if (test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags) && |
@@ -855,8 +854,6 @@ static inline void mtip_process_legacy(struct driver_data *dd, u32 port_stat) | |||
855 | */ | 854 | */ |
856 | static inline void mtip_process_errors(struct driver_data *dd, u32 port_stat) | 855 | static inline void mtip_process_errors(struct driver_data *dd, u32 port_stat) |
857 | { | 856 | { |
858 | if (likely(port_stat & (PORT_IRQ_TF_ERR | PORT_IRQ_IF_ERR))) | ||
859 | mtip_handle_tfe(dd); | ||
860 | 857 | ||
861 | if (unlikely(port_stat & PORT_IRQ_CONNECT)) { | 858 | if (unlikely(port_stat & PORT_IRQ_CONNECT)) { |
862 | dev_warn(&dd->pdev->dev, | 859 | dev_warn(&dd->pdev->dev, |
@@ -874,6 +871,12 @@ static inline void mtip_process_errors(struct driver_data *dd, u32 port_stat) | |||
874 | dev_warn(&dd->pdev->dev, | 871 | dev_warn(&dd->pdev->dev, |
875 | "Port stat errors %x unhandled\n", | 872 | "Port stat errors %x unhandled\n", |
876 | (port_stat & ~PORT_IRQ_HANDLED)); | 873 | (port_stat & ~PORT_IRQ_HANDLED)); |
874 | if (mtip_check_surprise_removal(dd->pdev)) | ||
875 | return; | ||
876 | } | ||
877 | if (likely(port_stat & (PORT_IRQ_TF_ERR | PORT_IRQ_IF_ERR))) { | ||
878 | set_bit(MTIP_PF_EH_ACTIVE_BIT, &dd->port->flags); | ||
879 | wake_up_interruptible(&dd->port->svc_wait); | ||
877 | } | 880 | } |
878 | } | 881 | } |
879 | 882 | ||
@@ -1040,8 +1043,13 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout) | |||
1040 | msleep(20); | 1043 | msleep(20); |
1041 | continue; /* svc thd is actively issuing commands */ | 1044 | continue; /* svc thd is actively issuing commands */ |
1042 | } | 1045 | } |
1046 | |||
1047 | msleep(100); | ||
1048 | if (mtip_check_surprise_removal(port->dd->pdev)) | ||
1049 | goto err_fault; | ||
1043 | if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag)) | 1050 | if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag)) |
1044 | goto err_fault; | 1051 | goto err_fault; |
1052 | |||
1045 | /* | 1053 | /* |
1046 | * Ignore s_active bit 0 of array element 0. | 1054 | * Ignore s_active bit 0 of array element 0. |
1047 | * This bit will always be set | 1055 | * This bit will always be set |
@@ -1052,8 +1060,6 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout) | |||
1052 | 1060 | ||
1053 | if (!active) | 1061 | if (!active) |
1054 | break; | 1062 | break; |
1055 | |||
1056 | msleep(20); | ||
1057 | } while (time_before(jiffies, to)); | 1063 | } while (time_before(jiffies, to)); |
1058 | 1064 | ||
1059 | blk_mq_start_stopped_hw_queues(port->dd->queue, true); | 1065 | blk_mq_start_stopped_hw_queues(port->dd->queue, true); |
@@ -1113,7 +1119,8 @@ static int mtip_exec_internal_command(struct mtip_port *port, | |||
1113 | if (atomic == GFP_KERNEL) { | 1119 | if (atomic == GFP_KERNEL) { |
1114 | if (fis->command != ATA_CMD_STANDBYNOW1) { | 1120 | if (fis->command != ATA_CMD_STANDBYNOW1) { |
1115 | /* wait for io to complete if non atomic */ | 1121 | /* wait for io to complete if non atomic */ |
1116 | if (mtip_quiesce_io(port, 5000) < 0) { | 1122 | if (mtip_quiesce_io(port, |
1123 | MTIP_QUIESCE_IO_TIMEOUT_MS) < 0) { | ||
1117 | dev_warn(&dd->pdev->dev, | 1124 | dev_warn(&dd->pdev->dev, |
1118 | "Failed to quiesce IO\n"); | 1125 | "Failed to quiesce IO\n"); |
1119 | mtip_put_int_command(dd, int_cmd); | 1126 | mtip_put_int_command(dd, int_cmd); |
@@ -1161,9 +1168,9 @@ static int mtip_exec_internal_command(struct mtip_port *port, | |||
1161 | 1168 | ||
1162 | if (atomic == GFP_KERNEL) { | 1169 | if (atomic == GFP_KERNEL) { |
1163 | /* Wait for the command to complete or timeout. */ | 1170 | /* Wait for the command to complete or timeout. */ |
1164 | if (wait_for_completion_interruptible_timeout( | 1171 | if ((rv = wait_for_completion_interruptible_timeout( |
1165 | &wait, | 1172 | &wait, |
1166 | msecs_to_jiffies(timeout)) <= 0) { | 1173 | msecs_to_jiffies(timeout))) <= 0) { |
1167 | if (rv == -ERESTARTSYS) { /* interrupted */ | 1174 | if (rv == -ERESTARTSYS) { /* interrupted */ |
1168 | dev_err(&dd->pdev->dev, | 1175 | dev_err(&dd->pdev->dev, |
1169 | "Internal command [%02X] was interrupted after %lu ms\n", | 1176 | "Internal command [%02X] was interrupted after %lu ms\n", |
@@ -1299,7 +1306,7 @@ static void mtip_set_timeout(struct driver_data *dd, | |||
1299 | *timeout = 15000; /* 15 seconds */ | 1306 | *timeout = 15000; /* 15 seconds */ |
1300 | break; | 1307 | break; |
1301 | default: | 1308 | default: |
1302 | *timeout = MTIP_IOCTL_COMMAND_TIMEOUT_MS; | 1309 | *timeout = MTIP_IOCTL_CMD_TIMEOUT_MS; |
1303 | break; | 1310 | break; |
1304 | } | 1311 | } |
1305 | } | 1312 | } |
@@ -1351,7 +1358,7 @@ static int mtip_get_identify(struct mtip_port *port, void __user *user_buffer) | |||
1351 | sizeof(u16) * ATA_ID_WORDS, | 1358 | sizeof(u16) * ATA_ID_WORDS, |
1352 | 0, | 1359 | 0, |
1353 | GFP_KERNEL, | 1360 | GFP_KERNEL, |
1354 | MTIP_INTERNAL_COMMAND_TIMEOUT_MS) | 1361 | MTIP_INT_CMD_TIMEOUT_MS) |
1355 | < 0) { | 1362 | < 0) { |
1356 | rv = -1; | 1363 | rv = -1; |
1357 | goto out; | 1364 | goto out; |
@@ -1483,7 +1490,7 @@ static int mtip_read_log_page(struct mtip_port *port, u8 page, u16 *buffer, | |||
1483 | sectors * ATA_SECT_SIZE, | 1490 | sectors * ATA_SECT_SIZE, |
1484 | 0, | 1491 | 0, |
1485 | GFP_ATOMIC, | 1492 | GFP_ATOMIC, |
1486 | MTIP_INTERNAL_COMMAND_TIMEOUT_MS); | 1493 | MTIP_INT_CMD_TIMEOUT_MS); |
1487 | } | 1494 | } |
1488 | 1495 | ||
1489 | /* | 1496 | /* |
@@ -1776,6 +1783,7 @@ static int exec_drive_task(struct mtip_port *port, u8 *command) | |||
1776 | { | 1783 | { |
1777 | struct host_to_dev_fis fis; | 1784 | struct host_to_dev_fis fis; |
1778 | struct host_to_dev_fis *reply = (port->rxfis + RX_FIS_D2H_REG); | 1785 | struct host_to_dev_fis *reply = (port->rxfis + RX_FIS_D2H_REG); |
1786 | unsigned int to; | ||
1779 | 1787 | ||
1780 | /* Build the FIS. */ | 1788 | /* Build the FIS. */ |
1781 | memset(&fis, 0, sizeof(struct host_to_dev_fis)); | 1789 | memset(&fis, 0, sizeof(struct host_to_dev_fis)); |
@@ -1789,6 +1797,8 @@ static int exec_drive_task(struct mtip_port *port, u8 *command) | |||
1789 | fis.cyl_hi = command[5]; | 1797 | fis.cyl_hi = command[5]; |
1790 | fis.device = command[6] & ~0x10; /* Clear the dev bit*/ | 1798 | fis.device = command[6] & ~0x10; /* Clear the dev bit*/ |
1791 | 1799 | ||
1800 | mtip_set_timeout(port->dd, &fis, &to, 0); | ||
1801 | |||
1792 | dbg_printk(MTIP_DRV_NAME " %s: User Command: cmd %x, feat %x, nsect %x, sect %x, lcyl %x, hcyl %x, sel %x\n", | 1802 | dbg_printk(MTIP_DRV_NAME " %s: User Command: cmd %x, feat %x, nsect %x, sect %x, lcyl %x, hcyl %x, sel %x\n", |
1793 | __func__, | 1803 | __func__, |
1794 | command[0], | 1804 | command[0], |
@@ -1807,7 +1817,7 @@ static int exec_drive_task(struct mtip_port *port, u8 *command) | |||
1807 | 0, | 1817 | 0, |
1808 | 0, | 1818 | 0, |
1809 | GFP_KERNEL, | 1819 | GFP_KERNEL, |
1810 | MTIP_IOCTL_COMMAND_TIMEOUT_MS) < 0) { | 1820 | to) < 0) { |
1811 | return -1; | 1821 | return -1; |
1812 | } | 1822 | } |
1813 | 1823 | ||
@@ -1847,6 +1857,7 @@ static int exec_drive_command(struct mtip_port *port, u8 *command, | |||
1847 | u8 *buf = NULL; | 1857 | u8 *buf = NULL; |
1848 | dma_addr_t dma_addr = 0; | 1858 | dma_addr_t dma_addr = 0; |
1849 | int rv = 0, xfer_sz = command[3]; | 1859 | int rv = 0, xfer_sz = command[3]; |
1860 | unsigned int to; | ||
1850 | 1861 | ||
1851 | if (xfer_sz) { | 1862 | if (xfer_sz) { |
1852 | if (!user_buffer) | 1863 | if (!user_buffer) |
@@ -1878,6 +1889,8 @@ static int exec_drive_command(struct mtip_port *port, u8 *command, | |||
1878 | fis.cyl_hi = 0xC2; | 1889 | fis.cyl_hi = 0xC2; |
1879 | } | 1890 | } |
1880 | 1891 | ||
1892 | mtip_set_timeout(port->dd, &fis, &to, 0); | ||
1893 | |||
1881 | if (xfer_sz) | 1894 | if (xfer_sz) |
1882 | reply = (port->rxfis + RX_FIS_PIO_SETUP); | 1895 | reply = (port->rxfis + RX_FIS_PIO_SETUP); |
1883 | else | 1896 | else |
@@ -1900,7 +1913,7 @@ static int exec_drive_command(struct mtip_port *port, u8 *command, | |||
1900 | (xfer_sz ? ATA_SECT_SIZE * xfer_sz : 0), | 1913 | (xfer_sz ? ATA_SECT_SIZE * xfer_sz : 0), |
1901 | 0, | 1914 | 0, |
1902 | GFP_KERNEL, | 1915 | GFP_KERNEL, |
1903 | MTIP_IOCTL_COMMAND_TIMEOUT_MS) | 1916 | to) |
1904 | < 0) { | 1917 | < 0) { |
1905 | rv = -EFAULT; | 1918 | rv = -EFAULT; |
1906 | goto exit_drive_command; | 1919 | goto exit_drive_command; |
@@ -2956,6 +2969,11 @@ static int mtip_service_thread(void *data) | |||
2956 | int ret; | 2969 | int ret; |
2957 | 2970 | ||
2958 | while (1) { | 2971 | while (1) { |
2972 | if (kthread_should_stop() || | ||
2973 | test_bit(MTIP_PF_SVC_THD_STOP_BIT, &port->flags)) | ||
2974 | goto st_out; | ||
2975 | clear_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags); | ||
2976 | |||
2959 | /* | 2977 | /* |
2960 | * the condition is to check neither an internal command is | 2978 | * the condition is to check neither an internal command is |
2961 | * is in progress nor error handling is active | 2979 | * is in progress nor error handling is active |
@@ -2963,11 +2981,12 @@ static int mtip_service_thread(void *data) | |||
2963 | wait_event_interruptible(port->svc_wait, (port->flags) && | 2981 | wait_event_interruptible(port->svc_wait, (port->flags) && |
2964 | !(port->flags & MTIP_PF_PAUSE_IO)); | 2982 | !(port->flags & MTIP_PF_PAUSE_IO)); |
2965 | 2983 | ||
2966 | if (kthread_should_stop()) | ||
2967 | goto st_out; | ||
2968 | |||
2969 | set_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags); | 2984 | set_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags); |
2970 | 2985 | ||
2986 | if (kthread_should_stop() || | ||
2987 | test_bit(MTIP_PF_SVC_THD_STOP_BIT, &port->flags)) | ||
2988 | goto st_out; | ||
2989 | |||
2971 | /* If I am an orphan, start self cleanup */ | 2990 | /* If I am an orphan, start self cleanup */ |
2972 | if (test_bit(MTIP_PF_SR_CLEANUP_BIT, &port->flags)) | 2991 | if (test_bit(MTIP_PF_SR_CLEANUP_BIT, &port->flags)) |
2973 | break; | 2992 | break; |
@@ -2976,6 +2995,16 @@ static int mtip_service_thread(void *data) | |||
2976 | &dd->dd_flag))) | 2995 | &dd->dd_flag))) |
2977 | goto st_out; | 2996 | goto st_out; |
2978 | 2997 | ||
2998 | restart_eh: | ||
2999 | /* Demux bits: start with error handling */ | ||
3000 | if (test_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags)) { | ||
3001 | mtip_handle_tfe(dd); | ||
3002 | clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); | ||
3003 | } | ||
3004 | |||
3005 | if (test_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags)) | ||
3006 | goto restart_eh; | ||
3007 | |||
2979 | if (test_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags)) { | 3008 | if (test_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags)) { |
2980 | slot = 1; | 3009 | slot = 1; |
2981 | /* used to restrict the loop to one iteration */ | 3010 | /* used to restrict the loop to one iteration */ |
@@ -3005,16 +3034,14 @@ static int mtip_service_thread(void *data) | |||
3005 | } | 3034 | } |
3006 | 3035 | ||
3007 | clear_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags); | 3036 | clear_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags); |
3008 | } else if (test_bit(MTIP_PF_REBUILD_BIT, &port->flags)) { | 3037 | } |
3038 | |||
3039 | if (test_bit(MTIP_PF_REBUILD_BIT, &port->flags)) { | ||
3009 | if (mtip_ftl_rebuild_poll(dd) < 0) | 3040 | if (mtip_ftl_rebuild_poll(dd) < 0) |
3010 | set_bit(MTIP_DDF_REBUILD_FAILED_BIT, | 3041 | set_bit(MTIP_DDF_REBUILD_FAILED_BIT, |
3011 | &dd->dd_flag); | 3042 | &dd->dd_flag); |
3012 | clear_bit(MTIP_PF_REBUILD_BIT, &port->flags); | 3043 | clear_bit(MTIP_PF_REBUILD_BIT, &port->flags); |
3013 | } | 3044 | } |
3014 | clear_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags); | ||
3015 | |||
3016 | if (test_bit(MTIP_PF_SVC_THD_STOP_BIT, &port->flags)) | ||
3017 | goto st_out; | ||
3018 | } | 3045 | } |
3019 | 3046 | ||
3020 | /* wait for pci remove to exit */ | 3047 | /* wait for pci remove to exit */ |
@@ -4499,8 +4526,6 @@ static void mtip_pci_remove(struct pci_dev *pdev) | |||
4499 | 4526 | ||
4500 | pcim_iounmap_regions(pdev, 1 << MTIP_ABAR); | 4527 | pcim_iounmap_regions(pdev, 1 << MTIP_ABAR); |
4501 | pci_set_drvdata(pdev, NULL); | 4528 | pci_set_drvdata(pdev, NULL); |
4502 | pci_dev_put(pdev); | ||
4503 | |||
4504 | } | 4529 | } |
4505 | 4530 | ||
4506 | /* | 4531 | /* |
diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index 982a88fe1ab2..4b9b554234bc 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h | |||
@@ -40,9 +40,11 @@ | |||
40 | #define MTIP_MAX_RETRIES 2 | 40 | #define MTIP_MAX_RETRIES 2 |
41 | 41 | ||
42 | /* Various timeout values in ms */ | 42 | /* Various timeout values in ms */ |
43 | #define MTIP_NCQ_COMMAND_TIMEOUT_MS 5000 | 43 | #define MTIP_NCQ_CMD_TIMEOUT_MS 15000 |
44 | #define MTIP_IOCTL_COMMAND_TIMEOUT_MS 5000 | 44 | #define MTIP_IOCTL_CMD_TIMEOUT_MS 5000 |
45 | #define MTIP_INTERNAL_COMMAND_TIMEOUT_MS 5000 | 45 | #define MTIP_INT_CMD_TIMEOUT_MS 5000 |
46 | #define MTIP_QUIESCE_IO_TIMEOUT_MS (MTIP_NCQ_CMD_TIMEOUT_MS * \ | ||
47 | (MTIP_MAX_RETRIES + 1)) | ||
46 | 48 | ||
47 | /* check for timeouts every 500ms */ | 49 | /* check for timeouts every 500ms */ |
48 | #define MTIP_TIMEOUT_CHECK_PERIOD 500 | 50 | #define MTIP_TIMEOUT_CHECK_PERIOD 500 |