diff options
-rw-r--r-- | drivers/infiniband/ulp/isert/ib_isert.c | 104 | ||||
-rw-r--r-- | drivers/infiniband/ulp/isert/ib_isert.h | 4 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 4 | ||||
-rw-r--r-- | include/target/iscsi/iscsi_transport.h | 1 |
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 | ||
576 | wake_up: | 576 | wake_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 | ||
1428 | static void | 1428 | static void |
1429 | isert_cq_comp_err(struct iser_tx_desc *tx_desc, struct isert_conn *isert_conn) | 1429 | isert_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) | 1440 | static void |
1437 | isert_unmap_tx_desc(tx_desc, ib_dev); | 1441 | isert_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 | ||
1456 | static void | 1463 | static 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 | ||
2221 | static int isert_check_state(struct isert_conn *isert_conn, int state) | 2228 | static 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 | |||
2232 | static 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 | |||
2262 | static 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 *); |