From aa6104d43850da8df58171cd57351378449957b7 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 14 Jan 2013 09:27:41 -0800 Subject: [PATCH] 3.0-stable patches added patches: libata-fix-null-pointer-dereference-on-disk-error.patch libata-set-dma_mode-to-0xff-in-reset.patch target-tcm_fc-fix-the-lockdep-warning-due-to-inconsistent-lock-state.patch --- ...ll-pointer-dereference-on-disk-error.patch | 56 +++++++ ...libata-set-dma_mode-to-0xff-in-reset.patch | 50 ++++++ queue-3.0/series | 3 + ...rning-due-to-inconsistent-lock-state.patch | 142 ++++++++++++++++++ 4 files changed, 251 insertions(+) create mode 100644 queue-3.0/libata-fix-null-pointer-dereference-on-disk-error.patch create mode 100644 queue-3.0/libata-set-dma_mode-to-0xff-in-reset.patch create mode 100644 queue-3.0/target-tcm_fc-fix-the-lockdep-warning-due-to-inconsistent-lock-state.patch diff --git a/queue-3.0/libata-fix-null-pointer-dereference-on-disk-error.patch b/queue-3.0/libata-fix-null-pointer-dereference-on-disk-error.patch new file mode 100644 index 00000000000..694cab7e2b1 --- /dev/null +++ b/queue-3.0/libata-fix-null-pointer-dereference-on-disk-error.patch @@ -0,0 +1,56 @@ +From 26cd4d65deba587f3cf2329b6869ce02bcbe68ec Mon Sep 17 00:00:00 2001 +From: Xiaotian Feng +Date: Thu, 13 Dec 2012 16:12:18 +0800 +Subject: libata: fix Null pointer dereference on disk error + +From: Xiaotian Feng + +commit 26cd4d65deba587f3cf2329b6869ce02bcbe68ec upstream. + +Following oops were observed when disk error happened: + +[ 4272.896937] sd 0:0:0:0: [sda] Unhandled error code +[ 4272.896939] sd 0:0:0:0: [sda] Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK +[ 4272.896942] sd 0:0:0:0: [sda] CDB: Read(10): 28 00 00 5a de a7 00 00 08 00 +[ 4272.896951] end_request: I/O error, dev sda, sector 5955239 +[ 4291.574947] BUG: unable to handle kernel NULL pointer dereference at (null) +[ 4291.658305] IP: [] ahci_activity_show+0x1/0x40 +[ 4291.730090] PGD 76dbbc067 PUD 6c4fba067 PMD 0 +[ 4291.783408] Oops: 0000 [#1] SMP +[ 4291.822100] last sysfs file: /sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/sw_activity +[ 4291.934235] CPU 9 +[ 4291.958301] Pid: 27942, comm: hwinfo ...... + +ata_scsi_find_dev could return NULL, so ata_scsi_activity_{show,store} should check if atadev is NULL. + +Signed-off-by: Xiaotian Feng +Cc: James Bottomley +Signed-off-by: Jeff Garzik +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/ata/libata-scsi.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/ata/libata-scsi.c ++++ b/drivers/ata/libata-scsi.c +@@ -308,7 +308,8 @@ ata_scsi_activity_show(struct device *de + struct ata_port *ap = ata_shost_to_port(sdev->host); + struct ata_device *atadev = ata_scsi_find_dev(ap, sdev); + +- if (ap->ops->sw_activity_show && (ap->flags & ATA_FLAG_SW_ACTIVITY)) ++ if (atadev && ap->ops->sw_activity_show && ++ (ap->flags & ATA_FLAG_SW_ACTIVITY)) + return ap->ops->sw_activity_show(atadev, buf); + return -EINVAL; + } +@@ -323,7 +324,8 @@ ata_scsi_activity_store(struct device *d + enum sw_activity val; + int rc; + +- if (ap->ops->sw_activity_store && (ap->flags & ATA_FLAG_SW_ACTIVITY)) { ++ if (atadev && ap->ops->sw_activity_store && ++ (ap->flags & ATA_FLAG_SW_ACTIVITY)) { + val = simple_strtoul(buf, NULL, 0); + switch (val) { + case OFF: case BLINK_ON: case BLINK_OFF: diff --git a/queue-3.0/libata-set-dma_mode-to-0xff-in-reset.patch b/queue-3.0/libata-set-dma_mode-to-0xff-in-reset.patch new file mode 100644 index 00000000000..cd7116843c9 --- /dev/null +++ b/queue-3.0/libata-set-dma_mode-to-0xff-in-reset.patch @@ -0,0 +1,50 @@ +From 5416912af75de9cba5d1c75b99a7888b0bbbd2fb Mon Sep 17 00:00:00 2001 +From: Aaron Lu +Date: Mon, 3 Dec 2012 11:35:02 +0800 +Subject: libata: set dma_mode to 0xff in reset + +From: Aaron Lu + +commit 5416912af75de9cba5d1c75b99a7888b0bbbd2fb upstream. + +ata_device->dma_mode's initial value is zero, which is not a valid dma +mode, but ata_dma_enabled will return true for this value. This patch +sets dma_mode to 0xff in reset function, so that ata_dma_enabled will +not return true for this case, or it will cause problem for pata_acpi. + +The corrsponding bugzilla page is at: +https://bugzilla.kernel.org/show_bug.cgi?id=49151 + +Reported-by: Phillip Wood +Signed-off-by: Aaron Lu +Tested-by: Szymon Janc +Tested-by: Dutra Julio +Acked-by: Alan Cox +Signed-off-by: Jeff Garzik +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/ata/libata-core.c | 1 + + drivers/ata/libata-eh.c | 1 + + 2 files changed, 2 insertions(+) + +--- a/drivers/ata/libata-core.c ++++ b/drivers/ata/libata-core.c +@@ -2543,6 +2543,7 @@ int ata_bus_probe(struct ata_port *ap) + * bus as we may be talking too fast. + */ + dev->pio_mode = XFER_PIO_0; ++ dev->dma_mode = 0xff; + + /* If the controller has a pio mode setup function + * then use it to set the chipset to rights. Don't +--- a/drivers/ata/libata-eh.c ++++ b/drivers/ata/libata-eh.c +@@ -2602,6 +2602,7 @@ int ata_eh_reset(struct ata_link *link, + * bus as we may be talking too fast. + */ + dev->pio_mode = XFER_PIO_0; ++ dev->dma_mode = 0xff; + + /* If the controller has a pio mode setup function + * then use it to set the chipset to rights. Don't diff --git a/queue-3.0/series b/queue-3.0/series index 12899de536b..e633fbe7b68 100644 --- a/queue-3.0/series +++ b/queue-3.0/series @@ -9,3 +9,6 @@ firewire-net-fix-handling-of-fragmented-multicast-broadcast-packets.patch scsi-mvsas-fix-undefined-bit-shift.patch scsi-qla2xxx-test-and-clear-fcport_update_needed-atomically.patch sata_promise-fix-hardreset-lockdep-error.patch +libata-set-dma_mode-to-0xff-in-reset.patch +libata-fix-null-pointer-dereference-on-disk-error.patch +target-tcm_fc-fix-the-lockdep-warning-due-to-inconsistent-lock-state.patch diff --git a/queue-3.0/target-tcm_fc-fix-the-lockdep-warning-due-to-inconsistent-lock-state.patch b/queue-3.0/target-tcm_fc-fix-the-lockdep-warning-due-to-inconsistent-lock-state.patch new file mode 100644 index 00000000000..2834036a111 --- /dev/null +++ b/queue-3.0/target-tcm_fc-fix-the-lockdep-warning-due-to-inconsistent-lock-state.patch @@ -0,0 +1,142 @@ +From 9f4ad44b264f8bb61ffdd607148215566568430d Mon Sep 17 00:00:00 2001 +From: Yi Zou +Date: Mon, 10 Dec 2012 17:04:00 -0800 +Subject: target/tcm_fc: fix the lockdep warning due to inconsistent lock state + +From: Yi Zou + +commit 9f4ad44b264f8bb61ffdd607148215566568430d upstream. + +The lockdep warning below is in theory correct but it will be in really weird +rare situation that ends up that deadlock since the tcm fc session is hashed +based the rport id. Nonetheless, the complaining below is about rcu callback +that does the transport_deregister_session() is happening in softirq, where +transport_register_session() that happens earlier is not. This triggers the +lockdep warning below. So, just fix this to make lockdep happy by disabling +the soft irq before calling transport_register_session() in ft_prli. + +BTW, this was found in FCoE VN2VN over two VMs, couple of create and destroy +would get this triggered. + +v1: was enforcing register to be in softirq context which was not righ. See, +http://www.spinics.net/lists/target-devel/msg03614.html + +v2: following comments from Roland&Nick (thanks), it seems we don't have to +do transport_deregister_session() in rcu callback, so move it into ft_sess_free() +but still do kfree() of the corresponding ft_sess struct in rcu callback to +make sure the ft_sess is not freed till the rcu callback. + +... +[ 1328.370592] scsi2 : FCoE Driver +[ 1328.383429] fcoe: No FDMI support. +[ 1328.384509] host2: libfc: Link up on port (000000) +[ 1328.934229] host2: Assigned Port ID 00a292 +[ 1357.232132] host2: rport 00a393: Remove port +[ 1357.232568] host2: rport 00a393: Port sending LOGO from Ready state +[ 1357.233692] host2: rport 00a393: Delete port +[ 1357.234472] host2: rport 00a393: work event 3 +[ 1357.234969] host2: rport 00a393: callback ev 3 +[ 1357.235979] host2: rport 00a393: Received a LOGO response closed +[ 1357.236706] host2: rport 00a393: work delete +[ 1357.237481] +[ 1357.237631] ================================= +[ 1357.238064] [ INFO: inconsistent lock state ] +[ 1357.238450] 3.7.0-rc7-yikvm+ #3 Tainted: G O +[ 1357.238450] --------------------------------- +[ 1357.238450] inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage. +[ 1357.238450] ksoftirqd/0/3 [HC0[0]:SC1[1]:HE0:SE0] takes: +[ 1357.238450] (&(&se_tpg->session_lock)->rlock){+.?...}, at: [] transport_deregister_session+0x41/0x148 [target_core_mod] +[ 1357.238450] {SOFTIRQ-ON-W} state was registered at: +[ 1357.238450] [] mark_held_locks+0x6d/0x95 +[ 1357.238450] [] trace_hardirqs_on_caller+0x12d/0x197 +[ 1357.238450] [] trace_hardirqs_on+0xd/0xf +[ 1357.238450] [] _raw_spin_unlock_irq+0x2d/0x45 +[ 1357.238450] [] __transport_register_session+0xb8/0x122 [target_core_mod] +[ 1357.238450] [] transport_register_session+0x44/0x5a [target_core_mod] +[ 1357.238450] [] ft_prli+0x1e3/0x275 [tcm_fc] +[ 1357.238450] [] fc_rport_recv_req+0x95e/0xdc5 [libfc] +[ 1357.238450] [] fc_lport_recv_els_req+0xc4/0xd5 [libfc] +[ 1357.238450] [] fc_lport_recv_req+0x12f/0x18f [libfc] +[ 1357.238450] [] fc_exch_recv+0x8ba/0x981 [libfc] +[ 1357.238450] [] fcoe_percpu_receive_thread+0x47a/0x4e2 [fcoe] +[ 1357.238450] [] kthread+0xb1/0xb9 +[ 1357.238450] [] ret_from_fork+0x7c/0xb0 +[ 1357.238450] irq event stamp: 275411 +[ 1357.238450] hardirqs last enabled at (275410): [] rcu_process_callbacks+0x229/0x42a +[ 1357.238450] hardirqs last disabled at (275411): [] _raw_spin_lock_irqsave+0x22/0x8e +[ 1357.238450] softirqs last enabled at (275394): [] __do_softirq+0x246/0x26f +[ 1357.238450] softirqs last disabled at (275399): [] run_ksoftirqd+0x29/0x62 +[ 1357.238450] +[ 1357.238450] other info that might help us debug this: +[ 1357.238450] Possible unsafe locking scenario: +[ 1357.238450] +[ 1357.238450] CPU0 +[ 1357.238450] ---- +[ 1357.238450] lock(&(&se_tpg->session_lock)->rlock); +[ 1357.238450] +[ 1357.238450] lock(&(&se_tpg->session_lock)->rlock); +[ 1357.238450] +[ 1357.238450] *** DEADLOCK *** +[ 1357.238450] +[ 1357.238450] no locks held by ksoftirqd/0/3. +[ 1357.238450] +[ 1357.238450] stack backtrace: +[ 1357.238450] Pid: 3, comm: ksoftirqd/0 Tainted: G O 3.7.0-rc7-yikvm+ #3 +[ 1357.238450] Call Trace: +[ 1357.238450] [] print_usage_bug+0x1f5/0x206 +[ 1357.238450] [] ? save_stack_trace+0x2c/0x49 +[ 1357.238450] [] ? print_irq_inversion_bug.part.14+0x1ae/0x1ae +[ 1357.238450] [] mark_lock+0x106/0x258 +[ 1357.238450] [] __lock_acquire+0x2e7/0xe53 +[ 1357.238450] [] ? pvclock_clocksource_read+0x48/0xb4 +[ 1357.238450] [] ? rcu_process_gp_end+0xc0/0xc9 +[ 1357.238450] [] ? transport_deregister_session+0x41/0x148 [target_core_mod] +[ 1357.238450] [] lock_acquire+0x119/0x143 +[ 1357.238450] [] ? transport_deregister_session+0x41/0x148 [target_core_mod] +[ 1357.238450] [] _raw_spin_lock_irqsave+0x54/0x8e +[ 1357.238450] [] ? transport_deregister_session+0x41/0x148 [target_core_mod] +[ 1357.238450] [] transport_deregister_session+0x41/0x148 [target_core_mod] +[ 1357.238450] [] ? rcu_process_callbacks+0x229/0x42a +[ 1357.238450] [] ft_sess_rcu_free+0x17/0x24 [tcm_fc] +[ 1357.238450] [] ? ft_sess_free+0x1b/0x1b [tcm_fc] +[ 1357.238450] [] rcu_process_callbacks+0x260/0x42a +[ 1357.238450] [] __do_softirq+0x13a/0x26f +[ 1357.238450] [] ? __schedule+0x65f/0x68e +[ 1357.238450] [] run_ksoftirqd+0x29/0x62 +[ 1357.238450] [] smpboot_thread_fn+0x1a5/0x1aa +[ 1357.238450] [] ? smpboot_unregister_percpu_thread+0x47/0x47 +[ 1357.238450] [] kthread+0xb1/0xb9 +[ 1357.238450] [] ? wait_for_common+0xbb/0x10a +[ 1357.238450] [] ? __init_kthread_worker+0x59/0x59 +[ 1357.238450] [] ret_from_fork+0x7c/0xb0 +[ 1357.238450] [] ? __init_kthread_worker+0x59/0x59 +[ 1417.440099] rport-2:0-0: blocked FC remote port time out: removing rport + +Signed-off-by: Yi Zou +Cc: Open-FCoE +Cc: Nicholas A. Bellinger +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/tcm_fc/tfc_sess.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/target/tcm_fc/tfc_sess.c ++++ b/drivers/target/tcm_fc/tfc_sess.c +@@ -468,7 +468,6 @@ static void ft_sess_rcu_free(struct rcu_ + { + struct ft_sess *sess = container_of(rcu, struct ft_sess, rcu); + +- transport_deregister_session(sess->se_sess); + kfree(sess); + } + +@@ -476,6 +475,7 @@ static void ft_sess_free(struct kref *kr + { + struct ft_sess *sess = container_of(kref, struct ft_sess, kref); + ++ transport_deregister_session(sess->se_sess); + call_rcu(&sess->rcu, ft_sess_rcu_free); + } + -- 2.47.3