From ab623fbc5a00f5525569e2c33b6b215e39a2453b Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Thu, 22 Jan 2015 00:56:53 -0800 Subject: [PATCH] iscsi-target: Drop problematic active_ts_list usage commit 3fd7b60f2c7418239d586e359e0c6d8503e10646 upstream. 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] [] dump_stack+0x49/0x62 [ 60.782615] [] warn_slowpath_common+0x8c/0xc0 [ 60.782618] [] warn_slowpath_fmt+0x46/0x50 [ 60.782620] [] __list_del_entry+0x63/0xd0 [ 60.782622] [] list_del+0x11/0x40 [ 60.782630] [] iscsi_del_ts_from_active_list+0x29/0x50 [iscsi_target_mod] [ 60.782635] [] iscsi_tx_thread_pre_handler+0xa1/0x180 [iscsi_target_mod] [ 60.782642] [] iscsi_target_tx_thread+0x4e/0x220 [iscsi_target_mod] [ 60.782647] [] ? iscsit_handle_snack+0x190/0x190 [iscsi_target_mod] [ 60.782652] [] ? iscsit_handle_snack+0x190/0x190 [iscsi_target_mod] [ 60.782655] [] kthread+0xce/0xe0 [ 60.782657] [] ? kthread_freezable_should_stop+0x70/0x70 [ 60.782660] [] ret_from_fork+0x7c/0xb0 [ 60.782662] [] ? 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 Reported-by: Moussa Ba Signed-off-by: Nicholas Bellinger [bwh: Backported to 3.2: - Adjust context - Also delete redundant initialisation, deleted upstream in commit d0f474e50192 ('target: Use LIST_HEAD()/DEFINE_MUTEX() for static objects')] Signed-off-by: Ben Hutchings --- drivers/target/iscsi/iscsi_target_tq.c | 30 +++++--------------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target_tq.c b/drivers/target/iscsi/iscsi_target_tq.c index 0baac5bcebd4..3f59a80238e0 100644 --- a/drivers/target/iscsi/iscsi_target_tq.c +++ b/drivers/target/iscsi/iscsi_target_tq.c @@ -26,36 +26,22 @@ #include "iscsi_target_tq.h" #include "iscsi_target.h" -static LIST_HEAD(active_ts_list); static LIST_HEAD(inactive_ts_list); -static DEFINE_SPINLOCK(active_ts_lock); static DEFINE_SPINLOCK(inactive_ts_lock); static DEFINE_SPINLOCK(ts_bitmap_lock); -static void iscsi_add_ts_to_active_list(struct iscsi_thread_set *ts) -{ - spin_lock(&active_ts_lock); - list_add_tail(&ts->ts_list, &active_ts_list); - iscsit_global->active_ts++; - spin_unlock(&active_ts_lock); -} - extern void iscsi_add_ts_to_inactive_list(struct iscsi_thread_set *ts) { + if (!list_empty(&ts->ts_list)) { + WARN_ON(1); + return; + } spin_lock(&inactive_ts_lock); list_add_tail(&ts->ts_list, &inactive_ts_list); iscsit_global->inactive_ts++; spin_unlock(&inactive_ts_lock); } -static void iscsi_del_ts_from_active_list(struct iscsi_thread_set *ts) -{ - spin_lock(&active_ts_lock); - list_del(&ts->ts_list); - iscsit_global->active_ts--; - spin_unlock(&active_ts_lock); -} - static struct iscsi_thread_set *iscsi_get_ts_from_inactive_list(void) { struct iscsi_thread_set *ts; @@ -69,7 +55,7 @@ static struct iscsi_thread_set *iscsi_get_ts_from_inactive_list(void) list_for_each_entry(ts, &inactive_ts_list, ts_list) break; - list_del(&ts->ts_list); + list_del_init(&ts->ts_list); iscsit_global->inactive_ts--; spin_unlock(&inactive_ts_lock); @@ -220,8 +206,6 @@ static void iscsi_deallocate_extra_thread_sets(void) void iscsi_activate_thread_set(struct iscsi_conn *conn, struct iscsi_thread_set *ts) { - iscsi_add_ts_to_active_list(ts); - spin_lock_bh(&ts->ts_state_lock); conn->thread_set = ts; ts->conn = conn; @@ -424,7 +408,6 @@ struct iscsi_conn *iscsi_rx_thread_pre_handler(struct iscsi_thread_set *ts) if (ts->delay_inactive && (--ts->thread_count == 0)) { spin_unlock_bh(&ts->ts_state_lock); - iscsi_del_ts_from_active_list(ts); if (!iscsit_global->in_shutdown) iscsi_deallocate_extra_thread_sets(); @@ -477,7 +460,6 @@ struct iscsi_conn *iscsi_tx_thread_pre_handler(struct iscsi_thread_set *ts) if (ts->delay_inactive && (--ts->thread_count == 0)) { spin_unlock_bh(&ts->ts_state_lock); - iscsi_del_ts_from_active_list(ts); if (!iscsit_global->in_shutdown) iscsi_deallocate_extra_thread_sets(); @@ -536,10 +518,8 @@ int iscsi_thread_set_init(void) return -ENOMEM; } - spin_lock_init(&active_ts_lock); spin_lock_init(&inactive_ts_lock); spin_lock_init(&ts_bitmap_lock); - INIT_LIST_HEAD(&active_ts_list); INIT_LIST_HEAD(&inactive_ts_list); return 0; -- 2.39.2