spin_lock_init(&conn->llist_lock);
        INIT_LIST_HEAD(&conn->lock_list);
 
+       init_rwsem(&conn->session_lock);
+
        down_write(&conn_list_lock);
        list_add(&conn->conns_list, &conn_list);
        up_write(&conn_list_lock);
 
        struct nls_table                *local_nls;
        struct unicode_map              *um;
        struct list_head                conns_list;
+       struct rw_semaphore             session_lock;
        /* smb session 1 per user */
        struct xarray                   sessions;
        unsigned long                   last_active;
 
        unsigned long id;
        struct ksmbd_session *sess;
 
-       down_write(&sessions_table_lock);
+       down_write(&conn->session_lock);
        xa_for_each(&conn->sessions, id, sess) {
                if (sess->state != SMB2_SESSION_VALID ||
                    time_after(jiffies,
                        continue;
                }
        }
-       up_write(&sessions_table_lock);
+       up_write(&conn->session_lock);
 }
 
 int ksmbd_session_register(struct ksmbd_conn *conn,
                        }
                }
        }
+       up_write(&sessions_table_lock);
 
+       down_write(&conn->session_lock);
        xa_for_each(&conn->sessions, id, sess) {
                unsigned long chann_id;
                struct channel *chann;
                        ksmbd_session_destroy(sess);
                }
        }
-       up_write(&sessions_table_lock);
+       up_write(&conn->session_lock);
 }
 
 struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn,
 {
        struct ksmbd_session *sess;
 
+       down_read(&conn->session_lock);
        sess = xa_load(&conn->sessions, id);
        if (sess)
                sess->last_active = jiffies;
+       up_read(&conn->session_lock);
        return sess;
 }