Eliminate the comparisions on list lookups, and it will make it easier
to shut down session on net namespace exit in the next patch.

Signed-off-by: Chris Leech <cle...@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 9a176ea0d866..3a068d8eca2d 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -1734,17 +1734,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);
@@ -1759,19 +1758,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;
 }
 
@@ -1783,19 +1781,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;
 }
 
@@ -2207,6 +2204,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;
@@ -2250,9 +2250,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");
@@ -2322,15 +2322,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);
@@ -2541,20 +2543,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);
@@ -2625,6 +2629,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) {
@@ -2640,9 +2646,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;
 }
@@ -2657,11 +2663,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);
@@ -3432,20 +3441,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;
 }
@@ -4157,7 +4167,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);
@@ -4166,15 +4176,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);
                }
@@ -5176,6 +5187,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

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20230410191033.1069293-2-cleech%40redhat.com.

Reply via email to