diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2015-02-27 05:21:06 -0500 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2015-03-26 17:49:49 -0400 |
commit | 073900bdb4e34109a647c7cb871856a771634460 (patch) | |
tree | ba3f0af323fdf659f088da43780d07de4cb1c6de /drivers/target | |
parent | 88dcd2dab5c23b1c9cfc396246d8f476c872f0ca (diff) |
iscsi-target: Drop legacy iscsi_target_tq.c logic
Now that iscsi_conn allocates new [rx,tx] threads using kthread.h
primitives on the fly, and kthread_stop() is called directly during
connection shutdown, it's time to go ahead and drop iscsi_target_tq.c
legacy code.
The use of multiple struct completion in iscsi_activate_thread_set()
has been proven to cause issues during repeated iser login/logout.
Tested-by: Sagi Grimberg <sagig@mellanox.com>
Cc: Slava Shwartsman <valyushash@gmail.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/iscsi/Makefile | 1 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 3 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_erl0.c | 1 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_login.c | 1 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_tq.c | 495 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_tq.h | 84 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_util.c | 1 |
7 files changed, 0 insertions, 586 deletions
diff --git a/drivers/target/iscsi/Makefile b/drivers/target/iscsi/Makefile index 13a92403fe3e..0f43be9c3453 100644 --- a/drivers/target/iscsi/Makefile +++ b/drivers/target/iscsi/Makefile | |||
@@ -1,6 +1,5 @@ | |||
1 | iscsi_target_mod-y += iscsi_target_parameters.o \ | 1 | iscsi_target_mod-y += iscsi_target_parameters.o \ |
2 | iscsi_target_seq_pdu_list.o \ | 2 | iscsi_target_seq_pdu_list.o \ |
3 | iscsi_target_tq.o \ | ||
4 | iscsi_target_auth.o \ | 3 | iscsi_target_auth.o \ |
5 | iscsi_target_datain_values.o \ | 4 | iscsi_target_datain_values.o \ |
6 | iscsi_target_device.o \ | 5 | iscsi_target_device.o \ |
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 163773fb4f84..cd611e740de7 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <target/iscsi/iscsi_target_core.h> | 33 | #include <target/iscsi/iscsi_target_core.h> |
34 | #include "iscsi_target_parameters.h" | 34 | #include "iscsi_target_parameters.h" |
35 | #include "iscsi_target_seq_pdu_list.h" | 35 | #include "iscsi_target_seq_pdu_list.h" |
36 | #include "iscsi_target_tq.h" | ||
37 | #include "iscsi_target_configfs.h" | 36 | #include "iscsi_target_configfs.h" |
38 | #include "iscsi_target_datain_values.h" | 37 | #include "iscsi_target_datain_values.h" |
39 | #include "iscsi_target_erl0.h" | 38 | #include "iscsi_target_erl0.h" |
@@ -4360,8 +4359,6 @@ int iscsit_close_connection( | |||
4360 | 4359 | ||
4361 | iscsit_put_transport(conn->conn_transport); | 4360 | iscsit_put_transport(conn->conn_transport); |
4362 | 4361 | ||
4363 | conn->thread_set = NULL; | ||
4364 | |||
4365 | pr_debug("Moving to TARG_CONN_STATE_FREE.\n"); | 4362 | pr_debug("Moving to TARG_CONN_STATE_FREE.\n"); |
4366 | conn->conn_state = TARG_CONN_STATE_FREE; | 4363 | conn->conn_state = TARG_CONN_STATE_FREE; |
4367 | kfree(conn); | 4364 | kfree(conn); |
diff --git a/drivers/target/iscsi/iscsi_target_erl0.c b/drivers/target/iscsi/iscsi_target_erl0.c index d4e2159f53c2..e1f4c7eedb08 100644 --- a/drivers/target/iscsi/iscsi_target_erl0.c +++ b/drivers/target/iscsi/iscsi_target_erl0.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <target/iscsi/iscsi_target_core.h> | 24 | #include <target/iscsi/iscsi_target_core.h> |
25 | #include <target/iscsi/iscsi_transport.h> | 25 | #include <target/iscsi/iscsi_transport.h> |
26 | #include "iscsi_target_seq_pdu_list.h" | 26 | #include "iscsi_target_seq_pdu_list.h" |
27 | #include "iscsi_target_tq.h" | ||
28 | #include "iscsi_target_erl0.h" | 27 | #include "iscsi_target_erl0.h" |
29 | #include "iscsi_target_erl1.h" | 28 | #include "iscsi_target_erl1.h" |
30 | #include "iscsi_target_erl2.h" | 29 | #include "iscsi_target_erl2.h" |
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index 345f073ff6dc..af20ddf2bbb4 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c | |||
@@ -26,7 +26,6 @@ | |||
26 | 26 | ||
27 | #include <target/iscsi/iscsi_target_core.h> | 27 | #include <target/iscsi/iscsi_target_core.h> |
28 | #include <target/iscsi/iscsi_target_stat.h> | 28 | #include <target/iscsi/iscsi_target_stat.h> |
29 | #include "iscsi_target_tq.h" | ||
30 | #include "iscsi_target_device.h" | 29 | #include "iscsi_target_device.h" |
31 | #include "iscsi_target_nego.h" | 30 | #include "iscsi_target_nego.h" |
32 | #include "iscsi_target_erl0.h" | 31 | #include "iscsi_target_erl0.h" |
diff --git a/drivers/target/iscsi/iscsi_target_tq.c b/drivers/target/iscsi/iscsi_target_tq.c deleted file mode 100644 index 26aa50996473..000000000000 --- a/drivers/target/iscsi/iscsi_target_tq.c +++ /dev/null | |||
@@ -1,495 +0,0 @@ | |||
1 | /******************************************************************************* | ||
2 | * This file contains the iSCSI Login Thread and Thread Queue functions. | ||
3 | * | ||
4 | * (c) Copyright 2007-2013 Datera, Inc. | ||
5 | * | ||
6 | * Author: Nicholas A. Bellinger <nab@linux-iscsi.org> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | ******************************************************************************/ | ||
18 | |||
19 | #include <linux/kthread.h> | ||
20 | #include <linux/list.h> | ||
21 | #include <linux/bitmap.h> | ||
22 | |||
23 | #include <target/iscsi/iscsi_target_core.h> | ||
24 | #include "iscsi_target_tq.h" | ||
25 | #include "iscsi_target.h" | ||
26 | |||
27 | static LIST_HEAD(inactive_ts_list); | ||
28 | static DEFINE_SPINLOCK(inactive_ts_lock); | ||
29 | static DEFINE_SPINLOCK(ts_bitmap_lock); | ||
30 | |||
31 | static void iscsi_add_ts_to_inactive_list(struct iscsi_thread_set *ts) | ||
32 | { | ||
33 | if (!list_empty(&ts->ts_list)) { | ||
34 | WARN_ON(1); | ||
35 | return; | ||
36 | } | ||
37 | spin_lock(&inactive_ts_lock); | ||
38 | list_add_tail(&ts->ts_list, &inactive_ts_list); | ||
39 | iscsit_global->inactive_ts++; | ||
40 | spin_unlock(&inactive_ts_lock); | ||
41 | } | ||
42 | |||
43 | static struct iscsi_thread_set *iscsi_get_ts_from_inactive_list(void) | ||
44 | { | ||
45 | struct iscsi_thread_set *ts; | ||
46 | |||
47 | spin_lock(&inactive_ts_lock); | ||
48 | if (list_empty(&inactive_ts_list)) { | ||
49 | spin_unlock(&inactive_ts_lock); | ||
50 | return NULL; | ||
51 | } | ||
52 | |||
53 | ts = list_first_entry(&inactive_ts_list, struct iscsi_thread_set, ts_list); | ||
54 | |||
55 | list_del_init(&ts->ts_list); | ||
56 | iscsit_global->inactive_ts--; | ||
57 | spin_unlock(&inactive_ts_lock); | ||
58 | |||
59 | return ts; | ||
60 | } | ||
61 | |||
62 | int iscsi_allocate_thread_sets(u32 thread_pair_count) | ||
63 | { | ||
64 | int allocated_thread_pair_count = 0, i, thread_id; | ||
65 | struct iscsi_thread_set *ts = NULL; | ||
66 | |||
67 | for (i = 0; i < thread_pair_count; i++) { | ||
68 | ts = kzalloc(sizeof(struct iscsi_thread_set), GFP_KERNEL); | ||
69 | if (!ts) { | ||
70 | pr_err("Unable to allocate memory for" | ||
71 | " thread set.\n"); | ||
72 | return allocated_thread_pair_count; | ||
73 | } | ||
74 | /* | ||
75 | * Locate the next available regision in the thread_set_bitmap | ||
76 | */ | ||
77 | spin_lock(&ts_bitmap_lock); | ||
78 | thread_id = bitmap_find_free_region(iscsit_global->ts_bitmap, | ||
79 | iscsit_global->ts_bitmap_count, get_order(1)); | ||
80 | spin_unlock(&ts_bitmap_lock); | ||
81 | if (thread_id < 0) { | ||
82 | pr_err("bitmap_find_free_region() failed for" | ||
83 | " thread_set_bitmap\n"); | ||
84 | kfree(ts); | ||
85 | return allocated_thread_pair_count; | ||
86 | } | ||
87 | |||
88 | ts->thread_id = thread_id; | ||
89 | ts->status = ISCSI_THREAD_SET_FREE; | ||
90 | INIT_LIST_HEAD(&ts->ts_list); | ||
91 | spin_lock_init(&ts->ts_state_lock); | ||
92 | init_completion(&ts->rx_restart_comp); | ||
93 | init_completion(&ts->tx_restart_comp); | ||
94 | init_completion(&ts->rx_start_comp); | ||
95 | init_completion(&ts->tx_start_comp); | ||
96 | sema_init(&ts->ts_activate_sem, 0); | ||
97 | |||
98 | ts->create_threads = 1; | ||
99 | ts->tx_thread = kthread_run(iscsi_target_tx_thread, ts, "%s", | ||
100 | ISCSI_TX_THREAD_NAME); | ||
101 | if (IS_ERR(ts->tx_thread)) { | ||
102 | dump_stack(); | ||
103 | pr_err("Unable to start iscsi_target_tx_thread\n"); | ||
104 | break; | ||
105 | } | ||
106 | |||
107 | ts->rx_thread = kthread_run(iscsi_target_rx_thread, ts, "%s", | ||
108 | ISCSI_RX_THREAD_NAME); | ||
109 | if (IS_ERR(ts->rx_thread)) { | ||
110 | kthread_stop(ts->tx_thread); | ||
111 | pr_err("Unable to start iscsi_target_rx_thread\n"); | ||
112 | break; | ||
113 | } | ||
114 | ts->create_threads = 0; | ||
115 | |||
116 | iscsi_add_ts_to_inactive_list(ts); | ||
117 | allocated_thread_pair_count++; | ||
118 | } | ||
119 | |||
120 | pr_debug("Spawned %d thread set(s) (%d total threads).\n", | ||
121 | allocated_thread_pair_count, allocated_thread_pair_count * 2); | ||
122 | return allocated_thread_pair_count; | ||
123 | } | ||
124 | |||
125 | static void iscsi_deallocate_thread_one(struct iscsi_thread_set *ts) | ||
126 | { | ||
127 | spin_lock_bh(&ts->ts_state_lock); | ||
128 | ts->status = ISCSI_THREAD_SET_DIE; | ||
129 | |||
130 | if (ts->rx_thread) { | ||
131 | complete(&ts->rx_start_comp); | ||
132 | spin_unlock_bh(&ts->ts_state_lock); | ||
133 | kthread_stop(ts->rx_thread); | ||
134 | spin_lock_bh(&ts->ts_state_lock); | ||
135 | } | ||
136 | if (ts->tx_thread) { | ||
137 | complete(&ts->tx_start_comp); | ||
138 | spin_unlock_bh(&ts->ts_state_lock); | ||
139 | kthread_stop(ts->tx_thread); | ||
140 | spin_lock_bh(&ts->ts_state_lock); | ||
141 | } | ||
142 | spin_unlock_bh(&ts->ts_state_lock); | ||
143 | /* | ||
144 | * Release this thread_id in the thread_set_bitmap | ||
145 | */ | ||
146 | spin_lock(&ts_bitmap_lock); | ||
147 | bitmap_release_region(iscsit_global->ts_bitmap, | ||
148 | ts->thread_id, get_order(1)); | ||
149 | spin_unlock(&ts_bitmap_lock); | ||
150 | |||
151 | kfree(ts); | ||
152 | } | ||
153 | |||
154 | void iscsi_deallocate_thread_sets(void) | ||
155 | { | ||
156 | struct iscsi_thread_set *ts = NULL; | ||
157 | u32 released_count = 0; | ||
158 | |||
159 | while ((ts = iscsi_get_ts_from_inactive_list())) { | ||
160 | |||
161 | iscsi_deallocate_thread_one(ts); | ||
162 | released_count++; | ||
163 | } | ||
164 | |||
165 | if (released_count) | ||
166 | pr_debug("Stopped %d thread set(s) (%d total threads)." | ||
167 | "\n", released_count, released_count * 2); | ||
168 | } | ||
169 | |||
170 | static void iscsi_deallocate_extra_thread_sets(void) | ||
171 | { | ||
172 | u32 orig_count, released_count = 0; | ||
173 | struct iscsi_thread_set *ts = NULL; | ||
174 | |||
175 | orig_count = TARGET_THREAD_SET_COUNT; | ||
176 | |||
177 | while ((iscsit_global->inactive_ts + 1) > orig_count) { | ||
178 | ts = iscsi_get_ts_from_inactive_list(); | ||
179 | if (!ts) | ||
180 | break; | ||
181 | |||
182 | iscsi_deallocate_thread_one(ts); | ||
183 | released_count++; | ||
184 | } | ||
185 | |||
186 | if (released_count) | ||
187 | pr_debug("Stopped %d thread set(s) (%d total threads)." | ||
188 | "\n", released_count, released_count * 2); | ||
189 | } | ||
190 | |||
191 | void iscsi_activate_thread_set(struct iscsi_conn *conn, struct iscsi_thread_set *ts) | ||
192 | { | ||
193 | spin_lock_bh(&ts->ts_state_lock); | ||
194 | conn->thread_set = ts; | ||
195 | ts->conn = conn; | ||
196 | ts->status = ISCSI_THREAD_SET_ACTIVE; | ||
197 | spin_unlock_bh(&ts->ts_state_lock); | ||
198 | |||
199 | complete(&ts->rx_start_comp); | ||
200 | complete(&ts->tx_start_comp); | ||
201 | |||
202 | down(&ts->ts_activate_sem); | ||
203 | } | ||
204 | |||
205 | struct iscsi_thread_set *iscsi_get_thread_set(void) | ||
206 | { | ||
207 | struct iscsi_thread_set *ts; | ||
208 | |||
209 | get_set: | ||
210 | ts = iscsi_get_ts_from_inactive_list(); | ||
211 | if (!ts) { | ||
212 | iscsi_allocate_thread_sets(1); | ||
213 | goto get_set; | ||
214 | } | ||
215 | |||
216 | ts->delay_inactive = 1; | ||
217 | ts->signal_sent = 0; | ||
218 | ts->thread_count = 2; | ||
219 | init_completion(&ts->rx_restart_comp); | ||
220 | init_completion(&ts->tx_restart_comp); | ||
221 | sema_init(&ts->ts_activate_sem, 0); | ||
222 | |||
223 | return ts; | ||
224 | } | ||
225 | |||
226 | void iscsi_set_thread_clear(struct iscsi_conn *conn, u8 thread_clear) | ||
227 | { | ||
228 | struct iscsi_thread_set *ts = NULL; | ||
229 | |||
230 | if (!conn->thread_set) { | ||
231 | pr_err("struct iscsi_conn->thread_set is NULL\n"); | ||
232 | return; | ||
233 | } | ||
234 | ts = conn->thread_set; | ||
235 | |||
236 | spin_lock_bh(&ts->ts_state_lock); | ||
237 | ts->thread_clear &= ~thread_clear; | ||
238 | |||
239 | if ((thread_clear & ISCSI_CLEAR_RX_THREAD) && | ||
240 | (ts->blocked_threads & ISCSI_BLOCK_RX_THREAD)) | ||
241 | complete(&ts->rx_restart_comp); | ||
242 | else if ((thread_clear & ISCSI_CLEAR_TX_THREAD) && | ||
243 | (ts->blocked_threads & ISCSI_BLOCK_TX_THREAD)) | ||
244 | complete(&ts->tx_restart_comp); | ||
245 | spin_unlock_bh(&ts->ts_state_lock); | ||
246 | } | ||
247 | |||
248 | void iscsi_set_thread_set_signal(struct iscsi_conn *conn, u8 signal_sent) | ||
249 | { | ||
250 | struct iscsi_thread_set *ts = NULL; | ||
251 | |||
252 | if (!conn->thread_set) { | ||
253 | pr_err("struct iscsi_conn->thread_set is NULL\n"); | ||
254 | return; | ||
255 | } | ||
256 | ts = conn->thread_set; | ||
257 | |||
258 | spin_lock_bh(&ts->ts_state_lock); | ||
259 | ts->signal_sent |= signal_sent; | ||
260 | spin_unlock_bh(&ts->ts_state_lock); | ||
261 | } | ||
262 | |||
263 | int iscsi_release_thread_set(struct iscsi_conn *conn) | ||
264 | { | ||
265 | int thread_called = 0; | ||
266 | struct iscsi_thread_set *ts = NULL; | ||
267 | |||
268 | if (!conn || !conn->thread_set) { | ||
269 | pr_err("connection or thread set pointer is NULL\n"); | ||
270 | BUG(); | ||
271 | } | ||
272 | ts = conn->thread_set; | ||
273 | |||
274 | spin_lock_bh(&ts->ts_state_lock); | ||
275 | ts->status = ISCSI_THREAD_SET_RESET; | ||
276 | |||
277 | if (!strncmp(current->comm, ISCSI_RX_THREAD_NAME, | ||
278 | strlen(ISCSI_RX_THREAD_NAME))) | ||
279 | thread_called = ISCSI_RX_THREAD; | ||
280 | else if (!strncmp(current->comm, ISCSI_TX_THREAD_NAME, | ||
281 | strlen(ISCSI_TX_THREAD_NAME))) | ||
282 | thread_called = ISCSI_TX_THREAD; | ||
283 | |||
284 | if (ts->rx_thread && (thread_called == ISCSI_TX_THREAD) && | ||
285 | (ts->thread_clear & ISCSI_CLEAR_RX_THREAD)) { | ||
286 | |||
287 | if (!(ts->signal_sent & ISCSI_SIGNAL_RX_THREAD)) { | ||
288 | send_sig(SIGINT, ts->rx_thread, 1); | ||
289 | ts->signal_sent |= ISCSI_SIGNAL_RX_THREAD; | ||
290 | } | ||
291 | ts->blocked_threads |= ISCSI_BLOCK_RX_THREAD; | ||
292 | spin_unlock_bh(&ts->ts_state_lock); | ||
293 | wait_for_completion(&ts->rx_restart_comp); | ||
294 | spin_lock_bh(&ts->ts_state_lock); | ||
295 | ts->blocked_threads &= ~ISCSI_BLOCK_RX_THREAD; | ||
296 | } | ||
297 | if (ts->tx_thread && (thread_called == ISCSI_RX_THREAD) && | ||
298 | (ts->thread_clear & ISCSI_CLEAR_TX_THREAD)) { | ||
299 | |||
300 | if (!(ts->signal_sent & ISCSI_SIGNAL_TX_THREAD)) { | ||
301 | send_sig(SIGINT, ts->tx_thread, 1); | ||
302 | ts->signal_sent |= ISCSI_SIGNAL_TX_THREAD; | ||
303 | } | ||
304 | ts->blocked_threads |= ISCSI_BLOCK_TX_THREAD; | ||
305 | spin_unlock_bh(&ts->ts_state_lock); | ||
306 | wait_for_completion(&ts->tx_restart_comp); | ||
307 | spin_lock_bh(&ts->ts_state_lock); | ||
308 | ts->blocked_threads &= ~ISCSI_BLOCK_TX_THREAD; | ||
309 | } | ||
310 | |||
311 | ts->conn = NULL; | ||
312 | ts->status = ISCSI_THREAD_SET_FREE; | ||
313 | spin_unlock_bh(&ts->ts_state_lock); | ||
314 | |||
315 | return 0; | ||
316 | } | ||
317 | |||
318 | int iscsi_thread_set_force_reinstatement(struct iscsi_conn *conn) | ||
319 | { | ||
320 | struct iscsi_thread_set *ts; | ||
321 | |||
322 | if (!conn->thread_set) | ||
323 | return -1; | ||
324 | ts = conn->thread_set; | ||
325 | |||
326 | spin_lock_bh(&ts->ts_state_lock); | ||
327 | if (ts->status != ISCSI_THREAD_SET_ACTIVE) { | ||
328 | spin_unlock_bh(&ts->ts_state_lock); | ||
329 | return -1; | ||
330 | } | ||
331 | |||
332 | if (ts->tx_thread && (!(ts->signal_sent & ISCSI_SIGNAL_TX_THREAD))) { | ||
333 | send_sig(SIGINT, ts->tx_thread, 1); | ||
334 | ts->signal_sent |= ISCSI_SIGNAL_TX_THREAD; | ||
335 | } | ||
336 | if (ts->rx_thread && (!(ts->signal_sent & ISCSI_SIGNAL_RX_THREAD))) { | ||
337 | send_sig(SIGINT, ts->rx_thread, 1); | ||
338 | ts->signal_sent |= ISCSI_SIGNAL_RX_THREAD; | ||
339 | } | ||
340 | spin_unlock_bh(&ts->ts_state_lock); | ||
341 | |||
342 | return 0; | ||
343 | } | ||
344 | |||
345 | static void iscsi_check_to_add_additional_sets(void) | ||
346 | { | ||
347 | int thread_sets_add; | ||
348 | |||
349 | spin_lock(&inactive_ts_lock); | ||
350 | thread_sets_add = iscsit_global->inactive_ts; | ||
351 | spin_unlock(&inactive_ts_lock); | ||
352 | if (thread_sets_add == 1) | ||
353 | iscsi_allocate_thread_sets(1); | ||
354 | } | ||
355 | |||
356 | static int iscsi_signal_thread_pre_handler(struct iscsi_thread_set *ts) | ||
357 | { | ||
358 | spin_lock_bh(&ts->ts_state_lock); | ||
359 | if (ts->status == ISCSI_THREAD_SET_DIE || kthread_should_stop() || | ||
360 | signal_pending(current)) { | ||
361 | spin_unlock_bh(&ts->ts_state_lock); | ||
362 | return -1; | ||
363 | } | ||
364 | spin_unlock_bh(&ts->ts_state_lock); | ||
365 | |||
366 | return 0; | ||
367 | } | ||
368 | |||
369 | struct iscsi_conn *iscsi_rx_thread_pre_handler(struct iscsi_thread_set *ts) | ||
370 | { | ||
371 | int ret; | ||
372 | |||
373 | spin_lock_bh(&ts->ts_state_lock); | ||
374 | if (ts->create_threads) { | ||
375 | spin_unlock_bh(&ts->ts_state_lock); | ||
376 | goto sleep; | ||
377 | } | ||
378 | |||
379 | if (ts->status != ISCSI_THREAD_SET_DIE) | ||
380 | flush_signals(current); | ||
381 | |||
382 | if (ts->delay_inactive && (--ts->thread_count == 0)) { | ||
383 | spin_unlock_bh(&ts->ts_state_lock); | ||
384 | |||
385 | if (!iscsit_global->in_shutdown) | ||
386 | iscsi_deallocate_extra_thread_sets(); | ||
387 | |||
388 | iscsi_add_ts_to_inactive_list(ts); | ||
389 | spin_lock_bh(&ts->ts_state_lock); | ||
390 | } | ||
391 | |||
392 | if ((ts->status == ISCSI_THREAD_SET_RESET) && | ||
393 | (ts->thread_clear & ISCSI_CLEAR_RX_THREAD)) | ||
394 | complete(&ts->rx_restart_comp); | ||
395 | |||
396 | ts->thread_clear &= ~ISCSI_CLEAR_RX_THREAD; | ||
397 | spin_unlock_bh(&ts->ts_state_lock); | ||
398 | sleep: | ||
399 | ret = wait_for_completion_interruptible(&ts->rx_start_comp); | ||
400 | if (ret != 0) | ||
401 | return NULL; | ||
402 | |||
403 | if (iscsi_signal_thread_pre_handler(ts) < 0) | ||
404 | return NULL; | ||
405 | |||
406 | iscsi_check_to_add_additional_sets(); | ||
407 | |||
408 | spin_lock_bh(&ts->ts_state_lock); | ||
409 | if (!ts->conn) { | ||
410 | pr_err("struct iscsi_thread_set->conn is NULL for" | ||
411 | " RX thread_id: %s/%d\n", current->comm, current->pid); | ||
412 | spin_unlock_bh(&ts->ts_state_lock); | ||
413 | return NULL; | ||
414 | } | ||
415 | ts->thread_clear |= ISCSI_CLEAR_RX_THREAD; | ||
416 | spin_unlock_bh(&ts->ts_state_lock); | ||
417 | |||
418 | up(&ts->ts_activate_sem); | ||
419 | |||
420 | return ts->conn; | ||
421 | } | ||
422 | |||
423 | struct iscsi_conn *iscsi_tx_thread_pre_handler(struct iscsi_thread_set *ts) | ||
424 | { | ||
425 | int ret; | ||
426 | |||
427 | spin_lock_bh(&ts->ts_state_lock); | ||
428 | if (ts->create_threads) { | ||
429 | spin_unlock_bh(&ts->ts_state_lock); | ||
430 | goto sleep; | ||
431 | } | ||
432 | |||
433 | if (ts->status != ISCSI_THREAD_SET_DIE) | ||
434 | flush_signals(current); | ||
435 | |||
436 | if (ts->delay_inactive && (--ts->thread_count == 0)) { | ||
437 | spin_unlock_bh(&ts->ts_state_lock); | ||
438 | |||
439 | if (!iscsit_global->in_shutdown) | ||
440 | iscsi_deallocate_extra_thread_sets(); | ||
441 | |||
442 | iscsi_add_ts_to_inactive_list(ts); | ||
443 | spin_lock_bh(&ts->ts_state_lock); | ||
444 | } | ||
445 | if ((ts->status == ISCSI_THREAD_SET_RESET) && | ||
446 | (ts->thread_clear & ISCSI_CLEAR_TX_THREAD)) | ||
447 | complete(&ts->tx_restart_comp); | ||
448 | |||
449 | ts->thread_clear &= ~ISCSI_CLEAR_TX_THREAD; | ||
450 | spin_unlock_bh(&ts->ts_state_lock); | ||
451 | sleep: | ||
452 | ret = wait_for_completion_interruptible(&ts->tx_start_comp); | ||
453 | if (ret != 0) | ||
454 | return NULL; | ||
455 | |||
456 | if (iscsi_signal_thread_pre_handler(ts) < 0) | ||
457 | return NULL; | ||
458 | |||
459 | iscsi_check_to_add_additional_sets(); | ||
460 | |||
461 | spin_lock_bh(&ts->ts_state_lock); | ||
462 | if (!ts->conn) { | ||
463 | pr_err("struct iscsi_thread_set->conn is NULL for" | ||
464 | " TX thread_id: %s/%d\n", current->comm, current->pid); | ||
465 | spin_unlock_bh(&ts->ts_state_lock); | ||
466 | return NULL; | ||
467 | } | ||
468 | ts->thread_clear |= ISCSI_CLEAR_TX_THREAD; | ||
469 | spin_unlock_bh(&ts->ts_state_lock); | ||
470 | |||
471 | up(&ts->ts_activate_sem); | ||
472 | |||
473 | return ts->conn; | ||
474 | } | ||
475 | |||
476 | int iscsi_thread_set_init(void) | ||
477 | { | ||
478 | int size; | ||
479 | |||
480 | iscsit_global->ts_bitmap_count = ISCSI_TS_BITMAP_BITS; | ||
481 | |||
482 | size = BITS_TO_LONGS(iscsit_global->ts_bitmap_count) * sizeof(long); | ||
483 | iscsit_global->ts_bitmap = kzalloc(size, GFP_KERNEL); | ||
484 | if (!iscsit_global->ts_bitmap) { | ||
485 | pr_err("Unable to allocate iscsit_global->ts_bitmap\n"); | ||
486 | return -ENOMEM; | ||
487 | } | ||
488 | |||
489 | return 0; | ||
490 | } | ||
491 | |||
492 | void iscsi_thread_set_free(void) | ||
493 | { | ||
494 | kfree(iscsit_global->ts_bitmap); | ||
495 | } | ||
diff --git a/drivers/target/iscsi/iscsi_target_tq.h b/drivers/target/iscsi/iscsi_target_tq.h deleted file mode 100644 index cc1eede5ab3a..000000000000 --- a/drivers/target/iscsi/iscsi_target_tq.h +++ /dev/null | |||
@@ -1,84 +0,0 @@ | |||
1 | #ifndef ISCSI_THREAD_QUEUE_H | ||
2 | #define ISCSI_THREAD_QUEUE_H | ||
3 | |||
4 | /* | ||
5 | * Defines for thread sets. | ||
6 | */ | ||
7 | extern int iscsi_thread_set_force_reinstatement(struct iscsi_conn *); | ||
8 | extern int iscsi_allocate_thread_sets(u32); | ||
9 | extern void iscsi_deallocate_thread_sets(void); | ||
10 | extern void iscsi_activate_thread_set(struct iscsi_conn *, struct iscsi_thread_set *); | ||
11 | extern struct iscsi_thread_set *iscsi_get_thread_set(void); | ||
12 | extern void iscsi_set_thread_clear(struct iscsi_conn *, u8); | ||
13 | extern void iscsi_set_thread_set_signal(struct iscsi_conn *, u8); | ||
14 | extern int iscsi_release_thread_set(struct iscsi_conn *); | ||
15 | extern struct iscsi_conn *iscsi_rx_thread_pre_handler(struct iscsi_thread_set *); | ||
16 | extern struct iscsi_conn *iscsi_tx_thread_pre_handler(struct iscsi_thread_set *); | ||
17 | extern int iscsi_thread_set_init(void); | ||
18 | extern void iscsi_thread_set_free(void); | ||
19 | |||
20 | extern int iscsi_target_tx_thread(void *); | ||
21 | extern int iscsi_target_rx_thread(void *); | ||
22 | |||
23 | #define TARGET_THREAD_SET_COUNT 4 | ||
24 | |||
25 | #define ISCSI_RX_THREAD 1 | ||
26 | #define ISCSI_TX_THREAD 2 | ||
27 | #define ISCSI_RX_THREAD_NAME "iscsi_trx" | ||
28 | #define ISCSI_TX_THREAD_NAME "iscsi_ttx" | ||
29 | #define ISCSI_BLOCK_RX_THREAD 0x1 | ||
30 | #define ISCSI_BLOCK_TX_THREAD 0x2 | ||
31 | #define ISCSI_CLEAR_RX_THREAD 0x1 | ||
32 | #define ISCSI_CLEAR_TX_THREAD 0x2 | ||
33 | #define ISCSI_SIGNAL_RX_THREAD 0x1 | ||
34 | #define ISCSI_SIGNAL_TX_THREAD 0x2 | ||
35 | |||
36 | /* struct iscsi_thread_set->status */ | ||
37 | #define ISCSI_THREAD_SET_FREE 1 | ||
38 | #define ISCSI_THREAD_SET_ACTIVE 2 | ||
39 | #define ISCSI_THREAD_SET_DIE 3 | ||
40 | #define ISCSI_THREAD_SET_RESET 4 | ||
41 | #define ISCSI_THREAD_SET_DEALLOCATE_THREADS 5 | ||
42 | |||
43 | /* By default allow a maximum of 32K iSCSI connections */ | ||
44 | #define ISCSI_TS_BITMAP_BITS 32768 | ||
45 | |||
46 | struct iscsi_thread_set { | ||
47 | /* flags used for blocking and restarting sets */ | ||
48 | int blocked_threads; | ||
49 | /* flag for creating threads */ | ||
50 | int create_threads; | ||
51 | /* flag for delaying readding to inactive list */ | ||
52 | int delay_inactive; | ||
53 | /* status for thread set */ | ||
54 | int status; | ||
55 | /* which threads have had signals sent */ | ||
56 | int signal_sent; | ||
57 | /* flag for which threads exited first */ | ||
58 | int thread_clear; | ||
59 | /* Active threads in the thread set */ | ||
60 | int thread_count; | ||
61 | /* Unique thread ID */ | ||
62 | u32 thread_id; | ||
63 | /* pointer to connection if set is active */ | ||
64 | struct iscsi_conn *conn; | ||
65 | /* used for controlling ts state accesses */ | ||
66 | spinlock_t ts_state_lock; | ||
67 | /* used for restarting thread queue */ | ||
68 | struct completion rx_restart_comp; | ||
69 | /* used for restarting thread queue */ | ||
70 | struct completion tx_restart_comp; | ||
71 | /* used for normal unused blocking */ | ||
72 | struct completion rx_start_comp; | ||
73 | /* used for normal unused blocking */ | ||
74 | struct completion tx_start_comp; | ||
75 | /* OS descriptor for rx thread */ | ||
76 | struct task_struct *rx_thread; | ||
77 | /* OS descriptor for tx thread */ | ||
78 | struct task_struct *tx_thread; | ||
79 | /* struct iscsi_thread_set in list list head*/ | ||
80 | struct list_head ts_list; | ||
81 | struct semaphore ts_activate_sem; | ||
82 | }; | ||
83 | |||
84 | #endif /*** ISCSI_THREAD_QUEUE_H ***/ | ||
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index 390df8ed72b2..b18edda3e8af 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include "iscsi_target_erl1.h" | 33 | #include "iscsi_target_erl1.h" |
34 | #include "iscsi_target_erl2.h" | 34 | #include "iscsi_target_erl2.h" |
35 | #include "iscsi_target_tpg.h" | 35 | #include "iscsi_target_tpg.h" |
36 | #include "iscsi_target_tq.h" | ||
37 | #include "iscsi_target_util.h" | 36 | #include "iscsi_target_util.h" |
38 | #include "iscsi_target.h" | 37 | #include "iscsi_target.h" |
39 | 38 | ||