diff options
author | Jitendra Bhivare <jitendra.bhivare@broadcom.com> | 2016-10-13 02:38:49 -0400 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2016-10-17 13:35:31 -0400 |
commit | 7d2c0d643244311d0ce04fde373cd371ad1f1cad (patch) | |
tree | 1037a18596a8b577d54136212782415ceef309ec /drivers | |
parent | 4fa507992f0a1063d7326abaf705f9408548349e (diff) |
scsi: be2iscsi: Replace _bh with _irqsave/irqrestore
[ 3843.132217] WARNING: CPU: 20 PID: 1227 at kernel/softirq.c:150 __local_bh_enable_ip+0x6b/0x90
[ 3843.142815] Modules linked in:
...
[ 3843.294328] CPU: 20 PID: 1227 Comm: kworker/20:1H Tainted: G E 4.8.0-rc1+ #3
[ 3843.304944] Hardware name: Dell Inc. PowerEdge R720/0X6H47, BIOS 1.4.8 10/25/2012
[ 3843.314798] Workqueue: kblockd blk_timeout_work
[ 3843.321350] 0000000000000086 00000000a32f4533 ffff8802216d7bd8 ffffffff8135c3cf
[ 3843.331146] 0000000000000000 0000000000000000 ffff8802216d7c18 ffffffff8108d661
[ 3843.340918] 00000096216d7c50 0000000000000200 ffff8802d07cc828 ffff8801b3632550
[ 3843.350687] Call Trace:
[ 3843.354866] [<ffffffff8135c3cf>] dump_stack+0x63/0x84
[ 3843.362061] [<ffffffff8108d661>] __warn+0xd1/0xf0
[ 3843.368851] [<ffffffff8108d79d>] warn_slowpath_null+0x1d/0x20
[ 3843.376791] [<ffffffff810930eb>] __local_bh_enable_ip+0x6b/0x90
[ 3843.384903] [<ffffffff816fe7be>] _raw_spin_unlock_bh+0x1e/0x20
[ 3843.392940] [<ffffffffa085f710>] beiscsi_alloc_pdu+0x2f0/0x6e0 [be2iscsi]
[ 3843.402076] [<ffffffffa06bc358>] __iscsi_conn_send_pdu+0xf8/0x370 [libiscsi]
[ 3843.411549] [<ffffffffa06bc6fe>] iscsi_send_nopout+0xbe/0x110 [libiscsi]
[ 3843.420639] [<ffffffffa06bd98b>] iscsi_eh_cmd_timed_out+0x29b/0x2b0 [libiscsi]
[ 3843.430339] [<ffffffff814cd1de>] scsi_times_out+0x5e/0x250
[ 3843.438119] [<ffffffff813374af>] blk_rq_timed_out+0x1f/0x60
[ 3843.446009] [<ffffffff8133759d>] blk_timeout_work+0xad/0x150
[ 3843.454010] [<ffffffff810a6642>] process_one_work+0x152/0x400
[ 3843.462114] [<ffffffff810a6f35>] worker_thread+0x125/0x4b0
[ 3843.469961] [<ffffffff810a6e10>] ? rescuer_thread+0x380/0x380
[ 3843.478116] [<ffffffff810aca28>] kthread+0xd8/0xf0
[ 3843.485212] [<ffffffff816fedff>] ret_from_fork+0x1f/0x40
[ 3843.492908] [<ffffffff810ac950>] ? kthread_park+0x60/0x60
[ 3843.500715] ---[ end trace 57ec0a1d8f0dd3a0 ]---
[ 3852.328667] NMI watchdog: Watchdog detected hard LOCKUP on cpu 1Kernel panic - not syncing: Hard LOCKUP
blk_timeout_work takes queue_lock spin_lock with interrupts disabled
before invoking iscsi_eh_cmd_timed_out. This causes a WARN_ON_ONCE in
spin_unlock_bh for wrb_lock/io_sgl_lock/mgmt_sgl_lock.
CPU was kept busy in lot of bottom half work with interrupts disabled
thus causing hard lock up.
Signed-off-by: Jitendra Bhivare <jitendra.bhivare@broadcom.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Reviewed-by: Chris Leech <cleech@redhat.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.c | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 6a6906f847db..75bfa14ed5ba 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c | |||
@@ -900,8 +900,9 @@ void hwi_ring_cq_db(struct beiscsi_hba *phba, | |||
900 | static struct sgl_handle *alloc_io_sgl_handle(struct beiscsi_hba *phba) | 900 | static struct sgl_handle *alloc_io_sgl_handle(struct beiscsi_hba *phba) |
901 | { | 901 | { |
902 | struct sgl_handle *psgl_handle; | 902 | struct sgl_handle *psgl_handle; |
903 | unsigned long flags; | ||
903 | 904 | ||
904 | spin_lock_bh(&phba->io_sgl_lock); | 905 | spin_lock_irqsave(&phba->io_sgl_lock, flags); |
905 | if (phba->io_sgl_hndl_avbl) { | 906 | if (phba->io_sgl_hndl_avbl) { |
906 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_IO, | 907 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_IO, |
907 | "BM_%d : In alloc_io_sgl_handle," | 908 | "BM_%d : In alloc_io_sgl_handle," |
@@ -919,14 +920,16 @@ static struct sgl_handle *alloc_io_sgl_handle(struct beiscsi_hba *phba) | |||
919 | phba->io_sgl_alloc_index++; | 920 | phba->io_sgl_alloc_index++; |
920 | } else | 921 | } else |
921 | psgl_handle = NULL; | 922 | psgl_handle = NULL; |
922 | spin_unlock_bh(&phba->io_sgl_lock); | 923 | spin_unlock_irqrestore(&phba->io_sgl_lock, flags); |
923 | return psgl_handle; | 924 | return psgl_handle; |
924 | } | 925 | } |
925 | 926 | ||
926 | static void | 927 | static void |
927 | free_io_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle) | 928 | free_io_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle) |
928 | { | 929 | { |
929 | spin_lock_bh(&phba->io_sgl_lock); | 930 | unsigned long flags; |
931 | |||
932 | spin_lock_irqsave(&phba->io_sgl_lock, flags); | ||
930 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_IO, | 933 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_IO, |
931 | "BM_%d : In free_,io_sgl_free_index=%d\n", | 934 | "BM_%d : In free_,io_sgl_free_index=%d\n", |
932 | phba->io_sgl_free_index); | 935 | phba->io_sgl_free_index); |
@@ -941,7 +944,7 @@ free_io_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle) | |||
941 | "value there=%p\n", phba->io_sgl_free_index, | 944 | "value there=%p\n", phba->io_sgl_free_index, |
942 | phba->io_sgl_hndl_base | 945 | phba->io_sgl_hndl_base |
943 | [phba->io_sgl_free_index]); | 946 | [phba->io_sgl_free_index]); |
944 | spin_unlock_bh(&phba->io_sgl_lock); | 947 | spin_unlock_irqrestore(&phba->io_sgl_lock, flags); |
945 | return; | 948 | return; |
946 | } | 949 | } |
947 | phba->io_sgl_hndl_base[phba->io_sgl_free_index] = psgl_handle; | 950 | phba->io_sgl_hndl_base[phba->io_sgl_free_index] = psgl_handle; |
@@ -950,7 +953,7 @@ free_io_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle) | |||
950 | phba->io_sgl_free_index = 0; | 953 | phba->io_sgl_free_index = 0; |
951 | else | 954 | else |
952 | phba->io_sgl_free_index++; | 955 | phba->io_sgl_free_index++; |
953 | spin_unlock_bh(&phba->io_sgl_lock); | 956 | spin_unlock_irqrestore(&phba->io_sgl_lock, flags); |
954 | } | 957 | } |
955 | 958 | ||
956 | static inline struct wrb_handle * | 959 | static inline struct wrb_handle * |
@@ -958,15 +961,16 @@ beiscsi_get_wrb_handle(struct hwi_wrb_context *pwrb_context, | |||
958 | unsigned int wrbs_per_cxn) | 961 | unsigned int wrbs_per_cxn) |
959 | { | 962 | { |
960 | struct wrb_handle *pwrb_handle; | 963 | struct wrb_handle *pwrb_handle; |
964 | unsigned long flags; | ||
961 | 965 | ||
962 | spin_lock_bh(&pwrb_context->wrb_lock); | 966 | spin_lock_irqsave(&pwrb_context->wrb_lock, flags); |
963 | pwrb_handle = pwrb_context->pwrb_handle_base[pwrb_context->alloc_index]; | 967 | pwrb_handle = pwrb_context->pwrb_handle_base[pwrb_context->alloc_index]; |
964 | pwrb_context->wrb_handles_available--; | 968 | pwrb_context->wrb_handles_available--; |
965 | if (pwrb_context->alloc_index == (wrbs_per_cxn - 1)) | 969 | if (pwrb_context->alloc_index == (wrbs_per_cxn - 1)) |
966 | pwrb_context->alloc_index = 0; | 970 | pwrb_context->alloc_index = 0; |
967 | else | 971 | else |
968 | pwrb_context->alloc_index++; | 972 | pwrb_context->alloc_index++; |
969 | spin_unlock_bh(&pwrb_context->wrb_lock); | 973 | spin_unlock_irqrestore(&pwrb_context->wrb_lock, flags); |
970 | 974 | ||
971 | if (pwrb_handle) | 975 | if (pwrb_handle) |
972 | memset(pwrb_handle->pwrb, 0, sizeof(*pwrb_handle->pwrb)); | 976 | memset(pwrb_handle->pwrb, 0, sizeof(*pwrb_handle->pwrb)); |
@@ -1001,14 +1005,16 @@ beiscsi_put_wrb_handle(struct hwi_wrb_context *pwrb_context, | |||
1001 | struct wrb_handle *pwrb_handle, | 1005 | struct wrb_handle *pwrb_handle, |
1002 | unsigned int wrbs_per_cxn) | 1006 | unsigned int wrbs_per_cxn) |
1003 | { | 1007 | { |
1004 | spin_lock_bh(&pwrb_context->wrb_lock); | 1008 | unsigned long flags; |
1009 | |||
1010 | spin_lock_irqsave(&pwrb_context->wrb_lock, flags); | ||
1005 | pwrb_context->pwrb_handle_base[pwrb_context->free_index] = pwrb_handle; | 1011 | pwrb_context->pwrb_handle_base[pwrb_context->free_index] = pwrb_handle; |
1006 | pwrb_context->wrb_handles_available++; | 1012 | pwrb_context->wrb_handles_available++; |
1007 | if (pwrb_context->free_index == (wrbs_per_cxn - 1)) | 1013 | if (pwrb_context->free_index == (wrbs_per_cxn - 1)) |
1008 | pwrb_context->free_index = 0; | 1014 | pwrb_context->free_index = 0; |
1009 | else | 1015 | else |
1010 | pwrb_context->free_index++; | 1016 | pwrb_context->free_index++; |
1011 | spin_unlock_bh(&pwrb_context->wrb_lock); | 1017 | spin_unlock_irqrestore(&pwrb_context->wrb_lock, flags); |
1012 | } | 1018 | } |
1013 | 1019 | ||
1014 | /** | 1020 | /** |
@@ -1037,8 +1043,9 @@ free_wrb_handle(struct beiscsi_hba *phba, struct hwi_wrb_context *pwrb_context, | |||
1037 | static struct sgl_handle *alloc_mgmt_sgl_handle(struct beiscsi_hba *phba) | 1043 | static struct sgl_handle *alloc_mgmt_sgl_handle(struct beiscsi_hba *phba) |
1038 | { | 1044 | { |
1039 | struct sgl_handle *psgl_handle; | 1045 | struct sgl_handle *psgl_handle; |
1046 | unsigned long flags; | ||
1040 | 1047 | ||
1041 | spin_lock_bh(&phba->mgmt_sgl_lock); | 1048 | spin_lock_irqsave(&phba->mgmt_sgl_lock, flags); |
1042 | if (phba->eh_sgl_hndl_avbl) { | 1049 | if (phba->eh_sgl_hndl_avbl) { |
1043 | psgl_handle = phba->eh_sgl_hndl_base[phba->eh_sgl_alloc_index]; | 1050 | psgl_handle = phba->eh_sgl_hndl_base[phba->eh_sgl_alloc_index]; |
1044 | phba->eh_sgl_hndl_base[phba->eh_sgl_alloc_index] = NULL; | 1051 | phba->eh_sgl_hndl_base[phba->eh_sgl_alloc_index] = NULL; |
@@ -1056,14 +1063,16 @@ static struct sgl_handle *alloc_mgmt_sgl_handle(struct beiscsi_hba *phba) | |||
1056 | phba->eh_sgl_alloc_index++; | 1063 | phba->eh_sgl_alloc_index++; |
1057 | } else | 1064 | } else |
1058 | psgl_handle = NULL; | 1065 | psgl_handle = NULL; |
1059 | spin_unlock_bh(&phba->mgmt_sgl_lock); | 1066 | spin_unlock_irqrestore(&phba->mgmt_sgl_lock, flags); |
1060 | return psgl_handle; | 1067 | return psgl_handle; |
1061 | } | 1068 | } |
1062 | 1069 | ||
1063 | void | 1070 | void |
1064 | free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle) | 1071 | free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle) |
1065 | { | 1072 | { |
1066 | spin_lock_bh(&phba->mgmt_sgl_lock); | 1073 | unsigned long flags; |
1074 | |||
1075 | spin_lock_irqsave(&phba->mgmt_sgl_lock, flags); | ||
1067 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, | 1076 | beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, |
1068 | "BM_%d : In free_mgmt_sgl_handle," | 1077 | "BM_%d : In free_mgmt_sgl_handle," |
1069 | "eh_sgl_free_index=%d\n", | 1078 | "eh_sgl_free_index=%d\n", |
@@ -1078,7 +1087,7 @@ free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle) | |||
1078 | "BM_%d : Double Free in eh SGL ," | 1087 | "BM_%d : Double Free in eh SGL ," |
1079 | "eh_sgl_free_index=%d\n", | 1088 | "eh_sgl_free_index=%d\n", |
1080 | phba->eh_sgl_free_index); | 1089 | phba->eh_sgl_free_index); |
1081 | spin_unlock_bh(&phba->mgmt_sgl_lock); | 1090 | spin_unlock_irqrestore(&phba->mgmt_sgl_lock, flags); |
1082 | return; | 1091 | return; |
1083 | } | 1092 | } |
1084 | phba->eh_sgl_hndl_base[phba->eh_sgl_free_index] = psgl_handle; | 1093 | phba->eh_sgl_hndl_base[phba->eh_sgl_free_index] = psgl_handle; |
@@ -1088,7 +1097,7 @@ free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle) | |||
1088 | phba->eh_sgl_free_index = 0; | 1097 | phba->eh_sgl_free_index = 0; |
1089 | else | 1098 | else |
1090 | phba->eh_sgl_free_index++; | 1099 | phba->eh_sgl_free_index++; |
1091 | spin_unlock_bh(&phba->mgmt_sgl_lock); | 1100 | spin_unlock_irqrestore(&phba->mgmt_sgl_lock, flags); |
1092 | } | 1101 | } |
1093 | 1102 | ||
1094 | static void | 1103 | static void |