aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2015-01-22 03:56:53 -0500
committerNicholas Bellinger <nab@linux-iscsi.org>2015-02-12 15:23:18 -0500
commit3fd7b60f2c7418239d586e359e0c6d8503e10646 (patch)
tree2516ec0582888548a751864dead3d8140cffe08c /drivers/target
parente4f4e8016e6823475291eb0da7cc95d0fada2237 (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.c28
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
27static LIST_HEAD(active_ts_list);
28static LIST_HEAD(inactive_ts_list); 27static LIST_HEAD(inactive_ts_list);
29static DEFINE_SPINLOCK(active_ts_lock);
30static DEFINE_SPINLOCK(inactive_ts_lock); 28static DEFINE_SPINLOCK(inactive_ts_lock);
31static DEFINE_SPINLOCK(ts_bitmap_lock); 29static DEFINE_SPINLOCK(ts_bitmap_lock);
32 30
33static 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
41static void iscsi_add_ts_to_inactive_list(struct iscsi_thread_set *ts) 31static 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
49static 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
57static struct iscsi_thread_set *iscsi_get_ts_from_inactive_list(void) 43static 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
205void iscsi_activate_thread_set(struct iscsi_conn *conn, struct iscsi_thread_set *ts) 191void 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();