From patchwork Fri Mar 11 17:57:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Jeffery X-Patchwork-Id: 12778488 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CD743C433F5 for ; Fri, 11 Mar 2022 17:57:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244623AbiCKR6q (ORCPT ); Fri, 11 Mar 2022 12:58:46 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47958 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1350458AbiCKR6p (ORCPT ); Fri, 11 Mar 2022 12:58:45 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id C101A8565B for ; Fri, 11 Mar 2022 09:57:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1647021459; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Nh9bTUIUacOod+DLliFISU6Ql6jfYfcDEklqeiHOHCg=; b=iVmsx9iI3YckEltHIGCnD3amA9ozri1/1IzLtfJ/6+l6bykFEsCBlwd1jwJ9bPpIgA8FWW RGbQx6/TcRJ/QqgJo59Ed6PUXx6a4lHzskGzfxRhv5vYzyENLoOcUZMzjxlUSPUg04NrTw ChUT95QUapdFjjOX+NS3yh9D/q13/IY= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-48-QmyS2XJYMOawwSrBd2dxkg-1; Fri, 11 Mar 2022 12:57:38 -0500 X-MC-Unique: QmyS2XJYMOawwSrBd2dxkg-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id CDDB71091DA3; Fri, 11 Mar 2022 17:57:37 +0000 (UTC) Received: from gluttony.redhat.com (unknown [10.22.19.22]) by smtp.corp.redhat.com (Postfix) with ESMTP id 325A980685; Fri, 11 Mar 2022 17:57:37 +0000 (UTC) From: David Jeffery To: linux-rdma@vger.kernel.org Cc: target-devel@vger.kernel.org, Sagi Grimberg , Max Gurtovoy , Laurence Oberman , David Jeffery Subject: [PATCH 1/2] isert: support for unsolicited NOPIN with no response. Date: Fri, 11 Mar 2022 12:57:12 -0500 Message-Id: <20220311175713.2344960-2-djeffery@redhat.com> In-Reply-To: <20220311175713.2344960-1-djeffery@redhat.com> References: <20220311175713.2344960-1-djeffery@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Precedence: bulk List-ID: X-Mailing-List: target-devel@vger.kernel.org The isert module has only supported sending a NOPIN as a response to a NOPOUT. In order to be able to use an unsolicited NOPIN to inform the initiator of max_cmd_sn changes, isert needs to be able to send a NOPIN as needed. Signed-off-by: David Jeffery Tested-by: Laurence Oberman --- drivers/infiniband/ulp/isert/ib_isert.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index 636d590765f9..b8390ad762eb 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c @@ -1469,6 +1469,7 @@ isert_put_cmd(struct isert_cmd *isert_cmd, bool comp_err) break; case ISCSI_OP_REJECT: case ISCSI_OP_NOOP_OUT: + case ISCSI_OP_NOOP_IN: case ISCSI_OP_TEXT: hdr = (struct iscsi_text_rsp *)&isert_cmd->tx_desc.iscsi_header; /* If the continue bit is on, keep the command alive */ @@ -1858,7 +1859,14 @@ isert_put_nopin(struct iscsi_cmd *cmd, struct iscsi_conn *conn, isert_dbg("conn %p Posting NOPIN Response\n", isert_conn); - return isert_post_response(isert_conn, isert_cmd); + if (nopout_response) + return isert_post_response(isert_conn, isert_cmd); + + /* pointer init since didn't go through isert_allocate_cmd */ + isert_cmd->conn = isert_conn; + isert_cmd->iscsi_cmd = cmd; + + return ib_post_send(isert_conn->qp, send_wr, NULL); } static int @@ -2159,6 +2167,7 @@ isert_immediate_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state) spin_unlock_bh(&conn->cmd_lock); isert_put_cmd(isert_cmd, true); break; + case ISTATE_SEND_NOPIN_NO_RESPONSE: case ISTATE_SEND_NOPIN_WANT_RESPONSE: ret = isert_put_nopin(cmd, conn, false); break; From patchwork Fri Mar 11 17:57:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Jeffery X-Patchwork-Id: 12778489 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BEA13C43219 for ; Fri, 11 Mar 2022 17:57:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1350472AbiCKR6x (ORCPT ); Fri, 11 Mar 2022 12:58:53 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48302 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1350493AbiCKR6x (ORCPT ); Fri, 11 Mar 2022 12:58:53 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 4B7C547574 for ; Fri, 11 Mar 2022 09:57:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1647021467; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=DVUBQ8FL4Hl/Ia3M5AmEcx8HiUggiZTeBF+BAgzy4rs=; b=doZtnaKnUI3DAnAQxq2Y7H34EeQi7GowP7xy235gelUvYOSy2IpPCK+sOTC0zq6HHuaRIb OQFrh7P4LMjccv6c7kisHyrYVpjUCS28/af+JPO71aKOtraJUoMkchrU2MvfoNIajBaWcy rHv3vCofGyJ7ojNlnTaRNZnwmVzTAno= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-582-RMK7YtYSNEaDzeJ58SHfMQ-1; Fri, 11 Mar 2022 12:57:44 -0500 X-MC-Unique: RMK7YtYSNEaDzeJ58SHfMQ-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 573DE1006AA6; Fri, 11 Mar 2022 17:57:43 +0000 (UTC) Received: from gluttony.redhat.com (unknown [10.22.19.22]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6EB68825ED; Fri, 11 Mar 2022 17:57:42 +0000 (UTC) From: David Jeffery To: linux-rdma@vger.kernel.org Cc: target-devel@vger.kernel.org, Sagi Grimberg , Max Gurtovoy , Laurence Oberman , David Jeffery Subject: [PATCH 2/2] iscsit: increment max_cmd_sn for isert on command release Date: Fri, 11 Mar 2022 12:57:13 -0500 Message-Id: <20220311175713.2344960-3-djeffery@redhat.com> In-Reply-To: <20220311175713.2344960-1-djeffery@redhat.com> References: <20220311175713.2344960-1-djeffery@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Precedence: bulk List-ID: X-Mailing-List: target-devel@vger.kernel.org iscsit with isert currently can suffer a rare deadlock due to how rdma delays the release of an iscsi_cmd. Because max_cmd_sn is increased and sent to the initiator before the last rdma completes, iscsit can end up in a state where all iscsi_cmd structs are active even though the number is more than double the iscsi window. Once out of iscsi_cmd structs, isert then deadlocks trying to receive new commands. It waits for an iscsi_cmd to become available, but the wait also blocks processing for receiving completion events which would release an iscsi_cmd waiting on rdma to finish. So neither can advance. This patch avoids the deadlock state by delaying the increase to max_cmd_sn until an iscsi_cmd is released. In this way, the number of iscsi_cmd structs in use for SCSI commands will be limited to the iscsi window size. An unsolicited NOPIN is then used to inform the initiator of changes to max_cmd_sn should the difference between the internal value and the value the initiator has been informed of grow too large (currently set to half the window). Signed-off-by: David Jeffery Tested-by: Laurence Oberman --- drivers/target/iscsi/iscsi_target.c | 18 +++++------ drivers/target/iscsi/iscsi_target_device.c | 35 +++++++++++++++++++++- drivers/target/iscsi/iscsi_target_login.c | 1 + drivers/target/iscsi/iscsi_target_util.c | 5 +++- drivers/target/iscsi/iscsi_target_util.h | 1 + include/target/iscsi/iscsi_target_core.h | 8 +++++ include/target/iscsi/iscsi_transport.h | 1 + 7 files changed, 58 insertions(+), 11 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 2c54c5d8412d..f67e909c5546 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -2757,7 +2757,7 @@ static int iscsit_send_conn_drop_async_message( cmd->stat_sn = conn->stat_sn++; hdr->statsn = cpu_to_be32(cmd->stat_sn); hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); - hdr->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn)); + iscsit_set_max_cmdsn(hdr, conn); hdr->async_event = ISCSI_ASYNC_MSG_DROPPING_CONNECTION; hdr->param1 = cpu_to_be16(cmd->logout_cid); hdr->param2 = cpu_to_be16(conn->sess->sess_ops->DefaultTime2Wait); @@ -2815,7 +2815,7 @@ iscsit_build_datain_pdu(struct iscsi_cmd *cmd, struct iscsi_conn *conn, hdr->statsn = cpu_to_be32(0xFFFFFFFF); hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); - hdr->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn)); + iscsit_set_max_cmdsn(hdr, conn); hdr->datasn = cpu_to_be32(datain->data_sn); hdr->offset = cpu_to_be32(datain->offset); @@ -2970,7 +2970,7 @@ iscsit_build_logout_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn, iscsit_increment_maxcmdsn(cmd, conn->sess); hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); - hdr->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn)); + iscsit_set_max_cmdsn(hdr, conn); pr_debug("Built Logout Response ITT: 0x%08x StatSN:" " 0x%08x Response: 0x%02x CID: %hu on CID: %hu\n", @@ -3013,7 +3013,7 @@ iscsit_build_nopin_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn, iscsit_increment_maxcmdsn(cmd, conn->sess); hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); - hdr->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn)); + iscsit_set_max_cmdsn(hdr, conn); pr_debug("Built NOPIN %s Response ITT: 0x%08x, TTT: 0x%08x," " StatSN: 0x%08x, Length %u\n", (nopout_response) ? @@ -3094,7 +3094,7 @@ static int iscsit_send_r2t( hdr->ttt = cpu_to_be32(r2t->targ_xfer_tag); hdr->statsn = cpu_to_be32(conn->stat_sn); hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); - hdr->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn)); + iscsit_set_max_cmdsn(hdr, conn); hdr->r2tsn = cpu_to_be32(r2t->r2t_sn); hdr->data_offset = cpu_to_be32(r2t->offset); hdr->data_length = cpu_to_be32(r2t->xfer_len); @@ -3234,7 +3234,7 @@ void iscsit_build_rsp_pdu(struct iscsi_cmd *cmd, struct iscsi_conn *conn, iscsit_increment_maxcmdsn(cmd, conn->sess); hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); - hdr->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn)); + iscsit_set_max_cmdsn(hdr, conn); pr_debug("Built SCSI Response, ITT: 0x%08x, StatSN: 0x%08x," " Response: 0x%02x, SAM Status: 0x%02x, CID: %hu\n", @@ -3314,7 +3314,7 @@ iscsit_build_task_mgt_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn, iscsit_increment_maxcmdsn(cmd, conn->sess); hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); - hdr->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn)); + iscsit_set_max_cmdsn(hdr, conn); pr_debug("Built Task Management Response ITT: 0x%08x," " StatSN: 0x%08x, Response: 0x%02x, CID: %hu\n", @@ -3522,7 +3522,7 @@ iscsit_build_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn, */ cmd->maxcmdsn_inc = 0; hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); - hdr->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn)); + iscsit_set_max_cmdsn(hdr, conn); pr_debug("Built Text Response: ITT: 0x%08x, TTT: 0x%08x, StatSN: 0x%08x," " Length: %u, CID: %hu F: %d C: %d\n", cmd->init_task_tag, @@ -3563,7 +3563,7 @@ iscsit_build_reject(struct iscsi_cmd *cmd, struct iscsi_conn *conn, cmd->stat_sn = conn->stat_sn++; hdr->statsn = cpu_to_be32(cmd->stat_sn); hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); - hdr->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn)); + iscsit_set_max_cmdsn(hdr, conn); } EXPORT_SYMBOL(iscsit_build_reject); diff --git a/drivers/target/iscsi/iscsi_target_device.c b/drivers/target/iscsi/iscsi_target_device.c index 8bf36ec86e3f..09b23c133dca 100644 --- a/drivers/target/iscsi/iscsi_target_device.c +++ b/drivers/target/iscsi/iscsi_target_device.c @@ -13,10 +13,14 @@ #include #include +#include #include "iscsi_target_device.h" #include "iscsi_target_tpg.h" #include "iscsi_target_util.h" +#define iscsit_needs_delayed_maxcmdsn_increment(conn) \ + (conn->conn_transport->transport_type == ISCSI_INFINIBAND) + void iscsit_determine_maxcmdsn(struct iscsi_session *sess) { struct se_node_acl *se_nacl; @@ -42,7 +46,7 @@ void iscsit_determine_maxcmdsn(struct iscsi_session *sess) atomic_add(se_nacl->queue_depth - 1, &sess->max_cmd_sn); } -void iscsit_increment_maxcmdsn(struct iscsi_cmd *cmd, struct iscsi_session *sess) +void __iscsit_increment_maxcmdsn(struct iscsi_cmd *cmd, struct iscsi_session *sess) { u32 max_cmd_sn; @@ -54,4 +58,33 @@ void iscsit_increment_maxcmdsn(struct iscsi_cmd *cmd, struct iscsi_session *sess max_cmd_sn = atomic_inc_return(&sess->max_cmd_sn); pr_debug("Updated MaxCmdSN to 0x%08x\n", max_cmd_sn); } + +void iscsit_increment_maxcmdsn(struct iscsi_cmd *cmd, struct iscsi_session *sess) +{ + if (!iscsit_needs_delayed_maxcmdsn_increment(cmd->conn)) + __iscsit_increment_maxcmdsn(cmd, sess); +} EXPORT_SYMBOL(iscsit_increment_maxcmdsn); + + + +void iscsit_increment_maxcmdsn_on_release(struct iscsi_cmd *cmd, struct iscsi_session *sess) +{ + if (iscsit_needs_delayed_maxcmdsn_increment(cmd->conn)) { + __iscsit_increment_maxcmdsn(cmd, sess); + if ((u32)atomic_read(&sess->max_cmd_sn) - + READ_ONCE(sess->last_max_cmd_sn) + > sess->cmdsn_window / 2) { + /* + * Prevent nopin races if one may be needed by using + * a lock and rechecking after grabbing the lock + */ + spin_lock_bh(&cmd->conn->nopin_timer_lock); + if ((u32)atomic_read(&sess->max_cmd_sn) - + READ_ONCE(sess->last_max_cmd_sn) + > sess->cmdsn_window / 2) + iscsit_add_nopin(cmd->conn, 0); + spin_unlock_bh(&cmd->conn->nopin_timer_lock); + } + } +} diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index 1a9c50401bdb..d97c3792f140 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c @@ -307,6 +307,7 @@ static int iscsi_login_zero_tsih_s1( * Initiator Node's ACL once the login has been successfully completed. */ atomic_set(&sess->max_cmd_sn, be32_to_cpu(pdu->cmdsn)); + sess->last_max_cmd_sn = be32_to_cpu(pdu->cmdsn); sess->sess_ops = kzalloc(sizeof(struct iscsi_sess_ops), GFP_KERNEL); if (!sess->sess_ops) { diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index 6dd5810e2af1..18685b23e1d0 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c @@ -708,6 +708,8 @@ void iscsit_release_cmd(struct iscsi_cmd *cmd) BUG_ON(!sess || !sess->se_sess); + iscsit_increment_maxcmdsn_on_release(cmd, sess); + kfree(cmd->buf_ptr); kfree(cmd->pdu_list); kfree(cmd->seq_list); @@ -867,7 +869,7 @@ void iscsit_inc_conn_usage_count(struct iscsi_conn *conn) spin_unlock_bh(&conn->conn_usage_lock); } -static int iscsit_add_nopin(struct iscsi_conn *conn, int want_response) +int iscsit_add_nopin(struct iscsi_conn *conn, int want_response) { u8 state; struct iscsi_cmd *cmd; @@ -877,6 +879,7 @@ static int iscsit_add_nopin(struct iscsi_conn *conn, int want_response) return -1; cmd->iscsi_opcode = ISCSI_OP_NOOP_IN; + cmd->immediate_cmd = 1; state = (want_response) ? ISTATE_SEND_NOPIN_WANT_RESPONSE : ISTATE_SEND_NOPIN_NO_RESPONSE; cmd->init_task_tag = RESERVED_ITT; diff --git a/drivers/target/iscsi/iscsi_target_util.h b/drivers/target/iscsi/iscsi_target_util.h index 8ee1c133a9b7..c4474943f310 100644 --- a/drivers/target/iscsi/iscsi_target_util.h +++ b/drivers/target/iscsi/iscsi_target_util.h @@ -68,5 +68,6 @@ extern int tx_data(struct iscsi_conn *, struct kvec *, int, int); extern void iscsit_collect_login_stats(struct iscsi_conn *, u8, u8); extern struct iscsi_tiqn *iscsit_snmp_get_tiqn(struct iscsi_conn *); extern void iscsit_fill_cxn_timeout_err_stats(struct iscsi_session *); +extern int iscsit_add_nopin(struct iscsi_conn *, int); #endif /*** ISCSI_TARGET_UTIL_H ***/ diff --git a/include/target/iscsi/iscsi_target_core.h b/include/target/iscsi/iscsi_target_core.h index 1eccb2ac7d02..2983d3798432 100644 --- a/include/target/iscsi/iscsi_target_core.h +++ b/include/target/iscsi/iscsi_target_core.h @@ -643,6 +643,7 @@ struct iscsi_session { u32 exp_cmd_sn; /* session wide counter: maximum allowed command sequence number */ atomic_t max_cmd_sn; + u32 last_max_cmd_sn; struct list_head sess_ooo_cmdsn_list; /* LIO specific session ID */ @@ -923,4 +924,11 @@ static inline void iscsit_thread_check_cpumask( */ set_cpus_allowed_ptr(p, conn->conn_cpumask); } + +#define iscsit_set_max_cmdsn(hdr, conn) \ +{ \ + u32 max_cmdsn = (u32) atomic_read(&conn->sess->max_cmd_sn); \ + hdr->max_cmdsn = cpu_to_be32(max_cmdsn); \ + conn->sess->last_max_cmd_sn = max_cmdsn; \ +} #endif /* ISCSI_TARGET_CORE_H */ diff --git a/include/target/iscsi/iscsi_transport.h b/include/target/iscsi/iscsi_transport.h index b8feba7ffebc..878733ca584c 100644 --- a/include/target/iscsi/iscsi_transport.h +++ b/include/target/iscsi/iscsi_transport.h @@ -106,6 +106,7 @@ extern int iscsit_response_queue(struct iscsi_conn *, struct iscsi_cmd *, int); * From iscsi_target_device.c */ extern void iscsit_increment_maxcmdsn(struct iscsi_cmd *, struct iscsi_session *); +extern void iscsit_increment_maxcmdsn_on_release(struct iscsi_cmd *, struct iscsi_session *); /* * From iscsi_target_erl0.c */