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
2022-09-28 09:02:20 +02:00
2022-09-28 09:02:20 +02:00
2022-09-28 09:02:20 +02:00
2022-10-16 15:36:24 -07:00

Linux kernel
============

There are several guides for kernel developers and users. These guides can
be rendered in a number of formats, like HTML and PDF. Please read
Documentation/admin-guide/README.rst first.

In order to build the documentation, use ``make htmldocs`` or
``make pdfdocs``.  The formatted documentation can also be read online at:

    https://www.kernel.org/doc/html/latest/

There are various text files in the Documentation/ subdirectory,
several of them using the Restructured Text markup notation.

Please read the Documentation/process/changes.rst file, as it contains the
requirements for building and running the kernel, and information about
the problems which may result by upgrading your kernel.
Description
No description provided
Readme 7.9 GiB
Languages
C 97.7%
Assembly 1.6%
Makefile 0.3%
Perl 0.1%