From 3c66e5bf825c2a584d85ae46eaf314870cabb33b Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 11 Aug 2016 18:36:48 +0000 Subject: [PATCH 01/26] scst/README.dlm: Correct instructions for waiting for logout git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6933 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/README.dlm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scst/README.dlm b/scst/README.dlm index 698602907..7ca663c0f 100644 --- a/scst/README.dlm +++ b/scst/README.dlm @@ -126,7 +126,8 @@ The proper shutdown order is as follows: echo 0 > $x & done wait - while ls -Ad /sys/kernel/scst_tgt/targets/*/*/sessions/* >/dev/null 2>&1; do + while ls -Ad /sys/kernel/scst_tgt/targets/*/*/sessions/* 2>&1 | + grep -vE '/sys/kernel/scst_tgt/targets/(copy_manager|scst_local)/'; do sleep 1 done * Tell SCST to release the DLM lockspaces: From 583f452957519d5cdb7f9055c3bdb9040b90398f Mon Sep 17 00:00:00 2001 From: Israel Rukshin Date: Wed, 17 Aug 2016 07:17:37 +0000 Subject: [PATCH 02/26] isert: make sure rdma_disconnect is called only once Signed-off-by: Israel Rukshin git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6934 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/isert-scst/iser_rdma.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/iscsi-scst/kernel/isert-scst/iser_rdma.c b/iscsi-scst/kernel/isert-scst/iser_rdma.c index 9f50728d9..5a1dd721f 100644 --- a/iscsi-scst/kernel/isert-scst/iser_rdma.c +++ b/iscsi-scst/kernel/isert-scst/iser_rdma.c @@ -163,10 +163,16 @@ void isert_post_drain(struct isert_connection *isert_conn) void isert_conn_disconnect(struct isert_connection *isert_conn) { - int err = rdma_disconnect(isert_conn->cm_id); + int err; - if (unlikely(err)) - pr_err("Failed to rdma disconnect, err:%d\n", err); + if (isert_conn->state != ISER_CONN_CLOSING) { + isert_conn->state = ISER_CONN_CLOSING; + + err = rdma_disconnect(isert_conn->cm_id); + + if (unlikely(err)) + pr_err("Failed to rdma disconnect, err:%d\n", err); + } } static int isert_pdu_handle_hello_req(struct isert_cmnd *pdu) @@ -1270,6 +1276,7 @@ static void isert_kref_free(struct kref *kref) isert_free_conn_resources(isert_conn); rdma_destroy_id(isert_conn->cm_id); + isert_conn->cm_id = NULL; dev = isert_get_priv(&isert_conn->iscsi); if (dev) From c3827a6f54e1a41bd2bd0e5ae13322619214efd4 Mon Sep 17 00:00:00 2001 From: Israel Rukshin Date: Wed, 17 Aug 2016 07:27:06 +0000 Subject: [PATCH 03/26] isert: fix cleaning isert_con_dev Clean pointers not to point to invalid memory. - While conn is released set conn_dev->conn to null as conn is invalid now. - While conn_dev is released set priv(conn) to null as conn_dev is invalid now. Signed-off-by: Israel Rukshin git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6935 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/isert-scst/iser_rdma.c | 6 +++++- iscsi-scst/kernel/isert-scst/isert_login.c | 9 ++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/iscsi-scst/kernel/isert-scst/iser_rdma.c b/iscsi-scst/kernel/isert-scst/iser_rdma.c index 5a1dd721f..ab8b2aa16 100644 --- a/iscsi-scst/kernel/isert-scst/iser_rdma.c +++ b/iscsi-scst/kernel/isert-scst/iser_rdma.c @@ -1279,8 +1279,12 @@ static void isert_kref_free(struct kref *kref) isert_conn->cm_id = NULL; dev = isert_get_priv(&isert_conn->iscsi); - if (dev) + if (dev) { isert_del_timer(dev); + set_bit(ISERT_CONN_PASSED, &dev->flags); + dev->conn = NULL; + dev->state = CS_DISCONNECTED; + } ib_destroy_qp(isert_conn->qp); isert_conn->qp = NULL; diff --git a/iscsi-scst/kernel/isert-scst/isert_login.c b/iscsi-scst/kernel/isert-scst/isert_login.c index 9d78bb1bc..1dd077537 100644 --- a/iscsi-scst/kernel/isert-scst/isert_login.c +++ b/iscsi-scst/kernel/isert-scst/isert_login.c @@ -454,6 +454,7 @@ int isert_connection_closed(struct iscsi_conn *iscsi_conn) wake_up(&dev->waitqueue); isert_dev_release(dev); + isert_set_priv(iscsi_conn, NULL); } isert_free_connection(iscsi_conn); @@ -528,13 +529,7 @@ static int isert_release(struct inode *inode, struct file *filp) dev->sg_virt = NULL; dev->is_discovery = 0; - if (!test_and_set_bit(ISERT_CONN_PASSED, &dev->flags)) { - BUG_ON(dev->conn == NULL); - isert_close_connection(dev->conn); - } - - isert_del_timer(dev); - + isert_delete_conn_dev(dev); isert_dev_release(dev); TRACE_EXIT_RES(res); From a3b45f61bfa5605a4eae795a0a098a212f45e80d Mon Sep 17 00:00:00 2001 From: Israel Rukshin Date: Wed, 17 Aug 2016 07:27:11 +0000 Subject: [PATCH 04/26] isert: add assertions for connection teardwon flow Signed-off-by: Israel Rukshin git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6936 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/iscsi.c | 2 ++ iscsi-scst/kernel/isert-scst/iser_rdma.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/iscsi-scst/kernel/iscsi.c b/iscsi-scst/kernel/iscsi.c index 4dc07f0b4..58ba36dfd 100644 --- a/iscsi-scst/kernel/iscsi.c +++ b/iscsi-scst/kernel/iscsi.c @@ -2035,6 +2035,8 @@ static int scsi_cmnd_start(struct iscsi_cmnd *req) atomic_inc(&session->active_cmds); req->dec_active_cmds = 1; + sBUG_ON(session->scst_sess == NULL); + scst_cmd = scst_rx_cmd(session->scst_sess, (uint8_t *)&req_hdr->lun, sizeof(req_hdr->lun), req_hdr->scb, sizeof(req_hdr->scb), SCST_NON_ATOMIC); diff --git a/iscsi-scst/kernel/isert-scst/iser_rdma.c b/iscsi-scst/kernel/isert-scst/iser_rdma.c index ab8b2aa16..c856f15d5 100644 --- a/iscsi-scst/kernel/isert-scst/iser_rdma.c +++ b/iscsi-scst/kernel/isert-scst/iser_rdma.c @@ -1271,7 +1271,7 @@ static void isert_kref_free(struct kref *kref) TRACE_ENTRY(); - pr_info("isert_conn_free conn:%p\n", isert_conn); + pr_info("%s conn:%p\n", __func__, isert_conn); isert_free_conn_resources(isert_conn); @@ -1306,6 +1306,7 @@ static void isert_kref_free(struct kref *kref) void isert_conn_free(struct isert_connection *isert_conn) { + sBUG_ON(atomic_read(&isert_conn->kref.refcount) == 0); kref_put(&isert_conn->kref, isert_kref_free); } From 32ca0a7846d0f7f92c15c23dd6ed7f6f085124fa Mon Sep 17 00:00:00 2001 From: Israel Rukshin Date: Wed, 17 Aug 2016 07:27:15 +0000 Subject: [PATCH 05/26] isert: fix a possible extra refcount put of isert connection On login logout stress we can start a teardown flow before connection is fully established. In this case we have one less refcount on isert connection. Signed-off-by: Israel Rukshin git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6937 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/isert-scst/iser.h | 1 + iscsi-scst/kernel/isert-scst/iser_rdma.c | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/iscsi-scst/kernel/isert-scst/iser.h b/iscsi-scst/kernel/isert-scst/iser.h index eeb8040fc..501fcf7d0 100644 --- a/iscsi-scst/kernel/isert-scst/iser.h +++ b/iscsi-scst/kernel/isert-scst/iser.h @@ -160,6 +160,7 @@ struct isert_cq { #define ISERT_DRAIN_POSTED 1 #define ISERT_DRAIN_FAILED 2 #define ISERT_DISCON_CALLED 3 +#define ISERT_CONNECTION_EST 4 struct isert_connection { struct iscsi_conn iscsi ____cacheline_aligned; diff --git a/iscsi-scst/kernel/isert-scst/iser_rdma.c b/iscsi-scst/kernel/isert-scst/iser_rdma.c index c856f15d5..d78e2e08b 100644 --- a/iscsi-scst/kernel/isert-scst/iser_rdma.c +++ b/iscsi-scst/kernel/isert-scst/iser_rdma.c @@ -599,7 +599,10 @@ static void isert_conn_closed_do_work(struct work_struct *work) if (!test_and_set_bit(ISERT_DISCON_CALLED, &isert_conn->flags)) isert_connection_closed(&isert_conn->iscsi); - isert_conn_free(isert_conn); + /* if connection established we have another refcount */ + if (test_bit(ISERT_CONNECTION_EST, &isert_conn->flags)) { + isert_conn_free(isert_conn); + } } static void isert_sched_conn_closed(struct isert_connection *isert_conn) @@ -1480,6 +1483,8 @@ static int isert_cm_connect_handler(struct rdma_cm_id *cm_id, goto out; } + set_bit(ISERT_CONNECTION_EST, &isert_conn->flags); + if (push_saved_pdu) { pr_info("iser push saved rx pdu\n"); isert_recv_completion_handler(isert_conn->saved_wr); From a67322d28866b7ef09f778c14558ad9673daae3b Mon Sep 17 00:00:00 2001 From: Israel Rukshin Date: Wed, 17 Aug 2016 07:27:19 +0000 Subject: [PATCH 06/26] isert: change wrong dev_conn bug on Signed-off-by: Israel Rukshin git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6938 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/isert-scst/isert_login.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/iscsi-scst/kernel/isert-scst/isert_login.c b/iscsi-scst/kernel/isert-scst/isert_login.c index 1dd077537..5dcd0e0a6 100644 --- a/iscsi-scst/kernel/isert-scst/isert_login.c +++ b/iscsi-scst/kernel/isert-scst/isert_login.c @@ -107,6 +107,7 @@ static void isert_kref_release_dev(struct kref *kref) static void isert_dev_release(struct isert_conn_dev *dev) { + sBUG_ON(atomic_read(&dev->kref.refcount) == 0); spin_lock(&isert_listen_dev.conn_lock); kref_put(&dev->kref, isert_kref_release_dev); spin_unlock(&isert_listen_dev.conn_lock); @@ -304,8 +305,8 @@ static void isert_delete_conn_dev(struct isert_conn_dev *conn_dev) isert_del_timer(conn_dev); if (!test_and_set_bit(ISERT_CONN_PASSED, &conn_dev->flags)) { - BUG_ON(conn_dev->conn == NULL); - isert_close_connection(conn_dev->conn); + if (conn_dev->conn) + isert_close_connection(conn_dev->conn); } } From e3f77ba979937c5e877b48b854b03a3df0cfabb1 Mon Sep 17 00:00:00 2001 From: Israel Rukshin Date: Wed, 17 Aug 2016 07:27:24 +0000 Subject: [PATCH 07/26] isert: fix fops ioctl using invalid conn On teardown flow we need to set dev conn state to disconnected. Signed-off-by: Israel Rukshin git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6939 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/isert-scst/isert.c | 5 +++++ iscsi-scst/kernel/isert-scst/isert_login.c | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/iscsi-scst/kernel/isert-scst/isert.c b/iscsi-scst/kernel/isert-scst/isert.c index 2a3693754..3493812e3 100644 --- a/iscsi-scst/kernel/isert-scst/isert.c +++ b/iscsi-scst/kernel/isert-scst/isert.c @@ -78,6 +78,11 @@ static void isert_mark_conn_closed(struct iscsi_conn *conn, int flags) static void isert_close_conn(struct iscsi_conn *conn, int flags) { + struct isert_conn_dev *dev; + + dev = isert_get_priv(conn); + if (dev) + dev->state = CS_DISCONNECTED; } static int isert_receive_cmnd_data(struct iscsi_cmnd *cmnd) diff --git a/iscsi-scst/kernel/isert-scst/isert_login.c b/iscsi-scst/kernel/isert-scst/isert_login.c index 5dcd0e0a6..9671a4252 100644 --- a/iscsi-scst/kernel/isert-scst/isert_login.c +++ b/iscsi-scst/kernel/isert-scst/isert_login.c @@ -211,6 +211,13 @@ int isert_conn_alloc(struct iscsi_session *session, dev = filp->private_data; + if (unlikely(dev->state == CS_DISCONNECTED)) { + res = -EBADF; + goto out; + } + + sBUG_ON(dev->state != CS_RSP_FINISHED); + cmnd = dev->login_rsp; sBUG_ON(cmnd == NULL); From 8587672dc4f84b347ff16b14999e2b3585aa7055 Mon Sep 17 00:00:00 2001 From: Israel Rukshin Date: Wed, 17 Aug 2016 07:27:28 +0000 Subject: [PATCH 08/26] isert: fix race between ioctl events and disconnect flow The ioctl events may arive after the isert connection has started the teardown flow. This scenario may occur on login logout stress. It may lead to NULL derefrence bugs. Signed-off-by: Israel Rukshin git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6940 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/isert-scst/isert_login.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/iscsi-scst/kernel/isert-scst/isert_login.c b/iscsi-scst/kernel/isert-scst/isert_login.c index 9671a4252..7ecab2595 100644 --- a/iscsi-scst/kernel/isert-scst/isert_login.c +++ b/iscsi-scst/kernel/isert-scst/isert_login.c @@ -51,6 +51,8 @@ #include "isert.h" #include "iser_datamover.h" +static DEFINE_MUTEX(conn_mgmt_mutex); + static unsigned int n_devs; static int isert_major; @@ -204,6 +206,8 @@ int isert_conn_alloc(struct iscsi_session *session, lockdep_assert_held(&session->target->target_mutex); + mutex_lock(&conn_mgmt_mutex); + if (unlikely(!filp)) { res = -EBADF; goto out; @@ -273,6 +277,7 @@ cleanup_conn: conn->session = NULL; isert_close_connection(conn); out: + mutex_unlock(&conn_mgmt_mutex); TRACE_EXIT_RES(res); return res; } @@ -445,7 +450,10 @@ int isert_connection_closed(struct iscsi_conn *iscsi_conn) TRACE_ENTRY(); + mutex_lock(&conn_mgmt_mutex); + if (iscsi_conn->rd_state) { + mutex_unlock(&conn_mgmt_mutex); res = isert_handle_close_connection(iscsi_conn); } else { struct isert_conn_dev *dev = isert_get_priv(iscsi_conn); @@ -465,6 +473,7 @@ int isert_connection_closed(struct iscsi_conn *iscsi_conn) isert_set_priv(iscsi_conn, NULL); } + mutex_unlock(&conn_mgmt_mutex); isert_free_connection(iscsi_conn); } @@ -681,6 +690,8 @@ static long isert_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) TRACE_ENTRY(); + mutex_lock(&conn_mgmt_mutex); + if (dev->state == CS_DISCONNECTED) { res = -EPIPE; goto out; @@ -767,6 +778,7 @@ static long isert_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } out: + mutex_unlock(&conn_mgmt_mutex); TRACE_EXIT_RES(res); return res; } From 2e4544e3519790020001ee181ecaefcbda0666b3 Mon Sep 17 00:00:00 2001 From: Israel Rukshin Date: Wed, 17 Aug 2016 07:27:33 +0000 Subject: [PATCH 09/26] isert: fix isert conn refcount release at unreachable event On unreachable event the isert conn kref is always 2. The refcount becomes 2 after successful connect event. Signed-off-by: Israel Rukshin git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6941 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/isert-scst/iser.h | 2 ++ iscsi-scst/kernel/isert-scst/iser_rdma.c | 30 ++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/iscsi-scst/kernel/isert-scst/iser.h b/iscsi-scst/kernel/isert-scst/iser.h index 501fcf7d0..f7f89e831 100644 --- a/iscsi-scst/kernel/isert-scst/iser.h +++ b/iscsi-scst/kernel/isert-scst/iser.h @@ -217,6 +217,7 @@ struct isert_connection { struct work_struct close_work; struct work_struct drain_work; struct work_struct discon_work; + struct work_struct free_work; struct isert_wr drain_wr; struct kref kref; @@ -288,6 +289,7 @@ void isert_free_conn_resources(struct isert_connection *isert_conn); void isert_conn_free(struct isert_connection *isert_conn); void isert_conn_disconnect(struct isert_connection *isert_conn); void isert_post_drain(struct isert_connection *isert_conn); +void isert_sched_conn_free(struct isert_connection *isert_conn); static inline struct isert_connection *isert_conn_zalloc(void) { diff --git a/iscsi-scst/kernel/isert-scst/iser_rdma.c b/iscsi-scst/kernel/isert-scst/iser_rdma.c index d78e2e08b..82b067bd6 100644 --- a/iscsi-scst/kernel/isert-scst/iser_rdma.c +++ b/iscsi-scst/kernel/isert-scst/iser_rdma.c @@ -616,6 +616,32 @@ static void isert_sched_conn_closed(struct isert_connection *isert_conn) isert_conn_queue_work(&isert_conn->close_work); } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) +static void isert_conn_free_do_work(void *ctx) +#else +static void isert_conn_free_do_work(struct work_struct *work) +#endif +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) + struct isert_connection *isert_conn = ctx; +#else + struct isert_connection *isert_conn = + container_of(work, struct isert_connection, free_work); +#endif + + isert_conn_free(isert_conn); +} + +void isert_sched_conn_free(struct isert_connection *isert_conn) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) + INIT_WORK(&isert_conn->free_work, isert_conn_free_do_work, + isert_conn); +#else + INIT_WORK(&isert_conn->free_work, isert_conn_free_do_work); +#endif + isert_conn_queue_work(&isert_conn->free_work); +} static void isert_handle_wc_error(struct ib_wc *wc) { @@ -1645,10 +1671,10 @@ static int isert_cm_evt_handler(struct rdma_cm_id *cm_id, /* * reaching here must be with the isert_conn refcount of 2, * one from the init and one from the connect request, - * thus it is safe to deref directly before the sched_conn_closed + * thus it is safe to deref directly before the sched_conn_free. */ isert_conn_free(isert_conn); - isert_sched_conn_closed(isert_conn); + isert_sched_conn_free(isert_conn); err = 0; } break; From b235efb8d2e421538539655eb1ab18ae01f9decd Mon Sep 17 00:00:00 2001 From: Israel Rukshin Date: Wed, 17 Aug 2016 07:27:38 +0000 Subject: [PATCH 10/26] isert: fix missing refcount cleanup at error flow Before calling to rdma_accept isert kref is 2, so on failure we must decrease it twice. Signed-off-by: Israel Rukshin git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6942 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/isert-scst/iser_rdma.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iscsi-scst/kernel/isert-scst/iser_rdma.c b/iscsi-scst/kernel/isert-scst/iser_rdma.c index 82b067bd6..48cb109f8 100644 --- a/iscsi-scst/kernel/isert-scst/iser_rdma.c +++ b/iscsi-scst/kernel/isert-scst/iser_rdma.c @@ -1460,7 +1460,8 @@ out: fail_accept: set_bit(ISERT_CONNECTION_ABORTED, &isert_conn->flags); - isert_cm_timewait_exit_handler(cm_id, NULL); + isert_conn_free(isert_conn); + isert_sched_conn_free(isert_conn); err = 0; goto out; From 854a7a060ddc4829080e3cd7edfe658eb2e9a377 Mon Sep 17 00:00:00 2001 From: Israel Rukshin Date: Wed, 17 Aug 2016 07:27:43 +0000 Subject: [PATCH 11/26] isert: add assertion if send/recv was posted after post drain After post drain we are not allowed to call post_recv or post_send, because the drain must be the last flush to let us know that we may close the conection safely. Signed-off-by: Israel Rukshin git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6943 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/isert-scst/iser_rdma.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/iscsi-scst/kernel/isert-scst/iser_rdma.c b/iscsi-scst/kernel/isert-scst/iser_rdma.c index 48cb109f8..2e1cf989a 100644 --- a/iscsi-scst/kernel/isert-scst/iser_rdma.c +++ b/iscsi-scst/kernel/isert-scst/iser_rdma.c @@ -75,6 +75,13 @@ int isert_post_recv(struct isert_connection *isert_conn, TRACE_ENTRY(); +#ifdef CONFIG_SCST_EXTRACHECKS + if (test_bit(ISERT_DRAIN_POSTED, &isert_conn->flags)) { + pr_err("conn:%p post recv after drain\n", isert_conn); + BUG(); + } +#endif + err = ib_post_recv(isert_conn->qp, first_ib_wr, &bad_wr); if (unlikely(err)) { num_posted = isert_num_recv_posted_on_err(first_ib_wr, bad_wr); @@ -115,6 +122,13 @@ int isert_post_send(struct isert_connection *isert_conn, TRACE_ENTRY(); +#ifdef CONFIG_SCST_EXTRACHECKS + if (test_bit(ISERT_DRAIN_POSTED, &isert_conn->flags)) { + pr_err("conn:%p post send after drain\n", isert_conn); + BUG(); + } +#endif + err = ib_post_send(isert_conn->qp, first_ib_wr, &bad_wr); if (unlikely(err)) { num_posted = isert_num_send_posted_on_err(first_ib_wr, bad_wr); From 1c3de9fa71cbc227caebd83320f17ae3f0a1edfa Mon Sep 17 00:00:00 2001 From: Israel Rukshin Date: Wed, 17 Aug 2016 07:27:48 +0000 Subject: [PATCH 12/26] isert: replace kernel prints with scst macros Signed-off-by: Israel Rukshin git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6944 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/isert-scst/iser_buf.c | 20 +- iscsi-scst/kernel/isert-scst/iser_datamover.c | 6 +- iscsi-scst/kernel/isert-scst/iser_global.c | 8 +- iscsi-scst/kernel/isert-scst/iser_pdu.c | 42 +-- iscsi-scst/kernel/isert-scst/iser_rdma.c | 242 +++++++++--------- iscsi-scst/kernel/isert-scst/isert.c | 6 +- iscsi-scst/kernel/isert-scst/isert_login.c | 20 +- 7 files changed, 171 insertions(+), 173 deletions(-) diff --git a/iscsi-scst/kernel/isert-scst/iser_buf.c b/iscsi-scst/kernel/isert-scst/iser_buf.c index 7bd34c9a2..f6bc47fab 100644 --- a/iscsi-scst/kernel/isert-scst/iser_buf.c +++ b/iscsi-scst/kernel/isert-scst/iser_buf.c @@ -52,7 +52,7 @@ static int isert_buf_alloc_pg(struct ib_device *ib_dev, isert_buf->sg = kmalloc_array(isert_buf->sg_cnt, sizeof(*isert_buf->sg), GFP_KERNEL); if (unlikely(!isert_buf->sg)) { - pr_err("Failed to allocate buffer SG\n"); + PRINT_ERROR("Failed to allocate buffer SG"); res = -ENOMEM; goto out; } @@ -63,7 +63,7 @@ static int isert_buf_alloc_pg(struct ib_device *ib_dev, page = alloc_page(GFP_KERNEL); if (unlikely(!page)) { - pr_err("Failed to allocate page\n"); + PRINT_ERROR("Failed to allocate page"); res = -ENOMEM; goto out_map_failed; } @@ -74,8 +74,8 @@ static int isert_buf_alloc_pg(struct ib_device *ib_dev, res = ib_dma_map_sg(ib_dev, isert_buf->sg, isert_buf->sg_cnt, dma_dir); if (unlikely(!res)) { --i; /* do not overrun isert_buf->sg */ - pr_err("Failed to DMA map iser sg:%p len:%d\n", - isert_buf->sg, isert_buf->sg_cnt); + PRINT_ERROR("Failed to DMA map iser sg:%p len:%d", + isert_buf->sg, isert_buf->sg_cnt); res = -ENOMEM; goto out_map_failed; } @@ -111,14 +111,14 @@ static int isert_buf_malloc(struct ib_device *ib_dev, isert_buf->sg_cnt = 1; isert_buf->sg = kmalloc(sizeof(isert_buf->sg[0]), GFP_KERNEL); if (unlikely(!isert_buf->sg)) { - pr_err("Failed to allocate buffer SG\n"); + PRINT_ERROR("Failed to allocate buffer SG"); res = -ENOMEM; goto out; } isert_buf->addr = kmalloc(size, GFP_KERNEL); if (unlikely(!isert_buf->addr)) { - pr_err("Failed to allocate data buffer\n"); + PRINT_ERROR("Failed to allocate data buffer"); res = -ENOMEM; goto data_malloc_failed; } @@ -127,8 +127,8 @@ static int isert_buf_malloc(struct ib_device *ib_dev, res = ib_dma_map_sg(ib_dev, isert_buf->sg, isert_buf->sg_cnt, dma_dir); if (unlikely(!res)) { - pr_err("Failed to DMA map iser sg:%p len:%d\n", - isert_buf->sg, isert_buf->sg_cnt); + PRINT_ERROR("Failed to DMA map iser sg:%p len:%d", + isert_buf->sg, isert_buf->sg_cnt); res = -ENOMEM; goto out_map_failed; } @@ -233,7 +233,7 @@ int isert_wr_init(struct isert_wr *wr, case ISER_WR_RDMA_READ: send_wr_op = IB_WR_RDMA_READ; if (unlikely(!pdu->is_wstag_valid)) { - pr_err("No write tag/va specified for RDMA op\n"); + PRINT_ERROR("No write tag/va specified for RDMA op"); isert_buf_release(isert_buf); buff_offset = -EFAULT; goto out; @@ -250,7 +250,7 @@ int isert_wr_init(struct isert_wr *wr, case ISER_WR_RDMA_WRITE: send_wr_op = IB_WR_RDMA_WRITE; if (unlikely(!pdu->is_rstag_valid)) { - pr_err("No read tag/va specified for RDMA op\n"); + PRINT_ERROR("No read tag/va specified for RDMA op"); isert_buf_release(isert_buf); buff_offset = -EFAULT; goto out; diff --git a/iscsi-scst/kernel/isert-scst/iser_datamover.c b/iscsi-scst/kernel/isert-scst/iser_datamover.c index 165ab071b..7dd723dbc 100644 --- a/iscsi-scst/kernel/isert-scst/iser_datamover.c +++ b/iscsi-scst/kernel/isert-scst/iser_datamover.c @@ -47,7 +47,7 @@ int isert_datamover_init(void) err = isert_global_init(); if (unlikely(err)) { - pr_err("iser datamover init failed, err:%d\n", err); + PRINT_ERROR("iser datamover init failed, err:%d", err); return err; } return 0; @@ -189,7 +189,7 @@ int isert_login_rsp_tx(struct iscsi_cmnd *login_rsp, int last, int discovery) if (last && !discovery) { err = isert_alloc_conn_resources(isert_conn); if (unlikely(err)) { - pr_err("Failed to init conn resources\n"); + PRINT_ERROR("Failed to init conn resources"); return err; } isert_pdu_free(isert_conn->login_req_pdu); @@ -199,7 +199,7 @@ int isert_login_rsp_tx(struct iscsi_cmnd *login_rsp, int last, int discovery) &isert_conn->login_req_pdu->wr[0], 1); if (unlikely(err)) { - pr_err("Failed to post recv login req rx buf, err:%d\n", err); + PRINT_ERROR("Failed to post recv login req rx buf, err:%d", err); return err; } } diff --git a/iscsi-scst/kernel/isert-scst/iser_global.c b/iscsi-scst/kernel/isert-scst/iser_global.c index 31fe1f306..2c0c92410 100644 --- a/iscsi-scst/kernel/isert-scst/iser_global.c +++ b/iscsi-scst/kernel/isert-scst/iser_global.c @@ -106,7 +106,7 @@ int isert_global_init(void) isert_glob.conn_wq = create_workqueue("isert_conn_wq"); if (!isert_glob.conn_wq) { - pr_err("Failed to alloc iser conn work queue\n"); + PRINT_ERROR("Failed to alloc iser conn work queue"); return -ENOMEM; } @@ -114,7 +114,7 @@ int isert_global_init(void) SCST_SLAB_FLAGS|SLAB_HWCACHE_ALIGN); if (!isert_cmnd_cache) { destroy_workqueue(isert_glob.conn_wq); - pr_err("Failed to alloc iser command cache\n"); + PRINT_ERROR("Failed to alloc iser command cache"); return -ENOMEM; } @@ -123,7 +123,7 @@ int isert_global_init(void) if (!isert_conn_cache) { destroy_workqueue(isert_glob.conn_wq); kmem_cache_destroy(isert_cmnd_cache); - pr_err("Failed to alloc iser connection cache\n"); + PRINT_ERROR("Failed to alloc iser connection cache"); return -ENOMEM; } @@ -153,7 +153,7 @@ int isert_get_addr_size(struct sockaddr *sa, size_t *addr_len) *addr_len = sizeof(struct sockaddr_in6); break; default: - pr_err("Unknown address family\n"); + PRINT_ERROR("Unknown address family"); ret = -EINVAL; goto out; } diff --git a/iscsi-scst/kernel/isert-scst/iser_pdu.c b/iscsi-scst/kernel/isert-scst/iser_pdu.c index cf30db258..177b71f3b 100644 --- a/iscsi-scst/kernel/isert-scst/iser_pdu.c +++ b/iscsi-scst/kernel/isert-scst/iser_pdu.c @@ -263,8 +263,8 @@ int isert_prepare_rdma(struct isert_cmnd *isert_pdu, err = ib_dma_map_sg(ib_dev, isert_buf->sg, isert_buf->sg_cnt, isert_buf->dma_dir); if (unlikely(!err)) { - pr_err("Failed to DMA map iser sg:%p len:%d\n", - isert_buf->sg, isert_buf->sg_cnt); + PRINT_ERROR("Failed to DMA map iser sg:%p len:%d", + isert_buf->sg, isert_buf->sg_cnt); wr_cnt = -EFAULT; goto out; } @@ -331,27 +331,27 @@ struct isert_cmnd *isert_rx_pdu_alloc(struct isert_connection *isert_conn, pdu = isert_pdu_alloc(); if (unlikely(!pdu)) { - pr_err("Failed to alloc pdu\n"); + PRINT_ERROR("Failed to alloc pdu"); goto out; } err = isert_alloc_for_rdma(pdu, 4, isert_conn); if (unlikely(err)) { - pr_err("Failed to alloc sge and wr for rx pdu\n"); + PRINT_ERROR("Failed to alloc sge and wr for rx pdu"); goto out; } err = isert_buf_alloc_data_buf(isert_conn->isert_dev->ib_dev, &pdu->buf, size, DMA_FROM_DEVICE); if (unlikely(err)) { - pr_err("Failed to alloc rx pdu buf sz:%zd\n", size); + PRINT_ERROR("Failed to alloc rx pdu buf sz:%zd", size); goto buf_alloc_failed; } err = isert_rx_pdu_init(pdu, isert_conn); if (unlikely(err)) { - pr_err("Failed to init rx pdu wr:%p size:%zd err:%d\n", - &pdu->wr, size, err); + PRINT_ERROR("Failed to init rx pdu wr:%p size:%zd err:%d", + &pdu->wr, size, err); goto pdu_init_failed; } @@ -379,27 +379,27 @@ struct isert_cmnd *isert_tx_pdu_alloc(struct isert_connection *isert_conn, pdu = isert_pdu_alloc(); if (unlikely(!pdu)) { - pr_err("Failed to alloc pdu\n"); + PRINT_ERROR("Failed to alloc pdu"); goto out; } err = isert_alloc_for_rdma(pdu, 4, isert_conn); if (unlikely(err)) { - pr_err("Failed to alloc sge and wr for tx pdu\n"); + PRINT_ERROR("Failed to alloc sge and wr for tx pdu"); goto out; } err = isert_buf_alloc_data_buf(isert_conn->isert_dev->ib_dev, &pdu->buf, size, DMA_TO_DEVICE); if (unlikely(err)) { - pr_err("Failed to alloc tx pdu buf sz:%zd\n", size); + PRINT_ERROR("Failed to alloc tx pdu buf sz:%zd", size); goto buf_alloc_failed; } err = isert_pdu_tx_buf_init(pdu, isert_conn); if (unlikely(err < 0)) { - pr_err("Failed to init tx pdu wr:%p size:%zd err:%d\n", - &pdu->wr, size, err); + PRINT_ERROR("Failed to init tx pdu wr:%p size:%zd err:%d", + &pdu->wr, size, err); goto buf_init_failed; } @@ -449,8 +449,8 @@ int isert_alloc_conn_resources(struct isert_connection *isert_conn) to_alloc = isert_conn->queue_depth * 2 + isert_conn->repost_threshold; if (unlikely(to_alloc > ISER_MAX_WCE)) { - pr_err("QueuedCommands larger than %d not supported\n", - (ISER_MAX_WCE - isert_conn->repost_threshold) / 2); + PRINT_ERROR("QueuedCommands larger than %d not supported", + (ISER_MAX_WCE - isert_conn->repost_threshold) / 2); err = -EINVAL; goto out; } @@ -478,7 +478,7 @@ int isert_alloc_conn_resources(struct isert_connection *isert_conn) err = isert_post_recv(isert_conn, &first_pdu->wr[0], to_alloc); if (unlikely(err)) { - pr_err("Failed to post recv err:%d\n", err); + PRINT_ERROR("Failed to post recv err:%d", err); goto clean_pdus; } @@ -596,8 +596,8 @@ int isert_pdu_send(struct isert_connection *isert_conn, err = isert_post_send(isert_conn, wr, 1); if (unlikely(err)) { - pr_err("Failed to send pdu conn:%p pdu:%p err:%d\n", - isert_conn, tx_pdu, err); + PRINT_ERROR("Failed to send pdu conn:%p pdu:%p err:%d", + isert_conn, tx_pdu, err); } TRACE_EXIT_RES(err); @@ -623,8 +623,8 @@ int isert_pdu_post_rdma_write(struct isert_connection *isert_conn, isert_link_send_pdu_wrs(isert_cmd, isert_rsp, wr_cnt); err = isert_post_send(isert_conn, &isert_cmd->wr[0], wr_cnt + 1); if (unlikely(err)) { - pr_err("Failed to send pdu conn:%p pdu:%p err:%d\n", - isert_conn, isert_cmd, err); + PRINT_ERROR("Failed to send pdu conn:%p pdu:%p err:%d", + isert_conn, isert_cmd, err); } TRACE_EXIT_RES(err); @@ -640,8 +640,8 @@ int isert_pdu_post_rdma_read(struct isert_connection *isert_conn, err = isert_post_send(isert_conn, &isert_cmd->wr[0], wr_cnt); if (unlikely(err)) { - pr_err("Failed to send pdu conn:%p pdu:%p err:%d\n", - isert_conn, isert_cmd, err); + PRINT_ERROR("Failed to send pdu conn:%p pdu:%p err:%d", + isert_conn, isert_cmd, err); } TRACE_EXIT_RES(err); diff --git a/iscsi-scst/kernel/isert-scst/iser_rdma.c b/iscsi-scst/kernel/isert-scst/iser_rdma.c index 2e1cf989a..0c8d11014 100644 --- a/iscsi-scst/kernel/isert-scst/iser_rdma.c +++ b/iscsi-scst/kernel/isert-scst/iser_rdma.c @@ -77,7 +77,7 @@ int isert_post_recv(struct isert_connection *isert_conn, #ifdef CONFIG_SCST_EXTRACHECKS if (test_bit(ISERT_DRAIN_POSTED, &isert_conn->flags)) { - pr_err("conn:%p post recv after drain\n", isert_conn); + PRINT_ERROR("conn:%p post recv after drain", isert_conn); BUG(); } #endif @@ -86,9 +86,9 @@ int isert_post_recv(struct isert_connection *isert_conn, if (unlikely(err)) { num_posted = isert_num_recv_posted_on_err(first_ib_wr, bad_wr); - pr_err("conn:%p recv posted:%d/%d 1st wr_id:0x%llx sz:%d err:%d\n", - isert_conn, num_posted, num_wr, first_ib_wr->wr_id, - first_ib_wr->sg_list->length, err); + PRINT_ERROR("conn:%p recv posted:%d/%d 1st wr_id:0x%llx sz:%d err:%d", + isert_conn, num_posted, num_wr, first_ib_wr->wr_id, + first_ib_wr->sg_list->length, err); } TRACE_EXIT_RES(err); @@ -124,7 +124,7 @@ int isert_post_send(struct isert_connection *isert_conn, #ifdef CONFIG_SCST_EXTRACHECKS if (test_bit(ISERT_DRAIN_POSTED, &isert_conn->flags)) { - pr_err("conn:%p post send after drain\n", isert_conn); + PRINT_ERROR("conn:%p post send after drain", isert_conn); BUG(); } #endif @@ -133,9 +133,9 @@ int isert_post_send(struct isert_connection *isert_conn, if (unlikely(err)) { num_posted = isert_num_send_posted_on_err(first_ib_wr, bad_wr); - pr_err("conn:%p send posted:%d/%d bad wr_id:0x%llx sz:%d num_sge: %d err:%d\n", - isert_conn, num_posted, num_wr, bad_wr->wr_id, - bad_wr->sg_list->length, bad_wr->num_sge, err); + PRINT_ERROR("conn:%p send posted:%d/%d bad wr_id:0x%llx sz:%d num_sge: %d err:%d", + isert_conn, num_posted, num_wr, bad_wr->wr_id, + bad_wr->sg_list->length, bad_wr->num_sge, err); } TRACE_EXIT_RES(err); @@ -164,7 +164,7 @@ void isert_post_drain(struct isert_connection *isert_conn) &isert_conn->drain_wr.send_wr.wr, &bad_wr); #endif if (unlikely(err)) { - pr_err("Failed to post drain wr, err:%d\n", err); + PRINT_ERROR("Failed to post drain wr, err:%d", err); /* * We need to decrement iser_conn->kref in order to be * able to cleanup the connection. @@ -185,13 +185,13 @@ void isert_conn_disconnect(struct isert_connection *isert_conn) err = rdma_disconnect(isert_conn->cm_id); if (unlikely(err)) - pr_err("Failed to rdma disconnect, err:%d\n", err); + PRINT_ERROR("Failed to rdma disconnect, err:%d", err); } } static int isert_pdu_handle_hello_req(struct isert_cmnd *pdu) { - pr_info("iSER Hello not supported\n"); + PRINT_INFO("iSER Hello not supported"); return -EINVAL; /* meanwhile disconnect immediately */ } @@ -226,7 +226,7 @@ static int isert_pdu_handle_tm_func(struct isert_cmnd *pdu) static int isert_pdu_handle_data_out(struct isert_cmnd *pdu) { - pr_info("iser iscsi data out not supported\n"); + PRINT_INFO("iser iscsi data out not supported"); return -EINVAL; /* meanwhile disconnect immediately */ } @@ -237,7 +237,7 @@ static int isert_pdu_handle_logout(struct isert_cmnd *pdu) static int isert_pdu_handle_snack(struct isert_cmnd *pdu) { - pr_info("iser iscsi SNACK not supported\n"); + PRINT_INFO("iser iscsi SNACK not supported"); return -EINVAL; /* meanwhile disconnect immediately */ } @@ -360,8 +360,8 @@ static void isert_recv_completion_handler(struct isert_wr *wr) err = isert_pdu_handle_snack(pdu); break; default: - pr_err("Unexpected iscsi opcode:0x%x\n", - pdu->iscsi_opcode); + PRINT_ERROR("Unexpected iscsi opcode:0x%x", + pdu->iscsi_opcode); err = -EINVAL; break; } @@ -370,14 +370,14 @@ static void isert_recv_completion_handler(struct isert_wr *wr) err = isert_pdu_handle_hello_req(pdu); break; default: - pr_err("malformed isert_hdr, iser op:%x flags 0x%02x\n", - pdu->isert_opcode, pdu->isert_hdr->flags); + PRINT_ERROR("malformed isert_hdr, iser op:%x flags 0x%02x", + pdu->isert_opcode, pdu->isert_hdr->flags); err = -EINVAL; break; } if (unlikely(err)) { - pr_err("err:%d while handling iser pdu\n", err); + PRINT_ERROR("err:%d while handling iser pdu", err); isert_conn_disconnect(wr->conn); } @@ -443,7 +443,7 @@ static void isert_handle_wc(struct ib_wc *wc) if (unlikely(isert_conn->state == ISER_CONN_HANDSHAKE)) { isert_conn->state = ISER_CONN_ACTIVE; isert_conn->saved_wr = wr; - pr_info("iser rx pdu before conn established, pdu saved\n"); + PRINT_INFO("iser rx pdu before conn established, pdu saved"); break; } isert_recv_completion_handler(wr); @@ -459,8 +459,8 @@ static void isert_handle_wc(struct ib_wc *wc) break; default: isert_conn = wr->conn; - pr_err("unexpected work req op:%d, wc op:%d, wc:%p wr_id:%p conn:%p\n", - wr->wr_op, wc->opcode, wc, wr, isert_conn); + PRINT_ERROR("unexpected work req op:%d, wc op:%d, wc:%p wr_id:%p conn:%p", + wr->wr_op, wc->opcode, wc, wr, isert_conn); if (isert_conn) isert_conn_disconnect(isert_conn); break; @@ -670,9 +670,9 @@ static void isert_handle_wc_error(struct ib_wc *wc) TRACE_ENTRY(); if (wc->status != IB_WC_WR_FLUSH_ERR) - pr_err("conn:%p wr_id:0x%p status:%s vendor_err:0x%0x\n", - isert_conn, wr, wr_status_str(wc->status), - wc->vendor_err); + PRINT_ERROR("conn:%p wr_id:0x%p status:%s vendor_err:0x%0x", + isert_conn, wr, wr_status_str(wc->status), + wc->vendor_err); if (!test_bit(ISERT_CONNECTION_ABORTED, &isert_conn->flags)) if (!test_and_set_bit(ISERT_DISCON_CALLED, &isert_conn->flags)) @@ -715,8 +715,8 @@ static void isert_handle_wc_error(struct ib_wc *wc) */ break; default: - pr_err("unexpected opcode %d, wc:%p wr_id:%p conn:%p\n", - wr->wr_op, wc, wr, isert_conn); + PRINT_ERROR("unexpected opcode %d, wc:%p wr_id:%p conn:%p", + wr->wr_op, wc, wr, isert_conn); break; } @@ -764,7 +764,7 @@ static void isert_cq_comp_work_cb(struct work_struct *work) ret = isert_poll_cq(cq_desc); if (unlikely(ret < 0)) { /* poll error */ - pr_err("ib_poll_cq failed\n"); + PRINT_ERROR("ib_poll_cq failed"); goto out; } @@ -852,9 +852,9 @@ static void isert_async_evt_handler(struct ib_event *async_ev, void *context) switch (ev_type) { case IB_EVENT_COMM_EST: isert_conn = async_ev->element.qp->qp_context; - pr_info("conn:0x%p cm_id:0x%p dev:%s, QP evt: %s\n", - isert_conn, isert_conn->cm_id, dev_name, - ib_event_type_str(IB_EVENT_COMM_EST)); + PRINT_INFO("conn:0x%p cm_id:0x%p dev:%s, QP evt: %s", + isert_conn, isert_conn->cm_id, dev_name, + ib_event_type_str(IB_EVENT_COMM_EST)); /* force "connection established" event */ rdma_notify(isert_conn->cm_id, IB_EVENT_COMM_EST); break; @@ -868,22 +868,22 @@ static void isert_async_evt_handler(struct ib_event *async_ev, void *context) case IB_EVENT_PATH_MIG_ERR: case IB_EVENT_QP_LAST_WQE_REACHED: isert_conn = async_ev->element.qp->qp_context; - pr_err("conn:0x%p cm_id:0x%p dev:%s, QP evt: %s\n", - isert_conn, isert_conn->cm_id, dev_name, - ib_event_type_str(ev_type)); + PRINT_ERROR("conn:0x%p cm_id:0x%p dev:%s, QP evt: %s", + isert_conn, isert_conn->cm_id, dev_name, + ib_event_type_str(ev_type)); break; /* CQ-related events */ case IB_EVENT_CQ_ERR: - pr_err("dev:%s CQ evt: %s\n", dev_name, - ib_event_type_str(ev_type)); + PRINT_ERROR("dev:%s CQ evt: %s", dev_name, + ib_event_type_str(ev_type)); break; /* SRQ events */ case IB_EVENT_SRQ_ERR: case IB_EVENT_SRQ_LIMIT_REACHED: - pr_err("dev:%s SRQ evt: %s\n", dev_name, - ib_event_type_str(ev_type)); + PRINT_ERROR("dev:%s SRQ evt: %s", dev_name, + ib_event_type_str(ev_type)); break; /* Port events */ @@ -893,20 +893,20 @@ static void isert_async_evt_handler(struct ib_event *async_ev, void *context) case IB_EVENT_PKEY_CHANGE: case IB_EVENT_SM_CHANGE: case IB_EVENT_CLIENT_REREGISTER: - pr_err("dev:%s port:%d evt: %s\n", - dev_name, async_ev->element.port_num, - ib_event_type_str(ev_type)); + PRINT_ERROR("dev:%s port:%d evt: %s", + dev_name, async_ev->element.port_num, + ib_event_type_str(ev_type)); break; /* HCA events */ case IB_EVENT_DEVICE_FATAL: - pr_err("dev:%s HCA evt: %s\n", dev_name, - ib_event_type_str(ev_type)); + PRINT_ERROR("dev:%s HCA evt: %s", dev_name, + ib_event_type_str(ev_type)); break; default: - pr_err("dev:%s evt: %s\n", dev_name, - ib_event_type_str(ev_type)); + PRINT_ERROR("dev:%s evt: %s", dev_name, + ib_event_type_str(ev_type)); break; } @@ -927,7 +927,7 @@ static struct isert_device *isert_device_create(struct ib_device *ib_dev) isert_dev = kzalloc(sizeof(*isert_dev), GFP_KERNEL); if (unlikely(isert_dev == NULL)) { - pr_err("Failed to allocate iser dev\n"); + PRINT_ERROR("Failed to allocate iser dev"); err = -ENOMEM; goto out; } @@ -935,7 +935,7 @@ static struct isert_device *isert_device_create(struct ib_device *ib_dev) #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0) err = ib_query_device(ib_dev, &isert_dev->device_attr); if (unlikely(err)) { - pr_err("Failed to query device, err: %d\n", err); + PRINT_ERROR("Failed to query device, err: %d", err); goto free_isert_dev; } #else @@ -949,15 +949,15 @@ static struct isert_device *isert_device_create(struct ib_device *ib_dev) sizeof(*isert_dev->cq_qps), GFP_KERNEL); if (unlikely(isert_dev->cq_qps == NULL)) { - pr_err("Failed to allocate iser cq_qps\n"); + PRINT_ERROR("Failed to allocate iser cq_qps"); err = -ENOMEM; goto free_isert_dev; } isert_dev->cq_desc = vmalloc(sizeof(*isert_dev->cq_desc) * isert_dev->num_cqs); if (unlikely(isert_dev->cq_desc == NULL)) { - pr_err("Failed to allocate %ld bytes for iser cq_desc\n", - sizeof(*isert_dev->cq_desc) * isert_dev->num_cqs); + PRINT_ERROR("Failed to allocate %ld bytes for iser cq_desc", + sizeof(*isert_dev->cq_desc) * isert_dev->num_cqs); err = -ENOMEM; goto fail_alloc_cq_desc; } @@ -965,14 +965,14 @@ static struct isert_device *isert_device_create(struct ib_device *ib_dev) pd = ib_alloc_pd(ib_dev); if (unlikely(IS_ERR(pd))) { err = PTR_ERR(pd); - pr_err("Failed to alloc iser dev pd, err:%d\n", err); + PRINT_ERROR("Failed to alloc iser dev pd, err:%d", err); goto fail_pd; } mr = ib_get_dma_mr(pd, IB_ACCESS_LOCAL_WRITE); if (unlikely(IS_ERR(mr))) { err = PTR_ERR(mr); - pr_err("Failed to get dma mr, err: %d\n", err); + PRINT_ERROR("Failed to get dma mr, err: %d", err); goto fail_mr; } @@ -981,7 +981,7 @@ static struct isert_device *isert_device_create(struct ib_device *ib_dev) #ifdef CONFIG_SCST_EXTRACHECKS if (isert_dev->device_attr.max_cqe == 0) - pr_err("Zero max_cqe encountered: you may have a compilation problem\n"); + PRINT_ERROR("Zero max_cqe encountered: you may have a compilation problem"); #endif for (i = 0; i < isert_dev->num_cqs; ++i) { @@ -1010,8 +1010,8 @@ static struct isert_device *isert_device_create(struct ib_device *ib_dev) #endif #endif if (unlikely(!cq_desc->cq_workqueue)) { - pr_err("Failed to alloc iser cq work queue for dev:%s\n", - ib_dev->name); + PRINT_ERROR("Failed to alloc iser cq work queue for dev:%s", + ib_dev->name); err = -ENOMEM; goto fail_cq; } @@ -1040,14 +1040,14 @@ static struct isert_device *isert_device_create(struct ib_device *ib_dev) if (unlikely(IS_ERR(cq))) { cq_desc->cq = NULL; err = PTR_ERR(cq); - pr_err("Failed to create iser dev cq, err:%d\n", err); + PRINT_ERROR("Failed to create iser dev cq, err:%d", err); goto fail_cq; } cq_desc->cq = cq; err = ib_req_notify_cq(cq, IB_CQ_NEXT_COMP | IB_CQ_REPORT_MISSED_EVENTS); if (unlikely(err)) { - pr_err("Failed to request notify cq, err: %d\n", err); + PRINT_ERROR("Failed to request notify cq, err: %d", err); goto fail_cq; } } @@ -1062,7 +1062,7 @@ static struct isert_device *isert_device_create(struct ib_device *ib_dev) isert_dev_list_add(isert_dev); - pr_info("iser created device:%p\n", isert_dev); + PRINT_INFO("iser created device:%p", isert_dev); return isert_dev; fail_cq: @@ -1111,14 +1111,14 @@ static void isert_device_release(struct isert_device *isert_dev) err = ib_destroy_cq(cq_desc->cq); if (unlikely(err)) - pr_err("Failed to destroy cq, err:%d\n", err); + PRINT_ERROR("Failed to destroy cq, err:%d", err); destroy_workqueue(cq_desc->cq_workqueue); } err = ib_dereg_mr(isert_dev->mr); if (unlikely(err)) - pr_err("Failed to destroy mr, err:%d\n", err); + PRINT_ERROR("Failed to destroy mr, err:%d", err); ib_dealloc_pd(isert_dev->pd); vfree(isert_dev->cq_desc); @@ -1176,7 +1176,7 @@ static int isert_conn_qp_create(struct isert_connection *isert_conn) do { if (max_wr < ISER_MIN_SQ_SIZE) { - pr_err("Failed to create qp, not enough memory\n"); + PRINT_ERROR("Failed to create qp, not enough memory"); goto fail_create_qp; } @@ -1185,7 +1185,7 @@ static int isert_conn_qp_create(struct isert_connection *isert_conn) err = rdma_create_qp(cm_id, isert_dev->pd, &qp_attr); if (err && err != -ENOMEM) { - pr_err("Failed to create qp, err:%d\n", err); + PRINT_ERROR("Failed to create qp, err:%d", err); goto fail_create_qp; } @@ -1194,7 +1194,7 @@ static int isert_conn_qp_create(struct isert_connection *isert_conn) isert_conn->qp = cm_id->qp; - pr_info("iser created cm_id:%p qp:0x%X\n", cm_id, cm_id->qp->qp_num); + PRINT_INFO("iser created cm_id:%p qp:0x%X", cm_id, cm_id->qp->qp_num); out: TRACE_EXIT_RES(err); @@ -1218,7 +1218,7 @@ static struct isert_connection *isert_conn_create(struct rdma_cm_id *cm_id, isert_conn = isert_conn_zalloc(); if (unlikely(!isert_conn)) { - pr_err("Unable to allocate iser conn, cm_id:%p\n", cm_id); + PRINT_ERROR("Unable to allocate iser conn, cm_id:%p", cm_id); err = -ENOMEM; goto fail_alloc; } @@ -1250,7 +1250,7 @@ static struct isert_connection *isert_conn_create(struct rdma_cm_id *cm_id, isert_conn->login_req_pdu = isert_rx_pdu_alloc(isert_conn, ISER_MAX_LOGIN_RDSL); if (unlikely(!isert_conn->login_req_pdu)) { - pr_err("Failed to init login req rx pdu\n"); + PRINT_ERROR("Failed to init login req rx pdu"); err = -ENOMEM; goto fail_login_req_pdu; } @@ -1258,7 +1258,7 @@ static struct isert_connection *isert_conn_create(struct rdma_cm_id *cm_id, isert_conn->login_rsp_pdu = isert_tx_pdu_alloc(isert_conn, ISER_MAX_LOGIN_RDSL); if (unlikely(!isert_conn->login_rsp_pdu)) { - pr_err("Failed to init login rsp tx pdu\n"); + PRINT_ERROR("Failed to init login rsp tx pdu"); err = -ENOMEM; goto fail_login_rsp_pdu; } @@ -1269,7 +1269,7 @@ static struct isert_connection *isert_conn_create(struct rdma_cm_id *cm_id, err = isert_post_recv(isert_conn, &isert_conn->login_req_pdu->wr[0], 1); if (unlikely(err)) { - pr_err("Failed to post recv login req rx buf, err:%d\n", err); + PRINT_ERROR("Failed to post recv login req rx buf, err:%d", err); goto fail_post_recv; } @@ -1314,7 +1314,7 @@ static void isert_kref_free(struct kref *kref) TRACE_ENTRY(); - pr_info("%s conn:%p\n", __func__, isert_conn); + PRINT_INFO("free conn:%p", isert_conn); isert_free_conn_resources(isert_conn); @@ -1433,39 +1433,39 @@ static int isert_cm_conn_req_handler(struct rdma_cm_id *cm_id, err = rdma_accept(cm_id, &tgt_conn_param); if (unlikely(err)) { - pr_err("Failed to accept conn request, err:%d\n", err); + PRINT_ERROR("Failed to accept conn request, err:%d", err); goto fail_accept; } switch (isert_conn->peer_addr.ss_family) { case AF_INET: #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) - pr_info("iser accepted connection cm_id:%p " - NIPQUAD_FMT "->" NIPQUAD_FMT "\n", cm_id, - NIPQUAD(((struct sockaddr_in *)&isert_conn->peer_addr)->sin_addr.s_addr), - NIPQUAD(((struct sockaddr_in *)&isert_conn->self_addr)->sin_addr.s_addr)); + PRINT_INFO("iser accepted connection cm_id:%p " + NIPQUAD_FMT "->" NIPQUAD_FMT, cm_id, + NIPQUAD(((struct sockaddr_in *)&isert_conn->peer_addr)->sin_addr.s_addr), + NIPQUAD(((struct sockaddr_in *)&isert_conn->self_addr)->sin_addr.s_addr)); #else - pr_info("iser accepted connection cm_id:%p " - "%pI4->%pI4\n", cm_id, - &((struct sockaddr_in *)&isert_conn->peer_addr)->sin_addr.s_addr, - &((struct sockaddr_in *)&isert_conn->self_addr)->sin_addr.s_addr); + PRINT_INFO("iser accepted connection cm_id:%p " + "%pI4->%pI4", cm_id, + &((struct sockaddr_in *)&isert_conn->peer_addr)->sin_addr.s_addr, + &((struct sockaddr_in *)&isert_conn->self_addr)->sin_addr.s_addr); #endif break; case AF_INET6: #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) - pr_info("iser accepted connection cm_id:%p " - NIP6_FMT "->" NIP6_FMT "\n", cm_id, - NIP6(((struct sockaddr_in6 *)&isert_conn->peer_addr)->sin6_addr), - NIP6(((struct sockaddr_in6 *)&isert_conn->self_addr)->sin6_addr)); + PRINT_INFO("iser accepted connection cm_id:%p " + NIP6_FMT "->" NIP6_FMT, cm_id, + NIP6(((struct sockaddr_in6 *)&isert_conn->peer_addr)->sin6_addr), + NIP6(((struct sockaddr_in6 *)&isert_conn->self_addr)->sin6_addr)); #else - pr_info("iser accepted connection cm_id:%p " - "%pI6->%pI6\n", cm_id, - &((struct sockaddr_in6 *)&isert_conn->peer_addr)->sin6_addr, - &((struct sockaddr_in6 *)&isert_conn->self_addr)->sin6_addr); + PRINT_INFO("iser accepted connection cm_id:%p " + "%pI6->%pI6", cm_id, + &((struct sockaddr_in6 *)&isert_conn->peer_addr)->sin6_addr, + &((struct sockaddr_in6 *)&isert_conn->self_addr)->sin6_addr); #endif break; default: - pr_info("iser accepted connection cm_id:%p\n", cm_id); + PRINT_INFO("iser accepted connection cm_id:%p", cm_id); } out: @@ -1527,7 +1527,7 @@ static int isert_cm_connect_handler(struct rdma_cm_id *cm_id, set_bit(ISERT_CONNECTION_EST, &isert_conn->flags); if (push_saved_pdu) { - pr_info("iser push saved rx pdu\n"); + PRINT_INFO("iser push saved rx pdu"); isert_recv_completion_handler(isert_conn->saved_wr); isert_conn->saved_wr = NULL; } @@ -1610,8 +1610,8 @@ static int isert_cm_evt_listener_handler(struct rdma_cm_id *cm_id, break; default: - pr_info("Listener event:%s(%d), ignored\n", - cm_event_type_str(ev_type), ev_type); + PRINT_INFO("Listener event:%s(%d), ignored", + cm_event_type_str(ev_type), ev_type); break; } @@ -1629,9 +1629,9 @@ static int isert_cm_evt_handler(struct rdma_cm_id *cm_id, ev_type = cm_ev->event; portal = cm_id->context; - pr_info("isert_cm_evt:%s(%d) status:%d portal:%p cm_id:%p\n", - cm_event_type_str(ev_type), ev_type, cm_ev->status, - portal, cm_id); + PRINT_INFO("isert_cm_evt:%s(%d) status:%d portal:%p cm_id:%p", + cm_event_type_str(ev_type), ev_type, cm_ev->status, + portal, cm_id); if (portal->cm_id == cm_id) { err = isert_cm_evt_listener_handler(cm_id, cm_ev); @@ -1665,7 +1665,7 @@ static int isert_cm_evt_handler(struct rdma_cm_id *cm_id, case RDMA_CM_EVENT_MULTICAST_JOIN: case RDMA_CM_EVENT_MULTICAST_ERROR: - pr_err("UD-related event:%d, ignored\n", ev_type); + PRINT_ERROR("UD-related event:%d, ignored", ev_type); break; case RDMA_CM_EVENT_ADDR_RESOLVED: @@ -1673,7 +1673,7 @@ static int isert_cm_evt_handler(struct rdma_cm_id *cm_id, case RDMA_CM_EVENT_ROUTE_RESOLVED: case RDMA_CM_EVENT_ROUTE_ERROR: case RDMA_CM_EVENT_CONNECT_RESPONSE: - pr_err("Active side event:%d, ignored\n", ev_type); + PRINT_ERROR("Active side event:%d, ignored", ev_type); break; /* We can receive this instead of RDMA_CM_EVENT_ESTABLISHED */ @@ -1695,13 +1695,13 @@ static int isert_cm_evt_handler(struct rdma_cm_id *cm_id, break; default: - pr_err("Illegal event:%d, ignored\n", ev_type); + PRINT_ERROR("Illegal event:%d, ignored", ev_type); break; } if (unlikely(err)) - pr_err("Failed to handle rdma cm evt:%d, err:%d\n", - ev_type, err); + PRINT_ERROR("Failed to handle rdma cm evt:%d, err:%d", + ev_type, err); out: TRACE_EXIT_RES(err); @@ -1718,14 +1718,14 @@ struct isert_portal *isert_portal_create(void) int err; if (unlikely(!try_module_get(THIS_MODULE))) { - pr_err("Unable increment module reference\n"); + PRINT_ERROR("Unable increment module reference"); portal = ERR_PTR(-EINVAL); goto out; } portal = kzalloc(sizeof(*portal), GFP_KERNEL); if (unlikely(!portal)) { - pr_err("Unable to allocate struct portal\n"); + PRINT_ERROR("Unable to allocate struct portal"); portal = ERR_PTR(-ENOMEM); goto err_alloc; } @@ -1742,7 +1742,7 @@ struct isert_portal *isert_portal_create(void) #endif if (unlikely(IS_ERR(cm_id))) { err = PTR_ERR(cm_id); - pr_err("Failed to create rdma id, err:%d\n", err); + PRINT_ERROR("Failed to create rdma id, err:%d", err); goto create_id_err; } portal->cm_id = cm_id; @@ -1754,7 +1754,7 @@ struct isert_portal *isert_portal_create(void) rdma_set_afonly(cm_id, 1); #endif - pr_info("Created iser portal cm_id:%p\n", cm_id); + PRINT_INFO("Created iser portal cm_id:%p", cm_id); out: return portal; @@ -1775,12 +1775,12 @@ int isert_portal_listen(struct isert_portal *portal, TRACE_ENTRY(); err = rdma_bind_addr(portal->cm_id, sa); if (err) { - pr_warn("Failed to bind rdma addr, err:%d\n", err); + PRINT_WARNING("Failed to bind rdma addr, err:%d", err); goto out; } err = rdma_listen(portal->cm_id, ISER_LISTEN_BACKLOG); if (err) { - pr_err("Failed rdma listen, err:%d\n", err); + PRINT_ERROR("Failed rdma listen, err:%d", err); goto out; } memcpy(&portal->addr, sa, addr_len); @@ -1788,33 +1788,33 @@ int isert_portal_listen(struct isert_portal *portal, switch (sa->sa_family) { case AF_INET: #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) - pr_info("iser portal cm_id:%p listens on: " - NIPQUAD_FMT ":%d\n", portal->cm_id, - NIPQUAD(((struct sockaddr_in *)sa)->sin_addr.s_addr), - (int)ntohs(((struct sockaddr_in *)sa)->sin_port)); + PRINT_INFO("iser portal cm_id:%p listens on: " + NIPQUAD_FMT ":%d", portal->cm_id, + NIPQUAD(((struct sockaddr_in *)sa)->sin_addr.s_addr), + (int)ntohs(((struct sockaddr_in *)sa)->sin_port)); #else - pr_info("iser portal cm_id:%p listens on: " - "%pI4:%d\n", portal->cm_id, - &((struct sockaddr_in *)sa)->sin_addr.s_addr, - (int)ntohs(((struct sockaddr_in *)sa)->sin_port)); + PRINT_INFO("iser portal cm_id:%p listens on: " + "%pI4:%d", portal->cm_id, + &((struct sockaddr_in *)sa)->sin_addr.s_addr, + (int)ntohs(((struct sockaddr_in *)sa)->sin_port)); #endif break; case AF_INET6: #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) - pr_info("iser portal cm_id:%p listens on: " - NIP6_FMT " %d\n", - portal->cm_id, - NIP6(((struct sockaddr_in6 *)sa)->sin6_addr), - (int)ntohs(((struct sockaddr_in6 *)sa)->sin6_port)); + PRINT_INFO("iser portal cm_id:%p listens on: " + NIP6_FMT " %d", + portal->cm_id, + NIP6(((struct sockaddr_in6 *)sa)->sin6_addr), + (int)ntohs(((struct sockaddr_in6 *)sa)->sin6_port)); #else - pr_info("iser portal cm_id:%p listens on: " - "%pI6 %d\n", portal->cm_id, - &((struct sockaddr_in6 *)sa)->sin6_addr, - (int)ntohs(((struct sockaddr_in6 *)sa)->sin6_port)); + PRINT_INFO("iser portal cm_id:%p listens on: " + "%pI6 %d", portal->cm_id, + &((struct sockaddr_in6 *)sa)->sin6_addr, + (int)ntohs(((struct sockaddr_in6 *)sa)->sin6_port)); #endif break; default: - pr_err("Unknown address family\n"); + PRINT_ERROR("Unknown address family"); err = -EINVAL; goto out; } @@ -1839,7 +1839,7 @@ void isert_portal_release(struct isert_portal *portal) { struct isert_connection *conn; - pr_info("iser portal cm_id:%p releasing\n", portal->cm_id); + PRINT_INFO("iser portal cm_id:%p releasing", portal->cm_id); if (portal->cm_id) { rdma_destroy_id(portal->cm_id); diff --git a/iscsi-scst/kernel/isert-scst/isert.c b/iscsi-scst/kernel/isert-scst/isert.c index 3493812e3..c0562e379 100644 --- a/iscsi-scst/kernel/isert-scst/isert.c +++ b/iscsi-scst/kernel/isert-scst/isert.c @@ -398,8 +398,8 @@ int isert_pdu_sent(struct iscsi_cmnd *pdu) struct iscsi_target *target = pdu->conn->session->target; PRINT_INFO("Closing all connections for target %x at " - "initiator's %s request", target->tid, - conn->session->initiator_name); + "initiator's %s request", target->tid, + conn->session->initiator_name); mutex_lock(&target->target_mutex); target_del_all_sess(target, 0); mutex_unlock(&target->target_mutex); @@ -497,7 +497,7 @@ static int __init isert_init_module(void) int ret; if (isert_nr_devs > 999) { - PRINT_ERROR("Invalid argument for isert_nr_devs provded: %d\n", + PRINT_ERROR("Invalid argument for isert_nr_devs provded: %d", isert_nr_devs); ret = -EINVAL; goto out; diff --git a/iscsi-scst/kernel/isert-scst/isert_login.c b/iscsi-scst/kernel/isert-scst/isert_login.c index 7ecab2595..cfce8f744 100644 --- a/iscsi-scst/kernel/isert-scst/isert_login.c +++ b/iscsi-scst/kernel/isert-scst/isert_login.c @@ -140,7 +140,7 @@ static void isert_conn_timer_fn(unsigned long arg) conn_dev->timer_active = 0; - PRINT_ERROR("Timeout on connection %p\n", conn_dev->conn); + PRINT_ERROR("Timeout on connection %p", conn_dev->conn); schedule_work(&conn->close_work); @@ -156,7 +156,7 @@ static int add_new_connection(struct isert_listener_dev *dev, TRACE_ENTRY(); if (!conn_dev) { - PRINT_WARNING("%s", "Unable to allocate new connection"); + PRINT_WARNING("Unable to allocate new connection"); res = -ENOSPC; goto out; } @@ -398,13 +398,13 @@ static long isert_listen_ioctl(struct file *filp, unsigned int cmd, case SET_LISTEN_ADDR: rc = copy_from_user(&dev->info, ptr, sizeof(dev->info)); if (unlikely(rc != 0)) { - PRINT_ERROR("Failed to copy %d user's bytes\n", rc); + PRINT_ERROR("Failed to copy %d user's bytes", rc); res = -EFAULT; goto out; } if (unlikely(dev->free_portal_idx >= ISERT_MAX_PORTALS)) { - PRINT_ERROR("Maximum number of portals exceeded: %d\n", + PRINT_ERROR("Maximum number of portals exceeded: %d", ISERT_MAX_PORTALS); res = -EINVAL; goto out; @@ -420,7 +420,7 @@ static long isert_listen_ioctl(struct file *filp, unsigned int cmd, portal = isert_portal_add((struct sockaddr *)&dev->info.addr, dev->info.addr_len); if (IS_ERR(portal)) { - PRINT_ERROR("Unable to add portal of size %zu\n", + PRINT_ERROR("Unable to add portal of size %zu", dev->info.addr_len); res = PTR_ERR(portal); goto out; @@ -622,8 +622,7 @@ static ssize_t isert_read(struct file *filp, char __user *buf, size_t count, break; default: - PRINT_ERROR("Invalid state in %s (%d)\n", __func__, - dev->state); + PRINT_ERROR("Invalid state %d", dev->state); to_read = 0; } @@ -666,8 +665,7 @@ static ssize_t isert_write(struct file *filp, const char __user *buf, break; default: - PRINT_ERROR("Invalid state in %s (%d)\n", __func__, - dev->state); + PRINT_ERROR("Invalid state %d", dev->state); to_write = 0; } @@ -959,7 +957,7 @@ int __init isert_init_login_devs(unsigned int ndevs) isert_major = MAJOR(devno); if (unlikely(res < 0)) { - PRINT_ERROR("isert: can't get major %d\n", isert_major); + PRINT_ERROR("can't get major %d", isert_major); goto out; } @@ -984,7 +982,7 @@ int __init isert_init_login_devs(unsigned int ndevs) res = isert_datamover_init(); if (unlikely(res)) { - PRINT_ERROR("Unable to initialize datamover: %d\n", res); + PRINT_ERROR("Unable to initialize datamover: %d", res); goto fail; } From 807ae45a76457ffd67e7e6dd53725e72f610f596 Mon Sep 17 00:00:00 2001 From: Israel Rukshin Date: Wed, 17 Aug 2016 07:27:53 +0000 Subject: [PATCH 13/26] isert: fix a race between timewait exit handler and poll cq Timewait exit event handler start to close iscsi conn before poll cq finish to handle all the good completions. This may lead to NULL deref at poll cq context or post recv after post drain. This commit close iscsi conn only when start getting flush. Flush is guaranteed if iscsi conn was created because when allocating iscsi conn we call post recv. Signed-off-by: Israel Rukshin git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6945 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/isert-scst/iser_datamover.h | 3 +- iscsi-scst/kernel/isert-scst/iser_rdma.c | 6 +- iscsi-scst/kernel/isert-scst/isert.c | 3 +- iscsi-scst/kernel/isert-scst/isert.h | 2 +- iscsi-scst/kernel/isert-scst/isert_login.c | 64 ++++++++++++------- 5 files changed, 48 insertions(+), 30 deletions(-) diff --git a/iscsi-scst/kernel/isert-scst/iser_datamover.h b/iscsi-scst/kernel/isert-scst/iser_datamover.h index 9a41dc291..6191fcd10 100644 --- a/iscsi-scst/kernel/isert-scst/iser_datamover.h +++ b/iscsi-scst/kernel/isert-scst/iser_datamover.h @@ -86,7 +86,8 @@ int isert_data_in_sent(struct iscsi_cmnd *cmd); int isert_pdu_sent(struct iscsi_cmnd *pdu); void isert_pdu_err(struct iscsi_cmnd *pdu); -int isert_connection_closed(struct iscsi_conn *iscsi_conn); +void isert_connection_closed(struct iscsi_conn *iscsi_conn); +void isert_connection_abort(struct iscsi_conn *iscsi_conn); void *isert_get_priv(struct iscsi_conn *iscsi_conn); void isert_set_priv(struct iscsi_conn *iscsi_conn, void *priv); diff --git a/iscsi-scst/kernel/isert-scst/iser_rdma.c b/iscsi-scst/kernel/isert-scst/iser_rdma.c index 0c8d11014..af33d4fa9 100644 --- a/iscsi-scst/kernel/isert-scst/iser_rdma.c +++ b/iscsi-scst/kernel/isert-scst/iser_rdma.c @@ -610,8 +610,7 @@ static void isert_conn_closed_do_work(struct work_struct *work) #endif if (!test_bit(ISERT_CONNECTION_ABORTED, &isert_conn->flags)) - if (!test_and_set_bit(ISERT_DISCON_CALLED, &isert_conn->flags)) - isert_connection_closed(&isert_conn->iscsi); + isert_connection_abort(&isert_conn->iscsi); /* if connection established we have another refcount */ if (test_bit(ISERT_CONNECTION_EST, &isert_conn->flags)) { @@ -1657,9 +1656,8 @@ static int isert_cm_evt_handler(struct rdma_cm_id *cm_id, break; case RDMA_CM_EVENT_DEVICE_REMOVAL: - isert_cm_disconnect_handler(cm_id, cm_ev); - /* fallthrough */ case RDMA_CM_EVENT_TIMEWAIT_EXIT: + isert_cm_disconnect_handler(cm_id, cm_ev); err = isert_cm_timewait_exit_handler(cm_id, cm_ev); break; diff --git a/iscsi-scst/kernel/isert-scst/isert.c b/iscsi-scst/kernel/isert-scst/isert.c index c0562e379..4d51073f8 100644 --- a/iscsi-scst/kernel/isert-scst/isert.c +++ b/iscsi-scst/kernel/isert-scst/isert.c @@ -288,7 +288,7 @@ static void isert_free_conn(struct iscsi_conn *conn) isert_free_connection(conn); } -int isert_handle_close_connection(struct iscsi_conn *conn) +void isert_handle_close_connection(struct iscsi_conn *conn) { isert_mark_conn_closed(conn, 0); /* @@ -300,7 +300,6 @@ int isert_handle_close_connection(struct iscsi_conn *conn) isert_free_connection(conn); else start_close_conn(conn); - return 0; } int isert_pdu_rx(struct iscsi_cmnd *cmnd) diff --git a/iscsi-scst/kernel/isert-scst/isert.h b/iscsi-scst/kernel/isert-scst/isert.h index 0c5113edf..d9052bd10 100644 --- a/iscsi-scst/kernel/isert-scst/isert.h +++ b/iscsi-scst/kernel/isert-scst/isert.h @@ -129,7 +129,7 @@ int isert_conn_alloc(struct iscsi_session *session, struct iscsi_kern_conn_info *info, struct iscsi_conn **new_conn, struct iscsit_transport *t); -int isert_handle_close_connection(struct iscsi_conn *conn); +void isert_handle_close_connection(struct iscsi_conn *conn); void isert_close_all_portals(void); void isert_del_timer(struct isert_conn_dev *dev); diff --git a/iscsi-scst/kernel/isert-scst/isert_login.c b/iscsi-scst/kernel/isert-scst/isert_login.c index cfce8f744..1a780949d 100644 --- a/iscsi-scst/kernel/isert-scst/isert_login.c +++ b/iscsi-scst/kernel/isert-scst/isert_login.c @@ -49,6 +49,7 @@ #include "isert_dbg.h" #include "../iscsi.h" #include "isert.h" +#include "iser.h" #include "iser_datamover.h" static DEFINE_MUTEX(conn_mgmt_mutex); @@ -444,41 +445,60 @@ int isert_conn_established(struct iscsi_conn *iscsi_conn, return add_new_connection(&isert_listen_dev, iscsi_conn); } -int isert_connection_closed(struct iscsi_conn *iscsi_conn) +static void isert_dev_disconnect(struct iscsi_conn* iscsi_conn) { - int res = 0; + struct isert_conn_dev* dev = isert_get_priv(iscsi_conn); + if (dev) { + isert_del_timer(dev); + dev->state = CS_DISCONNECTED; + if (dev->login_req) { + isert_task_abort(dev->login_req); + spin_lock(&dev->pdu_lock); + dev->login_req = NULL; + spin_unlock(&dev->pdu_lock); + } + wake_up(&dev->waitqueue); + isert_dev_release(dev); + isert_set_priv(iscsi_conn, NULL); + } +} + +void isert_connection_closed(struct iscsi_conn *iscsi_conn) +{ TRACE_ENTRY(); mutex_lock(&conn_mgmt_mutex); if (iscsi_conn->rd_state) { mutex_unlock(&conn_mgmt_mutex); - res = isert_handle_close_connection(iscsi_conn); + isert_handle_close_connection(iscsi_conn); } else { - struct isert_conn_dev *dev = isert_get_priv(iscsi_conn); - - if (dev) { - isert_del_timer(dev); - dev->state = CS_DISCONNECTED; - if (dev->login_req) { - res = isert_task_abort(dev->login_req); - spin_lock(&dev->pdu_lock); - dev->login_req = NULL; - spin_unlock(&dev->pdu_lock); - } - - wake_up(&dev->waitqueue); - isert_dev_release(dev); - isert_set_priv(iscsi_conn, NULL); - } - + isert_dev_disconnect(iscsi_conn); mutex_unlock(&conn_mgmt_mutex); isert_free_connection(iscsi_conn); } - TRACE_EXIT_RES(res); - return res; + TRACE_EXIT(); +} + +void isert_connection_abort(struct iscsi_conn *iscsi_conn) +{ + struct isert_connection *isert_conn = (struct isert_connection *)iscsi_conn; + + TRACE_ENTRY(); + + mutex_lock(&conn_mgmt_mutex); + + if (!iscsi_conn->rd_state) { + if (!test_and_set_bit(ISERT_DISCON_CALLED, &isert_conn->flags)) { + isert_dev_disconnect(iscsi_conn); + isert_free_connection(iscsi_conn); + } + } + mutex_unlock(&conn_mgmt_mutex); + + TRACE_EXIT(); } static bool will_read_block(struct isert_conn_dev *dev) From 3ce0f6604d72cb7b79f0a04857b57851fd3b83ad Mon Sep 17 00:00:00 2001 From: Israel Rukshin Date: Wed, 17 Aug 2016 07:27:57 +0000 Subject: [PATCH 14/26] isert: fix a race when drain wr is not the last flush We must wait for both the send and recv cqs to flush all pending work requests. To make sure that the drain will be the last flush we post a second drain work request on the recv queue. Signed-off-by: Israel Rukshin git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6946 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/isert-scst/iser.h | 10 ++- iscsi-scst/kernel/isert-scst/iser_rdma.c | 94 ++++++++++++++++-------- 2 files changed, 71 insertions(+), 33 deletions(-) diff --git a/iscsi-scst/kernel/isert-scst/iser.h b/iscsi-scst/kernel/isert-scst/iser.h index f7f89e831..104f8d5e7 100644 --- a/iscsi-scst/kernel/isert-scst/iser.h +++ b/iscsi-scst/kernel/isert-scst/iser.h @@ -158,9 +158,10 @@ struct isert_cq { #define ISERT_CONNECTION_ABORTED 0 #define ISERT_DRAIN_POSTED 1 -#define ISERT_DRAIN_FAILED 2 -#define ISERT_DISCON_CALLED 3 -#define ISERT_CONNECTION_EST 4 +#define ISERT_DISCON_CALLED 2 +#define ISERT_CONNECTION_EST 3 +#define ISERT_DRAINED_RQ 4 +#define ISERT_DRAINED_SQ 5 struct isert_connection { struct iscsi_conn iscsi ____cacheline_aligned; @@ -218,7 +219,8 @@ struct isert_connection { struct work_struct drain_work; struct work_struct discon_work; struct work_struct free_work; - struct isert_wr drain_wr; + struct isert_wr drain_wr_sq; + struct isert_wr drain_wr_rq; struct kref kref; struct isert_portal *portal; diff --git a/iscsi-scst/kernel/isert-scst/iser_rdma.c b/iscsi-scst/kernel/isert-scst/iser_rdma.c index af33d4fa9..c0ad08749 100644 --- a/iscsi-scst/kernel/isert-scst/iser_rdma.c +++ b/iscsi-scst/kernel/isert-scst/iser_rdma.c @@ -142,36 +142,61 @@ int isert_post_send(struct isert_connection *isert_conn, return err; } +static void isert_post_drain_sq(struct isert_connection* isert_conn) +{ + struct ib_send_wr* bad_wr; + struct isert_wr *drain_wr_sq = &isert_conn->drain_wr_sq; + int err; + + isert_wr_set_fields(drain_wr_sq, isert_conn, NULL); + drain_wr_sq->wr_op = ISER_WR_SEND; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) + drain_wr_sq->send_wr.wr_id = _ptr_to_u64(drain_wr_sq); + drain_wr_sq->send_wr.opcode = IB_WR_SEND; + err = ib_post_send(isert_conn->qp, + &drain_wr_sq->send_wr, &bad_wr); +#else + drain_wr_sq->send_wr.wr.wr_id = _ptr_to_u64(drain_wr_sq); + drain_wr_sq->send_wr.wr.opcode = IB_WR_SEND; + err = ib_post_send(isert_conn->qp, + &drain_wr_sq->send_wr.wr, &bad_wr); +#endif + if (unlikely(err)) { + PRINT_ERROR("Failed to post drain wr to send queue, err:%d", err); + /* We need to decrement iser_conn->kref in order to be able to cleanup + * the connection */ + set_bit(ISERT_DRAINED_SQ, &isert_conn->flags); + if (test_bit(ISERT_DRAINED_RQ, &isert_conn->flags)) { + isert_sched_conn_free(isert_conn); + } + } +} + +static void isert_post_drain_rq(struct isert_connection *isert_conn) +{ + struct ib_recv_wr *bad_wr; + struct isert_wr *drain_wr_rq = &isert_conn->drain_wr_rq; + int err; + + isert_wr_set_fields(drain_wr_rq, isert_conn, NULL); + drain_wr_rq->wr_op = ISER_WR_RECV; + drain_wr_rq->recv_wr.wr_id = _ptr_to_u64(drain_wr_rq); + err = ib_post_recv(isert_conn->qp, + &drain_wr_rq->recv_wr, &bad_wr); + if (unlikely(err)) { + PRINT_ERROR("Failed to post drain wr to receive queue, err:%d", err); + set_bit(ISERT_DRAINED_RQ, &isert_conn->flags); + if (test_bit(ISERT_DRAINED_SQ, &isert_conn->flags)) { + isert_sched_conn_free(isert_conn); + } + } +} + void isert_post_drain(struct isert_connection *isert_conn) { if (!test_and_set_bit(ISERT_DRAIN_POSTED, &isert_conn->flags)) { - struct ib_send_wr *bad_wr; - int err; - - isert_wr_set_fields(&isert_conn->drain_wr, isert_conn, NULL); - isert_conn->drain_wr.wr_op = ISER_WR_SEND; -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) - isert_conn->drain_wr.send_wr.wr_id = - _ptr_to_u64(&isert_conn->drain_wr); - isert_conn->drain_wr.send_wr.opcode = IB_WR_SEND; - err = ib_post_send(isert_conn->qp, - &isert_conn->drain_wr.send_wr, &bad_wr); -#else - isert_conn->drain_wr.send_wr.wr.wr_id = - _ptr_to_u64(&isert_conn->drain_wr); - isert_conn->drain_wr.send_wr.wr.opcode = IB_WR_SEND; - err = ib_post_send(isert_conn->qp, - &isert_conn->drain_wr.send_wr.wr, &bad_wr); -#endif - if (unlikely(err)) { - PRINT_ERROR("Failed to post drain wr, err:%d", err); - /* - * We need to decrement iser_conn->kref in order to be - * able to cleanup the connection. - */ - set_bit(ISERT_DRAIN_FAILED, &isert_conn->flags); - isert_conn_free(isert_conn); - } + isert_post_drain_rq(isert_conn); + isert_post_drain_sq(isert_conn); } } @@ -684,8 +709,12 @@ static void isert_handle_wc_error(struct ib_wc *wc) #else num_sge = wr->send_wr.wr.num_sge; #endif - if (unlikely(num_sge == 0)) /* Drain WR */ - isert_sched_conn_drained(isert_conn); + if (unlikely(num_sge == 0)) { /* Drain WR */ + set_bit(ISERT_DRAINED_SQ, &isert_conn->flags); + if (test_bit(ISERT_DRAINED_RQ, &isert_conn->flags)) { + isert_sched_conn_drained(isert_conn); + } + } else if (!isert_pdu->is_fake_rx) isert_pdu_err(&isert_pdu->iscsi); break; @@ -700,6 +729,13 @@ static void isert_handle_wc_error(struct ib_wc *wc) break; case ISER_WR_RECV: /* this should be the Flush, no task has been created yet */ + num_sge = wr->recv_wr.num_sge; + if (unlikely(num_sge == 0)) { /* Drain WR */ + set_bit(ISERT_DRAINED_RQ, &isert_conn->flags); + if (test_bit(ISERT_DRAINED_SQ, &isert_conn->flags)) { + isert_sched_conn_drained(isert_conn); + } + } break; case ISER_WR_RDMA_WRITE: if (isert_buf->sg_cnt != 0) { From 9c891f321e4b26f9021d855ec319b7f31db11806 Mon Sep 17 00:00:00 2001 From: Israel Rukshin Date: Wed, 17 Aug 2016 07:28:02 +0000 Subject: [PATCH 15/26] isert: fix isert connection kref leak at estabished event handler Fix a missing kref put when isert_conn_established return an error. By removing set bit ISERT_CONNECTION_ABORTED the connection teardown will start when recieving the flush WRs. Signed-off-by: Israel Rukshin git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6947 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/isert-scst/iser_rdma.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/iscsi-scst/kernel/isert-scst/iser_rdma.c b/iscsi-scst/kernel/isert-scst/iser_rdma.c index c0ad08749..346765843 100644 --- a/iscsi-scst/kernel/isert-scst/iser_rdma.c +++ b/iscsi-scst/kernel/isert-scst/iser_rdma.c @@ -1553,8 +1553,6 @@ static int isert_cm_connect_handler(struct rdma_cm_id *cm_id, (struct sockaddr *)&isert_conn->peer_addr, isert_conn->peer_addrsz); if (unlikely(ret)) { - set_bit(ISERT_CONNECTION_ABORTED, &isert_conn->flags); - isert_post_drain(isert_conn); isert_conn_free(isert_conn); goto out; } From dbf6975a3b201ff7b258010e29fe89ece75d18c9 Mon Sep 17 00:00:00 2001 From: Israel Rukshin Date: Wed, 17 Aug 2016 07:28:06 +0000 Subject: [PATCH 16/26] isert: close isert connection earlier We want to close the connection not only when timewait exit event arrive, but also on some other events. Signed-off-by: Israel Rukshin git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6948 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/isert-scst/iser.h | 1 + iscsi-scst/kernel/isert-scst/iser_rdma.c | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/iscsi-scst/kernel/isert-scst/iser.h b/iscsi-scst/kernel/isert-scst/iser.h index 104f8d5e7..10ce4fd7c 100644 --- a/iscsi-scst/kernel/isert-scst/iser.h +++ b/iscsi-scst/kernel/isert-scst/iser.h @@ -162,6 +162,7 @@ struct isert_cq { #define ISERT_CONNECTION_EST 3 #define ISERT_DRAINED_RQ 4 #define ISERT_DRAINED_SQ 5 +#define ISERT_CONNECTION_CLOSE 6 struct isert_connection { struct iscsi_conn iscsi ____cacheline_aligned; diff --git a/iscsi-scst/kernel/isert-scst/iser_rdma.c b/iscsi-scst/kernel/isert-scst/iser_rdma.c index 346765843..dccd7bb80 100644 --- a/iscsi-scst/kernel/isert-scst/iser_rdma.c +++ b/iscsi-scst/kernel/isert-scst/iser_rdma.c @@ -1388,12 +1388,12 @@ void isert_conn_free(struct isert_connection *isert_conn) kref_put(&isert_conn->kref, isert_kref_free); } -static int isert_cm_timewait_exit_handler(struct rdma_cm_id *cm_id, +static int isert_cm_disconnected_handler(struct rdma_cm_id *cm_id, struct rdma_cm_event *event) { struct isert_connection *isert_conn = cm_id->qp->qp_context; - - isert_sched_conn_closed(isert_conn); + if (!test_and_set_bit(ISERT_CONNECTION_CLOSE, &isert_conn->flags)) + isert_sched_conn_closed(isert_conn); return 0; } @@ -1684,15 +1684,15 @@ static int isert_cm_evt_handler(struct rdma_cm_id *cm_id, case RDMA_CM_EVENT_CONNECT_ERROR: case RDMA_CM_EVENT_REJECTED: - case RDMA_CM_EVENT_ADDR_CHANGE: - case RDMA_CM_EVENT_DISCONNECTED: err = isert_cm_disconnect_handler(cm_id, cm_ev); break; + case RDMA_CM_EVENT_ADDR_CHANGE: + case RDMA_CM_EVENT_DISCONNECTED: case RDMA_CM_EVENT_DEVICE_REMOVAL: case RDMA_CM_EVENT_TIMEWAIT_EXIT: isert_cm_disconnect_handler(cm_id, cm_ev); - err = isert_cm_timewait_exit_handler(cm_id, cm_ev); + err = isert_cm_disconnected_handler(cm_id, cm_ev); break; case RDMA_CM_EVENT_MULTICAST_JOIN: From 79949e9b4c460802dee9f499b5d8c1a335c0b85f Mon Sep 17 00:00:00 2001 From: Israel Rukshin Date: Wed, 17 Aug 2016 07:28:11 +0000 Subject: [PATCH 17/26] isert: change dev conn_lock spinlock to mutex Signed-off-by: Israel Rukshin git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6949 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/isert-scst/isert.h | 2 +- iscsi-scst/kernel/isert-scst/isert_login.c | 34 +++++++++++----------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/iscsi-scst/kernel/isert-scst/isert.h b/iscsi-scst/kernel/isert-scst/isert.h index d9052bd10..b66845b99 100644 --- a/iscsi-scst/kernel/isert-scst/isert.h +++ b/iscsi-scst/kernel/isert-scst/isert.h @@ -71,7 +71,7 @@ struct isert_listener_dev { struct cdev cdev; dev_t devno; wait_queue_head_t waitqueue; - spinlock_t conn_lock; + struct mutex conn_lock; struct list_head new_conn_list; struct list_head curr_conn_list; struct isert_addr_info info; diff --git a/iscsi-scst/kernel/isert-scst/isert_login.c b/iscsi-scst/kernel/isert-scst/isert_login.c index 1a780949d..30ca54915 100644 --- a/iscsi-scst/kernel/isert-scst/isert_login.c +++ b/iscsi-scst/kernel/isert-scst/isert_login.c @@ -70,7 +70,7 @@ static struct isert_conn_dev *get_available_dev(struct isert_listener_dev *dev, unsigned int i; struct isert_conn_dev *res = NULL; - spin_lock(&dev->conn_lock); + mutex_lock(&dev->conn_lock); for (i = 0; i < n_devs; ++i) { if (!isert_conn_devices[i].occupied) { res = &isert_conn_devices[i]; @@ -81,7 +81,7 @@ static struct isert_conn_dev *get_available_dev(struct isert_listener_dev *dev, break; } } - spin_unlock(&dev->conn_lock); + mutex_unlock(&dev->conn_lock); return res; } @@ -111,9 +111,9 @@ static void isert_kref_release_dev(struct kref *kref) static void isert_dev_release(struct isert_conn_dev *dev) { sBUG_ON(atomic_read(&dev->kref.refcount) == 0); - spin_lock(&isert_listen_dev.conn_lock); + mutex_lock(&isert_listen_dev.conn_lock); kref_put(&dev->kref, isert_kref_release_dev); - spin_unlock(&isert_listen_dev.conn_lock); + mutex_unlock(&isert_listen_dev.conn_lock); } #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) @@ -185,9 +185,9 @@ static bool have_new_connection(struct isert_listener_dev *dev) { bool ret; - spin_lock(&dev->conn_lock); + mutex_lock(&dev->conn_lock); ret = !list_empty(&dev->new_conn_list); - spin_unlock(&dev->conn_lock); + mutex_unlock(&dev->conn_lock); return ret; } @@ -328,13 +328,13 @@ static int isert_listen_release(struct inode *inode, struct file *filp) struct isert_listener_dev *dev = filp->private_data; struct isert_conn_dev *conn_dev; - spin_lock(&isert_listen_dev.conn_lock); + mutex_lock(&isert_listen_dev.conn_lock); list_for_each_entry(conn_dev, &dev->new_conn_list, conn_list_entry) isert_delete_conn_dev(conn_dev); list_for_each_entry(conn_dev, &dev->curr_conn_list, conn_list_entry) isert_delete_conn_dev(conn_dev); - spin_unlock(&isert_listen_dev.conn_lock); + mutex_unlock(&isert_listen_dev.conn_lock); atomic_inc(&dev->available); return 0; @@ -361,16 +361,16 @@ wait_for_connection: goto out; } - spin_lock(&dev->conn_lock); + mutex_lock(&dev->conn_lock); if (list_empty(&dev->new_conn_list)) { /* could happen if we got disconnect */ - spin_unlock(&dev->conn_lock); + mutex_unlock(&dev->conn_lock); goto wait_for_connection; } conn_dev = list_first_entry(&dev->new_conn_list, struct isert_conn_dev, conn_list_entry); list_move(&conn_dev->conn_list_entry, &dev->curr_conn_list); - spin_unlock(&dev->conn_lock); + mutex_unlock(&dev->conn_lock); to_write = min_t(size_t, sizeof(k_buff), count); res = scnprintf(k_buff, to_write, "/dev/"ISER_CONN_DEV_PREFIX"%d", @@ -530,13 +530,13 @@ static int isert_open(struct inode *inode, struct file *filp) dev = container_of(inode->i_cdev, struct isert_conn_dev, cdev); - spin_lock(&isert_listen_dev.conn_lock); + mutex_lock(&isert_listen_dev.conn_lock); if (unlikely(dev->occupied == 0)) { - spin_unlock(&isert_listen_dev.conn_lock); + mutex_unlock(&isert_listen_dev.conn_lock); res = -ENODEV; /* already closed */ goto out; } - spin_unlock(&isert_listen_dev.conn_lock); + mutex_unlock(&isert_listen_dev.conn_lock); if (unlikely(!atomic_dec_and_test(&dev->available))) { atomic_inc(&dev->available); @@ -544,9 +544,9 @@ static int isert_open(struct inode *inode, struct file *filp) goto out; } - spin_lock(&isert_listen_dev.conn_lock); + mutex_lock(&isert_listen_dev.conn_lock); kref_get(&dev->kref); - spin_unlock(&isert_listen_dev.conn_lock); + mutex_unlock(&isert_listen_dev.conn_lock); filp->private_data = dev; /* for other methods */ @@ -947,7 +947,7 @@ static void __init isert_setup_listener_cdev(struct isert_listener_dev *dev) init_waitqueue_head(&dev->waitqueue); INIT_LIST_HEAD(&dev->new_conn_list); INIT_LIST_HEAD(&dev->curr_conn_list); - spin_lock_init(&dev->conn_lock); + mutex_init(&dev->conn_lock); atomic_set(&dev->available, 1); err = cdev_add(&dev->cdev, dev->devno, 1); /* Fail gracefully if need be */ From 87902c872236c0d1fc101b93db0f6e9f42d1dd91 Mon Sep 17 00:00:00 2001 From: Israel Rukshin Date: Wed, 17 Aug 2016 07:28:16 +0000 Subject: [PATCH 18/26] isert: fix a race between calling to rdma_disconnect and connect flow 1) The race can happen after unreachable event handler close isert connection and calling to rdma_disconnect from another thread on illegal cm_id. For example call rdma_disconnect from isert_portal_release function. 2) It is also possible to get ESTABLISHED RDMACM event while rdma_disconnect is called from another thread. In established event we need to check conn is not in teardown flow by checking the connection state with a mutex. Signed-off-by: Israel Rukshin git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6950 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/isert-scst/iser.h | 1 + iscsi-scst/kernel/isert-scst/iser_rdma.c | 39 +++++++++++++++++------- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/iscsi-scst/kernel/isert-scst/iser.h b/iscsi-scst/kernel/isert-scst/iser.h index 10ce4fd7c..a72cedc4b 100644 --- a/iscsi-scst/kernel/isert-scst/iser.h +++ b/iscsi-scst/kernel/isert-scst/iser.h @@ -188,6 +188,7 @@ struct isert_connection { struct isert_cq *cq_desc; enum isert_conn_state state; + struct mutex state_mutex; u32 responder_resources; u32 initiator_depth; diff --git a/iscsi-scst/kernel/isert-scst/iser_rdma.c b/iscsi-scst/kernel/isert-scst/iser_rdma.c index dccd7bb80..b01748c31 100644 --- a/iscsi-scst/kernel/isert-scst/iser_rdma.c +++ b/iscsi-scst/kernel/isert-scst/iser_rdma.c @@ -204,6 +204,7 @@ void isert_conn_disconnect(struct isert_connection *isert_conn) { int err; + mutex_lock(&isert_conn->state_mutex); if (isert_conn->state != ISER_CONN_CLOSING) { isert_conn->state = ISER_CONN_CLOSING; @@ -212,6 +213,7 @@ void isert_conn_disconnect(struct isert_connection *isert_conn) if (unlikely(err)) PRINT_ERROR("Failed to rdma disconnect, err:%d", err); } + mutex_unlock(&isert_conn->state_mutex); } static int isert_pdu_handle_hello_req(struct isert_cmnd *pdu) @@ -1309,6 +1311,7 @@ static struct isert_connection *isert_conn_create(struct rdma_cm_id *cm_id, } kref_init(&isert_conn->kref); + mutex_init(&isert_conn->state_mutex); TRACE_EXIT(); return isert_conn; @@ -1397,6 +1400,20 @@ static int isert_cm_disconnected_handler(struct rdma_cm_id *cm_id, return 0; } +static void isert_immediate_conn_close(struct isert_connection* isert_conn) +{ + set_bit(ISERT_CONNECTION_ABORTED, &isert_conn->flags); + set_bit(ISERT_CONNECTION_CLOSE, &isert_conn->flags); + isert_conn->state = ISER_CONN_CLOSING; + /* + * reaching here must be with the isert_conn refcount of 2, + * one from the init and one from the connect request, + * thus it is safe to deref directly before the sched_conn_free. + */ + isert_conn_free(isert_conn); + isert_sched_conn_free(isert_conn); +} + static int isert_cm_conn_req_handler(struct rdma_cm_id *cm_id, struct rdma_cm_event *event) { @@ -1530,14 +1547,17 @@ static int isert_cm_connect_handler(struct rdma_cm_id *cm_id, { struct isert_connection *isert_conn = cm_id->qp->qp_context; int push_saved_pdu = 0; - int ret; + int ret = 0; TRACE_ENTRY(); + mutex_lock(&isert_conn->state_mutex); if (isert_conn->state == ISER_CONN_HANDSHAKE) isert_conn->state = ISER_CONN_ACTIVE; else if (isert_conn->state == ISER_CONN_ACTIVE) push_saved_pdu = 1; + else if (isert_conn->state == ISER_CONN_CLOSING) + goto out; ret = isert_get_addr_size((struct sockaddr *)&isert_conn->peer_addr, &isert_conn->peer_addrsz); @@ -1566,6 +1586,7 @@ static int isert_cm_connect_handler(struct rdma_cm_id *cm_id, } out: + mutex_unlock(&isert_conn->state_mutex); TRACE_EXIT_RES(ret); return ret; } @@ -1711,17 +1732,13 @@ static int isert_cm_evt_handler(struct rdma_cm_id *cm_id, /* We can receive this instead of RDMA_CM_EVENT_ESTABLISHED */ case RDMA_CM_EVENT_UNREACHABLE: { - struct isert_connection *isert_conn; + struct isert_connection *isert_conn = cm_id->qp->qp_context; - isert_conn = cm_id->qp->qp_context; - set_bit(ISERT_CONNECTION_ABORTED, &isert_conn->flags); - /* - * reaching here must be with the isert_conn refcount of 2, - * one from the init and one from the connect request, - * thus it is safe to deref directly before the sched_conn_free. - */ - isert_conn_free(isert_conn); - isert_sched_conn_free(isert_conn); + mutex_lock(&isert_conn->state_mutex); + if (isert_conn->state != ISER_CONN_CLOSING) { + isert_immediate_conn_close(isert_conn); + } + mutex_unlock(&isert_conn->state_mutex); err = 0; } break; From 45256dd8882182ee47dfcb67d012ed29f407e6ac Mon Sep 17 00:00:00 2001 From: Israel Rukshin Date: Wed, 17 Aug 2016 07:28:20 +0000 Subject: [PATCH 19/26] isert: fix isert connection kref leak To avoid rare cases when checking ISERT_CONNECTION_EST bit may lead to kref leak, we now take the third refcount earlier before calling to rdma_accept. Signed-off-by: Israel Rukshin git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6951 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/isert-scst/iser.h | 7 +++---- iscsi-scst/kernel/isert-scst/iser_rdma.c | 19 ++++++------------- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/iscsi-scst/kernel/isert-scst/iser.h b/iscsi-scst/kernel/isert-scst/iser.h index a72cedc4b..07f8b881a 100644 --- a/iscsi-scst/kernel/isert-scst/iser.h +++ b/iscsi-scst/kernel/isert-scst/iser.h @@ -159,10 +159,9 @@ struct isert_cq { #define ISERT_CONNECTION_ABORTED 0 #define ISERT_DRAIN_POSTED 1 #define ISERT_DISCON_CALLED 2 -#define ISERT_CONNECTION_EST 3 -#define ISERT_DRAINED_RQ 4 -#define ISERT_DRAINED_SQ 5 -#define ISERT_CONNECTION_CLOSE 6 +#define ISERT_DRAINED_RQ 3 +#define ISERT_DRAINED_SQ 4 +#define ISERT_CONNECTION_CLOSE 5 struct isert_connection { struct iscsi_conn iscsi ____cacheline_aligned; diff --git a/iscsi-scst/kernel/isert-scst/iser_rdma.c b/iscsi-scst/kernel/isert-scst/iser_rdma.c index b01748c31..70d3e2aef 100644 --- a/iscsi-scst/kernel/isert-scst/iser_rdma.c +++ b/iscsi-scst/kernel/isert-scst/iser_rdma.c @@ -639,10 +639,7 @@ static void isert_conn_closed_do_work(struct work_struct *work) if (!test_bit(ISERT_CONNECTION_ABORTED, &isert_conn->flags)) isert_connection_abort(&isert_conn->iscsi); - /* if connection established we have another refcount */ - if (test_bit(ISERT_CONNECTION_EST, &isert_conn->flags)) { - isert_conn_free(isert_conn); - } + isert_conn_free(isert_conn); } static void isert_sched_conn_closed(struct isert_connection *isert_conn) @@ -1406,11 +1403,12 @@ static void isert_immediate_conn_close(struct isert_connection* isert_conn) set_bit(ISERT_CONNECTION_CLOSE, &isert_conn->flags); isert_conn->state = ISER_CONN_CLOSING; /* - * reaching here must be with the isert_conn refcount of 2, - * one from the init and one from the connect request, + * reaching here must be with the isert_conn refcount of 3, + * one from the init and two from the connect request, * thus it is safe to deref directly before the sched_conn_free. */ isert_conn_free(isert_conn); + isert_conn_free(isert_conn); isert_sched_conn_free(isert_conn); } @@ -1481,6 +1479,7 @@ static int isert_cm_conn_req_handler(struct rdma_cm_id *cm_id, tgt_conn_param.private_data = &cm_hdr; cm_hdr.flags = ISER_ZBVA_NOT_SUPPORTED | ISER_SEND_W_INV_NOT_SUPPORTED; + kref_get(&isert_conn->kref); kref_get(&isert_conn->kref); err = rdma_accept(cm_id, &tgt_conn_param); @@ -1527,6 +1526,7 @@ out: fail_accept: set_bit(ISERT_CONNECTION_ABORTED, &isert_conn->flags); isert_conn_free(isert_conn); + isert_conn_free(isert_conn); isert_sched_conn_free(isert_conn); err = 0; goto out; @@ -1564,21 +1564,14 @@ static int isert_cm_connect_handler(struct rdma_cm_id *cm_id, if (unlikely(ret)) goto out; - /* check if already started teardown */ - if (!unlikely(kref_get_unless_zero(&isert_conn->kref))) - goto out; - /* notify upper layer */ ret = isert_conn_established(&isert_conn->iscsi, (struct sockaddr *)&isert_conn->peer_addr, isert_conn->peer_addrsz); if (unlikely(ret)) { - isert_conn_free(isert_conn); goto out; } - set_bit(ISERT_CONNECTION_EST, &isert_conn->flags); - if (push_saved_pdu) { PRINT_INFO("iser push saved rx pdu"); isert_recv_completion_handler(isert_conn->saved_wr); From 9dee83d555ad68de81349907e97d2aff26379e64 Mon Sep 17 00:00:00 2001 From: Israel Rukshin Date: Wed, 17 Aug 2016 07:28:25 +0000 Subject: [PATCH 20/26] isert: faster release of isert_scst module If there is a dead connection we don't want to wait 60 seconds for the connection timeout error. So when closing the portal we close now all the connections immediately without waiting for events to arrive. Signed-off-by: Israel Rukshin git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6952 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/isert-scst/iser_rdma.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/iscsi-scst/kernel/isert-scst/iser_rdma.c b/iscsi-scst/kernel/isert-scst/iser_rdma.c index 70d3e2aef..600b5182a 100644 --- a/iscsi-scst/kernel/isert-scst/iser_rdma.c +++ b/iscsi-scst/kernel/isert-scst/iser_rdma.c @@ -1891,11 +1891,20 @@ void isert_portal_release(struct isert_portal *portal) isert_portal_list_remove(portal); mutex_lock(&dev_list_mutex); - list_for_each_entry(conn, &portal->conn_list, portal_node) + list_for_each_entry(conn, &portal->conn_list, portal_node) { isert_conn_disconnect(conn); + if (!test_and_set_bit(ISERT_CONNECTION_CLOSE, &conn->flags)) + isert_sched_conn_closed(conn); + } portal->state = ISERT_PORTAL_INACTIVE; isert_portal_free(portal); mutex_unlock(&dev_list_mutex); + + while (!list_empty(&portal->conn_list)) { + msleep(100); + } + + PRINT_INFO("done releasing portal %p", portal); } struct isert_portal *isert_portal_start(struct sockaddr *sa, size_t addr_len) From 09d719a009c149414c8c2b1b5deee87f19236ed4 Mon Sep 17 00:00:00 2001 From: Israel Rukshin Date: Wed, 17 Aug 2016 07:28:29 +0000 Subject: [PATCH 21/26] isert: fix races between conn fops read/write and disconnect flow read/write events may arive after the isert connection has started the teardown flow. This scenario may occur on login logout stress. It may lead to NULL derefrence bugs. Signed-off-by: Israel Rukshin git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6953 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/isert-scst/isert_login.c | 40 +++++++++++++++++----- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/iscsi-scst/kernel/isert-scst/isert_login.c b/iscsi-scst/kernel/isert-scst/isert_login.c index 30ca54915..af45f4595 100644 --- a/iscsi-scst/kernel/isert-scst/isert_login.c +++ b/iscsi-scst/kernel/isert-scst/isert_login.c @@ -594,23 +594,33 @@ static ssize_t isert_read(struct file *filp, char __user *buf, size_t count, struct isert_conn_dev *dev = filp->private_data; size_t to_read; - if (dev->state == CS_DISCONNECTED) + mutex_lock(&conn_mgmt_mutex); + + if (dev->state == CS_DISCONNECTED) { + mutex_unlock(&conn_mgmt_mutex); return -EPIPE; + } if (will_read_block(dev)) { int ret; - if (filp->f_flags & O_NONBLOCK) + if (filp->f_flags & O_NONBLOCK) { + mutex_unlock(&conn_mgmt_mutex); return -EAGAIN; + } ret = wait_event_freezable(dev->waitqueue, !will_read_block(dev)); - if (ret < 0) + if (ret < 0) { + mutex_unlock(&conn_mgmt_mutex); return ret; + } } to_read = min(count, dev->read_len); - if (copy_to_user(buf, dev->read_buf, to_read)) + if (copy_to_user(buf, dev->read_buf, to_read)) { + mutex_unlock(&conn_mgmt_mutex); return -EFAULT; + } dev->read_len -= to_read; dev->read_buf += to_read; @@ -622,8 +632,10 @@ static ssize_t isert_read(struct file *filp, char __user *buf, size_t count, dev->sg_virt = isert_vmap_sg(dev->pages, dev->login_req->sg, dev->login_req->sg_cnt); - if (!dev->sg_virt) + if (!dev->sg_virt) { + mutex_unlock(&conn_mgmt_mutex); return -ENOMEM; + } dev->read_buf = dev->sg_virt + ISER_HDRS_SZ; dev->state = CS_REQ_DATA; } @@ -646,6 +658,8 @@ static ssize_t isert_read(struct file *filp, char __user *buf, size_t count, to_read = 0; } + mutex_unlock(&conn_mgmt_mutex); + return to_read; } @@ -655,12 +669,18 @@ static ssize_t isert_write(struct file *filp, const char __user *buf, struct isert_conn_dev *dev = filp->private_data; size_t to_write; - if (dev->state == CS_DISCONNECTED) + mutex_lock(&conn_mgmt_mutex); + + if (dev->state == CS_DISCONNECTED) { + mutex_unlock(&conn_mgmt_mutex); return -EPIPE; + } to_write = min(count, dev->write_len); - if (copy_from_user(dev->write_buf, buf, to_write)) + if (copy_from_user(dev->write_buf, buf, to_write)) { + mutex_unlock(&conn_mgmt_mutex); return -EFAULT; + } dev->write_len -= to_write; dev->write_buf += to_write; @@ -672,8 +692,10 @@ static ssize_t isert_write(struct file *filp, const char __user *buf, dev->sg_virt = isert_vmap_sg(dev->pages, dev->login_rsp->sg, dev->login_rsp->sg_cnt); - if (!dev->sg_virt) + if (!dev->sg_virt) { + mutex_unlock(&conn_mgmt_mutex); return -ENOMEM; + } dev->write_buf = dev->sg_virt + ISER_HDRS_SZ; dev->write_len = dev->login_rsp->bufflen - sizeof(dev->login_rsp->pdu.bhs); @@ -689,6 +711,8 @@ static ssize_t isert_write(struct file *filp, const char __user *buf, to_write = 0; } + mutex_unlock(&conn_mgmt_mutex); + return to_write; } From b292383396c6cf5fd60a5163a153dc329682a942 Mon Sep 17 00:00:00 2001 From: Israel Rukshin Date: Wed, 17 Aug 2016 07:28:34 +0000 Subject: [PATCH 22/26] isert: add missing fd put on error flow Signed-off-by: Israel Rukshin git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6954 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/isert-scst/isert_login.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iscsi-scst/kernel/isert-scst/isert_login.c b/iscsi-scst/kernel/isert-scst/isert_login.c index af45f4595..2956f5236 100644 --- a/iscsi-scst/kernel/isert-scst/isert_login.c +++ b/iscsi-scst/kernel/isert-scst/isert_login.c @@ -217,6 +217,7 @@ int isert_conn_alloc(struct iscsi_session *session, dev = filp->private_data; if (unlikely(dev->state == CS_DISCONNECTED)) { + fput(filp); res = -EBADF; goto out; } From 73b50bce1b184d7865093a150e0c062be6f5e6f2 Mon Sep 17 00:00:00 2001 From: Israel Rukshin Date: Wed, 17 Aug 2016 07:28:38 +0000 Subject: [PATCH 23/26] isert: fix working with freed conn object isert_delete_conn_dev function checks if it needs to close the connection by checking that dev conn is not NULL. We were missing set conn to null when freeing it and that caused working with memory that was already freed. Signed-off-by: Israel Rukshin git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6955 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/isert-scst/isert_login.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iscsi-scst/kernel/isert-scst/isert_login.c b/iscsi-scst/kernel/isert-scst/isert_login.c index 2956f5236..c43193bc4 100644 --- a/iscsi-scst/kernel/isert-scst/isert_login.c +++ b/iscsi-scst/kernel/isert-scst/isert_login.c @@ -453,6 +453,7 @@ static void isert_dev_disconnect(struct iscsi_conn* iscsi_conn) if (dev) { isert_del_timer(dev); dev->state = CS_DISCONNECTED; + dev->conn = NULL; if (dev->login_req) { isert_task_abort(dev->login_req); spin_lock(&dev->pdu_lock); From 183ef8273120ca4a9055a803a2e2e5e1be835fd1 Mon Sep 17 00:00:00 2001 From: Israel Rukshin Date: Wed, 17 Aug 2016 07:28:43 +0000 Subject: [PATCH 24/26] isert: fix isert conn cleanup when rdma_accept fails If rdma_accept fails the state of the qp is modified to error and all posted recieve buffers will be flushed and because of the flush the isert conn teardown flow will start. Signed-off-by: Israel Rukshin git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6956 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/isert-scst/iser_rdma.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/iscsi-scst/kernel/isert-scst/iser_rdma.c b/iscsi-scst/kernel/isert-scst/iser_rdma.c index 600b5182a..7debe6541 100644 --- a/iscsi-scst/kernel/isert-scst/iser_rdma.c +++ b/iscsi-scst/kernel/isert-scst/iser_rdma.c @@ -1524,9 +1524,6 @@ out: return err; fail_accept: - set_bit(ISERT_CONNECTION_ABORTED, &isert_conn->flags); - isert_conn_free(isert_conn); - isert_conn_free(isert_conn); isert_sched_conn_free(isert_conn); err = 0; goto out; From 0498de2100dece9f83d006341436e594b565952c Mon Sep 17 00:00:00 2001 From: Israel Rukshin Date: Wed, 17 Aug 2016 07:28:47 +0000 Subject: [PATCH 25/26] isert: add conn to portal conn list only if rdma_accept succeeded If rdma_accept() failed then we shouldn't call rdma_disconnect() on that QP as the result is unexpected. Signed-off-by: Israel Rukshin git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6957 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/isert-scst/iser.h | 2 ++ iscsi-scst/kernel/isert-scst/iser_rdma.c | 17 ++++++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/iscsi-scst/kernel/isert-scst/iser.h b/iscsi-scst/kernel/isert-scst/iser.h index 07f8b881a..ccf1bd66e 100644 --- a/iscsi-scst/kernel/isert-scst/iser.h +++ b/iscsi-scst/kernel/isert-scst/iser.h @@ -63,6 +63,7 @@ struct isert_portal { /* protected by dev_list_mutex */ struct list_head conn_list; /* head of conns list */ enum isert_portal_state state; + int refcnt; }; struct isert_buf { @@ -162,6 +163,7 @@ struct isert_cq { #define ISERT_DRAINED_RQ 3 #define ISERT_DRAINED_SQ 4 #define ISERT_CONNECTION_CLOSE 5 +#define ISERT_IN_PORTAL_LIST 6 struct isert_connection { struct iscsi_conn iscsi ____cacheline_aligned; diff --git a/iscsi-scst/kernel/isert-scst/iser_rdma.c b/iscsi-scst/kernel/isert-scst/iser_rdma.c index 7debe6541..a9deb5b61 100644 --- a/iscsi-scst/kernel/isert-scst/iser_rdma.c +++ b/iscsi-scst/kernel/isert-scst/iser_rdma.c @@ -1368,8 +1368,10 @@ static void isert_kref_free(struct kref *kref) isert_conn->qp = NULL; mutex_lock(&dev_list_mutex); + isert_conn->portal->refcnt--; isert_dev->cq_qps[cq->idx]--; - list_del(&isert_conn->portal_node); + if (test_bit(ISERT_IN_PORTAL_LIST, &isert_conn->flags)) + list_del(&isert_conn->portal_node); isert_deref_device(isert_dev); if (unlikely(isert_conn->portal->state == ISERT_PORTAL_INACTIVE)) isert_portal_free(isert_conn->portal); @@ -1455,7 +1457,7 @@ static int isert_cm_conn_req_handler(struct rdma_cm_id *cm_id, isert_conn->portal = portal; mutex_lock(&dev_list_mutex); - list_add_tail(&isert_conn->portal_node, &portal->conn_list); + portal->refcnt++; mutex_unlock(&dev_list_mutex); /* initiator is dst, target is src */ @@ -1484,7 +1486,7 @@ static int isert_cm_conn_req_handler(struct rdma_cm_id *cm_id, err = rdma_accept(cm_id, &tgt_conn_param); if (unlikely(err)) { - PRINT_ERROR("Failed to accept conn request, err:%d", err); + PRINT_ERROR("Failed to accept conn request, err:%d conn:%p", err, isert_conn); goto fail_accept; } @@ -1519,6 +1521,11 @@ static int isert_cm_conn_req_handler(struct rdma_cm_id *cm_id, PRINT_INFO("iser accepted connection cm_id:%p", cm_id); } + mutex_lock(&dev_list_mutex); + list_add_tail(&isert_conn->portal_node, &portal->conn_list); + set_bit(ISERT_IN_PORTAL_LIST, &isert_conn->flags); + mutex_unlock(&dev_list_mutex); + out: TRACE_EXIT_RES(err); return err; @@ -1867,7 +1874,7 @@ static void isert_portal_free(struct isert_portal *portal) { lockdep_assert_held(&dev_list_mutex); - if (!list_empty(&portal->conn_list)) + if (portal->refcnt > 0) return; kfree(portal); @@ -1897,7 +1904,7 @@ void isert_portal_release(struct isert_portal *portal) isert_portal_free(portal); mutex_unlock(&dev_list_mutex); - while (!list_empty(&portal->conn_list)) { + while (portal->refcnt > 0) { msleep(100); } From 40fd212bdf3be06d19d2b19a521af317af779889 Mon Sep 17 00:00:00 2001 From: Israel Rukshin Date: Wed, 17 Aug 2016 07:28:52 +0000 Subject: [PATCH 26/26] isert: fix redundant module put on error flow when handling connect request Signed-off-by: Israel Rukshin git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6958 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/isert-scst/iser_rdma.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/iscsi-scst/kernel/isert-scst/iser_rdma.c b/iscsi-scst/kernel/isert-scst/iser_rdma.c index a9deb5b61..9a48679a2 100644 --- a/iscsi-scst/kernel/isert-scst/iser_rdma.c +++ b/iscsi-scst/kernel/isert-scst/iser_rdma.c @@ -1326,7 +1326,6 @@ fail_login_rsp_pdu: fail_login_req_pdu: isert_conn_kfree(isert_conn); fail_alloc: - module_put(THIS_MODULE); TRACE_EXIT_RES(err); return ERR_PTR(err); } @@ -1431,7 +1430,7 @@ static int isert_cm_conn_req_handler(struct rdma_cm_id *cm_id, if (unlikely(!try_module_get(THIS_MODULE))) { err = -EINVAL; - goto fail_get; + goto out; } mutex_lock(&dev_list_mutex); @@ -1541,7 +1540,6 @@ fail_conn_create: mutex_unlock(&dev_list_mutex); fail_dev_create: rdma_reject(cm_id, NULL, 0); -fail_get: module_put(THIS_MODULE); goto out; }