diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2011-07-30 08:03:58 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2011-07-30 08:01:25 -0400 |
commit | dd8ae59d48790d5c25f47ebbe502c8ca379fdde0 (patch) | |
tree | 16a7b7094108099836446f9e52f299045d559c4f /drivers/target | |
parent | d52a10d003694e48d28cf0218db16372ed61f1bd (diff) |
target: Fix bug for transport_generic_wait_for_tasks with direct operation
This patch fixes a bug in transport_handle_cdb_direct() usage with target_core
where transport_generic_wait_for_tasks() was bypassing active I/O + usage of
cmd->t_transport_stop_comp because cmd->t_transport_active=1 was not being set
before dispatching with transport_generic_new_cmd(). The fix follows existing
usage in transport_generic_handle_cdb*() -> transport_add_cmd_to_queue() and
set these directly, as well as handle transport_generic_new_cmd() exceptions
for QUEUE_FULL and CHECK_CONDITION instead of propigating up to RX context
fabric code.
The bug was manifesting itself with the following SLUB poison overwritten
warnings with iscsi-target v4.1 LUNs using the new process context direct
operation during session reinstatement with active I/O exception handling:
[885410.498267] =============================================================================
[885410.621622] BUG lio_cmd_cache: Poison overwritten
[885410.621791] -----------------------------------------------------------------------------
[885410.621792]
[885410.623420] INFO: 0xffff880000cf3750-0xffff880000cf378d. First byte 0x6a instead of 0x6b
[885410.626332] INFO: Allocated in iscsit_allocate_cmd+0x1c/0xd4 [iscsi_target_mod] age=345 cpu=1 pid=22554
[885411.855189] INFO: Freed in iscsit_release_cmd+0x208/0x217 [iscsi_target_mod] age=1410 cpu=1 pid=22554
[885411.856048] INFO: Slab 0xffffea000002d480 objects=22 used=0 fp=0xffff880000cf7300 flags=0x4080
[885411.856368] INFO: Object 0xffff880000cf33c0 @offset=13248 fp=0xffff880000cf6780
<SNIP>
[885411.955678] Pid: 22554, comm: iscsi_trx Not tainted 3.0.0-rc7+ #30
[885411.956040] Call Trace:
[885411.957029] [<ffffffff810e5cf9>] print_trailer+0x12e/0x137
[885412.752879] [<ffffffff810e61d9>] check_bytes_and_report+0xb9/0xfd
[885412.754933] [<ffffffff810e62d2>] check_object+0xb5/0x192
[885412.755099] [<ffffffff810e6445>] __free_slab+0x96/0x13a
[885412.757008] [<ffffffff810e652a>] discard_slab+0x41/0x43
[885412.758171] [<ffffffff810e7a4c>] __slab_free+0xf3/0xfe
[885412.761027] [<ffffffffa030a536>] ? iscsit_release_cmd+0x208/0x217 [iscsi_target_mod]
[885412.761354] [<ffffffff810e7e95>] kmem_cache_free+0x6f/0xac
[885412.761536] [<ffffffffa030a536>] iscsit_release_cmd+0x208/0x217 [iscsi_target_mod]
[885412.762056] [<ffffffffa020e467>] ? iblock_free_task+0x34/0x39 [target_core_iblock]
[885412.762368] [<ffffffffa0314131>] lio_release_cmd+0x10/0x12 [iscsi_target_mod]
[885412.764129] [<ffffffffa02c2254>] transport_release_cmd+0x2f/0x33 [target_core_mod]
[885412.805024] [<ffffffffa02c230e>] transport_generic_remove+0xb6/0xc3 [target_core_mod]
[885412.806424] [<ffffffff81035b5f>] ? try_to_wake_up+0x1bd/0x1bd
[885412.809033] [<ffffffffa02c241f>] transport_generic_free_cmd+0x75/0x7d [target_core_mod]
[885412.810066] [<ffffffffa02c2643>] transport_generic_wait_for_tasks+0x21c/0x22b [target_core_mod]
[885412.811056] [<ffffffff8139f0b1>] ? mutex_lock+0x11/0x32
[885412.813059] [<ffffffff8139f0b1>] ? mutex_lock+0x11/0x32
[885412.813200] [<ffffffffa030b81d>] iscsit_close_connection+0x1d5/0x63a [iscsi_target_mod]
[885412.813517] [<ffffffffa0300a82>] iscsit_take_action_for_connection_exit+0xdb/0xe0 [iscsi_target_mod]
[885412.813851] [<ffffffffa03111e9>] iscsi_target_rx_thread+0x11f6/0x1221 [iscsi_target_mod]
[885412.829024] [<ffffffff81033e8d>] ? pick_next_task_fair+0xbe/0x10e
[885412.831010] [<ffffffffa030fff3>] ? iscsit_handle_scsi_cmd+0x91d/0x91d [iscsi_target_mod]
[885412.833011] [<ffffffffa030fff3>] ? iscsit_handle_scsi_cmd+0x91d/0x91d [iscsi_target_mod]
[885412.835010] [<ffffffff8105388a>] kthread+0x7d/0x85
[885412.837022] [<ffffffff813a7124>] kernel_thread_helper+0x4/0x10
[885412.838008] [<ffffffff8105380d>] ? kthread_worker_fn+0x145/0x145
[885412.840047] [<ffffffff813a7120>] ? gs_change+0x13/0x13
[885412.842007] FIX lio_cmd_cache: Restoring 0xffff880000cf3750-0xffff880000cf378d=0x6
Cc: Christoph Hellwig <hch@lst.de>
Cc: Andy Grover <agrover@redhat.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/target_core_transport.c | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index ff7fcf8366a0..89760329d5d0 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -1747,6 +1747,8 @@ int transport_generic_handle_cdb( | |||
1747 | } | 1747 | } |
1748 | EXPORT_SYMBOL(transport_generic_handle_cdb); | 1748 | EXPORT_SYMBOL(transport_generic_handle_cdb); |
1749 | 1749 | ||
1750 | static void transport_generic_request_failure(struct se_cmd *, | ||
1751 | struct se_device *, int, int); | ||
1750 | /* | 1752 | /* |
1751 | * Used by fabric module frontends to queue tasks directly. | 1753 | * Used by fabric module frontends to queue tasks directly. |
1752 | * Many only be used from process context only | 1754 | * Many only be used from process context only |
@@ -1754,6 +1756,8 @@ EXPORT_SYMBOL(transport_generic_handle_cdb); | |||
1754 | int transport_handle_cdb_direct( | 1756 | int transport_handle_cdb_direct( |
1755 | struct se_cmd *cmd) | 1757 | struct se_cmd *cmd) |
1756 | { | 1758 | { |
1759 | int ret; | ||
1760 | |||
1757 | if (!cmd->se_lun) { | 1761 | if (!cmd->se_lun) { |
1758 | dump_stack(); | 1762 | dump_stack(); |
1759 | pr_err("cmd->se_lun is NULL\n"); | 1763 | pr_err("cmd->se_lun is NULL\n"); |
@@ -1765,8 +1769,31 @@ int transport_handle_cdb_direct( | |||
1765 | " from interrupt context\n"); | 1769 | " from interrupt context\n"); |
1766 | return -EINVAL; | 1770 | return -EINVAL; |
1767 | } | 1771 | } |
1768 | 1772 | /* | |
1769 | return transport_generic_new_cmd(cmd); | 1773 | * Set TRANSPORT_NEW_CMD state and cmd->t_transport_active=1 following |
1774 | * transport_generic_handle_cdb*() -> transport_add_cmd_to_queue() | ||
1775 | * in existing usage to ensure that outstanding descriptors are handled | ||
1776 | * correctly during shutdown via transport_generic_wait_for_tasks() | ||
1777 | * | ||
1778 | * Also, we don't take cmd->t_state_lock here as we only expect | ||
1779 | * this to be called for initial descriptor submission. | ||
1780 | */ | ||
1781 | cmd->t_state = TRANSPORT_NEW_CMD; | ||
1782 | atomic_set(&cmd->t_transport_active, 1); | ||
1783 | /* | ||
1784 | * transport_generic_new_cmd() is already handling QUEUE_FULL, | ||
1785 | * so follow TRANSPORT_NEW_CMD processing thread context usage | ||
1786 | * and call transport_generic_request_failure() if necessary.. | ||
1787 | */ | ||
1788 | ret = transport_generic_new_cmd(cmd); | ||
1789 | if (ret == -EAGAIN) | ||
1790 | return 0; | ||
1791 | else if (ret < 0) { | ||
1792 | cmd->transport_error_status = ret; | ||
1793 | transport_generic_request_failure(cmd, NULL, 0, | ||
1794 | (cmd->data_direction != DMA_TO_DEVICE)); | ||
1795 | } | ||
1796 | return 0; | ||
1770 | } | 1797 | } |
1771 | EXPORT_SYMBOL(transport_handle_cdb_direct); | 1798 | EXPORT_SYMBOL(transport_handle_cdb_direct); |
1772 | 1799 | ||