From: Chris Leech <cleech@redhat.com>
To: Lee Duncan <lduncan@suse.com>,
linux-scsi@vger.kernel.org, open-iscsi@googlegroups.com,
netdev@vger.kernel.org
Cc: Chris Leech <cleech@redhat.com>
Subject: [PATCH 10/11] iscsi: make session and connection lists per-net
Date: Sat, 6 May 2023 16:29:29 -0700 [thread overview]
Message-ID: <20230506232930.195451-11-cleech@redhat.com> (raw)
In-Reply-To: <20230506232930.195451-1-cleech@redhat.com>
Eliminate the comparisions on list lookups, and it will make it easier
to shut down session on net namespace exit in the next patch.
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Chris Leech <cleech@redhat.com>
---
drivers/scsi/scsi_transport_iscsi.c | 104 ++++++++++++++++------------
1 file changed, 61 insertions(+), 43 deletions(-)
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index cd3228293a64..15d28186996d 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -1755,17 +1755,16 @@ static DECLARE_TRANSPORT_CLASS_NS(iscsi_connection_class,
struct iscsi_net {
struct sock *nls;
+ spinlock_t sesslock;
+ struct list_head sesslist;
+ spinlock_t connlock;
+ struct list_head connlist;
+ struct list_head connlist_err;
};
static int iscsi_net_id __read_mostly;
static DEFINE_MUTEX(rx_queue_mutex);
-static LIST_HEAD(sesslist);
-static DEFINE_SPINLOCK(sesslock);
-static LIST_HEAD(connlist);
-static LIST_HEAD(connlist_err);
-static DEFINE_SPINLOCK(connlock);
-
static uint32_t iscsi_conn_get_sid(struct iscsi_cls_conn *conn)
{
struct iscsi_cls_session *sess = iscsi_dev_to_session(conn->dev.parent);
@@ -1780,19 +1779,18 @@ static struct iscsi_cls_session *iscsi_session_lookup(struct net *net,
{
unsigned long flags;
struct iscsi_cls_session *sess;
- struct net *ns;
+ struct iscsi_net *isn;
- spin_lock_irqsave(&sesslock, flags);
- list_for_each_entry(sess, &sesslist, sess_list) {
+ isn = net_generic(net, iscsi_net_id);
+
+ spin_lock_irqsave(&isn->sesslock, flags);
+ list_for_each_entry(sess, &isn->sesslist, sess_list) {
if (sess->sid == sid) {
- ns = iscsi_sess_net(sess);
- if (ns != net)
- continue;
- spin_unlock_irqrestore(&sesslock, flags);
+ spin_unlock_irqrestore(&isn->sesslock, flags);
return sess;
}
}
- spin_unlock_irqrestore(&sesslock, flags);
+ spin_unlock_irqrestore(&isn->sesslock, flags);
return NULL;
}
@@ -1804,19 +1802,18 @@ static struct iscsi_cls_conn *iscsi_conn_lookup(struct net *net, uint32_t sid,
{
unsigned long flags;
struct iscsi_cls_conn *conn;
- struct net *ns;
+ struct iscsi_net *isn;
- spin_lock_irqsave(&connlock, flags);
- list_for_each_entry(conn, &connlist, conn_list) {
+ isn = net_generic(net, iscsi_net_id);
+
+ spin_lock_irqsave(&isn->connlock, flags);
+ list_for_each_entry(conn, &isn->connlist, conn_list) {
if ((conn->cid == cid) && (iscsi_conn_get_sid(conn) == sid)) {
- ns = iscsi_conn_net(conn);
- if (ns != net)
- continue;
- spin_unlock_irqrestore(&connlock, flags);
+ spin_unlock_irqrestore(&isn->connlock, flags);
return conn;
}
}
- spin_unlock_irqrestore(&connlock, flags);
+ spin_unlock_irqrestore(&isn->connlock, flags);
return NULL;
}
@@ -2228,6 +2225,9 @@ EXPORT_SYMBOL_GPL(iscsi_alloc_session);
int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id)
{
struct Scsi_Host *shost = iscsi_session_to_shost(session);
+ struct iscsi_cls_host *ihost = shost->shost_data;
+ struct net *net = iscsi_host_net(ihost);
+ struct iscsi_net *isn = net_generic(net, iscsi_net_id);
unsigned long flags;
int id = 0;
int err;
@@ -2271,9 +2271,9 @@ int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id)
goto release_dev;
}
- spin_lock_irqsave(&sesslock, flags);
- list_add(&session->sess_list, &sesslist);
- spin_unlock_irqrestore(&sesslock, flags);
+ spin_lock_irqsave(&isn->sesslock, flags);
+ list_add(&session->sess_list, &isn->sesslist);
+ spin_unlock_irqrestore(&isn->sesslock, flags);
iscsi_session_event(session, ISCSI_KEVENT_CREATE_SESSION);
ISCSI_DBG_TRANS_SESSION(session, "Completed session adding\n");
@@ -2343,15 +2343,17 @@ static int iscsi_iter_destroy_conn_fn(struct device *dev, void *data)
void iscsi_remove_session(struct iscsi_cls_session *session)
{
+ struct net *net = iscsi_sess_net(session);
+ struct iscsi_net *isn = net_generic(net, iscsi_net_id);
unsigned long flags;
int err;
ISCSI_DBG_TRANS_SESSION(session, "Removing session\n");
- spin_lock_irqsave(&sesslock, flags);
+ spin_lock_irqsave(&isn->sesslock, flags);
if (!list_empty(&session->sess_list))
list_del(&session->sess_list);
- spin_unlock_irqrestore(&sesslock, flags);
+ spin_unlock_irqrestore(&isn->sesslock, flags);
if (!cancel_work_sync(&session->block_work))
cancel_delayed_work_sync(&session->recovery_work);
@@ -2562,20 +2564,22 @@ static int iscsi_iter_force_destroy_conn_fn(struct device *dev, void *data)
void iscsi_force_destroy_session(struct iscsi_cls_session *session)
{
struct iscsi_transport *transport = session->transport;
+ struct net *net = iscsi_sess_net(session);
+ struct iscsi_net *isn = net_generic(net, iscsi_net_id);
unsigned long flags;
WARN_ON_ONCE(system_state == SYSTEM_RUNNING);
- spin_lock_irqsave(&sesslock, flags);
+ spin_lock_irqsave(&isn->sesslock, flags);
if (list_empty(&session->sess_list)) {
- spin_unlock_irqrestore(&sesslock, flags);
+ spin_unlock_irqrestore(&isn->sesslock, flags);
/*
* Conn/ep is already freed. Session is being torn down via
* async path. For shutdown we don't care about it so return.
*/
return;
}
- spin_unlock_irqrestore(&sesslock, flags);
+ spin_unlock_irqrestore(&isn->sesslock, flags);
device_for_each_child(&session->dev, NULL,
iscsi_iter_force_destroy_conn_fn);
@@ -2646,6 +2650,8 @@ int iscsi_add_conn(struct iscsi_cls_conn *conn)
int err;
unsigned long flags;
struct iscsi_cls_session *session = iscsi_dev_to_session(conn->dev.parent);
+ struct net *net = iscsi_sess_net(session);
+ struct iscsi_net *isn = net_generic(net, iscsi_net_id);
err = device_add(&conn->dev);
if (err) {
@@ -2661,9 +2667,9 @@ int iscsi_add_conn(struct iscsi_cls_conn *conn)
return err;
}
- spin_lock_irqsave(&connlock, flags);
- list_add(&conn->conn_list, &connlist);
- spin_unlock_irqrestore(&connlock, flags);
+ spin_lock_irqsave(&isn->connlock, flags);
+ list_add(&conn->conn_list, &isn->connlist);
+ spin_unlock_irqrestore(&isn->connlock, flags);
return 0;
}
@@ -2678,11 +2684,14 @@ EXPORT_SYMBOL_GPL(iscsi_add_conn);
*/
void iscsi_remove_conn(struct iscsi_cls_conn *conn)
{
+ struct net *net = iscsi_conn_net(conn);
+ struct iscsi_net *isn = net_generic(net, iscsi_net_id);
+
unsigned long flags;
- spin_lock_irqsave(&connlock, flags);
+ spin_lock_irqsave(&isn->connlock, flags);
list_del(&conn->conn_list);
- spin_unlock_irqrestore(&connlock, flags);
+ spin_unlock_irqrestore(&isn->connlock, flags);
transport_unregister_device(&conn->dev);
device_del(&conn->dev);
@@ -3466,20 +3475,21 @@ iscsi_set_path(struct net *net, struct iscsi_transport *transport,
return err;
}
-static int iscsi_session_has_conns(int sid)
+static int iscsi_session_has_conns(struct net *net, int sid)
{
+ struct iscsi_net *isn = net_generic(net, iscsi_net_id);
struct iscsi_cls_conn *conn;
unsigned long flags;
int found = 0;
- spin_lock_irqsave(&connlock, flags);
- list_for_each_entry(conn, &connlist, conn_list) {
+ spin_lock_irqsave(&isn->connlock, flags);
+ list_for_each_entry(conn, &isn->connlist, conn_list) {
if (iscsi_conn_get_sid(conn) == sid) {
found = 1;
break;
}
}
- spin_unlock_irqrestore(&connlock, flags);
+ spin_unlock_irqrestore(&isn->connlock, flags);
return found;
}
@@ -4192,7 +4202,7 @@ iscsi_if_recv_msg(struct net *net, struct sk_buff *skb,
session = iscsi_session_lookup(net, ev->u.d_session.sid);
if (!session)
err = -EINVAL;
- else if (iscsi_session_has_conns(ev->u.d_session.sid))
+ else if (iscsi_session_has_conns(net, ev->u.d_session.sid))
err = -EBUSY;
else
transport->destroy_session(session);
@@ -4201,15 +4211,16 @@ iscsi_if_recv_msg(struct net *net, struct sk_buff *skb,
session = iscsi_session_lookup(net, ev->u.d_session.sid);
if (!session)
err = -EINVAL;
- else if (iscsi_session_has_conns(ev->u.d_session.sid))
+ else if (iscsi_session_has_conns(net, ev->u.d_session.sid))
err = -EBUSY;
else {
+ struct iscsi_net *isn = net_generic(net, iscsi_net_id);
unsigned long flags;
/* Prevent this session from being found again */
- spin_lock_irqsave(&sesslock, flags);
+ spin_lock_irqsave(&isn->sesslock, flags);
list_del_init(&session->sess_list);
- spin_unlock_irqrestore(&sesslock, flags);
+ spin_unlock_irqrestore(&isn->sesslock, flags);
queue_work(system_unbound_wq, &session->destroy_work);
}
@@ -5211,6 +5222,13 @@ static int __net_init iscsi_net_init(struct net *net)
if (!nls)
return -ENOMEM;
isn = net_generic(net, iscsi_net_id);
+
+ INIT_LIST_HEAD(&isn->sesslist);
+ spin_lock_init(&isn->sesslock);
+ INIT_LIST_HEAD(&isn->connlist);
+ INIT_LIST_HEAD(&isn->connlist_err);
+ spin_lock_init(&isn->connlock);
+
isn->nls = nls;
return 0;
}
--
2.39.2
next prev parent reply other threads:[~2023-05-06 23:31 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-05-06 23:29 [PATCH v2 00/11] Make iscsid-kernel communications namespace-aware Chris Leech
2023-05-06 23:29 ` [PATCH 01/11] iscsi: create per-net iscsi netlink kernel sockets Chris Leech
2023-05-06 23:29 ` [PATCH 02/11] iscsi: associate endpoints with a host Chris Leech
2023-05-06 23:29 ` [PATCH 03/11] iscsi: sysfs filtering by network namespace Chris Leech
2023-05-10 19:50 ` michael.christie
2023-05-06 23:29 ` [PATCH 04/11] iscsi: make all iSCSI netlink multicast namespace aware Chris Leech
2023-05-10 19:48 ` michael.christie
2023-05-06 23:29 ` [PATCH 05/11] iscsi: check net namespace for all iscsi lookup Chris Leech
2023-05-12 22:30 ` Mike Christie
2023-05-06 23:29 ` [PATCH 06/11] iscsi: set netns for tcp and iser hosts Chris Leech
2023-05-07 1:29 ` kernel test robot
2023-05-07 2:01 ` kernel test robot
2023-05-10 19:40 ` michael.christie
2023-05-06 23:29 ` [PATCH 07/11] iscsi: convert flashnode devices from bus to class Chris Leech
2023-05-10 19:28 ` michael.christie
2023-05-06 23:29 ` [PATCH 08/11] iscsi: rename iscsi_bus_flash_* to iscsi_flash_* Chris Leech
2023-05-06 23:29 ` [PATCH 09/11] iscsi: filter flashnode sysfs by net namespace Chris Leech
2023-05-06 23:29 ` Chris Leech [this message]
2023-05-10 19:25 ` [PATCH 10/11] iscsi: make session and connection lists per-net michael.christie
2023-05-06 23:29 ` [PATCH 11/11] iscsi: force destroy sesions when a network namespace exits Chris Leech
2023-05-10 20:09 ` michael.christie
2023-05-10 20:14 ` michael.christie
2023-05-10 19:54 ` [PATCH v2 00/11] Make iscsid-kernel communications namespace-aware michael.christie
-- strict thread matches above, loose matches on Subject: below --
2023-03-14 16:27 [RFC PATCH 4/9] iscsi: make all iSCSI netlink multicast namespace aware Hannes Reinecke
2023-04-10 19:10 ` [PATCH 10/11] iscsi: make session and connection lists per-net Chris Leech
2023-04-11 6:17 ` Hannes Reinecke
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230506232930.195451-11-cleech@redhat.com \
--to=cleech@redhat.com \
--cc=lduncan@suse.com \
--cc=linux-scsi@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=open-iscsi@googlegroups.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).