Received: by 2002:a25:1506:0:0:0:0:0 with SMTP id 6csp1865698ybv; Thu, 6 Feb 2020 11:12:46 -0800 (PST) X-Google-Smtp-Source: APXvYqx+z0VE3Lm2OEz2O34/VFqraY4RVLh9tAv4cBVrC1xUS0qnoI+O6ylYp1aTLV3/KEJ1hyNI X-Received: by 2002:aca:4e02:: with SMTP id c2mr8327822oib.142.1581016366077; Thu, 06 Feb 2020 11:12:46 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1581016366; cv=none; d=google.com; s=arc-20160816; b=mkKA6Lpc7x1c0P5ZUOD2kKSGPQuK9G8V5jQITBV9AmzUtMQfwrVt9ftFqdiQ0GmmqW XpYQeaeYgh2y3aLeTu1etgLMfUtkp/XiA1SeckysF2NbWdh9/dQNf46oVPEYoOImcDM4 MWE2OHYrNWexEagleGNXOqYoJw34dc6T+D/8oGB5HsoZFMQYNQJJ7o0Eiu0p/nWYzP+m XnkzlmG0m7qGX0Lun8vb2mGcQqsE+BFIsnUMHav8BGIX35pojpMxZekdkKT8JebSQqEH qBOQu20a15wfu6A5drMV/xkGS75kYj+U3XWTROyo+rPttY3gApRRmfEcHLc8USGCtlGE kbog== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from; bh=KEyEtUAybGQ2oGa+j3AkY7QEjEZhF+0YTJ5+uYG824o=; b=JXXH9BqzlvAK3WQQZyXcv6q0FgiXeOIPvjILbW2FYkHCRFV6iFoBc+ETNTiifVdM+U BwBWA/gcWcF9vUGSIoSnqpGN3XdeCIFkMeqJmUDBGiNxpHYpFtltgHbpy9+mnstCdPpx +4OZONAJBkCrAn1+/DzoENV/HWl9Tt6rKgkwDBw5LLUMapmYU0j2oWYUkEr6ac9yD9qI tLvfKF4uVxbr/VbaZg+9c3EHMIQ8PsXcVzyAWU06jjucMkMvj0/mZTel4r9qTobEm8mP fg0PCAZGPVsg1zWp1PlQZkWUhOAYOwb3wWueP+uqK74jghqN/XK3UK0DnKM2iBFy3zub WTSg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=collabora.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id m19si268818otq.40.2020.02.06.11.12.33; Thu, 06 Feb 2020 11:12:46 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=collabora.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727940AbgBFTLb (ORCPT + 99 others); Thu, 6 Feb 2020 14:11:31 -0500 Received: from bhuna.collabora.co.uk ([46.235.227.227]:43472 "EHLO bhuna.collabora.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727479AbgBFTLb (ORCPT ); Thu, 6 Feb 2020 14:11:31 -0500 Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: tonyk) with ESMTPSA id BC0AA295836 From: =?UTF-8?q?Andr=C3=A9=20Almeida?= To: open-iscsi@googlegroups.com, linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org Cc: krisman@collabora.com, lduncan@suse.com, cleech@redhat.com, jejb@linux.ibm.com, martin.petersen@oracle.com, kernel@collabora.com, Frank Mayhar , Khazhismel Kumykov , =?UTF-8?q?Andr=C3=A9=20Almeida?= Subject: [PATCH v2] iscsi: Add support for asynchronous iSCSI session destruction Date: Thu, 6 Feb 2020 16:09:03 -0300 Message-Id: <20200206190903.104089-1-andrealmeid@collabora.com> X-Mailer: git-send-email 2.25.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Frank Mayhar iSCSI session destruction can be arbitrarily slow, since it might require network operations and serialization inside the scsi layer. This patch adds a new user event to trigger the destruction work asynchronously, releasing the rx_queue_mutex as soon as the operation is queued and before it is performed. This change allow other operations to run in other sessions in the meantime, removing one of the major iSCSI bottlenecks for us. To prevent the session from being used after the destruction request, we remove it immediately from the sesslist. This simplifies the locking required during the asynchronous removal. Reviewed-by: Lee Duncan Co-developed-by: Khazhismel Kumykov Signed-off-by: Khazhismel Kumykov Co-developed-by: Gabriel Krisman Bertazi Signed-off-by: Gabriel Krisman Bertazi Signed-off-by: Frank Mayhar Signed-off-by: André Almeida --- This patch depends on ("iscsi: Don't destroy session if there are outstanding connections"), which can be found at Martin tree at 5.7/scsi-queue Changes from v1: - Return a ENONMEM if creation of workqueue failed. --- drivers/scsi/scsi_transport_iscsi.c | 38 +++++++++++++++++++++++++++++ include/scsi/iscsi_if.h | 1 + include/scsi/scsi_transport_iscsi.h | 1 + 3 files changed, 40 insertions(+) diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index f3f0ecdb09a2..17a45716a0fe 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -95,6 +95,8 @@ static DECLARE_WORK(stop_conn_work, stop_conn_work_fn); static atomic_t iscsi_session_nr; /* sysfs session id for next new session */ static struct workqueue_struct *iscsi_eh_timer_workq; +static struct workqueue_struct *iscsi_destroy_workq; + static DEFINE_IDA(iscsi_sess_ida); /* * list of registered transports and lock that must @@ -1615,6 +1617,7 @@ static struct sock *nls; static DEFINE_MUTEX(rx_queue_mutex); static LIST_HEAD(sesslist); +static LIST_HEAD(sessdestroylist); static DEFINE_SPINLOCK(sesslock); static LIST_HEAD(connlist); static LIST_HEAD(connlist_err); @@ -2035,6 +2038,14 @@ static void __iscsi_unbind_session(struct work_struct *work) ISCSI_DBG_TRANS_SESSION(session, "Completed target removal\n"); } +static void __iscsi_destroy_session(struct work_struct *work) +{ + struct iscsi_cls_session *session = + container_of(work, struct iscsi_cls_session, destroy_work); + + session->transport->destroy_session(session); +} + struct iscsi_cls_session * iscsi_alloc_session(struct Scsi_Host *shost, struct iscsi_transport *transport, int dd_size) @@ -2057,6 +2068,7 @@ iscsi_alloc_session(struct Scsi_Host *shost, struct iscsi_transport *transport, INIT_WORK(&session->block_work, __iscsi_block_session); INIT_WORK(&session->unbind_work, __iscsi_unbind_session); INIT_WORK(&session->scan_work, iscsi_scan_session); + INIT_WORK(&session->destroy_work, __iscsi_destroy_session); spin_lock_init(&session->lock); /* this is released in the dev's release function */ @@ -3631,6 +3643,23 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group) else transport->destroy_session(session); break; + case ISCSI_UEVENT_DESTROY_SESSION_ASYNC: + session = iscsi_session_lookup(ev->u.d_session.sid); + if (!session) + err = -EINVAL; + else if (iscsi_session_has_conns(ev->u.d_session.sid)) + err = -EBUSY; + else { + unsigned long flags; + + /* Prevent this session from being found again */ + spin_lock_irqsave(&sesslock, flags); + list_move(&session->sess_list, &sessdestroylist); + spin_unlock_irqrestore(&sesslock, flags); + + queue_work(iscsi_destroy_workq, &session->destroy_work); + } + break; case ISCSI_UEVENT_UNBIND_SESSION: session = iscsi_session_lookup(ev->u.d_session.sid); if (session) @@ -4676,8 +4705,16 @@ static __init int iscsi_transport_init(void) goto release_nls; } + iscsi_destroy_workq = create_singlethread_workqueue("iscsi_destroy"); + if (!iscsi_destroy_workq) { + err = -ENOMEM; + goto destroy_wq; + } + return 0; +destroy_wq: + destroy_workqueue(iscsi_eh_timer_workq); release_nls: netlink_kernel_release(nls); unregister_flashnode_bus: @@ -4699,6 +4736,7 @@ static __init int iscsi_transport_init(void) static void __exit iscsi_transport_exit(void) { + destroy_workqueue(iscsi_destroy_workq); destroy_workqueue(iscsi_eh_timer_workq); netlink_kernel_release(nls); bus_unregister(&iscsi_flashnode_bus); diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h index 92b11c7e0b4f..deacaee53e61 100644 --- a/include/scsi/iscsi_if.h +++ b/include/scsi/iscsi_if.h @@ -60,6 +60,7 @@ enum iscsi_uevent_e { ISCSI_UEVENT_LOGOUT_FLASHNODE_SID = UEVENT_BASE + 30, ISCSI_UEVENT_SET_CHAP = UEVENT_BASE + 31, ISCSI_UEVENT_GET_HOST_STATS = UEVENT_BASE + 32, + ISCSI_UEVENT_DESTROY_SESSION_ASYNC = UEVENT_BASE + 33, /* up events */ ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1, diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index 2129dc9e2dec..fa8814245796 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -226,6 +226,7 @@ struct iscsi_cls_session { struct work_struct unblock_work; struct work_struct scan_work; struct work_struct unbind_work; + struct work_struct destroy_work; /* recovery fields */ int recovery_tmo; -- 2.25.0