1. 29 Feb, 2012 15 commits
    • Dan Williams's avatar
      [SCSI] libsas: close scsi_remove_target() vs libata-eh race · 8abda4d2
      Dan Williams authored
      ata_port lifetime in libata follows the host.  In libsas it follows the
      scsi_target.  Once scsi_remove_device() has caused all commands to be
      completed it allows scsi_remove_target() to immediately proceed to
      freeing the ata_port causing bug reports like:
      [  848.393333] BUG: spinlock bad magic on CPU#4, kworker/u:2/5107
      [  848.400262] general protection fault: 0000 [#1] SMP
      [  848.406244] CPU 4
      [  848.408310] Modules linked in: nls_utf8 ipv6 uinput i2c_i801 i2c_core iTCO_wdt iTCO_vendor_support ioatdma dca sg sd_mod sr_mod cdrom ahci libahci isci libsas libata scsi_transport_sas [last unloaded: scsi_wait_scan]
      [  848.432060]
      [  848.434137] Pid: 5107, comm: kworker/u:2 Not tainted 3.2.0-isci+ #8 Intel Corporation S2600CP/S2600CP
      [  848.445310] RIP: 0010:[<ffffffff8126a68c>]  [<ffffffff8126a68c>] spin_dump+0x5e/0x8c
      [  848.454787] RSP: 0018:ffff8807f868dca0  EFLAGS: 00010002
      [  848.461137] RAX: 0000000000000048 RBX: ffff8807fe86a630 RCX: ffffffff817d0be0
      [  848.469520] RDX: 0000000000000000 RSI: ffffffff814af1cf RDI: 0000000000000002
      [  848.477959] RBP: ffff8807f868dcb0 R08: 00000000ffffffff R09: 000000006b6b6b6b
      [  848.486327] R10: 000000000003fb8c R11: ffffffff81a19448 R12: 6b6b6b6b6b6b6b6b
      [  848.494699] R13: ffff8808027dc520 R14: 0000000000000000 R15: 000000000000001e
      [  848.503067] FS:  0000000000000000(0000) GS:ffff88083fd00000(0000) knlGS:0000000000000000
      [  848.512899] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
      [  848.519710] CR2: 00007ff77d001000 CR3: 00000007f7a5d000 CR4: 00000000000406e0
      [  848.528072] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
      [  848.536446] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
      [  848.544831] Process kworker/u:2 (pid: 5107, threadinfo ffff8807f868c000, task ffff8807ff348000)
      [  848.555327] Stack:
      [  848.557959]  ffff8807fe86a630 ffff8807fe86a630 ffff8807f868dcd0 ffffffff8126a6e0
      [  848.567072]  ffffffff817c142f ffff8807fe86a630 ffff8807f868dcf0 ffffffff8126a703
      [  848.576190]  ffff8808027dc520 0000000000000286 ffff8807f868dd10 ffffffff814af1bb
      [  848.585281] Call Trace:
      [  848.588409]  [<ffffffff8126a6e0>] spin_bug+0x26/0x28
      [  848.594357]  [<ffffffff8126a703>] do_raw_spin_unlock+0x21/0x88
      [  848.601283]  [<ffffffff814af1bb>] _raw_spin_unlock_irqrestore+0x2c/0x65
      [  848.609089]  [<ffffffffa001c103>] ata_scsi_port_error_handler+0x548/0x557 [libata]
      [  848.618331]  [<ffffffff81061813>] ? async_schedule+0x17/0x17
      [  848.625060]  [<ffffffffa004f30f>] async_sas_ata_eh+0x45/0x69 [libsas]
      [  848.632655]  [<ffffffff810618aa>] async_run_entry_fn+0x97/0x125
      [  848.639670]  [<ffffffff81057439>] process_one_work+0x207/0x38d
      [  848.646577]  [<ffffffff8105738c>] ? process_one_work+0x15a/0x38d
      [  848.653681]  [<ffffffff810576f7>] worker_thread+0x138/0x21c
      [  848.660305]  [<ffffffff810575bf>] ? process_one_work+0x38d/0x38d
      [  848.667493]  [<ffffffff8105b098>] kthread+0x9d/0xa5
      [  848.673382]  [<ffffffff8106e1bd>] ? trace_hardirqs_on_caller+0x12f/0x166
      [  848.681304]  [<ffffffff814b7704>] kernel_thread_helper+0x4/0x10
      [  848.688324]  [<ffffffff814af534>] ? retint_restore_args+0x13/0x13
      [  848.695530]  [<ffffffff8105affb>] ? __init_kthread_worker+0x5b/0x5b
      [  848.702929]  [<ffffffff814b7700>] ? gs_change+0x13/0x13
      [  848.709155] Code: 00 00 48 8d 88 38 04 00 00 44 8b 80 84 02 00 00 31 c0 e8 cf 1b 24 00 41 83 c8 ff 44 8b 4b 08 48 c7 c1 e0 0b 7d 81 4d 85 e4 74 10 <45> 8b 84 24 84 02 00 00 49 8d 8c 24 38 04 00 00 8b 53 04 48 89
      [  848.732467] RIP  [<ffffffff8126a68c>] spin_dump+0x5e/0x8c
      [  848.738905]  RSP <ffff8807f868dca0>
      [  848.743743] ---[ end trace 143161646eee8caa ]---
      ...so arrange for the ata_port to have the same end of life as the domain
      Reported-by: default avatarMarcin Tomczak <marcin.tomczak@intel.com>
      Acked-by: default avatarJeff Garzik <jgarzik@redhat.com>
      Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
      Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
    • Dan Williams's avatar
      [SCSI] libsas: mark all domain devices gone if root port disappears · 7d05919a
      Dan Williams authored
      If the top level expander is hot removed, mark all child devices as gone
      before unregistration to short circuit futile recovery.
      Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
      Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
    • Dan Williams's avatar
      [SCSI] libsas: pre-clean commands that won the eh vs completion race · 45c73b65
      Dan Williams authored
      When scrolling forward through the eh list (in a clear_q scenario) it is
      possible to encounter commands that won the completion vs eh race.  Rather
      than sprinkle more "if (!task)" throughout the handler just make a pass
      through the list and delete the race winners before handling the rest.
      Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
      Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
    • Dan Williams's avatar
      [SCSI] isci: remove IDEV_EH hack to disable "discovery-time" ata resets · 5a998328
      Dan Williams authored
      Prior to commit 61aaff49 "isci: filter broadcast change notifications
      during SMP phy resets" we borrowed the MVS_DEV_EH approach from the
      mvsas driver for preventing ->lldd_I_T_nexus_reset() events during ata
      discovery.  This hack was protecting against the old ->phy_reset() in
      ata_bus_probe(), but since the conversion to the new error handling this
      hack is preventing resets from reaching ata devices.
      Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
      Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
    • Dan Williams's avatar
      [SCSI] isci: remove bus and reset handlers · 6a719391
      Dan Williams authored
      Remove ->eh_device_reset_handler() and ->eh_bus_reset_handler() for the
      same reason they are not implemented for libata hosts, they cannot be
      implemented reliably with ata-eh.  ATA error recovery wants to divert
      all resets to the eh thread and wait for completion, these handlers may
      be invoked from a non-blocking ioctl.
      The other path they are called from is libsas-eh, and if we escalate
      past I_T_nexus reset we have larger problems i.e. tear down all
      in-flight commands in the domain potentially without notification to the
      lldd if it has chosen not to implement ->lldd_clear_nexus_port() /
      Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
      Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
    • Dan Williams's avatar
      [SCSI] isci: ->lldd_ata_check_ready handler · 687833a0
      Dan Williams authored
      Report to libata whether the link to the given domain_device is up and the
      signature fis has been received.
      Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
      Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
    • Dan Williams's avatar
      [SCSI] isci: stop interpreting ->lldd_lu_reset() as an ata soft-reset · 43a5ab15
      Dan Williams authored
      Driving resets from libsas-eh is pre-mature as libata will make a
      decision about performing a softreset.  Currently libata determines
      whether to perform a softreset based on ata_eh_followup_srst_needed(),
      and none of those conditions apply to isci.
      Remove the srst implementation and translate ->lldd_lu_reset() for ata
      devices as a request to drive a reset via libata-eh.
      Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
      Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
    • Dan Williams's avatar
      [SCSI] isci: fix interpretation of "hard" reset · 92776991
      Dan Williams authored
      A hard reset to isci in the direct-attached case is one where the driver
      internally manages debouncing the link.  In the sas-expander-attached
      case a hard reset is one that clears affiliations.  The driver should
      not be prematurely dropping affiliations at run time, that decision (to
      force expander hard resets to ata devices) is left to userspace to
      manage.  So, arrange for I_T_nexus resets to be sas-link-resets in the
      expander-attached case and isci-hard-resets in the direct-attached case.
      Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
      Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
    • Dan Williams's avatar
      [SCSI] isci: kill isci_port->status · fca4ecbd
      Dan Williams authored
      It only tracks whether the port is stopping in order to gate new devices
      being discovered while the port is stopping.  However, since the check
      and subsequent handling is unlocked there is nothing to stop the port
      from going down immediately after the check.
      Driver is already prepared to handle devices arriving on stale ports,
      and those will be cleaned up by an eventual ->lldd_dev_gone()
      Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
      Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
    • Dan Williams's avatar
      [SCSI] isci: kill iphy->isci_port lookups · c132f692
      Dan Williams authored
      This field is a holdover from the OS abstraction conversion.  The stable
      phy to port lookups are done via iphy->ownining_port under scic_lock.
      After this conversion to use port->lldd_port the only volatile lookup is
      the initial lookup in isci_port_formed().  After that point any lookup
      via a successfully notified domain_device is guaranteed to be valid
      until the domain_device is destroyed.
      Delete ->start_complete as it is only set once and is set as a
      consequence of the port going link up, by definition of getting a port
      formed event the port is "ready".
      While we are correcting port lookups also move the asd_sas_port table
      out from under the isci_port.  This is to preclude any temptation to use
      container_of() to convert an asd_sas_port to an isci_port, the
      association is dynamic and under libsas control.
      Tested-by: default avatarMaciej Trela <maciej.trela@intel.com>
      [dmilburn@redhat.com: fix i686 compile error]
      Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
      Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
    • Dan Williams's avatar
      [SCSI] libsas: don't recover 'gone' devices in sas_ata_hard_reset() · cb48d672
      Dan Williams authored
      The commands that timeout when a disk is forcibly removed may trigger
      libata to attempt recovery of the device.  If libsas has decided to
      remove the device don't permit ata to continue to issue resets to its
      last known phy.
      The primary motivation for this patch is hotplug testing by writing 0 to
      /sys/class/sas_phy/phyX/enable.  Without this check this test leads to
      libata issuing a reset and re-enabling the device that wants to be torn
      Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
      Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
    • Dan Williams's avatar
      [SCSI] libsas: fix sas_find_local_phy(), take phy references · f41a0c44
      Dan Williams authored
      In the direct-attached case this routine returns the phy on which this
      device was first discovered.  Which is broken if we want to support
      wide-targets, as this phy reference can become stale even though the
      port is still active.
      In the expander-attached case this routine tries to lookup the phy by
      scanning the attached sas addresses of the parent expander, and BUG_ONs
      if it can't find it.  However since eh and the libsas workqueue run
      independently we can still be attempting device recovery via eh after
      libsas has recorded the device as detached.  This is even easier to hit
      now that eh is blocked while device domain rediscovery takes place, and
      that libata is fed more timed out commands increasing the chances that
      it will try to recover the ata device.
      Arrange for dev->phy to always point to a last known good phy, it may be
      stale after the port is torn down, but it will catch up for wide port
      reconfigurations, and never be NULL.
      Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
      Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
    • Dan Williams's avatar
      [SCSI] libsas: check for 'gone' expanders in smp_execute_task() · 3a9c5560
      Dan Williams authored
      No sense in issuing or retrying commands to an expander that has been
      Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
      Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
    • Dan Williams's avatar
      [SCSI] libsas: don't mark expanders as gone when a child device is removed · 0508c2f3
      Dan Williams authored
      Commit 56dd2c06 "[SCSI] libsas: Don't issue commands to devices that
      have been hot-removed" marked the parent device of an end-device as gone
      when all the phys to the end device have been deleted.
      The expander device is still present until its parent is removed.  This
      is a benign change until the smp_execute_task() path is taught to check
      Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
      Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
    • Dan Williams's avatar
      [SCSI] libsas: poll for ata device readiness after reset · 36a39947
      Dan Williams authored
      Use ata_wait_after_reset() to poll for link recovery after a reset.
      This combined with sas_ha->eh_mutex prevents expander rediscovery from
      probing phys in an intermediate state.  Local discovery does not have a
      mechanism to filter link status changes during this timeout, so it
      remains the responsibility of lldds to prevent premature port teardown.
      Although once all lldd's support ->lldd_ata_check_ready() that could be
      used as a gate to local port teardown.
      The signature fis is re-transmitted when the link comes back so we
      should be revalidating the ata device class, but that is left to a future
      Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
      Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
  2. 19 Feb, 2012 25 commits