diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2015-01-22 03:56:53 -0500 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2015-02-12 15:23:18 -0500 |
commit | 3fd7b60f2c7418239d586e359e0c6d8503e10646 (patch) | |
tree | 2516ec0582888548a751864dead3d8140cffe08c /drivers/target | |
parent | e4f4e8016e6823475291eb0da7cc95d0fada2237 (diff) |
iscsi-target: Drop problematic active_ts_list usage
This patch drops legacy active_ts_list usage within iscsi_target_tq.c
code. It was originally used to track the active thread sets during
iscsi-target shutdown, and is no longer used by modern upstream code.
Two people have reported list corruption using traditional iscsi-target
and iser-target with the following backtrace, that appears to be related
to iscsi_thread_set->ts_list being used across both active_ts_list and
inactive_ts_list.
[ 60.782534] ------------[ cut here ]------------
[ 60.782543] WARNING: CPU: 0 PID: 9430 at lib/list_debug.c:53 __list_del_entry+0x63/0xd0()
[ 60.782545] list_del corruption, ffff88045b00d180->next is LIST_POISON1 (dead000000100100)
[ 60.782546] Modules linked in: ib_srpt tcm_qla2xxx qla2xxx tcm_loop tcm_fc libfc scsi_transport_fc scsi_tgt ib_isert rdma_cm iw_cm ib_addr iscsi_target_mod target_core_pscsi target_core_file target_core_iblock target_core_mod configfs ebtable_nat ebtables ipt_MASQUERADE iptable_nat nf_nat_ipv4 nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 ipt_REJECT xt_CHECKSUM iptable_mangle iptable_filter ip_tables bridge stp llc autofs4 sunrpc ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables ipv6 ib_ipoib ib_cm ib_uverbs ib_umad mlx4_en mlx4_ib ib_sa ib_mad ib_core mlx4_core dm_mirror dm_region_hash dm_log dm_mod vhost_net macvtap macvlan vhost tun kvm_intel kvm uinput iTCO_wdt iTCO_vendor_support microcode serio_raw pcspkr sb_edac edac_core sg i2c_i801 lpc_ich mfd_core mtip32xx igb i2c_algo_bit i2c_core ptp pps_core ioatdma dca wmi ext3(F) jbd(F) mbcache(F) sd_mod(F) crc_t10dif(F) crct10dif_common(F) ahci(F) libahci(F) isci(F) libsas(F) scsi_transport_sas(F) [last unloaded: speedstep_lib]
[ 60.782597] CPU: 0 PID: 9430 Comm: iscsi_ttx Tainted: GF 3.12.19+ #2
[ 60.782598] Hardware name: Supermicro X9DRX+-F/X9DRX+-F, BIOS 3.00 07/09/2013
[ 60.782599] 0000000000000035 ffff88044de31d08 ffffffff81553ae7 0000000000000035
[ 60.782602] ffff88044de31d58 ffff88044de31d48 ffffffff8104d1cc 0000000000000002
[ 60.782605] ffff88045b00d180 ffff88045b00d0c0 ffff88045b00d0c0 ffff88044de31e58
[ 60.782607] Call Trace:
[ 60.782611] [<ffffffff81553ae7>] dump_stack+0x49/0x62
[ 60.782615] [<ffffffff8104d1cc>] warn_slowpath_common+0x8c/0xc0
[ 60.782618] [<ffffffff8104d2b6>] warn_slowpath_fmt+0x46/0x50
[ 60.782620] [<ffffffff81280933>] __list_del_entry+0x63/0xd0
[ 60.782622] [<ffffffff812809b1>] list_del+0x11/0x40
[ 60.782630] [<ffffffffa06e7cf9>] iscsi_del_ts_from_active_list+0x29/0x50 [iscsi_target_mod]
[ 60.782635] [<ffffffffa06e87b1>] iscsi_tx_thread_pre_handler+0xa1/0x180 [iscsi_target_mod]
[ 60.782642] [<ffffffffa06fb9ae>] iscsi_target_tx_thread+0x4e/0x220 [iscsi_target_mod]
[ 60.782647] [<ffffffffa06fb960>] ? iscsit_handle_snack+0x190/0x190 [iscsi_target_mod]
[ 60.782652] [<ffffffffa06fb960>] ? iscsit_handle_snack+0x190/0x190 [iscsi_target_mod]
[ 60.782655] [<ffffffff8106f99e>] kthread+0xce/0xe0
[ 60.782657] [<ffffffff8106f8d0>] ? kthread_freezable_should_stop+0x70/0x70
[ 60.782660] [<ffffffff8156026c>] ret_from_fork+0x7c/0xb0
[ 60.782662] [<ffffffff8106f8d0>] ? kthread_freezable_should_stop+0x70/0x70
[ 60.782663] ---[ end trace 9662f4a661d33965 ]---
Since this code is no longer used, go ahead and drop the problematic usage
all-together.
Reported-by: Gavin Guo <gavin.guo@canonical.com>
Reported-by: Moussa Ba <moussaba@micron.com>
Cc: stable@vger.kernel.org # 3.1+
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/iscsi/iscsi_target_tq.c | 28 |
1 files changed, 5 insertions, 23 deletions
diff --git a/drivers/target/iscsi/iscsi_target_tq.c b/drivers/target/iscsi/iscsi_target_tq.c index 18e1971b54f8..26aa50996473 100644 --- a/drivers/target/iscsi/iscsi_target_tq.c +++ b/drivers/target/iscsi/iscsi_target_tq.c | |||
@@ -24,36 +24,22 @@ | |||
24 | #include "iscsi_target_tq.h" | 24 | #include "iscsi_target_tq.h" |
25 | #include "iscsi_target.h" | 25 | #include "iscsi_target.h" |
26 | 26 | ||
27 | static LIST_HEAD(active_ts_list); | ||
28 | static LIST_HEAD(inactive_ts_list); | 27 | static LIST_HEAD(inactive_ts_list); |
29 | static DEFINE_SPINLOCK(active_ts_lock); | ||
30 | static DEFINE_SPINLOCK(inactive_ts_lock); | 28 | static DEFINE_SPINLOCK(inactive_ts_lock); |
31 | static DEFINE_SPINLOCK(ts_bitmap_lock); | 29 | static DEFINE_SPINLOCK(ts_bitmap_lock); |
32 | 30 | ||
33 | static void iscsi_add_ts_to_active_list(struct iscsi_thread_set *ts) | ||
34 | { | ||
35 | spin_lock(&active_ts_lock); | ||
36 | list_add_tail(&ts->ts_list, &active_ts_list); | ||
37 | iscsit_global->active_ts++; | ||
38 | spin_unlock(&active_ts_lock); | ||
39 | } | ||
40 | |||
41 | static void iscsi_add_ts_to_inactive_list(struct iscsi_thread_set *ts) | 31 | static void iscsi_add_ts_to_inactive_list(struct iscsi_thread_set *ts) |
42 | { | 32 | { |
33 | if (!list_empty(&ts->ts_list)) { | ||
34 | WARN_ON(1); | ||
35 | return; | ||
36 | } | ||
43 | spin_lock(&inactive_ts_lock); | 37 | spin_lock(&inactive_ts_lock); |
44 | list_add_tail(&ts->ts_list, &inactive_ts_list); | 38 | list_add_tail(&ts->ts_list, &inactive_ts_list); |
45 | iscsit_global->inactive_ts++; | 39 | iscsit_global->inactive_ts++; |
46 | spin_unlock(&inactive_ts_lock); | 40 | spin_unlock(&inactive_ts_lock); |
47 | } | 41 | } |
48 | 42 | ||
49 | static void iscsi_del_ts_from_active_list(struct iscsi_thread_set *ts) | ||
50 | { | ||
51 | spin_lock(&active_ts_lock); | ||
52 | list_del(&ts->ts_list); | ||
53 | iscsit_global->active_ts--; | ||
54 | spin_unlock(&active_ts_lock); | ||
55 | } | ||
56 | |||
57 | static struct iscsi_thread_set *iscsi_get_ts_from_inactive_list(void) | 43 | static struct iscsi_thread_set *iscsi_get_ts_from_inactive_list(void) |
58 | { | 44 | { |
59 | struct iscsi_thread_set *ts; | 45 | struct iscsi_thread_set *ts; |
@@ -66,7 +52,7 @@ static struct iscsi_thread_set *iscsi_get_ts_from_inactive_list(void) | |||
66 | 52 | ||
67 | ts = list_first_entry(&inactive_ts_list, struct iscsi_thread_set, ts_list); | 53 | ts = list_first_entry(&inactive_ts_list, struct iscsi_thread_set, ts_list); |
68 | 54 | ||
69 | list_del(&ts->ts_list); | 55 | list_del_init(&ts->ts_list); |
70 | iscsit_global->inactive_ts--; | 56 | iscsit_global->inactive_ts--; |
71 | spin_unlock(&inactive_ts_lock); | 57 | spin_unlock(&inactive_ts_lock); |
72 | 58 | ||
@@ -204,8 +190,6 @@ static void iscsi_deallocate_extra_thread_sets(void) | |||
204 | 190 | ||
205 | void iscsi_activate_thread_set(struct iscsi_conn *conn, struct iscsi_thread_set *ts) | 191 | void iscsi_activate_thread_set(struct iscsi_conn *conn, struct iscsi_thread_set *ts) |
206 | { | 192 | { |
207 | iscsi_add_ts_to_active_list(ts); | ||
208 | |||
209 | spin_lock_bh(&ts->ts_state_lock); | 193 | spin_lock_bh(&ts->ts_state_lock); |
210 | conn->thread_set = ts; | 194 | conn->thread_set = ts; |
211 | ts->conn = conn; | 195 | ts->conn = conn; |
@@ -397,7 +381,6 @@ struct iscsi_conn *iscsi_rx_thread_pre_handler(struct iscsi_thread_set *ts) | |||
397 | 381 | ||
398 | if (ts->delay_inactive && (--ts->thread_count == 0)) { | 382 | if (ts->delay_inactive && (--ts->thread_count == 0)) { |
399 | spin_unlock_bh(&ts->ts_state_lock); | 383 | spin_unlock_bh(&ts->ts_state_lock); |
400 | iscsi_del_ts_from_active_list(ts); | ||
401 | 384 | ||
402 | if (!iscsit_global->in_shutdown) | 385 | if (!iscsit_global->in_shutdown) |
403 | iscsi_deallocate_extra_thread_sets(); | 386 | iscsi_deallocate_extra_thread_sets(); |
@@ -452,7 +435,6 @@ struct iscsi_conn *iscsi_tx_thread_pre_handler(struct iscsi_thread_set *ts) | |||
452 | 435 | ||
453 | if (ts->delay_inactive && (--ts->thread_count == 0)) { | 436 | if (ts->delay_inactive && (--ts->thread_count == 0)) { |
454 | spin_unlock_bh(&ts->ts_state_lock); | 437 | spin_unlock_bh(&ts->ts_state_lock); |
455 | iscsi_del_ts_from_active_list(ts); | ||
456 | 438 | ||
457 | if (!iscsit_global->in_shutdown) | 439 | if (!iscsit_global->in_shutdown) |
458 | iscsi_deallocate_extra_thread_sets(); | 440 | iscsi_deallocate_extra_thread_sets(); |