1 /*******************************************************************************
2 * This file contains the iSCSI Login Thread and Thread Queue functions.
4 * \u00a9 Copyright 2007-2011 RisingTide Systems LLC.
6 * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
8 * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 ******************************************************************************/
21 #include <linux/kthread.h>
22 #include <linux/list.h>
23 #include <linux/bitmap.h>
25 #include "iscsi_target_core.h"
26 #include "iscsi_target_tq.h"
27 #include "iscsi_target.h"
29 static LIST_HEAD(active_ts_list
);
30 static LIST_HEAD(inactive_ts_list
);
31 static DEFINE_SPINLOCK(active_ts_lock
);
32 static DEFINE_SPINLOCK(inactive_ts_lock
);
33 static DEFINE_SPINLOCK(ts_bitmap_lock
);
35 static void iscsi_add_ts_to_active_list(struct iscsi_thread_set
*ts
)
37 spin_lock(&active_ts_lock
);
38 list_add_tail(&ts
->ts_list
, &active_ts_list
);
39 iscsit_global
->active_ts
++;
40 spin_unlock(&active_ts_lock
);
43 static void iscsi_add_ts_to_inactive_list(struct iscsi_thread_set
*ts
)
45 spin_lock(&inactive_ts_lock
);
46 list_add_tail(&ts
->ts_list
, &inactive_ts_list
);
47 iscsit_global
->inactive_ts
++;
48 spin_unlock(&inactive_ts_lock
);
51 static void iscsi_del_ts_from_active_list(struct iscsi_thread_set
*ts
)
53 spin_lock(&active_ts_lock
);
54 list_del(&ts
->ts_list
);
55 iscsit_global
->active_ts
--;
56 spin_unlock(&active_ts_lock
);
59 static struct iscsi_thread_set
*iscsi_get_ts_from_inactive_list(void)
61 struct iscsi_thread_set
*ts
;
63 spin_lock(&inactive_ts_lock
);
64 if (list_empty(&inactive_ts_list
)) {
65 spin_unlock(&inactive_ts_lock
);
69 ts
= list_first_entry(&inactive_ts_list
, struct iscsi_thread_set
, ts_list
);
71 list_del(&ts
->ts_list
);
72 iscsit_global
->inactive_ts
--;
73 spin_unlock(&inactive_ts_lock
);
78 int iscsi_allocate_thread_sets(u32 thread_pair_count
)
80 int allocated_thread_pair_count
= 0, i
, thread_id
;
81 struct iscsi_thread_set
*ts
= NULL
;
83 for (i
= 0; i
< thread_pair_count
; i
++) {
84 ts
= kzalloc(sizeof(struct iscsi_thread_set
), GFP_KERNEL
);
86 pr_err("Unable to allocate memory for"
88 return allocated_thread_pair_count
;
91 * Locate the next available regision in the thread_set_bitmap
93 spin_lock(&ts_bitmap_lock
);
94 thread_id
= bitmap_find_free_region(iscsit_global
->ts_bitmap
,
95 iscsit_global
->ts_bitmap_count
, get_order(1));
96 spin_unlock(&ts_bitmap_lock
);
98 pr_err("bitmap_find_free_region() failed for"
99 " thread_set_bitmap\n");
101 return allocated_thread_pair_count
;
104 ts
->thread_id
= thread_id
;
105 ts
->status
= ISCSI_THREAD_SET_FREE
;
106 INIT_LIST_HEAD(&ts
->ts_list
);
107 spin_lock_init(&ts
->ts_state_lock
);
108 init_completion(&ts
->rx_post_start_comp
);
109 init_completion(&ts
->tx_post_start_comp
);
110 init_completion(&ts
->rx_restart_comp
);
111 init_completion(&ts
->tx_restart_comp
);
112 init_completion(&ts
->rx_start_comp
);
113 init_completion(&ts
->tx_start_comp
);
115 ts
->create_threads
= 1;
116 ts
->tx_thread
= kthread_run(iscsi_target_tx_thread
, ts
, "%s",
117 ISCSI_TX_THREAD_NAME
);
118 if (IS_ERR(ts
->tx_thread
)) {
120 pr_err("Unable to start iscsi_target_tx_thread\n");
124 ts
->rx_thread
= kthread_run(iscsi_target_rx_thread
, ts
, "%s",
125 ISCSI_RX_THREAD_NAME
);
126 if (IS_ERR(ts
->rx_thread
)) {
127 kthread_stop(ts
->tx_thread
);
128 pr_err("Unable to start iscsi_target_rx_thread\n");
131 ts
->create_threads
= 0;
133 iscsi_add_ts_to_inactive_list(ts
);
134 allocated_thread_pair_count
++;
137 pr_debug("Spawned %d thread set(s) (%d total threads).\n",
138 allocated_thread_pair_count
, allocated_thread_pair_count
* 2);
139 return allocated_thread_pair_count
;
142 void iscsi_deallocate_thread_sets(void)
144 u32 released_count
= 0;
145 struct iscsi_thread_set
*ts
= NULL
;
147 while ((ts
= iscsi_get_ts_from_inactive_list())) {
149 spin_lock_bh(&ts
->ts_state_lock
);
150 ts
->status
= ISCSI_THREAD_SET_DIE
;
151 spin_unlock_bh(&ts
->ts_state_lock
);
154 send_sig(SIGINT
, ts
->rx_thread
, 1);
155 kthread_stop(ts
->rx_thread
);
158 send_sig(SIGINT
, ts
->tx_thread
, 1);
159 kthread_stop(ts
->tx_thread
);
162 * Release this thread_id in the thread_set_bitmap
164 spin_lock(&ts_bitmap_lock
);
165 bitmap_release_region(iscsit_global
->ts_bitmap
,
166 ts
->thread_id
, get_order(1));
167 spin_unlock(&ts_bitmap_lock
);
174 pr_debug("Stopped %d thread set(s) (%d total threads)."
175 "\n", released_count
, released_count
* 2);
178 static void iscsi_deallocate_extra_thread_sets(void)
180 u32 orig_count
, released_count
= 0;
181 struct iscsi_thread_set
*ts
= NULL
;
183 orig_count
= TARGET_THREAD_SET_COUNT
;
185 while ((iscsit_global
->inactive_ts
+ 1) > orig_count
) {
186 ts
= iscsi_get_ts_from_inactive_list();
190 spin_lock_bh(&ts
->ts_state_lock
);
191 ts
->status
= ISCSI_THREAD_SET_DIE
;
192 spin_unlock_bh(&ts
->ts_state_lock
);
195 send_sig(SIGINT
, ts
->rx_thread
, 1);
196 kthread_stop(ts
->rx_thread
);
199 send_sig(SIGINT
, ts
->tx_thread
, 1);
200 kthread_stop(ts
->tx_thread
);
203 * Release this thread_id in the thread_set_bitmap
205 spin_lock(&ts_bitmap_lock
);
206 bitmap_release_region(iscsit_global
->ts_bitmap
,
207 ts
->thread_id
, get_order(1));
208 spin_unlock(&ts_bitmap_lock
);
214 if (released_count
) {
215 pr_debug("Stopped %d thread set(s) (%d total threads)."
216 "\n", released_count
, released_count
* 2);
220 void iscsi_activate_thread_set(struct iscsi_conn
*conn
, struct iscsi_thread_set
*ts
)
222 iscsi_add_ts_to_active_list(ts
);
224 spin_lock_bh(&ts
->ts_state_lock
);
225 conn
->thread_set
= ts
;
227 spin_unlock_bh(&ts
->ts_state_lock
);
229 * Start up the RX thread and wait on rx_post_start_comp. The RX
230 * Thread will then do the same for the TX Thread in
231 * iscsi_rx_thread_pre_handler().
233 complete(&ts
->rx_start_comp
);
234 wait_for_completion(&ts
->rx_post_start_comp
);
237 struct iscsi_thread_set
*iscsi_get_thread_set(void)
240 struct completion comp
;
241 struct iscsi_thread_set
*ts
= NULL
;
243 * If no inactive thread set is available on the first call to
244 * iscsi_get_ts_from_inactive_list(), sleep for a second and
245 * try again. If still none are available after two attempts,
246 * allocate a set ourselves.
249 ts
= iscsi_get_ts_from_inactive_list();
251 if (allocate_ts
== 2)
252 iscsi_allocate_thread_sets(1);
254 init_completion(&comp
);
255 wait_for_completion_timeout(&comp
, 1 * HZ
);
261 ts
->delay_inactive
= 1;
263 ts
->thread_count
= 2;
264 init_completion(&ts
->rx_restart_comp
);
265 init_completion(&ts
->tx_restart_comp
);
270 void iscsi_set_thread_clear(struct iscsi_conn
*conn
, u8 thread_clear
)
272 struct iscsi_thread_set
*ts
= NULL
;
274 if (!conn
->thread_set
) {
275 pr_err("struct iscsi_conn->thread_set is NULL\n");
278 ts
= conn
->thread_set
;
280 spin_lock_bh(&ts
->ts_state_lock
);
281 ts
->thread_clear
&= ~thread_clear
;
283 if ((thread_clear
& ISCSI_CLEAR_RX_THREAD
) &&
284 (ts
->blocked_threads
& ISCSI_BLOCK_RX_THREAD
))
285 complete(&ts
->rx_restart_comp
);
286 else if ((thread_clear
& ISCSI_CLEAR_TX_THREAD
) &&
287 (ts
->blocked_threads
& ISCSI_BLOCK_TX_THREAD
))
288 complete(&ts
->tx_restart_comp
);
289 spin_unlock_bh(&ts
->ts_state_lock
);
292 void iscsi_set_thread_set_signal(struct iscsi_conn
*conn
, u8 signal_sent
)
294 struct iscsi_thread_set
*ts
= NULL
;
296 if (!conn
->thread_set
) {
297 pr_err("struct iscsi_conn->thread_set is NULL\n");
300 ts
= conn
->thread_set
;
302 spin_lock_bh(&ts
->ts_state_lock
);
303 ts
->signal_sent
|= signal_sent
;
304 spin_unlock_bh(&ts
->ts_state_lock
);
307 int iscsi_release_thread_set(struct iscsi_conn
*conn
)
309 int thread_called
= 0;
310 struct iscsi_thread_set
*ts
= NULL
;
312 if (!conn
|| !conn
->thread_set
) {
313 pr_err("connection or thread set pointer is NULL\n");
316 ts
= conn
->thread_set
;
318 spin_lock_bh(&ts
->ts_state_lock
);
319 ts
->status
= ISCSI_THREAD_SET_RESET
;
321 if (!strncmp(current
->comm
, ISCSI_RX_THREAD_NAME
,
322 strlen(ISCSI_RX_THREAD_NAME
)))
323 thread_called
= ISCSI_RX_THREAD
;
324 else if (!strncmp(current
->comm
, ISCSI_TX_THREAD_NAME
,
325 strlen(ISCSI_TX_THREAD_NAME
)))
326 thread_called
= ISCSI_TX_THREAD
;
328 if (ts
->rx_thread
&& (thread_called
== ISCSI_TX_THREAD
) &&
329 (ts
->thread_clear
& ISCSI_CLEAR_RX_THREAD
)) {
331 if (!(ts
->signal_sent
& ISCSI_SIGNAL_RX_THREAD
)) {
332 send_sig(SIGINT
, ts
->rx_thread
, 1);
333 ts
->signal_sent
|= ISCSI_SIGNAL_RX_THREAD
;
335 ts
->blocked_threads
|= ISCSI_BLOCK_RX_THREAD
;
336 spin_unlock_bh(&ts
->ts_state_lock
);
337 wait_for_completion(&ts
->rx_restart_comp
);
338 spin_lock_bh(&ts
->ts_state_lock
);
339 ts
->blocked_threads
&= ~ISCSI_BLOCK_RX_THREAD
;
341 if (ts
->tx_thread
&& (thread_called
== ISCSI_RX_THREAD
) &&
342 (ts
->thread_clear
& ISCSI_CLEAR_TX_THREAD
)) {
344 if (!(ts
->signal_sent
& ISCSI_SIGNAL_TX_THREAD
)) {
345 send_sig(SIGINT
, ts
->tx_thread
, 1);
346 ts
->signal_sent
|= ISCSI_SIGNAL_TX_THREAD
;
348 ts
->blocked_threads
|= ISCSI_BLOCK_TX_THREAD
;
349 spin_unlock_bh(&ts
->ts_state_lock
);
350 wait_for_completion(&ts
->tx_restart_comp
);
351 spin_lock_bh(&ts
->ts_state_lock
);
352 ts
->blocked_threads
&= ~ISCSI_BLOCK_TX_THREAD
;
356 ts
->status
= ISCSI_THREAD_SET_FREE
;
357 spin_unlock_bh(&ts
->ts_state_lock
);
362 int iscsi_thread_set_force_reinstatement(struct iscsi_conn
*conn
)
364 struct iscsi_thread_set
*ts
;
366 if (!conn
->thread_set
)
368 ts
= conn
->thread_set
;
370 spin_lock_bh(&ts
->ts_state_lock
);
371 if (ts
->status
!= ISCSI_THREAD_SET_ACTIVE
) {
372 spin_unlock_bh(&ts
->ts_state_lock
);
376 if (ts
->tx_thread
&& (!(ts
->signal_sent
& ISCSI_SIGNAL_TX_THREAD
))) {
377 send_sig(SIGINT
, ts
->tx_thread
, 1);
378 ts
->signal_sent
|= ISCSI_SIGNAL_TX_THREAD
;
380 if (ts
->rx_thread
&& (!(ts
->signal_sent
& ISCSI_SIGNAL_RX_THREAD
))) {
381 send_sig(SIGINT
, ts
->rx_thread
, 1);
382 ts
->signal_sent
|= ISCSI_SIGNAL_RX_THREAD
;
384 spin_unlock_bh(&ts
->ts_state_lock
);
389 static void iscsi_check_to_add_additional_sets(void)
393 spin_lock(&inactive_ts_lock
);
394 thread_sets_add
= iscsit_global
->inactive_ts
;
395 spin_unlock(&inactive_ts_lock
);
396 if (thread_sets_add
== 1)
397 iscsi_allocate_thread_sets(1);
400 static int iscsi_signal_thread_pre_handler(struct iscsi_thread_set
*ts
)
402 spin_lock_bh(&ts
->ts_state_lock
);
403 if ((ts
->status
== ISCSI_THREAD_SET_DIE
) || signal_pending(current
)) {
404 spin_unlock_bh(&ts
->ts_state_lock
);
407 spin_unlock_bh(&ts
->ts_state_lock
);
412 struct iscsi_conn
*iscsi_rx_thread_pre_handler(struct iscsi_thread_set
*ts
)
416 spin_lock_bh(&ts
->ts_state_lock
);
417 if (ts
->create_threads
) {
418 spin_unlock_bh(&ts
->ts_state_lock
);
422 flush_signals(current
);
424 if (ts
->delay_inactive
&& (--ts
->thread_count
== 0)) {
425 spin_unlock_bh(&ts
->ts_state_lock
);
426 iscsi_del_ts_from_active_list(ts
);
428 if (!iscsit_global
->in_shutdown
)
429 iscsi_deallocate_extra_thread_sets();
431 iscsi_add_ts_to_inactive_list(ts
);
432 spin_lock_bh(&ts
->ts_state_lock
);
435 if ((ts
->status
== ISCSI_THREAD_SET_RESET
) &&
436 (ts
->thread_clear
& ISCSI_CLEAR_RX_THREAD
))
437 complete(&ts
->rx_restart_comp
);
439 ts
->thread_clear
&= ~ISCSI_CLEAR_RX_THREAD
;
440 spin_unlock_bh(&ts
->ts_state_lock
);
442 ret
= wait_for_completion_interruptible(&ts
->rx_start_comp
);
446 if (iscsi_signal_thread_pre_handler(ts
) < 0)
450 pr_err("struct iscsi_thread_set->conn is NULL for"
451 " thread_id: %d, going back to sleep\n", ts
->thread_id
);
454 iscsi_check_to_add_additional_sets();
456 * The RX Thread starts up the TX Thread and sleeps.
458 ts
->thread_clear
|= ISCSI_CLEAR_RX_THREAD
;
459 complete(&ts
->tx_start_comp
);
460 wait_for_completion(&ts
->tx_post_start_comp
);
465 struct iscsi_conn
*iscsi_tx_thread_pre_handler(struct iscsi_thread_set
*ts
)
469 spin_lock_bh(&ts
->ts_state_lock
);
470 if (ts
->create_threads
) {
471 spin_unlock_bh(&ts
->ts_state_lock
);
475 flush_signals(current
);
477 if (ts
->delay_inactive
&& (--ts
->thread_count
== 0)) {
478 spin_unlock_bh(&ts
->ts_state_lock
);
479 iscsi_del_ts_from_active_list(ts
);
481 if (!iscsit_global
->in_shutdown
)
482 iscsi_deallocate_extra_thread_sets();
484 iscsi_add_ts_to_inactive_list(ts
);
485 spin_lock_bh(&ts
->ts_state_lock
);
487 if ((ts
->status
== ISCSI_THREAD_SET_RESET
) &&
488 (ts
->thread_clear
& ISCSI_CLEAR_TX_THREAD
))
489 complete(&ts
->tx_restart_comp
);
491 ts
->thread_clear
&= ~ISCSI_CLEAR_TX_THREAD
;
492 spin_unlock_bh(&ts
->ts_state_lock
);
494 ret
= wait_for_completion_interruptible(&ts
->tx_start_comp
);
498 if (iscsi_signal_thread_pre_handler(ts
) < 0)
502 pr_err("struct iscsi_thread_set->conn is NULL for "
503 " thread_id: %d, going back to sleep\n",
508 iscsi_check_to_add_additional_sets();
510 * From the TX thread, up the tx_post_start_comp that the RX Thread is
511 * sleeping on in iscsi_rx_thread_pre_handler(), then up the
512 * rx_post_start_comp that iscsi_activate_thread_set() is sleeping on.
514 ts
->thread_clear
|= ISCSI_CLEAR_TX_THREAD
;
515 complete(&ts
->tx_post_start_comp
);
516 complete(&ts
->rx_post_start_comp
);
518 spin_lock_bh(&ts
->ts_state_lock
);
519 ts
->status
= ISCSI_THREAD_SET_ACTIVE
;
520 spin_unlock_bh(&ts
->ts_state_lock
);
525 int iscsi_thread_set_init(void)
529 iscsit_global
->ts_bitmap_count
= ISCSI_TS_BITMAP_BITS
;
531 size
= BITS_TO_LONGS(iscsit_global
->ts_bitmap_count
) * sizeof(long);
532 iscsit_global
->ts_bitmap
= kzalloc(size
, GFP_KERNEL
);
533 if (!iscsit_global
->ts_bitmap
) {
534 pr_err("Unable to allocate iscsit_global->ts_bitmap\n");
541 void iscsi_thread_set_free(void)
543 kfree(iscsit_global
->ts_bitmap
);