From patchwork Tue Feb 7 13:17:48 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Nicholas A. Bellinger" X-Patchwork-Id: 9560075 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 094526047A for ; Tue, 7 Feb 2017 13:27:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F0A2F28173 for ; Tue, 7 Feb 2017 13:27:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E59DC28047; Tue, 7 Feb 2017 13:27:09 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0D40128173 for ; Tue, 7 Feb 2017 13:27:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754625AbdBGN0v (ORCPT ); Tue, 7 Feb 2017 08:26:51 -0500 Received: from mail.linux-iscsi.org ([67.23.28.174]:41073 "EHLO linux-iscsi.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754310AbdBGN0P (ORCPT ); Tue, 7 Feb 2017 08:26:15 -0500 Received: from linux-iscsi.org (localhost [127.0.0.1]) by linux-iscsi.org (Postfix) with ESMTP id 82D4B40B09; Tue, 7 Feb 2017 13:17:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=linux-iscsi.org; s=default.private; t=1486473476; bh=G2DUUkGyeu/sLTv0uqpCz+EF53x3poO vDei8cMxBKRs=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To: References; b=A5pG1++MUI8qNsH3izcSc4T2ryVXPwVfWK88hzcEwV8JN/QxpKD4 O4AF2U5OfFEXIqoBxaJ6xBKJqhuL3zpuMmdHZuS0cD3w9oAMsQOSEmaWH0WY5k5f0SX HzP4J5iTZSV3hkS9osS9vB59RvTenkPI/BsFzXYjdzXjEG1hlmoE= From: "Nicholas A. Bellinger" To: target-devel Cc: linux-scsi , lkml , Nicholas Bellinger , Rob Millner Subject: [PATCH 3/5] target: Fix early transport_generic_handle_tmr abort scenario Date: Tue, 7 Feb 2017 13:17:48 +0000 Message-Id: <1486473470-15837-4-git-send-email-nab@linux-iscsi.org> X-Mailer: git-send-email 1.7.2.5 In-Reply-To: <1486473470-15837-1-git-send-email-nab@linux-iscsi.org> References: <1486473470-15837-1-git-send-email-nab@linux-iscsi.org> Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Nicholas Bellinger This patch fixes a bug where incoming task management requests can be explicitly aborted during an active LUN_RESET, but who's struct work_struct are canceled in-flight before execution. This occurs when core_tmr_drain_tmr_list() invokes cancel_work_sync() for the incoming se_tmr_req->task_cmd->work, resulting in cmd->work for target_tmr_work() never getting invoked and the aborted TMR waiting indefinately within transport_wait_for_tasks(). To address this case, perform a CMD_T_ABORTED check early in transport_generic_handle_tmr(), and invoke the normal path via transport_cmd_check_stop_to_fabric() to complete any TMR kthreads blocked waiting for CMD_T_STOP in transport_wait_for_tasks(). Also, move the TRANSPORT_ISTATE_PROCESSING assignment earlier into transport_generic_handle_tmr() so the existing check in core_tmr_drain_tmr_list() avoids attempting abort the incoming se_tmr_req->task_cmd->work if it has already been queued into se_device->tmr_wq. Reported-by: Rob Millner Tested-by: Rob Millner Cc: Rob Millner Cc: stable@vger.kernel.org # 3.14+ Signed-off-by: Nicholas Bellinger Reviewed-by: Christoph Hellwig --- drivers/target/target_core_transport.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 1cadc9e..8b69843 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -3110,7 +3110,6 @@ static void target_tmr_work(struct work_struct *work) spin_unlock_irqrestore(&cmd->t_state_lock, flags); goto check_stop; } - cmd->t_state = TRANSPORT_ISTATE_PROCESSING; spin_unlock_irqrestore(&cmd->t_state_lock, flags); cmd->se_tfo->queue_tm_rsp(cmd); @@ -3123,11 +3122,25 @@ int transport_generic_handle_tmr( struct se_cmd *cmd) { unsigned long flags; + bool aborted = false; spin_lock_irqsave(&cmd->t_state_lock, flags); - cmd->transport_state |= CMD_T_ACTIVE; + if (cmd->transport_state & CMD_T_ABORTED) { + aborted = true; + } else { + cmd->t_state = TRANSPORT_ISTATE_PROCESSING; + cmd->transport_state |= CMD_T_ACTIVE; + } spin_unlock_irqrestore(&cmd->t_state_lock, flags); + if (aborted) { + pr_warn_ratelimited("handle_tmr caught CMD_T_ABORTED TMR %d" + "ref_tag: %llu tag: %llu\n", cmd->se_tmr_req->function, + cmd->se_tmr_req->ref_task_tag, cmd->tag); + transport_cmd_check_stop_to_fabric(cmd); + return 0; + } + INIT_WORK(&cmd->work, target_tmr_work); queue_work(cmd->se_dev->tmr_wq, &cmd->work); return 0;