alistair23-linux/drivers/ata
Tejun Heo c0c362b60e libata: implement cross-port EH exclusion
In libata, the non-EH code paths should always take and release
ap->lock explicitly when accessing hardware or shared data structures.
However, once EH is active, it's assumed that the port is owned by EH
and EH methods don't explicitly take ap->lock unless race from irq
handler or other code paths are expected.  However, libata EH didn't
guarantee exclusion among EHs for ports of the same host.  IOW,
multiple EHs may execute in parallel on multiple ports of the same
controller.

In many cases, especially in SATA, the ports are completely
independent of each other and this doesn't cause problems; however,
there are cases where different ports share the same resource, which
lead to obscure timing related bugs such as the one fixed by commit
213373cf (ata_piix: fix locking around SIDPR access).

This patch implements exclusion among EHs of the same host.  When EH
begins, it acquires per-host EH ownership by calling ata_eh_acquire().
When EH finishes, the ownership is released by calling
ata_eh_release().  EH ownership is also released whenever the EH
thread goes to sleep from ata_msleep() or explicitly and reacquired
after waking up.

This ensures that while EH is actively accessing the hardware, it has
exclusive access to it while allowing EHs to interleave and progress
in parallel as they hit waiting stages, which dominate the time spent
in EH.  This achieves cross-port EH exclusion without pervasive and
fragile changes while still allowing parallel EH for the most part.

This was first reported by yuanding02@gmail.com more than three years
ago in the following bugzilla.  :-)

  https://bugzilla.kernel.org/show_bug.cgi?id=8223

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Reported-by: yuanding02@gmail.com
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
2010-10-21 20:21:05 -04:00
..
ahci.c libata: reimplement link power management 2010-10-21 20:21:04 -04:00
ahci.h libata: reimplement link power management 2010-10-21 20:21:04 -04:00
ahci_platform.c libata: reimplement link power management 2010-10-21 20:21:04 -04:00
ata_generic.c ata_generic: drop hard coded DMA force logic for CENATEK 2010-08-01 19:36:04 -04:00
ata_piix.c ata_piix: implement LPM support 2010-10-21 20:21:04 -04:00
Kconfig libata: remove no longer needed pata_winbond driver 2010-08-25 19:24:15 -04:00
libahci.c libata: add @ap to ata_wait_register() and introduce ata_msleep() 2010-10-21 20:21:05 -04:00
libata-acpi.c gcc-4.6: ACPI: fix unused but set variables in ACPI 2010-08-15 00:53:08 -04:00
libata-core.c libata: implement cross-port EH exclusion 2010-10-21 20:21:05 -04:00
libata-eh.c libata: implement cross-port EH exclusion 2010-10-21 20:21:05 -04:00
libata-pmp.c libata: implement LPM support for port multipliers 2010-10-21 20:21:04 -04:00
libata-scsi.c libata: reimplement link power management 2010-10-21 20:21:04 -04:00
libata-sff.c libata: add @ap to ata_wait_register() and introduce ata_msleep() 2010-10-21 20:21:05 -04:00
libata-transport.c drivers/ata/libata-transport.c: include linux/slab.h 2010-10-21 20:21:04 -04:00
libata-transport.h [libata] Add ATA transport class 2010-10-21 20:21:03 -04:00
libata.h libata: implement cross-port EH exclusion 2010-10-21 20:21:05 -04:00
Makefile [libata] Add ATA transport class 2010-10-21 20:21:03 -04:00
pata_acpi.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_ali.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_amd.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_artop.c pata_artop: Fix device ID parity check 2010-09-09 14:19:18 -04:00
pata_at32.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
pata_at91.c libata-sff: clean up BMDMA initialization 2010-05-19 13:32:19 -04:00
pata_atiixp.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_atp867x.c libata-sff: separate out BMDMA irq handler 2010-05-25 19:40:24 -04:00
pata_bf54x.c libata: add @ap to ata_wait_register() and introduce ata_msleep() 2010-10-21 20:21:05 -04:00
pata_cmd64x.c pata_cmd64x: revert commit d62f5576 2010-08-25 19:24:15 -04:00
pata_cmd640.c libata-sff: clean up BMDMA initialization 2010-05-19 13:32:19 -04:00
pata_cs5520.c libata-sff: separate out BMDMA irq handler 2010-05-25 19:40:24 -04:00
pata_cs5530.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_cs5535.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_cs5536.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_cypress.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_efar.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_hpt3x2n.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_hpt3x3.c libata-sff: separate out BMDMA irq handler 2010-05-25 19:40:24 -04:00
pata_hpt37x.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_hpt366.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_icside.c libata-sff: separate out BMDMA irq handler 2010-05-25 19:40:24 -04:00
pata_isapnp.c [libata] Improve timeout handling 2009-03-24 22:52:39 -04:00
pata_it821x.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_it8213.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_ixp4xx_cf.c dma-mapping: replace all DMA_32BIT_MASK macro with DMA_BIT_MASK(32) 2009-04-07 08:31:11 -07:00
pata_jmicron.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_legacy.c libata: remove no longer needed pata_winbond driver 2010-08-25 19:24:15 -04:00
pata_macio.c powerpc/macio: Fix probing of macio devices by using the right of match table 2010-06-02 17:50:38 +10:00
pata_marvell.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_mpc52xx.c of/device: Replace struct of_device with struct platform_device 2010-08-06 09:25:50 -06:00
pata_mpiix.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_netcell.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_ninja32.c libata-sff: separate out BMDMA irq handler 2010-05-25 19:40:24 -04:00
pata_ns87410.c libata: Pass host flags into the pci helper 2010-03-01 14:58:46 -05:00
pata_ns87415.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_octeon_cf.c libata-sff: kill dummy BMDMA ops from sata_qstor and pata_octeon_cf 2010-05-25 19:40:45 -04:00
pata_of_platform.c of/device: Replace struct of_device with struct platform_device 2010-08-06 09:25:50 -06:00
pata_oldpiix.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_opti.c libata: Pass host flags into the pci helper 2010-03-01 14:58:46 -05:00
pata_optidma.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_palmld.c [ARM] 5522/1: PalmLD: IDE support 2009-05-31 14:50:40 +01:00
pata_pcmcia.c pcmcia: do not use io_req_t when calling pcmcia_request_io() 2010-08-03 09:04:11 +02:00
pata_pdc202xx_old.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_pdc2027x.c libata-sff: separate out BMDMA irq handler 2010-05-25 19:40:24 -04:00
pata_piccolo.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_platform.c libata-sff: clean up BMDMA initialization 2010-05-19 13:32:19 -04:00
pata_pxa.c [ARM] pata_pxa: DMA-capable PATA driver 2010-06-18 15:07:32 +08:00
pata_qdi.c [libata] convert drivers to use ata.h mode mask defines 2009-03-24 22:13:27 -04:00
pata_radisys.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_rb532_cf.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
pata_rdc.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_rz1000.c libata: Pass host flags into the pci helper 2010-03-01 14:58:46 -05:00
pata_samsung_cf.c libata: add @ap to ata_wait_register() and introduce ata_msleep() 2010-10-21 20:21:05 -04:00
pata_sc1200.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_scc.c libata: add @ap to ata_wait_register() and introduce ata_msleep() 2010-10-21 20:21:05 -04:00
pata_sch.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_serverworks.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_sil680.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_sis.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_sl82c105.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_triflex.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
pata_via.c libata,pata_via: revert ata_wait_idle() removal from ata_sff/via_tf_load() 2010-09-09 22:27:44 -04:00
pdc_adma.c libata-sff: ata_sff_[dumb_]qc_prep are BMDMA specific 2010-05-19 13:36:50 -04:00
sata_dwc_460ex.c [libata] sata_dwc_460ex: signdness bug 2010-08-25 19:24:16 -04:00
sata_fsl.c libata: add @ap to ata_wait_register() and introduce ata_msleep() 2010-10-21 20:21:05 -04:00
sata_inic162x.c libata: add @ap to ata_wait_register() and introduce ata_msleep() 2010-10-21 20:21:05 -04:00
sata_mv.c libata: always use ata_qc_complete_multiple() for NCQ command completions 2010-10-21 20:21:03 -04:00
sata_nv.c libata: always use ata_qc_complete_multiple() for NCQ command completions 2010-10-21 20:21:03 -04:00
sata_promise.c libata-sff: prd is BMDMA specific 2010-05-19 13:38:54 -04:00
sata_promise.h
sata_qstor.c libata-sff: kill dummy BMDMA ops from sata_qstor and pata_octeon_cf 2010-05-25 19:40:45 -04:00
sata_sil.c libata-sff: ata_sff_irq_clear() is BMDMA specific 2010-05-25 19:40:19 -04:00
sata_sil24.c libata: add @ap to ata_wait_register() and introduce ata_msleep() 2010-10-21 20:21:05 -04:00
sata_sis.c libata-sff: separate out BMDMA init 2010-05-25 19:40:30 -04:00
sata_svw.c libata-sff: separate out BMDMA irq handler 2010-05-25 19:40:24 -04:00
sata_sx4.c libata-sff: separate out BMDMA EH 2010-05-19 13:36:46 -04:00
sata_uli.c libata-sff: separate out BMDMA irq handler 2010-05-25 19:40:24 -04:00
sata_via.c libata: add @ap to ata_wait_register() and introduce ata_msleep() 2010-10-21 20:21:05 -04:00
sata_vsc.c libata-sff: separate out BMDMA irq handler 2010-05-25 19:40:24 -04:00
sis.h