diff options
author | Dan Williams <dan.j.williams@intel.com> | 2012-03-20 13:53:24 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-04-23 07:08:56 -0400 |
commit | 9487669fc225092cf315e1291ece28e23e6754f3 (patch) | |
tree | b07d2c3250f44e3262d9580295ef4ecd501ba371 /drivers/scsi/libsas/sas_expander.c | |
parent | ec236e526777ea8825e6e0c3673a40389692eabf (diff) |
[SCSI] libsas: unify domain_device sas_rphy lifetimes
Since the domain_device can out live the scsi_target we need the rphy to
follow suit otherwise we run into issues like:
BUG: unable to handle kernel NULL pointer dereference at 0000000000000050
IP: [<ffffffffa011561b>] sas_ata_printk+0x43/0x6f [libsas]
PGD 0
Oops: 0000 [#1] SMP
CPU 1
Modules linked in: ses enclosure isci libsas scsi_transport_sas fuse sunrpc cpufreq_ondemand acpi_cpufreq freq_table mperf microcode pcspkr igb joydev iTCO_wdt ioatdma iTCO_vendor_support i2c_i801 i2c_core dca wmi hed ipv6 pata_acpi ata_generic [last unloaded: scsi_wait_scan]
Pid: 129, comm: kworker/u:3 Not tainted 3.3.0-rc5-isci+ #1 Intel Corporation SandyBridge Platform/To be filled by O.E.M.
RIP: 0010:[<ffffffffa011561b>] [<ffffffffa011561b>] sas_ata_printk+0x43/0x6f [libsas]
RSP: 0018:ffff88042232dd70 EFLAGS: 00010282
RAX: 0000000000000000 RBX: ffff8804283165b8 RCX: ffff88042232dda0
RDX: ffff88042232dd78 RSI: ffff8804283165b8 RDI: ffffffffa01188d7
RBP: ffff88042232ddd0 R08: ffff880388454000 R09: ffff8803edfde1f8
R10: ffff8803edfde1f8 R11: ffff8803edfde1f8 R12: ffff880428316750
R13: ffff880388454000 R14: ffff8803f88b31d0 R15: ffff8803f8b21d50
FS: 0000000000000000(0000) GS:ffff88042ee20000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 0000000000000050 CR3: 0000000001a05000 CR4: 00000000000406e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process kworker/u:3 (pid: 129, threadinfo ffff88042232c000, task ffff88042230c920)
Stack:
0000000000000000 ffff880400000018 ffff88042232dde0 ffff88042232dda0
ffffffffa01188c4 ffff88042ee93af0 ffff88042232ddb0 ffffffff8100e047
ffff88042232de10 ffff880420e5a2c8 ffff8803f8b21d50 ffff8803edfde1f8
Call Trace:
[<ffffffff8100e047>] ? load_TLS+0xb/0xf
[<ffffffffa01156ad>] async_sas_ata_eh+0x66/0x95 [libsas]
[<ffffffff810655e1>] async_run_entry_fn+0x9e/0x131
Reported-by: Tom Jackson <thomas.p.jackson@intel.com>
Tested-by: Tom Jackson <thomas.p.jackson@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/libsas/sas_expander.c')
-rw-r--r-- | drivers/scsi/libsas/sas_expander.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 833bea067a77..37c3c3f5f35d 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c | |||
@@ -783,6 +783,7 @@ static struct domain_device *sas_ex_discover_end_dev( | |||
783 | sas_init_dev(child); | 783 | sas_init_dev(child); |
784 | 784 | ||
785 | child->rphy = rphy; | 785 | child->rphy = rphy; |
786 | get_device(&rphy->dev); | ||
786 | 787 | ||
787 | list_add_tail(&child->disco_list_node, &parent->port->disco_list); | 788 | list_add_tail(&child->disco_list_node, &parent->port->disco_list); |
788 | 789 | ||
@@ -806,6 +807,7 @@ static struct domain_device *sas_ex_discover_end_dev( | |||
806 | sas_init_dev(child); | 807 | sas_init_dev(child); |
807 | 808 | ||
808 | child->rphy = rphy; | 809 | child->rphy = rphy; |
810 | get_device(&rphy->dev); | ||
809 | sas_fill_in_rphy(child, rphy); | 811 | sas_fill_in_rphy(child, rphy); |
810 | 812 | ||
811 | list_add_tail(&child->disco_list_node, &parent->port->disco_list); | 813 | list_add_tail(&child->disco_list_node, &parent->port->disco_list); |
@@ -830,8 +832,6 @@ static struct domain_device *sas_ex_discover_end_dev( | |||
830 | 832 | ||
831 | out_list_del: | 833 | out_list_del: |
832 | sas_rphy_free(child->rphy); | 834 | sas_rphy_free(child->rphy); |
833 | child->rphy = NULL; | ||
834 | |||
835 | list_del(&child->disco_list_node); | 835 | list_del(&child->disco_list_node); |
836 | spin_lock_irq(&parent->port->dev_list_lock); | 836 | spin_lock_irq(&parent->port->dev_list_lock); |
837 | list_del(&child->dev_list_node); | 837 | list_del(&child->dev_list_node); |
@@ -911,6 +911,7 @@ static struct domain_device *sas_ex_discover_expander( | |||
911 | } | 911 | } |
912 | port = parent->port; | 912 | port = parent->port; |
913 | child->rphy = rphy; | 913 | child->rphy = rphy; |
914 | get_device(&rphy->dev); | ||
914 | edev = rphy_to_expander_device(rphy); | 915 | edev = rphy_to_expander_device(rphy); |
915 | child->dev_type = phy->attached_dev_type; | 916 | child->dev_type = phy->attached_dev_type; |
916 | kref_get(&parent->kref); | 917 | kref_get(&parent->kref); |
@@ -934,6 +935,7 @@ static struct domain_device *sas_ex_discover_expander( | |||
934 | 935 | ||
935 | res = sas_discover_expander(child); | 936 | res = sas_discover_expander(child); |
936 | if (res) { | 937 | if (res) { |
938 | sas_rphy_delete(rphy); | ||
937 | spin_lock_irq(&parent->port->dev_list_lock); | 939 | spin_lock_irq(&parent->port->dev_list_lock); |
938 | list_del(&child->dev_list_node); | 940 | list_del(&child->dev_list_node); |
939 | spin_unlock_irq(&parent->port->dev_list_lock); | 941 | spin_unlock_irq(&parent->port->dev_list_lock); |