aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/ulp/isert/ib_isert.c104
-rw-r--r--drivers/infiniband/ulp/isert/ib_isert.h4
-rw-r--r--drivers/target/iscsi/iscsi_target.c4
-rw-r--r--include/target/iscsi/iscsi_transport.h1
4 files changed, 53 insertions, 60 deletions
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
index 45ac70bfd7e3..fe23f372c765 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -392,8 +392,8 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
392 isert_conn->state = ISER_CONN_INIT; 392 isert_conn->state = ISER_CONN_INIT;
393 INIT_LIST_HEAD(&isert_conn->conn_accept_node); 393 INIT_LIST_HEAD(&isert_conn->conn_accept_node);
394 init_completion(&isert_conn->conn_login_comp); 394 init_completion(&isert_conn->conn_login_comp);
395 init_waitqueue_head(&isert_conn->conn_wait); 395 init_completion(&isert_conn->conn_wait);
396 init_waitqueue_head(&isert_conn->conn_wait_comp_err); 396 init_completion(&isert_conn->conn_wait_comp_err);
397 kref_init(&isert_conn->conn_kref); 397 kref_init(&isert_conn->conn_kref);
398 kref_get(&isert_conn->conn_kref); 398 kref_get(&isert_conn->conn_kref);
399 mutex_init(&isert_conn->conn_mutex); 399 mutex_init(&isert_conn->conn_mutex);
@@ -550,11 +550,11 @@ isert_disconnect_work(struct work_struct *work)
550 550
551 pr_debug("isert_disconnect_work(): >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); 551 pr_debug("isert_disconnect_work(): >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
552 mutex_lock(&isert_conn->conn_mutex); 552 mutex_lock(&isert_conn->conn_mutex);
553 isert_conn->state = ISER_CONN_DOWN; 553 if (isert_conn->state == ISER_CONN_UP)
554 isert_conn->state = ISER_CONN_TERMINATING;
554 555
555 if (isert_conn->post_recv_buf_count == 0 && 556 if (isert_conn->post_recv_buf_count == 0 &&
556 atomic_read(&isert_conn->post_send_buf_count) == 0) { 557 atomic_read(&isert_conn->post_send_buf_count) == 0) {
557 pr_debug("Calling wake_up(&isert_conn->conn_wait);\n");
558 mutex_unlock(&isert_conn->conn_mutex); 558 mutex_unlock(&isert_conn->conn_mutex);
559 goto wake_up; 559 goto wake_up;
560 } 560 }
@@ -574,7 +574,7 @@ isert_disconnect_work(struct work_struct *work)
574 mutex_unlock(&isert_conn->conn_mutex); 574 mutex_unlock(&isert_conn->conn_mutex);
575 575
576wake_up: 576wake_up:
577 wake_up(&isert_conn->conn_wait); 577 complete(&isert_conn->conn_wait);
578 isert_put_conn(isert_conn); 578 isert_put_conn(isert_conn);
579} 579}
580 580
@@ -1348,7 +1348,7 @@ isert_do_control_comp(struct work_struct *work)
1348 pr_debug("Calling iscsit_logout_post_handler >>>>>>>>>>>>>>\n"); 1348 pr_debug("Calling iscsit_logout_post_handler >>>>>>>>>>>>>>\n");
1349 /* 1349 /*
1350 * Call atomic_dec(&isert_conn->post_send_buf_count) 1350 * Call atomic_dec(&isert_conn->post_send_buf_count)
1351 * from isert_free_conn() 1351 * from isert_wait_conn()
1352 */ 1352 */
1353 isert_conn->logout_posted = true; 1353 isert_conn->logout_posted = true;
1354 iscsit_logout_post_handler(cmd, cmd->conn); 1354 iscsit_logout_post_handler(cmd, cmd->conn);
@@ -1426,31 +1426,38 @@ isert_send_completion(struct iser_tx_desc *tx_desc,
1426} 1426}
1427 1427
1428static void 1428static void
1429isert_cq_comp_err(struct iser_tx_desc *tx_desc, struct isert_conn *isert_conn) 1429isert_cq_tx_comp_err(struct iser_tx_desc *tx_desc, struct isert_conn *isert_conn)
1430{ 1430{
1431 struct ib_device *ib_dev = isert_conn->conn_cm_id->device; 1431 struct ib_device *ib_dev = isert_conn->conn_cm_id->device;
1432 struct isert_cmd *isert_cmd = tx_desc->isert_cmd;
1432 1433
1433 if (tx_desc) { 1434 if (!isert_cmd)
1434 struct isert_cmd *isert_cmd = tx_desc->isert_cmd; 1435 isert_unmap_tx_desc(tx_desc, ib_dev);
1436 else
1437 isert_completion_put(tx_desc, isert_cmd, ib_dev);
1438}
1435 1439
1436 if (!isert_cmd) 1440static void
1437 isert_unmap_tx_desc(tx_desc, ib_dev); 1441isert_cq_rx_comp_err(struct isert_conn *isert_conn)
1438 else 1442{
1439 isert_completion_put(tx_desc, isert_cmd, ib_dev); 1443 struct iscsi_conn *conn = isert_conn->conn;
1444
1445 if (isert_conn->post_recv_buf_count)
1446 return;
1447
1448 if (conn->sess) {
1449 target_sess_cmd_list_set_waiting(conn->sess->se_sess);
1450 target_wait_for_sess_cmds(conn->sess->se_sess);
1440 } 1451 }
1441 1452
1442 if (isert_conn->post_recv_buf_count == 0 && 1453 while (atomic_read(&isert_conn->post_send_buf_count))
1443 atomic_read(&isert_conn->post_send_buf_count) == 0) { 1454 msleep(3000);
1444 pr_debug("isert_cq_comp_err >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
1445 pr_debug("Calling wake_up from isert_cq_comp_err\n");
1446 1455
1447 mutex_lock(&isert_conn->conn_mutex); 1456 mutex_lock(&isert_conn->conn_mutex);
1448 if (isert_conn->state != ISER_CONN_DOWN) 1457 isert_conn->state = ISER_CONN_DOWN;
1449 isert_conn->state = ISER_CONN_TERMINATING; 1458 mutex_unlock(&isert_conn->conn_mutex);
1450 mutex_unlock(&isert_conn->conn_mutex);
1451 1459
1452 wake_up(&isert_conn->conn_wait_comp_err); 1460 complete(&isert_conn->conn_wait_comp_err);
1453 }
1454} 1461}
1455 1462
1456static void 1463static void
@@ -1475,7 +1482,7 @@ isert_cq_tx_work(struct work_struct *work)
1475 pr_debug("TX wc.status != IB_WC_SUCCESS >>>>>>>>>>>>>>\n"); 1482 pr_debug("TX wc.status != IB_WC_SUCCESS >>>>>>>>>>>>>>\n");
1476 pr_debug("TX wc.status: 0x%08x\n", wc.status); 1483 pr_debug("TX wc.status: 0x%08x\n", wc.status);
1477 atomic_dec(&isert_conn->post_send_buf_count); 1484 atomic_dec(&isert_conn->post_send_buf_count);
1478 isert_cq_comp_err(tx_desc, isert_conn); 1485 isert_cq_tx_comp_err(tx_desc, isert_conn);
1479 } 1486 }
1480 } 1487 }
1481 1488
@@ -1517,7 +1524,7 @@ isert_cq_rx_work(struct work_struct *work)
1517 pr_debug("RX wc.status: 0x%08x\n", wc.status); 1524 pr_debug("RX wc.status: 0x%08x\n", wc.status);
1518 1525
1519 isert_conn->post_recv_buf_count--; 1526 isert_conn->post_recv_buf_count--;
1520 isert_cq_comp_err(NULL, isert_conn); 1527 isert_cq_rx_comp_err(isert_conn);
1521 } 1528 }
1522 } 1529 }
1523 1530
@@ -2218,22 +2225,11 @@ isert_free_np(struct iscsi_np *np)
2218 kfree(isert_np); 2225 kfree(isert_np);
2219} 2226}
2220 2227
2221static int isert_check_state(struct isert_conn *isert_conn, int state) 2228static void isert_wait_conn(struct iscsi_conn *conn)
2222{
2223 int ret;
2224
2225 mutex_lock(&isert_conn->conn_mutex);
2226 ret = (isert_conn->state == state);
2227 mutex_unlock(&isert_conn->conn_mutex);
2228
2229 return ret;
2230}
2231
2232static void isert_free_conn(struct iscsi_conn *conn)
2233{ 2229{
2234 struct isert_conn *isert_conn = conn->context; 2230 struct isert_conn *isert_conn = conn->context;
2235 2231
2236 pr_debug("isert_free_conn: Starting \n"); 2232 pr_debug("isert_wait_conn: Starting \n");
2237 /* 2233 /*
2238 * Decrement post_send_buf_count for special case when called 2234 * Decrement post_send_buf_count for special case when called
2239 * from isert_do_control_comp() -> iscsit_logout_post_handler() 2235 * from isert_do_control_comp() -> iscsit_logout_post_handler()
@@ -2243,38 +2239,29 @@ static void isert_free_conn(struct iscsi_conn *conn)
2243 atomic_dec(&isert_conn->post_send_buf_count); 2239 atomic_dec(&isert_conn->post_send_buf_count);
2244 2240
2245 if (isert_conn->conn_cm_id && isert_conn->state != ISER_CONN_DOWN) { 2241 if (isert_conn->conn_cm_id && isert_conn->state != ISER_CONN_DOWN) {
2246 pr_debug("Calling rdma_disconnect from isert_free_conn\n"); 2242 pr_debug("Calling rdma_disconnect from isert_wait_conn\n");
2247 rdma_disconnect(isert_conn->conn_cm_id); 2243 rdma_disconnect(isert_conn->conn_cm_id);
2248 } 2244 }
2249 /* 2245 /*
2250 * Only wait for conn_wait_comp_err if the isert_conn made it 2246 * Only wait for conn_wait_comp_err if the isert_conn made it
2251 * into full feature phase.. 2247 * into full feature phase..
2252 */ 2248 */
2253 if (isert_conn->state == ISER_CONN_UP) {
2254 pr_debug("isert_free_conn: Before wait_event comp_err %d\n",
2255 isert_conn->state);
2256 mutex_unlock(&isert_conn->conn_mutex);
2257
2258 wait_event(isert_conn->conn_wait_comp_err,
2259 (isert_check_state(isert_conn, ISER_CONN_TERMINATING)));
2260
2261 wait_event(isert_conn->conn_wait,
2262 (isert_check_state(isert_conn, ISER_CONN_DOWN)));
2263
2264 isert_put_conn(isert_conn);
2265 return;
2266 }
2267 if (isert_conn->state == ISER_CONN_INIT) { 2249 if (isert_conn->state == ISER_CONN_INIT) {
2268 mutex_unlock(&isert_conn->conn_mutex); 2250 mutex_unlock(&isert_conn->conn_mutex);
2269 isert_put_conn(isert_conn);
2270 return; 2251 return;
2271 } 2252 }
2272 pr_debug("isert_free_conn: wait_event conn_wait %d\n", 2253 if (isert_conn->state == ISER_CONN_UP)
2273 isert_conn->state); 2254 isert_conn->state = ISER_CONN_TERMINATING;
2274 mutex_unlock(&isert_conn->conn_mutex); 2255 mutex_unlock(&isert_conn->conn_mutex);
2275 2256
2276 wait_event(isert_conn->conn_wait, 2257 wait_for_completion(&isert_conn->conn_wait_comp_err);
2277 (isert_check_state(isert_conn, ISER_CONN_DOWN))); 2258
2259 wait_for_completion(&isert_conn->conn_wait);
2260}
2261
2262static void isert_free_conn(struct iscsi_conn *conn)
2263{
2264 struct isert_conn *isert_conn = conn->context;
2278 2265
2279 isert_put_conn(isert_conn); 2266 isert_put_conn(isert_conn);
2280} 2267}
@@ -2286,6 +2273,7 @@ static struct iscsit_transport iser_target_transport = {
2286 .iscsit_setup_np = isert_setup_np, 2273 .iscsit_setup_np = isert_setup_np,
2287 .iscsit_accept_np = isert_accept_np, 2274 .iscsit_accept_np = isert_accept_np,
2288 .iscsit_free_np = isert_free_np, 2275 .iscsit_free_np = isert_free_np,
2276 .iscsit_wait_conn = isert_wait_conn,
2289 .iscsit_free_conn = isert_free_conn, 2277 .iscsit_free_conn = isert_free_conn,
2290 .iscsit_alloc_cmd = isert_alloc_cmd, 2278 .iscsit_alloc_cmd = isert_alloc_cmd,
2291 .iscsit_get_login_rx = isert_get_login_rx, 2279 .iscsit_get_login_rx = isert_get_login_rx,
diff --git a/drivers/infiniband/ulp/isert/ib_isert.h b/drivers/infiniband/ulp/isert/ib_isert.h
index 5795c82a2306..b9d6cc6917cf 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.h
+++ b/drivers/infiniband/ulp/isert/ib_isert.h
@@ -103,8 +103,8 @@ struct isert_conn {
103 struct isert_device *conn_device; 103 struct isert_device *conn_device;
104 struct work_struct conn_logout_work; 104 struct work_struct conn_logout_work;
105 struct mutex conn_mutex; 105 struct mutex conn_mutex;
106 wait_queue_head_t conn_wait; 106 struct completion conn_wait;
107 wait_queue_head_t conn_wait_comp_err; 107 struct completion conn_wait_comp_err;
108 struct kref conn_kref; 108 struct kref conn_kref;
109}; 109};
110 110
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index 59a5319ee50c..5232ac7b0745 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -4144,6 +4144,10 @@ int iscsit_close_connection(
4144 iscsit_stop_timers_for_cmds(conn); 4144 iscsit_stop_timers_for_cmds(conn);
4145 iscsit_stop_nopin_response_timer(conn); 4145 iscsit_stop_nopin_response_timer(conn);
4146 iscsit_stop_nopin_timer(conn); 4146 iscsit_stop_nopin_timer(conn);
4147
4148 if (conn->conn_transport->iscsit_wait_conn)
4149 conn->conn_transport->iscsit_wait_conn(conn);
4150
4147 iscsit_free_queue_reqs_for_conn(conn); 4151 iscsit_free_queue_reqs_for_conn(conn);
4148 4152
4149 /* 4153 /*
diff --git a/include/target/iscsi/iscsi_transport.h b/include/target/iscsi/iscsi_transport.h
index c5aade523863..4a5f00e2e6cd 100644
--- a/include/target/iscsi/iscsi_transport.h
+++ b/include/target/iscsi/iscsi_transport.h
@@ -11,6 +11,7 @@ struct iscsit_transport {
11 int (*iscsit_setup_np)(struct iscsi_np *, struct __kernel_sockaddr_storage *); 11 int (*iscsit_setup_np)(struct iscsi_np *, struct __kernel_sockaddr_storage *);
12 int (*iscsit_accept_np)(struct iscsi_np *, struct iscsi_conn *); 12 int (*iscsit_accept_np)(struct iscsi_np *, struct iscsi_conn *);
13 void (*iscsit_free_np)(struct iscsi_np *); 13 void (*iscsit_free_np)(struct iscsi_np *);
14 void (*iscsit_wait_conn)(struct iscsi_conn *);
14 void (*iscsit_free_conn)(struct iscsi_conn *); 15 void (*iscsit_free_conn)(struct iscsi_conn *);
15 struct iscsi_cmd *(*iscsit_alloc_cmd)(struct iscsi_conn *, gfp_t); 16 struct iscsi_cmd *(*iscsit_alloc_cmd)(struct iscsi_conn *, gfp_t);
16 int (*iscsit_get_login_rx)(struct iscsi_conn *, struct iscsi_login *); 17 int (*iscsit_get_login_rx)(struct iscsi_conn *, struct iscsi_login *);