@@ -4460,7 +4460,7 @@ int iscsit_close_connection(
atomic_read(&sess->session_fall_back_to_erl0)) {
spin_unlock_bh(&sess->conn_lock);
complete_all(&sess->session_wait_comp);
- iscsit_close_session(sess, true);
+ iscsit_close_session(sess);
return 0;
} else if (atomic_read(&sess->session_logout)) {
@@ -4470,7 +4470,7 @@ int iscsit_close_connection(
if (atomic_read(&sess->session_close)) {
spin_unlock_bh(&sess->conn_lock);
complete_all(&sess->session_wait_comp);
- iscsit_close_session(sess, true);
+ iscsit_close_session(sess);
} else {
spin_unlock_bh(&sess->conn_lock);
}
@@ -4486,7 +4486,7 @@ int iscsit_close_connection(
if (atomic_read(&sess->session_close)) {
spin_unlock_bh(&sess->conn_lock);
complete_all(&sess->session_wait_comp);
- iscsit_close_session(sess, true);
+ iscsit_close_session(sess);
} else {
spin_unlock_bh(&sess->conn_lock);
}
@@ -4500,18 +4500,20 @@ void iscsit_session_close_worker(struct work_struct *workp)
struct iscsit_session *sess = container_of(workp, struct iscsit_session,
session_close_worker);
- iscsit_close_session(sess, true);
+ iscsit_close_session(sess);
}
/*
* If the iSCSI Session for the iSCSI Initiator Node exists,
* forcefully shutdown the iSCSI NEXUS.
*/
-int iscsit_close_session(struct iscsit_session *sess, bool can_sleep)
+int iscsit_close_session(struct iscsit_session *sess)
{
struct iscsi_portal_group *tpg = sess->tpg;
struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
+ might_sleep();
+
if (atomic_read(&sess->nconn)) {
pr_err("%d connection(s) still exist for iSCSI session"
" to %s\n", atomic_read(&sess->nconn),
@@ -4536,15 +4538,9 @@ int iscsit_close_session(struct iscsit_session *sess, bool can_sleep)
/*
* If any other processes are accessing this session pointer we must
- * wait until they have completed. If we are in an interrupt (the
- * time2retain handler) and contain and active session usage count we
- * restart the timer and exit.
+ * wait until they have completed.
*/
- if (iscsit_check_session_usage_count(sess, can_sleep)) {
- atomic_set(&sess->session_logout, 0);
- iscsit_start_time2retain_handler(sess);
- return 0;
- }
+ iscsit_check_session_usage_count(sess);
transport_deregister_session(sess->se_sess);
@@ -41,7 +41,7 @@ extern void iscsit_thread_get_cpumask(struct iscsit_conn *);
extern int iscsi_target_tx_thread(void *);
extern int iscsi_target_rx_thread(void *);
extern int iscsit_close_connection(struct iscsit_conn *);
-extern int iscsit_close_session(struct iscsit_session *, bool can_sleep);
+extern int iscsit_close_session(struct iscsit_session *sess);
extern void iscsit_session_close_worker(struct work_struct *workp);
extern void iscsit_fail_session(struct iscsit_session *);
extern void iscsit_stop_session(struct iscsit_session *, int, int);
@@ -762,15 +762,12 @@ void iscsit_free_cmd(struct iscsit_cmd *cmd, bool shutdown)
}
EXPORT_SYMBOL(iscsit_free_cmd);
-bool iscsit_check_session_usage_count(struct iscsit_session *sess,
- bool can_sleep)
+bool iscsit_check_session_usage_count(struct iscsit_session *sess)
{
spin_lock_bh(&sess->session_usage_lock);
if (sess->session_usage_count != 0) {
sess->session_waiting_on_uc = 1;
spin_unlock_bh(&sess->session_usage_lock);
- if (!can_sleep)
- return true;
wait_for_completion(&sess->session_waiting_on_uc_comp);
return false;
@@ -40,7 +40,7 @@ extern void iscsit_free_queue_reqs_for_conn(struct iscsit_conn *);
extern void iscsit_release_cmd(struct iscsit_cmd *);
extern void __iscsit_free_cmd(struct iscsit_cmd *, bool);
extern void iscsit_free_cmd(struct iscsit_cmd *, bool);
-extern bool iscsit_check_session_usage_count(struct iscsit_session *sess, bool can_sleep);
+extern bool iscsit_check_session_usage_count(struct iscsit_session *sess);
extern void iscsit_dec_session_usage_count(struct iscsit_session *);
extern void iscsit_inc_session_usage_count(struct iscsit_session *);
extern struct iscsit_conn *iscsit_get_conn_from_cid(struct iscsit_session *, u16);
Since all calls iscsit_close_session() are now from non-atomic context, remove can_sleep argument and forbid call iscsit_close_session() from an atomic context in the future. Signed-off-by: Dmitry Bogdanov <d.bogdanov@yadro.com> --- drivers/target/iscsi/iscsi_target.c | 22 +++++++++------------- drivers/target/iscsi/iscsi_target.h | 2 +- drivers/target/iscsi/iscsi_target_util.c | 5 +---- drivers/target/iscsi/iscsi_target_util.h | 2 +- 4 files changed, 12 insertions(+), 19 deletions(-)