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(inactive_ts_list);
30 static DEFINE_SPINLOCK(inactive_ts_lock);
31 static DEFINE_SPINLOCK(ts_bitmap_lock);
33 extern void iscsi_add_ts_to_inactive_list(struct iscsi_thread_set *ts)
35 if (!list_empty(&ts->ts_list)) {
39 spin_lock(&inactive_ts_lock);
40 list_add_tail(&ts->ts_list, &inactive_ts_list);
41 iscsit_global->inactive_ts++;
42 spin_unlock(&inactive_ts_lock);
45 static struct iscsi_thread_set *iscsi_get_ts_from_inactive_list(void)
47 struct iscsi_thread_set *ts;
49 spin_lock(&inactive_ts_lock);
50 if (list_empty(&inactive_ts_list)) {
51 spin_unlock(&inactive_ts_lock);
55 list_for_each_entry(ts, &inactive_ts_list, ts_list)
58 list_del_init(&ts->ts_list);
59 iscsit_global->inactive_ts--;
60 spin_unlock(&inactive_ts_lock);
65 extern int iscsi_allocate_thread_sets(u32 thread_pair_count)
67 int allocated_thread_pair_count = 0, i, thread_id;
68 struct iscsi_thread_set *ts = NULL;
70 for (i = 0; i < thread_pair_count; i++) {
71 ts = kzalloc(sizeof(struct iscsi_thread_set), GFP_KERNEL);
73 pr_err("Unable to allocate memory for"
75 return allocated_thread_pair_count;
78 * Locate the next available regision in the thread_set_bitmap
80 spin_lock(&ts_bitmap_lock);
81 thread_id = bitmap_find_free_region(iscsit_global->ts_bitmap,
82 iscsit_global->ts_bitmap_count, get_order(1));
83 spin_unlock(&ts_bitmap_lock);
85 pr_err("bitmap_find_free_region() failed for"
86 " thread_set_bitmap\n");
88 return allocated_thread_pair_count;
91 ts->thread_id = thread_id;
92 ts->status = ISCSI_THREAD_SET_FREE;
93 INIT_LIST_HEAD(&ts->ts_list);
94 spin_lock_init(&ts->ts_state_lock);
95 init_completion(&ts->rx_post_start_comp);
96 init_completion(&ts->tx_post_start_comp);
97 init_completion(&ts->rx_restart_comp);
98 init_completion(&ts->tx_restart_comp);
99 init_completion(&ts->rx_start_comp);
100 init_completion(&ts->tx_start_comp);
102 ts->create_threads = 1;
103 ts->tx_thread = kthread_run(iscsi_target_tx_thread, ts, "%s",
104 ISCSI_TX_THREAD_NAME);
105 if (IS_ERR(ts->tx_thread)) {
107 pr_err("Unable to start iscsi_target_tx_thread\n");
111 ts->rx_thread = kthread_run(iscsi_target_rx_thread, ts, "%s",
112 ISCSI_RX_THREAD_NAME);
113 if (IS_ERR(ts->rx_thread)) {
114 kthread_stop(ts->tx_thread);
115 pr_err("Unable to start iscsi_target_rx_thread\n");
118 ts->create_threads = 0;
120 iscsi_add_ts_to_inactive_list(ts);
121 allocated_thread_pair_count++;
124 pr_debug("Spawned %d thread set(s) (%d total threads).\n",
125 allocated_thread_pair_count, allocated_thread_pair_count * 2);
126 return allocated_thread_pair_count;
129 extern void iscsi_deallocate_thread_sets(void)
131 u32 released_count = 0;
132 struct iscsi_thread_set *ts = NULL;
134 while ((ts = iscsi_get_ts_from_inactive_list())) {
136 spin_lock_bh(&ts->ts_state_lock);
137 ts->status = ISCSI_THREAD_SET_DIE;
138 spin_unlock_bh(&ts->ts_state_lock);
141 send_sig(SIGINT, ts->rx_thread, 1);
142 kthread_stop(ts->rx_thread);
145 send_sig(SIGINT, ts->tx_thread, 1);
146 kthread_stop(ts->tx_thread);
149 * Release this thread_id in the thread_set_bitmap
151 spin_lock(&ts_bitmap_lock);
152 bitmap_release_region(iscsit_global->ts_bitmap,
153 ts->thread_id, get_order(1));
154 spin_unlock(&ts_bitmap_lock);
161 pr_debug("Stopped %d thread set(s) (%d total threads)."
162 "\n", released_count, released_count * 2);
165 static void iscsi_deallocate_extra_thread_sets(void)
167 u32 orig_count, released_count = 0;
168 struct iscsi_thread_set *ts = NULL;
170 orig_count = TARGET_THREAD_SET_COUNT;
172 while ((iscsit_global->inactive_ts + 1) > orig_count) {
173 ts = iscsi_get_ts_from_inactive_list();
177 spin_lock_bh(&ts->ts_state_lock);
178 ts->status = ISCSI_THREAD_SET_DIE;
179 spin_unlock_bh(&ts->ts_state_lock);
182 send_sig(SIGINT, ts->rx_thread, 1);
183 kthread_stop(ts->rx_thread);
186 send_sig(SIGINT, ts->tx_thread, 1);
187 kthread_stop(ts->tx_thread);
190 * Release this thread_id in the thread_set_bitmap
192 spin_lock(&ts_bitmap_lock);
193 bitmap_release_region(iscsit_global->ts_bitmap,
194 ts->thread_id, get_order(1));
195 spin_unlock(&ts_bitmap_lock);
201 if (released_count) {
202 pr_debug("Stopped %d thread set(s) (%d total threads)."
203 "\n", released_count, released_count * 2);
207 void iscsi_activate_thread_set(struct iscsi_conn *conn, struct iscsi_thread_set *ts)
209 spin_lock_bh(&ts->ts_state_lock);
210 conn->thread_set = ts;
212 spin_unlock_bh(&ts->ts_state_lock);
214 * Start up the RX thread and wait on rx_post_start_comp. The RX
215 * Thread will then do the same for the TX Thread in
216 * iscsi_rx_thread_pre_handler().
218 complete(&ts->rx_start_comp);
219 wait_for_completion(&ts->rx_post_start_comp);
222 struct iscsi_thread_set *iscsi_get_thread_set(void)
225 struct completion comp;
226 struct iscsi_thread_set *ts = NULL;
228 * If no inactive thread set is available on the first call to
229 * iscsi_get_ts_from_inactive_list(), sleep for a second and
230 * try again. If still none are available after two attempts,
231 * allocate a set ourselves.
234 ts = iscsi_get_ts_from_inactive_list();
236 if (allocate_ts == 2)
237 iscsi_allocate_thread_sets(1);
239 init_completion(&comp);
240 wait_for_completion_timeout(&comp, 1 * HZ);
246 ts->delay_inactive = 1;
248 ts->thread_count = 2;
249 init_completion(&ts->rx_restart_comp);
250 init_completion(&ts->tx_restart_comp);
255 void iscsi_set_thread_clear(struct iscsi_conn *conn, u8 thread_clear)
257 struct iscsi_thread_set *ts = NULL;
259 if (!conn->thread_set) {
260 pr_err("struct iscsi_conn->thread_set is NULL\n");
263 ts = conn->thread_set;
265 spin_lock_bh(&ts->ts_state_lock);
266 ts->thread_clear &= ~thread_clear;
268 if ((thread_clear & ISCSI_CLEAR_RX_THREAD) &&
269 (ts->blocked_threads & ISCSI_BLOCK_RX_THREAD))
270 complete(&ts->rx_restart_comp);
271 else if ((thread_clear & ISCSI_CLEAR_TX_THREAD) &&
272 (ts->blocked_threads & ISCSI_BLOCK_TX_THREAD))
273 complete(&ts->tx_restart_comp);
274 spin_unlock_bh(&ts->ts_state_lock);
277 void iscsi_set_thread_set_signal(struct iscsi_conn *conn, u8 signal_sent)
279 struct iscsi_thread_set *ts = NULL;
281 if (!conn->thread_set) {
282 pr_err("struct iscsi_conn->thread_set is NULL\n");
285 ts = conn->thread_set;
287 spin_lock_bh(&ts->ts_state_lock);
288 ts->signal_sent |= signal_sent;
289 spin_unlock_bh(&ts->ts_state_lock);
292 int iscsi_release_thread_set(struct iscsi_conn *conn)
294 int thread_called = 0;
295 struct iscsi_thread_set *ts = NULL;
297 if (!conn || !conn->thread_set) {
298 pr_err("connection or thread set pointer is NULL\n");
301 ts = conn->thread_set;
303 spin_lock_bh(&ts->ts_state_lock);
304 ts->status = ISCSI_THREAD_SET_RESET;
306 if (!strncmp(current->comm, ISCSI_RX_THREAD_NAME,
307 strlen(ISCSI_RX_THREAD_NAME)))
308 thread_called = ISCSI_RX_THREAD;
309 else if (!strncmp(current->comm, ISCSI_TX_THREAD_NAME,
310 strlen(ISCSI_TX_THREAD_NAME)))
311 thread_called = ISCSI_TX_THREAD;
313 if (ts->rx_thread && (thread_called == ISCSI_TX_THREAD) &&
314 (ts->thread_clear & ISCSI_CLEAR_RX_THREAD)) {
316 if (!(ts->signal_sent & ISCSI_SIGNAL_RX_THREAD)) {
317 send_sig(SIGINT, ts->rx_thread, 1);
318 ts->signal_sent |= ISCSI_SIGNAL_RX_THREAD;
320 ts->blocked_threads |= ISCSI_BLOCK_RX_THREAD;
321 spin_unlock_bh(&ts->ts_state_lock);
322 wait_for_completion(&ts->rx_restart_comp);
323 spin_lock_bh(&ts->ts_state_lock);
324 ts->blocked_threads &= ~ISCSI_BLOCK_RX_THREAD;
326 if (ts->tx_thread && (thread_called == ISCSI_RX_THREAD) &&
327 (ts->thread_clear & ISCSI_CLEAR_TX_THREAD)) {
329 if (!(ts->signal_sent & ISCSI_SIGNAL_TX_THREAD)) {
330 send_sig(SIGINT, ts->tx_thread, 1);
331 ts->signal_sent |= ISCSI_SIGNAL_TX_THREAD;
333 ts->blocked_threads |= ISCSI_BLOCK_TX_THREAD;
334 spin_unlock_bh(&ts->ts_state_lock);
335 wait_for_completion(&ts->tx_restart_comp);
336 spin_lock_bh(&ts->ts_state_lock);
337 ts->blocked_threads &= ~ISCSI_BLOCK_TX_THREAD;
341 ts->status = ISCSI_THREAD_SET_FREE;
342 spin_unlock_bh(&ts->ts_state_lock);
347 int iscsi_thread_set_force_reinstatement(struct iscsi_conn *conn)
349 struct iscsi_thread_set *ts;
351 if (!conn->thread_set)
353 ts = conn->thread_set;
355 spin_lock_bh(&ts->ts_state_lock);
356 if (ts->status != ISCSI_THREAD_SET_ACTIVE) {
357 spin_unlock_bh(&ts->ts_state_lock);
361 if (ts->tx_thread && (!(ts->signal_sent & ISCSI_SIGNAL_TX_THREAD))) {
362 send_sig(SIGINT, ts->tx_thread, 1);
363 ts->signal_sent |= ISCSI_SIGNAL_TX_THREAD;
365 if (ts->rx_thread && (!(ts->signal_sent & ISCSI_SIGNAL_RX_THREAD))) {
366 send_sig(SIGINT, ts->rx_thread, 1);
367 ts->signal_sent |= ISCSI_SIGNAL_RX_THREAD;
369 spin_unlock_bh(&ts->ts_state_lock);
374 static void iscsi_check_to_add_additional_sets(void)
378 spin_lock(&inactive_ts_lock);
379 thread_sets_add = iscsit_global->inactive_ts;
380 spin_unlock(&inactive_ts_lock);
381 if (thread_sets_add == 1)
382 iscsi_allocate_thread_sets(1);
385 static int iscsi_signal_thread_pre_handler(struct iscsi_thread_set *ts)
387 spin_lock_bh(&ts->ts_state_lock);
388 if ((ts->status == ISCSI_THREAD_SET_DIE) || signal_pending(current)) {
389 spin_unlock_bh(&ts->ts_state_lock);
392 spin_unlock_bh(&ts->ts_state_lock);
397 struct iscsi_conn *iscsi_rx_thread_pre_handler(struct iscsi_thread_set *ts)
401 spin_lock_bh(&ts->ts_state_lock);
402 if (ts->create_threads) {
403 spin_unlock_bh(&ts->ts_state_lock);
407 flush_signals(current);
409 if (ts->delay_inactive && (--ts->thread_count == 0)) {
410 spin_unlock_bh(&ts->ts_state_lock);
412 if (!iscsit_global->in_shutdown)
413 iscsi_deallocate_extra_thread_sets();
415 iscsi_add_ts_to_inactive_list(ts);
416 spin_lock_bh(&ts->ts_state_lock);
419 if ((ts->status == ISCSI_THREAD_SET_RESET) &&
420 (ts->thread_clear & ISCSI_CLEAR_RX_THREAD))
421 complete(&ts->rx_restart_comp);
423 ts->thread_clear &= ~ISCSI_CLEAR_RX_THREAD;
424 spin_unlock_bh(&ts->ts_state_lock);
426 ret = wait_for_completion_interruptible(&ts->rx_start_comp);
430 if (iscsi_signal_thread_pre_handler(ts) < 0)
434 pr_err("struct iscsi_thread_set->conn is NULL for"
435 " thread_id: %d, going back to sleep\n", ts->thread_id);
438 iscsi_check_to_add_additional_sets();
440 * The RX Thread starts up the TX Thread and sleeps.
442 ts->thread_clear |= ISCSI_CLEAR_RX_THREAD;
443 complete(&ts->tx_start_comp);
444 wait_for_completion(&ts->tx_post_start_comp);
449 struct iscsi_conn *iscsi_tx_thread_pre_handler(struct iscsi_thread_set *ts)
453 spin_lock_bh(&ts->ts_state_lock);
454 if (ts->create_threads) {
455 spin_unlock_bh(&ts->ts_state_lock);
459 flush_signals(current);
461 if (ts->delay_inactive && (--ts->thread_count == 0)) {
462 spin_unlock_bh(&ts->ts_state_lock);
464 if (!iscsit_global->in_shutdown)
465 iscsi_deallocate_extra_thread_sets();
467 iscsi_add_ts_to_inactive_list(ts);
468 spin_lock_bh(&ts->ts_state_lock);
470 if ((ts->status == ISCSI_THREAD_SET_RESET) &&
471 (ts->thread_clear & ISCSI_CLEAR_TX_THREAD))
472 complete(&ts->tx_restart_comp);
474 ts->thread_clear &= ~ISCSI_CLEAR_TX_THREAD;
475 spin_unlock_bh(&ts->ts_state_lock);
477 ret = wait_for_completion_interruptible(&ts->tx_start_comp);
481 if (iscsi_signal_thread_pre_handler(ts) < 0)
485 pr_err("struct iscsi_thread_set->conn is NULL for "
486 " thread_id: %d, going back to sleep\n",
491 iscsi_check_to_add_additional_sets();
493 * From the TX thread, up the tx_post_start_comp that the RX Thread is
494 * sleeping on in iscsi_rx_thread_pre_handler(), then up the
495 * rx_post_start_comp that iscsi_activate_thread_set() is sleeping on.
497 ts->thread_clear |= ISCSI_CLEAR_TX_THREAD;
498 complete(&ts->tx_post_start_comp);
499 complete(&ts->rx_post_start_comp);
501 spin_lock_bh(&ts->ts_state_lock);
502 ts->status = ISCSI_THREAD_SET_ACTIVE;
503 spin_unlock_bh(&ts->ts_state_lock);
508 int iscsi_thread_set_init(void)
512 iscsit_global->ts_bitmap_count = ISCSI_TS_BITMAP_BITS;
514 size = BITS_TO_LONGS(iscsit_global->ts_bitmap_count) * sizeof(long);
515 iscsit_global->ts_bitmap = kzalloc(size, GFP_KERNEL);
516 if (!iscsit_global->ts_bitmap) {
517 pr_err("Unable to allocate iscsit_global->ts_bitmap\n");
521 spin_lock_init(&inactive_ts_lock);
522 spin_lock_init(&ts_bitmap_lock);
523 INIT_LIST_HEAD(&inactive_ts_list);
528 void iscsi_thread_set_free(void)
530 kfree(iscsit_global->ts_bitmap);