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;
194 complete(&ts->rx_start_comp);
195 spin_unlock_bh(&ts->ts_state_lock);
196 kthread_stop(ts->rx_thread);
197 spin_lock_bh(&ts->ts_state_lock);
200 complete(&ts->tx_start_comp);
201 spin_unlock_bh(&ts->ts_state_lock);
202 kthread_stop(ts->tx_thread);
203 spin_lock_bh(&ts->ts_state_lock);
205 spin_unlock_bh(&ts->ts_state_lock);
207 * Release this thread_id in the thread_set_bitmap
209 spin_lock(&ts_bitmap_lock);
210 bitmap_release_region(iscsit_global->ts_bitmap,
211 ts->thread_id, get_order(1));
212 spin_unlock(&ts_bitmap_lock);
218 if (released_count) {
219 pr_debug("Stopped %d thread set(s) (%d total threads)."
220 "\n", released_count, released_count * 2);
224 void iscsi_activate_thread_set(struct iscsi_conn *conn, struct iscsi_thread_set *ts)
226 iscsi_add_ts_to_active_list(ts);
228 spin_lock_bh(&ts->ts_state_lock);
229 conn->thread_set = ts;
231 spin_unlock_bh(&ts->ts_state_lock);
233 * Start up the RX thread and wait on rx_post_start_comp. The RX
234 * Thread will then do the same for the TX Thread in
235 * iscsi_rx_thread_pre_handler().
237 complete(&ts->rx_start_comp);
238 wait_for_completion(&ts->rx_post_start_comp);
241 struct iscsi_thread_set *iscsi_get_thread_set(void)
244 struct completion comp;
245 struct iscsi_thread_set *ts = NULL;
247 * If no inactive thread set is available on the first call to
248 * iscsi_get_ts_from_inactive_list(), sleep for a second and
249 * try again. If still none are available after two attempts,
250 * allocate a set ourselves.
253 ts = iscsi_get_ts_from_inactive_list();
255 if (allocate_ts == 2)
256 iscsi_allocate_thread_sets(1);
258 init_completion(&comp);
259 wait_for_completion_timeout(&comp, 1 * HZ);
265 ts->delay_inactive = 1;
267 ts->thread_count = 2;
268 init_completion(&ts->rx_restart_comp);
269 init_completion(&ts->tx_restart_comp);
274 void iscsi_set_thread_clear(struct iscsi_conn *conn, u8 thread_clear)
276 struct iscsi_thread_set *ts = NULL;
278 if (!conn->thread_set) {
279 pr_err("struct iscsi_conn->thread_set is NULL\n");
282 ts = conn->thread_set;
284 spin_lock_bh(&ts->ts_state_lock);
285 ts->thread_clear &= ~thread_clear;
287 if ((thread_clear & ISCSI_CLEAR_RX_THREAD) &&
288 (ts->blocked_threads & ISCSI_BLOCK_RX_THREAD))
289 complete(&ts->rx_restart_comp);
290 else if ((thread_clear & ISCSI_CLEAR_TX_THREAD) &&
291 (ts->blocked_threads & ISCSI_BLOCK_TX_THREAD))
292 complete(&ts->tx_restart_comp);
293 spin_unlock_bh(&ts->ts_state_lock);
296 void iscsi_set_thread_set_signal(struct iscsi_conn *conn, u8 signal_sent)
298 struct iscsi_thread_set *ts = NULL;
300 if (!conn->thread_set) {
301 pr_err("struct iscsi_conn->thread_set is NULL\n");
304 ts = conn->thread_set;
306 spin_lock_bh(&ts->ts_state_lock);
307 ts->signal_sent |= signal_sent;
308 spin_unlock_bh(&ts->ts_state_lock);
311 int iscsi_release_thread_set(struct iscsi_conn *conn)
313 int thread_called = 0;
314 struct iscsi_thread_set *ts = NULL;
316 if (!conn || !conn->thread_set) {
317 pr_err("connection or thread set pointer is NULL\n");
320 ts = conn->thread_set;
322 spin_lock_bh(&ts->ts_state_lock);
323 ts->status = ISCSI_THREAD_SET_RESET;
325 if (!strncmp(current->comm, ISCSI_RX_THREAD_NAME,
326 strlen(ISCSI_RX_THREAD_NAME)))
327 thread_called = ISCSI_RX_THREAD;
328 else if (!strncmp(current->comm, ISCSI_TX_THREAD_NAME,
329 strlen(ISCSI_TX_THREAD_NAME)))
330 thread_called = ISCSI_TX_THREAD;
332 if (ts->rx_thread && (thread_called == ISCSI_TX_THREAD) &&
333 (ts->thread_clear & ISCSI_CLEAR_RX_THREAD)) {
335 if (!(ts->signal_sent & ISCSI_SIGNAL_RX_THREAD)) {
336 send_sig(SIGINT, ts->rx_thread, 1);
337 ts->signal_sent |= ISCSI_SIGNAL_RX_THREAD;
339 ts->blocked_threads |= ISCSI_BLOCK_RX_THREAD;
340 spin_unlock_bh(&ts->ts_state_lock);
341 wait_for_completion(&ts->rx_restart_comp);
342 spin_lock_bh(&ts->ts_state_lock);
343 ts->blocked_threads &= ~ISCSI_BLOCK_RX_THREAD;
345 if (ts->tx_thread && (thread_called == ISCSI_RX_THREAD) &&
346 (ts->thread_clear & ISCSI_CLEAR_TX_THREAD)) {
348 if (!(ts->signal_sent & ISCSI_SIGNAL_TX_THREAD)) {
349 send_sig(SIGINT, ts->tx_thread, 1);
350 ts->signal_sent |= ISCSI_SIGNAL_TX_THREAD;
352 ts->blocked_threads |= ISCSI_BLOCK_TX_THREAD;
353 spin_unlock_bh(&ts->ts_state_lock);
354 wait_for_completion(&ts->tx_restart_comp);
355 spin_lock_bh(&ts->ts_state_lock);
356 ts->blocked_threads &= ~ISCSI_BLOCK_TX_THREAD;
360 ts->status = ISCSI_THREAD_SET_FREE;
361 spin_unlock_bh(&ts->ts_state_lock);
366 int iscsi_thread_set_force_reinstatement(struct iscsi_conn *conn)
368 struct iscsi_thread_set *ts;
370 if (!conn->thread_set)
372 ts = conn->thread_set;
374 spin_lock_bh(&ts->ts_state_lock);
375 if (ts->status != ISCSI_THREAD_SET_ACTIVE) {
376 spin_unlock_bh(&ts->ts_state_lock);
380 if (ts->tx_thread && (!(ts->signal_sent & ISCSI_SIGNAL_TX_THREAD))) {
381 send_sig(SIGINT, ts->tx_thread, 1);
382 ts->signal_sent |= ISCSI_SIGNAL_TX_THREAD;
384 if (ts->rx_thread && (!(ts->signal_sent & ISCSI_SIGNAL_RX_THREAD))) {
385 send_sig(SIGINT, ts->rx_thread, 1);
386 ts->signal_sent |= ISCSI_SIGNAL_RX_THREAD;
388 spin_unlock_bh(&ts->ts_state_lock);
393 static void iscsi_check_to_add_additional_sets(void)
397 spin_lock(&inactive_ts_lock);
398 thread_sets_add = iscsit_global->inactive_ts;
399 spin_unlock(&inactive_ts_lock);
400 if (thread_sets_add == 1)
401 iscsi_allocate_thread_sets(1);
404 static int iscsi_signal_thread_pre_handler(struct iscsi_thread_set *ts)
406 spin_lock_bh(&ts->ts_state_lock);
407 if (ts->status == ISCSI_THREAD_SET_DIE || kthread_should_stop() ||
408 signal_pending(current)) {
409 spin_unlock_bh(&ts->ts_state_lock);
412 spin_unlock_bh(&ts->ts_state_lock);
417 struct iscsi_conn *iscsi_rx_thread_pre_handler(struct iscsi_thread_set *ts)
421 spin_lock_bh(&ts->ts_state_lock);
422 if (ts->create_threads) {
423 spin_unlock_bh(&ts->ts_state_lock);
427 if (ts->status != ISCSI_THREAD_SET_DIE)
428 flush_signals(current);
430 if (ts->delay_inactive && (--ts->thread_count == 0)) {
431 spin_unlock_bh(&ts->ts_state_lock);
432 iscsi_del_ts_from_active_list(ts);
434 if (!iscsit_global->in_shutdown)
435 iscsi_deallocate_extra_thread_sets();
437 iscsi_add_ts_to_inactive_list(ts);
438 spin_lock_bh(&ts->ts_state_lock);
441 if ((ts->status == ISCSI_THREAD_SET_RESET) &&
442 (ts->thread_clear & ISCSI_CLEAR_RX_THREAD))
443 complete(&ts->rx_restart_comp);
445 ts->thread_clear &= ~ISCSI_CLEAR_RX_THREAD;
446 spin_unlock_bh(&ts->ts_state_lock);
448 ret = wait_for_completion_interruptible(&ts->rx_start_comp);
452 if (iscsi_signal_thread_pre_handler(ts) < 0)
456 pr_err("struct iscsi_thread_set->conn is NULL for"
457 " thread_id: %d, going back to sleep\n", ts->thread_id);
460 iscsi_check_to_add_additional_sets();
462 * The RX Thread starts up the TX Thread and sleeps.
464 ts->thread_clear |= ISCSI_CLEAR_RX_THREAD;
465 complete(&ts->tx_start_comp);
466 wait_for_completion(&ts->tx_post_start_comp);
471 struct iscsi_conn *iscsi_tx_thread_pre_handler(struct iscsi_thread_set *ts)
475 spin_lock_bh(&ts->ts_state_lock);
476 if (ts->create_threads) {
477 spin_unlock_bh(&ts->ts_state_lock);
481 if (ts->status != ISCSI_THREAD_SET_DIE)
482 flush_signals(current);
484 if (ts->delay_inactive && (--ts->thread_count == 0)) {
485 spin_unlock_bh(&ts->ts_state_lock);
486 iscsi_del_ts_from_active_list(ts);
488 if (!iscsit_global->in_shutdown)
489 iscsi_deallocate_extra_thread_sets();
491 iscsi_add_ts_to_inactive_list(ts);
492 spin_lock_bh(&ts->ts_state_lock);
494 if ((ts->status == ISCSI_THREAD_SET_RESET) &&
495 (ts->thread_clear & ISCSI_CLEAR_TX_THREAD))
496 complete(&ts->tx_restart_comp);
498 ts->thread_clear &= ~ISCSI_CLEAR_TX_THREAD;
499 spin_unlock_bh(&ts->ts_state_lock);
501 ret = wait_for_completion_interruptible(&ts->tx_start_comp);
505 if (iscsi_signal_thread_pre_handler(ts) < 0)
509 pr_err("struct iscsi_thread_set->conn is NULL for "
510 " thread_id: %d, going back to sleep\n",
515 iscsi_check_to_add_additional_sets();
517 * From the TX thread, up the tx_post_start_comp that the RX Thread is
518 * sleeping on in iscsi_rx_thread_pre_handler(), then up the
519 * rx_post_start_comp that iscsi_activate_thread_set() is sleeping on.
521 ts->thread_clear |= ISCSI_CLEAR_TX_THREAD;
522 complete(&ts->tx_post_start_comp);
523 complete(&ts->rx_post_start_comp);
525 spin_lock_bh(&ts->ts_state_lock);
526 ts->status = ISCSI_THREAD_SET_ACTIVE;
527 spin_unlock_bh(&ts->ts_state_lock);
532 int iscsi_thread_set_init(void)
536 iscsit_global->ts_bitmap_count = ISCSI_TS_BITMAP_BITS;
538 size = BITS_TO_LONGS(iscsit_global->ts_bitmap_count) * sizeof(long);
539 iscsit_global->ts_bitmap = kzalloc(size, GFP_KERNEL);
540 if (!iscsit_global->ts_bitmap) {
541 pr_err("Unable to allocate iscsit_global->ts_bitmap\n");
548 void iscsi_thread_set_free(void)
550 kfree(iscsit_global->ts_bitmap);