File iscsi-cancel-conn-worker-threads-using-the-task_pipe.patch of Package istgt
From 88f929d2c17739e88eaed15fe22c6c898c7dde4d Mon Sep 17 00:00:00 2001
From: David Disseldorp <ddiss@suse.de>
Date: Wed, 27 Mar 2013 18:30:27 +0100
Subject: [PATCH 4/7] iscsi: cancel conn worker threads using the task_pipe
Currently istgt_iscsi_drop_*_conns() use pthread_cancel() to tell the
connection worker thread to exit. This is unnecessary, as the worker
thread already accepts exit requests via the task_pipe.
---
src/istgt_iscsi.c | 87 ++++++++++---------------------------------------------
1 file changed, 16 insertions(+), 71 deletions(-)
diff --git src/istgt_iscsi.c src/istgt_iscsi.c
index 1ca226c..5fa5fbc 100644
--- src/istgt_iscsi.c
+++ src/istgt_iscsi.c
@@ -5260,9 +5260,8 @@ wait_all_task(CONN_Ptr conn)
}
static void
-worker_cleanup(void *arg)
+worker_cleanup(CONN_Ptr conn)
{
- CONN_Ptr conn = (CONN_Ptr) arg;
ISTGT_LU_Ptr lu;
int rc;
@@ -5534,9 +5533,6 @@ worker(void *arg)
conn->exec_lu_task = NULL;
lu_task = NULL;
- pthread_cleanup_push(worker_cleanup, conn);
- pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
-
conn->use_sender = 0;
if (conn->istgt->swmode >= ISTGT_SWMODE_NORMAL) {
/* create sender thread */
@@ -5585,7 +5581,6 @@ worker(void *arg)
}
}
- pthread_testcancel();
if (conn->state != CONN_STATE_RUNNING) {
break;
}
@@ -5701,9 +5696,6 @@ worker(void *arg)
execute_pdu:
opcode = BGET8W(&conn->pdu.bhs.opcode, 5, 6);
-#if 0
- pthread_testcancel();
-#endif
if (conn->state != CONN_STATE_RUNNING) {
break;
}
@@ -5913,62 +5905,7 @@ worker(void *arg)
cleanup_exit:
;
- pthread_cleanup_pop(0);
- conn->state = CONN_STATE_EXITING;
- if (conn->sess != NULL) {
- SESS_MTX_LOCK(conn);
- lu = conn->sess->lu;
- if (lu != NULL && lu->queue_depth != 0) {
- rc = istgt_lu_clear_task_IT(conn, lu);
- if (rc < 0) {
- ISTGT_ERRLOG("lu_clear_task_IT() failed\n");
- }
- istgt_clear_all_transfer_task(conn);
- }
- SESS_MTX_UNLOCK(conn);
- }
- if (conn->pdu.copy_pdu == 0) {
- xfree(conn->pdu.ahs);
- conn->pdu.ahs = NULL;
- if (conn->pdu.data != conn->pdu.shortdata) {
- xfree(conn->pdu.data);
- }
- conn->pdu.data = NULL;
- }
- wait_all_task(conn);
-
- if (conn->use_sender) {
- ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "stop sender thread (%d)\n", conn->id);
- /* stop sender thread */
- MTX_LOCK(&conn->result_queue_mutex);
- rc = pthread_cond_broadcast(&conn->result_queue_cond);
- MTX_UNLOCK(&conn->result_queue_mutex);
- if (rc != 0) {
- ISTGT_ERRLOG("cond_broadcast() failed\n");
- /* ignore errors */
- }
- rc = pthread_join(conn->sender_thread, NULL);
- if (rc != 0) {
- ISTGT_ERRLOG("pthread_join() failed\n");
- /* ignore errors */
- }
- }
-
- close(conn->sock);
-#ifdef ISTGT_USE_KQUEUE
- close(kq);
- conn->kq = -1;
-#endif /* ISTGT_USE_KQUEUE */
- sleep(1);
- ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "worker %d end\n", conn->id);
-
- /* cleanup conn & sess */
- ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "cleanup LOCK\n");
- MTX_LOCK(&g_conns_mutex);
- g_conns[conn->id] = NULL;
- istgt_remove_conn(conn);
- MTX_UNLOCK(&g_conns_mutex);
- ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "cleanup UNLOCK\n");
+ worker_cleanup(conn);
return NULL;
}
@@ -6697,7 +6634,6 @@ istgt_iscsi_drop_all_conns(CONN_Ptr conn)
istgt_yield();
sleep(1);
if (num > max_conns + 1) {
- printf("try pthread_cancel\n");
for (i = 0; i < g_nconns; i++) {
xconn = g_conns[i];
if (xconn == NULL)
@@ -6719,9 +6655,14 @@ istgt_iscsi_drop_all_conns(CONN_Ptr conn)
xconn->initiator_addr,
xconn->cid);
}
- rc = pthread_cancel(xconn->thread);
+ rc = write(xconn->task_pipe[1], "E", 1);
+ if (rc < 0 || rc != 1) {
+ ISTGT_ERRLOG("write() failed\n");
+ continue;
+ }
+ rc = pthread_join(xconn->thread, NULL);
if (rc != 0) {
- ISTGT_ERRLOG("pthread_cancel() failed rc=%d\n", rc);
+ ISTGT_ERRLOG("pthread_join() failed rc=%d\n", rc);
}
}
}
@@ -6781,7 +6722,6 @@ istgt_iscsi_drop_old_conns(CONN_Ptr conn)
istgt_yield();
sleep(1);
if (num > max_conns + 1) {
- printf("try pthread_cancel\n");
for (i = 0; i < g_nconns; i++) {
xconn = g_conns[i];
if (xconn == NULL)
@@ -6803,9 +6743,14 @@ istgt_iscsi_drop_old_conns(CONN_Ptr conn)
xconn->initiator_addr,
xconn->cid);
}
- rc = pthread_cancel(xconn->thread);
+ rc = write(xconn->task_pipe[1], "E", 1);
+ if (rc < 0 || rc != 1) {
+ ISTGT_ERRLOG("write() failed\n");
+ continue;
+ }
+ rc = pthread_join(xconn->thread, NULL);
if (rc != 0) {
- ISTGT_ERRLOG("pthread_cancel() failed rc=%d\n", rc);
+ ISTGT_ERRLOG("pthread_join() failed rc=%d\n", rc);
}
}
}
--
1.8.1.4