linux-stable/drivers/target
Maurizio Lombardi a72629b5cd scsi: target: core: Fix hard lockup when executing a compare-and-write command
While handling an I/O completion for the compare portion of a
COMPARE_AND_WRITE command, it may happen that the
compare_and_write_callback function submits new bio structs while still in
softirq context.

Low level drivers like md raid5 do not expect their make_request call to be
used in softirq context, they call into schedule() and create a deadlocked
system.

 __schedule at ffffffff873a0807
 schedule at ffffffff873a0cc5
 raid5_get_active_stripe at ffffffffc0875744 [raid456]
 raid5_make_request at ffffffffc0875a50 [raid456]
 md_handle_request at ffffffff8713b9f9
 md_make_request at ffffffff8713bacb
 generic_make_request at ffffffff86e6f14b
 submit_bio at ffffffff86e6f27c
 iblock_submit_bios at ffffffffc0b4e4dc [target_core_iblock]
 iblock_execute_rw at ffffffffc0b4f3ce [target_core_iblock]
 __target_execute_cmd at ffffffffc1090079 [target_core_mod]
 compare_and_write_callback at ffffffffc1093602 [target_core_mod]
 target_cmd_interrupted at ffffffffc108d1ec [target_core_mod]
 target_complete_cmd_with_sense at ffffffffc108d27c [target_core_mod]
 iblock_complete_cmd at ffffffffc0b4e23a [target_core_iblock]
 dm_io_dec_pending at ffffffffc00db29e [dm_mod]
 clone_endio at ffffffffc00dbf07 [dm_mod]
 raid5_align_endio at ffffffffc086d6c2 [raid456]
 blk_update_request at ffffffff86e6d950
 scsi_end_request at ffffffff87063d48
 scsi_io_completion at ffffffff87063ee8
 blk_complete_reqs at ffffffff86e77b05
 __softirqentry_text_start at ffffffff876000d7

This problem appears to be an issue between target_cmd_interrupted() and
compare_and_write_callback(). target_cmd_interrupted() calls the se_cmd's
transport_complete_callback function pointer if the se_cmd is being stopped
or aborted, and CMD_T_ABORTED was set on the se_cmd.

When calling compare_and_write_callback(), the success parameter was set to
false. target_cmd_interrupted() seems to expect this means the callback
will do cleanup that does not require a process context. But
compare_and_write_callback() ignores the parameter if there was I/O done
for the compare part of COMPARE_AND_WRITE.

Since there was data, the function continued on, passed the compare, and
issued a write while ignoring the value of the success parameter.  The
submit of a bio for the write portion of the COMPARE_AND_WRITE then causes
schedule to be unsafely called from the softirq context.

Fix the bug in compare_and_write_callback by jumping to the out label if
success == "false", after checking if we have been called by
transport_generic_request_failure(); The command is being aborted or
stopped so there is no need to submit the write bio for the write part of
the COMPARE_AND_WRITE command.

Signed-off-by: Maurizio Lombardi <mlombard@redhat.com>
Link: https://lore.kernel.org/r/20221121092703.316489-1-mlombard@redhat.com
Reviewed-by: Mike Christie <michael.christie@oracle.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2022-11-24 03:22:58 +00:00
..
iscsi scsi: target: iscsi: Fix a race condition between login_work and the login thread 2022-11-24 03:22:53 +00:00
loopback scsi: target: tcm_loop: Call scsi_done() directly 2021-10-16 21:31:43 -04:00
sbp scsi: target: sbp: Replace enable attr with ops.enable 2021-10-04 23:27:38 -04:00
tcm_fc scsi: target: tcm_fc: Fix a kernel-doc header 2021-04-15 22:44:41 -04:00
Kconfig scsi: core: Rename CONFIG_BLK_SCSI_REQUEST to CONFIG_SCSI_COMMON 2021-07-28 22:24:27 -04:00
Makefile
target_core_alua.c scsi: target: alua: Do not report emtpy port group 2022-09-15 21:42:44 -04:00
target_core_alua.h
target_core_configfs.c scsi: target: core: Send max transfer length in blocks 2022-11-24 02:16:19 +00:00
target_core_device.c scsi: target: core: Add emulate_rsoc attribute 2022-10-27 01:44:32 +00:00
target_core_fabric_configfs.c scsi: target: Use kstrtobool() instead of strtobool() 2022-11-08 03:53:37 +00:00
target_core_fabric_lib.c
target_core_file.c scsi: target: core: Send max transfer length in blocks 2022-11-24 02:16:19 +00:00
target_core_file.h
target_core_hba.c
target_core_iblock.c scsi: target: core: Make hw_max_sectors store the sectors amount in blocks 2022-11-24 02:16:19 +00:00
target_core_iblock.h scsi: target: iblock: Add backend plug/unplug callouts 2021-03-04 17:37:02 -05:00
target_core_internal.h scsi: target: Remove unused se_tmr_req_cache declaration 2022-09-15 21:46:46 -04:00
target_core_pr.c scsi: target: core: De-RCU of se_lun and se_lun acl 2022-08-01 19:36:02 -04:00
target_core_pr.h scsi: target: core: Unify NAA identifier generation 2021-05-15 14:14:28 -04:00
target_core_pscsi.c SCSI misc on 20221007 2022-10-07 12:33:18 -07:00
target_core_pscsi.h scsi: target: pscsi: Remove struct pscsi_plugin_task 2022-03-01 22:21:49 -05:00
target_core_rd.c scsi: target: Add the DUMMY flag to rd_mcp 2021-04-05 23:26:38 -04:00
target_core_rd.h scsi: target: Add the DUMMY flag to rd_mcp 2021-04-05 23:26:38 -04:00
target_core_sbc.c scsi: target: core: Fix hard lockup when executing a compare-and-write command 2022-11-24 03:22:58 +00:00
target_core_spc.c scsi: target: core: Send max transfer length in blocks 2022-11-24 02:16:19 +00:00
target_core_stat.c scsi: target: core: De-RCU of se_lun and se_lun acl 2022-08-01 19:36:02 -04:00
target_core_tmr.c scsi: target: core: Remove from tmr_list during LUN unlink 2021-10-26 23:15:23 -04:00
target_core_tpg.c
target_core_transport.c scsi: target: core: Remove from tmr_list during LUN unlink 2021-10-26 23:15:23 -04:00
target_core_ua.c
target_core_ua.h
target_core_user.c genetlink: start to validate reserved header bytes 2022-08-29 12:47:15 +01:00
target_core_xcopy.c scsi: target: core: Change the way target_xcopy_do_work() sets restiction on max I/O 2022-11-24 02:16:19 +00:00
target_core_xcopy.h scsi: target: core: Change the way target_xcopy_do_work() sets restiction on max I/O 2022-11-24 02:16:19 +00:00