From: Greg Kroah-Hartman Date: Mon, 5 Nov 2012 13:41:53 +0000 (+0100) Subject: 3.6-stable patches X-Git-Tag: v3.0.52~44 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0a6ceb09dd697fc6736262967b190fb5f725e8d2;p=thirdparty%2Fkernel%2Fstable-queue.git 3.6-stable patches added patches: iscsi-target-fix-missed-wakeup-race-in-tx-thread.patch rt2800-validate-step-value-for-temperature-compensation.patch target-avoid-integer-overflow-in-se_dev_align_max_sectors.patch target-don-t-return-success-from-module_init-if-setup-fails.patch target-fix-incorrect-usage-of-nested-irq-spinlocks-in-abort_task-path.patch target-re-add-explict-zeroing-of-inquiry-bounce-buffer-memory.patch --- diff --git a/queue-3.6/iscsi-target-fix-missed-wakeup-race-in-tx-thread.patch b/queue-3.6/iscsi-target-fix-missed-wakeup-race-in-tx-thread.patch new file mode 100644 index 00000000000..41ffd4e47c6 --- /dev/null +++ b/queue-3.6/iscsi-target-fix-missed-wakeup-race-in-tx-thread.patch @@ -0,0 +1,130 @@ +From d5627acba9ae584cf4928af19f7ddf5f6837de32 Mon Sep 17 00:00:00 2001 +From: Roland Dreier +Date: Wed, 31 Oct 2012 09:16:46 -0700 +Subject: iscsi-target: Fix missed wakeup race in TX thread + +From: Roland Dreier + +commit d5627acba9ae584cf4928af19f7ddf5f6837de32 upstream. + +The sleeping code in iscsi_target_tx_thread() is susceptible to the classic +missed wakeup race: + + - TX thread finishes handle_immediate_queue() and handle_response_queue(), + thinks both queues are empty. + - Another thread adds a queue entry and does wake_up_process(), which does + nothing because the TX thread is still awake. + - TX thread does schedule_timeout() and sleeps forever. + +In practice this can kill an iSCSI connection if for example an initiator +does single-threaded writes and the target misses the wakeup window when +queueing an R2T; in this case the connection will be stuck until the +initiator loses patience and does some task management operation (or kills +the connection entirely). + +Fix this by converting to wait_event_interruptible(), which does not +suffer from this sort of race. + +Signed-off-by: Roland Dreier +Cc: Andy Grover +Cc: Hannes Reinecke +Cc: Christoph Hellwig +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/iscsi/iscsi_target.c | 4 +++- + drivers/target/iscsi/iscsi_target_core.h | 1 + + drivers/target/iscsi/iscsi_target_login.c | 1 + + drivers/target/iscsi/iscsi_target_util.c | 22 ++++++++++++++++++++-- + drivers/target/iscsi/iscsi_target_util.h | 1 + + 5 files changed, 26 insertions(+), 3 deletions(-) + +--- a/drivers/target/iscsi/iscsi_target.c ++++ b/drivers/target/iscsi/iscsi_target.c +@@ -3735,7 +3735,9 @@ restart: + */ + iscsit_thread_check_cpumask(conn, current, 1); + +- schedule_timeout_interruptible(MAX_SCHEDULE_TIMEOUT); ++ wait_event_interruptible(conn->queues_wq, ++ !iscsit_conn_all_queues_empty(conn) || ++ ts->status == ISCSI_THREAD_SET_RESET); + + if ((ts->status == ISCSI_THREAD_SET_RESET) || + signal_pending(current)) +--- a/drivers/target/iscsi/iscsi_target_core.h ++++ b/drivers/target/iscsi/iscsi_target_core.h +@@ -486,6 +486,7 @@ struct iscsi_tmr_req { + }; + + struct iscsi_conn { ++ wait_queue_head_t queues_wq; + /* Authentication Successful for this connection */ + u8 auth_complete; + /* State connection is currently in */ +--- a/drivers/target/iscsi/iscsi_target_login.c ++++ b/drivers/target/iscsi/iscsi_target_login.c +@@ -45,6 +45,7 @@ extern spinlock_t sess_idr_lock; + + static int iscsi_login_init_conn(struct iscsi_conn *conn) + { ++ init_waitqueue_head(&conn->queues_wq); + INIT_LIST_HEAD(&conn->conn_list); + INIT_LIST_HEAD(&conn->conn_cmd_list); + INIT_LIST_HEAD(&conn->immed_queue_list); +--- a/drivers/target/iscsi/iscsi_target_util.c ++++ b/drivers/target/iscsi/iscsi_target_util.c +@@ -488,7 +488,7 @@ void iscsit_add_cmd_to_immediate_queue( + atomic_set(&conn->check_immediate_queue, 1); + spin_unlock_bh(&conn->immed_queue_lock); + +- wake_up_process(conn->thread_set->tx_thread); ++ wake_up(&conn->queues_wq); + } + + struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_conn *conn) +@@ -562,7 +562,7 @@ void iscsit_add_cmd_to_response_queue( + atomic_inc(&cmd->response_queue_count); + spin_unlock_bh(&conn->response_queue_lock); + +- wake_up_process(conn->thread_set->tx_thread); ++ wake_up(&conn->queues_wq); + } + + struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *conn) +@@ -616,6 +616,24 @@ static void iscsit_remove_cmd_from_respo + } + } + ++bool iscsit_conn_all_queues_empty(struct iscsi_conn *conn) ++{ ++ bool empty; ++ ++ spin_lock_bh(&conn->immed_queue_lock); ++ empty = list_empty(&conn->immed_queue_list); ++ spin_unlock_bh(&conn->immed_queue_lock); ++ ++ if (!empty) ++ return empty; ++ ++ spin_lock_bh(&conn->response_queue_lock); ++ empty = list_empty(&conn->response_queue_list); ++ spin_unlock_bh(&conn->response_queue_lock); ++ ++ return empty; ++} ++ + void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *conn) + { + struct iscsi_queue_req *qr, *qr_tmp; +--- a/drivers/target/iscsi/iscsi_target_util.h ++++ b/drivers/target/iscsi/iscsi_target_util.h +@@ -25,6 +25,7 @@ extern struct iscsi_queue_req *iscsit_ge + extern void iscsit_add_cmd_to_response_queue(struct iscsi_cmd *, struct iscsi_conn *, u8); + extern struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *); + extern void iscsit_remove_cmd_from_tx_queues(struct iscsi_cmd *, struct iscsi_conn *); ++extern bool iscsit_conn_all_queues_empty(struct iscsi_conn *); + extern void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *); + extern void iscsit_release_cmd(struct iscsi_cmd *); + extern void iscsit_free_cmd(struct iscsi_cmd *); diff --git a/queue-3.6/rt2800-validate-step-value-for-temperature-compensation.patch b/queue-3.6/rt2800-validate-step-value-for-temperature-compensation.patch new file mode 100644 index 00000000000..80c2fb83714 --- /dev/null +++ b/queue-3.6/rt2800-validate-step-value-for-temperature-compensation.patch @@ -0,0 +1,34 @@ +From bf7e1abe434ba9e22e8dc04a4cba4ab504b788b8 Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Thu, 25 Oct 2012 09:51:39 +0200 +Subject: rt2800: validate step value for temperature compensation + +From: Stanislaw Gruszka + +commit bf7e1abe434ba9e22e8dc04a4cba4ab504b788b8 upstream. + +Some hardware has correct (!= 0xff) value of tssi_bounds[4] in the +EEPROM, but step is equal to 0xff. This results on ridiculous delta +calculations and completely broke TX power settings. + +Reported-and-tested-by: Pavel Lucik +Signed-off-by: Stanislaw Gruszka +Acked-by: Ivo van Doorn +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/rt2x00/rt2800lib.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c +@@ -2395,7 +2395,7 @@ static int rt2800_get_gain_calibration_d + /* + * Check if temperature compensation is supported. + */ +- if (tssi_bounds[4] == 0xff) ++ if (tssi_bounds[4] == 0xff || step == 0xff) + return 0; + + /* diff --git a/queue-3.6/series b/queue-3.6/series index 3de14478813..761725a7105 100644 --- a/queue-3.6/series +++ b/queue-3.6/series @@ -4,3 +4,9 @@ ixgbe-ptp-get_ts_info-missing-software-support.patch input-tsc40-remove-wrong-announcement-of-pressure-support.patch ath9k-fix-stale-pointers-potentially-causing-access-to-free-d-skbs.patch ath9k-test-for-tid-only-in-blockacks-while-checking-tx-status.patch +rt2800-validate-step-value-for-temperature-compensation.patch +target-don-t-return-success-from-module_init-if-setup-fails.patch +target-avoid-integer-overflow-in-se_dev_align_max_sectors.patch +iscsi-target-fix-missed-wakeup-race-in-tx-thread.patch +target-fix-incorrect-usage-of-nested-irq-spinlocks-in-abort_task-path.patch +target-re-add-explict-zeroing-of-inquiry-bounce-buffer-memory.patch diff --git a/queue-3.6/target-avoid-integer-overflow-in-se_dev_align_max_sectors.patch b/queue-3.6/target-avoid-integer-overflow-in-se_dev_align_max_sectors.patch new file mode 100644 index 00000000000..68b24b318df --- /dev/null +++ b/queue-3.6/target-avoid-integer-overflow-in-se_dev_align_max_sectors.patch @@ -0,0 +1,58 @@ +From 3e03989b5868acf69a391a424dc71fcd6cc48167 Mon Sep 17 00:00:00 2001 +From: Roland Dreier +Date: Wed, 31 Oct 2012 09:16:45 -0700 +Subject: target: Avoid integer overflow in se_dev_align_max_sectors() + +From: Roland Dreier + +commit 3e03989b5868acf69a391a424dc71fcd6cc48167 upstream. + +The expression (max_sectors * block_size) might overflow a u32 +(indeed, since iblock sets max_hw_sectors to UINT_MAX, it is +guaranteed to overflow and end up with a much-too-small result in many +common cases). Fix this by doing an equivalent calculation that +doesn't require multiplication. + +While we're touching this code, avoid splitting a printk format across +two lines and use pr_info(...) instead of printk(KERN_INFO ...). + +Signed-off-by: Roland Dreier +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_device.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +--- a/drivers/target/target_core_device.c ++++ b/drivers/target/target_core_device.c +@@ -850,20 +850,20 @@ int se_dev_check_shutdown(struct se_devi + + static u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size) + { +- u32 tmp, aligned_max_sectors; ++ u32 aligned_max_sectors; ++ u32 alignment; + /* + * Limit max_sectors to a PAGE_SIZE aligned value for modern + * transport_allocate_data_tasks() operation. + */ +- tmp = rounddown((max_sectors * block_size), PAGE_SIZE); +- aligned_max_sectors = (tmp / block_size); +- if (max_sectors != aligned_max_sectors) { +- printk(KERN_INFO "Rounding down aligned max_sectors from %u" +- " to %u\n", max_sectors, aligned_max_sectors); +- return aligned_max_sectors; +- } ++ alignment = max(1ul, PAGE_SIZE / block_size); ++ aligned_max_sectors = rounddown(max_sectors, alignment); + +- return max_sectors; ++ if (max_sectors != aligned_max_sectors) ++ pr_info("Rounding down aligned max_sectors from %u to %u\n", ++ max_sectors, aligned_max_sectors); ++ ++ return aligned_max_sectors; + } + + void se_dev_set_default_attribs( diff --git a/queue-3.6/target-don-t-return-success-from-module_init-if-setup-fails.patch b/queue-3.6/target-don-t-return-success-from-module_init-if-setup-fails.patch new file mode 100644 index 00000000000..0cbf3f7083e --- /dev/null +++ b/queue-3.6/target-don-t-return-success-from-module_init-if-setup-fails.patch @@ -0,0 +1,35 @@ +From 0d0f9dfb31e0a6c92063e235417b42df185b3275 Mon Sep 17 00:00:00 2001 +From: Roland Dreier +Date: Wed, 31 Oct 2012 09:16:44 -0700 +Subject: target: Don't return success from module_init() if setup fails + +From: Roland Dreier + +commit 0d0f9dfb31e0a6c92063e235417b42df185b3275 upstream. + +If the call to core_dev_release_virtual_lun0() fails, then nothing +sets ret to anything other than 0, so even though everything is +torn down and freed, target_core_init_configfs() will seem to succeed +and the module will be loaded. Fix this by passing the return value +on up the chain. + +Signed-off-by: Roland Dreier +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_configfs.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/target/target_core_configfs.c ++++ b/drivers/target/target_core_configfs.c +@@ -3214,7 +3214,8 @@ static int __init target_core_init_confi + if (ret < 0) + goto out; + +- if (core_dev_setup_virtual_lun0() < 0) ++ ret = core_dev_setup_virtual_lun0(); ++ if (ret < 0) + goto out; + + return 0; diff --git a/queue-3.6/target-fix-incorrect-usage-of-nested-irq-spinlocks-in-abort_task-path.patch b/queue-3.6/target-fix-incorrect-usage-of-nested-irq-spinlocks-in-abort_task-path.patch new file mode 100644 index 00000000000..a1074fdeabb --- /dev/null +++ b/queue-3.6/target-fix-incorrect-usage-of-nested-irq-spinlocks-in-abort_task-path.patch @@ -0,0 +1,43 @@ +From ab74b3d62f05192bf8fb8f169e7999d1183b2e08 Mon Sep 17 00:00:00 2001 +From: Steve Hodgson +Date: Wed, 31 Oct 2012 10:24:02 -0700 +Subject: target: Fix incorrect usage of nested IRQ spinlocks in ABORT_TASK path + +From: Steve Hodgson + +commit ab74b3d62f05192bf8fb8f169e7999d1183b2e08 upstream. + +This patch changes core_tmr_abort_task() to use spin_lock -> spin_unlock +around se_cmd->t_state_lock while spin_lock_irqsave is held via +se_sess->sess_cmd_lock. + +Signed-off-by: Steve Hodgson +Signed-off-by: Roland Dreier +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_tmr.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/target/target_core_tmr.c ++++ b/drivers/target/target_core_tmr.c +@@ -140,15 +140,15 @@ void core_tmr_abort_task( + printk("ABORT_TASK: Found referenced %s task_tag: %u\n", + se_cmd->se_tfo->get_fabric_name(), ref_tag); + +- spin_lock_irq(&se_cmd->t_state_lock); ++ spin_lock(&se_cmd->t_state_lock); + if (se_cmd->transport_state & CMD_T_COMPLETE) { + printk("ABORT_TASK: ref_tag: %u already complete, skipping\n", ref_tag); +- spin_unlock_irq(&se_cmd->t_state_lock); ++ spin_unlock(&se_cmd->t_state_lock); + spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); + goto out; + } + se_cmd->transport_state |= CMD_T_ABORTED; +- spin_unlock_irq(&se_cmd->t_state_lock); ++ spin_unlock(&se_cmd->t_state_lock); + + list_del_init(&se_cmd->se_cmd_list); + kref_get(&se_cmd->cmd_kref); diff --git a/queue-3.6/target-re-add-explict-zeroing-of-inquiry-bounce-buffer-memory.patch b/queue-3.6/target-re-add-explict-zeroing-of-inquiry-bounce-buffer-memory.patch new file mode 100644 index 00000000000..42603956797 --- /dev/null +++ b/queue-3.6/target-re-add-explict-zeroing-of-inquiry-bounce-buffer-memory.patch @@ -0,0 +1,48 @@ +From dea5f0998aa82bdeca260b87c653db11e91329b2 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Wed, 31 Oct 2012 22:04:26 -0700 +Subject: target: Re-add explict zeroing of INQUIRY bounce buffer memory + +From: Nicholas Bellinger + +commit dea5f0998aa82bdeca260b87c653db11e91329b2 upstream. + +This patch fixes a regression in spc_emulate_inquiry() code where the +local scope bounce buffer was no longer getting it's memory zeroed, +causing various problems with SCSI initiators that depend upon areas +of INQUIRY EVPD=0x83 payload having been zeroed. + +This bug was introduced with the following v3.7-rc1 patch + CC'ed +stable commit: + +commit ffe7b0e9326d9c68f5688bef691dd49f1e0d3651 +Author: Paolo Bonzini +Date: Fri Sep 7 17:30:38 2012 +0200 + + target: support zero allocation length in INQUIRY + +Go ahead and re-add the missing memset of bounce buffer memory to be +copied into the outgoing se_cmd descriptor kmapped SGL payload. + +Reported-by: Kelsey Prantis +Cc: Kelsey Prantis +Cc: Paolo Bonzini +Cc: Andy Grover +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_spc.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/target/target_core_spc.c ++++ b/drivers/target/target_core_spc.c +@@ -605,6 +605,8 @@ static int spc_emulate_inquiry(struct se + unsigned char buf[SE_INQUIRY_BUF]; + int p, ret; + ++ memset(buf, 0, SE_INQUIRY_BUF); ++ + if (dev == tpg->tpg_virt_lun0.lun_se_dev) + buf[0] = 0x3f; /* Not connected */ + else