From patchwork Sun Feb 7 03:18:02 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Nicholas A. Bellinger" X-Patchwork-Id: 8243721 Return-Path: X-Original-To: patchwork-linux-scsi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 7100F9F6E4 for ; Sun, 7 Feb 2016 03:21:28 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 51FB5201EC for ; Sun, 7 Feb 2016 03:21:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3C6142022A for ; Sun, 7 Feb 2016 03:21:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753123AbcBGDVZ (ORCPT ); Sat, 6 Feb 2016 22:21:25 -0500 Received: from mail-ob0-f172.google.com ([209.85.214.172]:34627 "EHLO mail-ob0-f172.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753250AbcBGDVW (ORCPT ); Sat, 6 Feb 2016 22:21:22 -0500 Received: by mail-ob0-f172.google.com with SMTP id wb13so121411335obb.1 for ; Sat, 06 Feb 2016 19:21:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daterainc-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=h77GDhpR95Zhu0PBKYr7Rwe6/YVmxr6nnCmKT65+ZSc=; b=HlWOaL7xJkCmSwDAR+S75sN5cuYpqqaIdws+67lszI6uZ4iCy7QfzpUiflWLuQR0Iw PAezy4xHzrgItGd5J0On1zQ8uxa1mSdBeqTi+1O3JYbFVVVhQdTKcFaQZewzmkJ4/Pm/ W62xVFdOqsxPH76e9Wz/Y2wv1Jqcb8lbn6YDJ1rVtXT7MXDgj1iDIrsM22TQkT4BGYmp t44AKThHAsPQpqmf10DDT7kyM1rtpnFqPVl+H6rGRNVVplpNxIGfEWXRloTp7ov6yWyJ AxME2Ep69E+OzHdbWA5kP+5FHSbIAd1knf80sJbzMQNoB+eYC/CW76qHcYVfZ5BTh/Ah L7Nw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=h77GDhpR95Zhu0PBKYr7Rwe6/YVmxr6nnCmKT65+ZSc=; b=Su+WaXcOqm7vkJJzHqkJcCHDUUwTHMI5JTsq9jA3dhXYw+Rp8pa7IYOBZEZTnzxA9B 78amlPDa9FG5njJkM+V2nNEqZVg/aDGpaLJjfvpLvOsAy+Ibjcqf0Gc61kQXbBzPFPh3 ezzq7043mgOnhudY68ebfGOuubQT1DnUkwf4N7ycHrjcEADxw/HpXIIkdLrSibfCB2QZ R1+GGC5SxfbHOV/Ez5V+5kmh2HMDPCnkGQDdECRO/cc2CvPr2odEbjKXCHCo1/vFDwig GjyKYzQCJHmksn5g1+q3Q/Q7j9n7nTxi8yWCDEjpwarVBG/lrOF5PrtGrcGYU+9yO5pq f1fg== X-Gm-Message-State: AG10YOTMFEXsuexUAZWMsgZF4d+Z41udUjBcEMeyCug2Q0gYW+NzsmS1Zfl+Br2lH2XDig== X-Received: by 10.60.220.230 with SMTP id pz6mr18929728oec.49.1454815280505; Sat, 06 Feb 2016 19:21:20 -0800 (PST) Received: from localhost.localdomain (mail.linux-iscsi.org. [67.23.28.174]) by smtp.gmail.com with ESMTPSA id e188sm8424803oih.29.2016.02.06.19.21.19 (version=TLS1 cipher=AES128-SHA bits=128/128); Sat, 06 Feb 2016 19:21:20 -0800 (PST) From: "Nicholas A. Bellinger" To: target-devel Cc: linux-scsi , Quinn Tran , Himanshu Madhani , Sagi Grimberg , Christoph Hellwig , Hannes Reinecke , Andy Grover , Mike Christie , Nicholas Bellinger Subject: [PATCH-v4 5/5] target: Fix race with SCF_SEND_DELAYED_TAS handling Date: Sun, 7 Feb 2016 03:18:02 +0000 Message-Id: <1454815082-15380-6-git-send-email-nab@daterainc.com> X-Mailer: git-send-email 1.7.2.5 In-Reply-To: <1454815082-15380-1-git-send-email-nab@daterainc.com> References: <1454815082-15380-1-git-send-email-nab@daterainc.com> Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org X-Spam-Status: No, score=-7.2 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Nicholas Bellinger This patch fixes a race between setting of SCF_SEND_DELAYED_TAS in transport_send_task_abort(), and check of the same bit in transport_check_aborted_status(). It adds a __transport_check_aborted_status() version that is used by target_execute_cmd() when se_cmd->t_state_lock is held, and a transport_check_aborted_status() wrapper for all other existing callers. Also, it handles the case where the check happens before transport_send_task_abort() gets called. For this, go ahead and set SCF_SEND_DELAYED_TAS early when necessary, and have transport_send_task_abort() send the abort. Cc: Quinn Tran Cc: Himanshu Madhani Cc: Sagi Grimberg Cc: Christoph Hellwig Cc: Hannes Reinecke Cc: Andy Grover Cc: Mike Christie Cc: stable@vger.kernel.org # 3.10+ Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_transport.c | 53 ++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 3441b15..2e0b23a 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1858,19 +1858,21 @@ static bool target_handle_task_attr(struct se_cmd *cmd) return true; } +static int __transport_check_aborted_status(struct se_cmd *, int); + void target_execute_cmd(struct se_cmd *cmd) { /* - * If the received CDB has aleady been aborted stop processing it here. - */ - if (transport_check_aborted_status(cmd, 1)) - return; - - /* * Determine if frontend context caller is requesting the stopping of * this command for frontend exceptions. + * + * If the received CDB has aleady been aborted stop processing it here. */ spin_lock_irq(&cmd->t_state_lock); + if (__transport_check_aborted_status(cmd, 1)) { + spin_unlock_irq(&cmd->t_state_lock); + return; + } if (cmd->transport_state & CMD_T_STOP) { pr_debug("%s:%d CMD_T_STOP for ITT: 0x%08llx\n", __func__, __LINE__, cmd->tag); @@ -2911,28 +2913,49 @@ transport_send_check_condition_and_sense(struct se_cmd *cmd, } EXPORT_SYMBOL(transport_send_check_condition_and_sense); -int transport_check_aborted_status(struct se_cmd *cmd, int send_status) +static int __transport_check_aborted_status(struct se_cmd *cmd, int send_status) + __releases(&cmd->t_state_lock) + __acquires(&cmd->t_state_lock) { + assert_spin_locked(&cmd->t_state_lock); + WARN_ON_ONCE(!irqs_disabled()); + if (!(cmd->transport_state & CMD_T_ABORTED)) return 0; - /* * If cmd has been aborted but either no status is to be sent or it has * already been sent, just return */ - if (!send_status || !(cmd->se_cmd_flags & SCF_SEND_DELAYED_TAS)) + if (!send_status || !(cmd->se_cmd_flags & SCF_SEND_DELAYED_TAS)) { + if (send_status) + cmd->se_cmd_flags |= SCF_SEND_DELAYED_TAS; return 1; + } - pr_debug("Sending delayed SAM_STAT_TASK_ABORTED status for CDB: 0x%02x ITT: 0x%08llx\n", - cmd->t_task_cdb[0], cmd->tag); + pr_debug("Sending delayed SAM_STAT_TASK_ABORTED status for CDB:" + " 0x%02x ITT: 0x%08llx\n", cmd->t_task_cdb[0], cmd->tag); cmd->se_cmd_flags &= ~SCF_SEND_DELAYED_TAS; cmd->scsi_status = SAM_STAT_TASK_ABORTED; trace_target_cmd_complete(cmd); + + spin_unlock_irq(&cmd->t_state_lock); cmd->se_tfo->queue_status(cmd); + spin_lock_irq(&cmd->t_state_lock); return 1; } + +int transport_check_aborted_status(struct se_cmd *cmd, int send_status) +{ + int ret; + + spin_lock_irq(&cmd->t_state_lock); + ret = __transport_check_aborted_status(cmd, send_status); + spin_unlock_irq(&cmd->t_state_lock); + + return ret; +} EXPORT_SYMBOL(transport_check_aborted_status); void transport_send_task_abort(struct se_cmd *cmd) @@ -2954,11 +2977,17 @@ void transport_send_task_abort(struct se_cmd *cmd) */ if (cmd->data_direction == DMA_TO_DEVICE) { if (cmd->se_tfo->write_pending_status(cmd) != 0) { - cmd->transport_state |= CMD_T_ABORTED; + spin_lock_irqsave(&cmd->t_state_lock, flags); + if (cmd->se_cmd_flags & SCF_SEND_DELAYED_TAS) { + spin_unlock_irqrestore(&cmd->t_state_lock, flags); + goto send_abort; + } cmd->se_cmd_flags |= SCF_SEND_DELAYED_TAS; + spin_unlock_irqrestore(&cmd->t_state_lock, flags); return; } } +send_abort: cmd->scsi_status = SAM_STAT_TASK_ABORTED; transport_lun_remove_cmd(cmd);