mirror-linux/drivers/ata
Niklas Cassel d5ae9d9f0c ata: libata-eh: do not clear ATA_PFLAG_EH_PENDING in ata_eh_reset()
[ Upstream commit 80cc944eca ]

ata_scsi_port_error_handler() starts off by clearing ATA_PFLAG_EH_PENDING,
before calling ap->ops->error_handler() (without holding the ap->lock).

If an error IRQ is received while ap->ops->error_handler() is running,
the irq handler will set ATA_PFLAG_EH_PENDING.

Once ap->ops->error_handler() returns, ata_scsi_port_error_handler()
checks if ATA_PFLAG_EH_PENDING is set, and if it is, another iteration
of ATA EH is performed.

The problem is that ATA_PFLAG_EH_PENDING is not only cleared by
ata_scsi_port_error_handler(), it is also cleared by ata_eh_reset().

ata_eh_reset() is called by ap->ops->error_handler(). This additional
clearing done by ata_eh_reset() breaks the whole retry logic in
ata_scsi_port_error_handler(). Thus, if an error IRQ is received while
ap->ops->error_handler() is running, the port will currently remain
frozen and will never get re-enabled.

The additional clearing in ata_eh_reset() was introduced in commit
1e641060c4 ("libata: clear eh_info on reset completion").

Looking at the original error report:
https://marc.info/?l=linux-ide&m=124765325828495&w=2

We can see the following happening:
[    1.074659] ata3: XXX port freeze
[    1.074700] ata3: XXX hardresetting link, stopping engine
[    1.074746] ata3: XXX flipping SControl

[    1.411471] ata3: XXX irq_stat=400040 CONN|PHY
[    1.411475] ata3: XXX port freeze

[    1.420049] ata3: XXX starting engine
[    1.420096] ata3: XXX rc=0, class=1
[    1.420142] ata3: XXX clearing IRQs for thawing
[    1.420188] ata3: XXX port thawed
[    1.420234] ata3: SATA link up 3.0 Gbps (SStatus 123 SControl 300)

We are not supposed to be able to receive an error IRQ while the port is
frozen (PxIE is set to 0, i.e. all IRQs for the port are disabled).

AHCI 1.3.1 section 10.7.1.1 First Tier (IS Register) states:
"Each bit location can be thought of as reporting a '1' if the virtual
"interrupt line" for that port is indicating it wishes to generate an
interrupt. That is, if a port has one or more interrupt status bit set,
and the enables for those status bits are set, then this bit shall be set."

Additionally, AHCI state P:ComInit clearly shows that the state machine
will only jump to P:ComInitSetIS (which sets IS.IPS(x) to '1'), if PxIE.PCE
is set to '1'. In our case, PxIE is set to 0, so IS.IPS(x) won't get set.

So IS.IPS(x) only gets set if PxIS and PxIE is set.

AHCI 1.3.1 section 10.7.1.1 First Tier (IS Register) also states:
"The bits in this register are read/write clear. It is set by the level of
the virtual interrupt line being a set, and cleared by a write of '1' from
the software."

So if IS.IPS(x) is set, you need to explicitly clear it by writing a 1 to
IS.IPS(x) for that port.

Since PxIE is cleared, the only way to get an interrupt while the port is
frozen, is if IS.IPS(x) is set, and the only way IS.IPS(x) can be set when
the port is frozen, is if it was set before the port was frozen.

However, since commit 737dd811a3 ("ata: libahci: clear pending interrupt
status"), we clear both PxIS and IS.IPS(x) after freezing the port, but
before the COMRESET, so the problem that commit 1e641060c4 ("libata:
clear eh_info on reset completion") fixed can no longer happen.

Thus, revert commit 1e641060c4 ("libata: clear eh_info on reset
completion"), so that the retry logic in ata_scsi_port_error_handler()
works once again. (The retry logic is still needed, since we can still
get an error IRQ _after_ the port has been thawed, but before
ata_scsi_port_error_handler() takes the ap->lock in order to check
if ATA_PFLAG_EH_PENDING is set.)

Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2023-10-06 14:56:54 +02:00
..
Kconfig ata: pata_cs5535: Don't build on UML 2023-02-01 08:34:34 +01:00
Makefile ata: ahci: Add DWC AHCI SATA controller support 2022-09-17 01:40:15 +09:00
acard-ahci.c ata: add/use ata_taskfile::{error|status} fields 2022-02-20 09:06:05 +09:00
ahci.c ata: libata: disallow dev-initiated LPM transitions to unsupported states 2023-09-23 11:11:12 +02:00
ahci.h ata: ahci: fix enum constants for gcc-13 2023-01-07 11:11:46 +01:00
ahci_brcm.c ata: ahci_brcm: Fix compilation warning 2022-10-18 08:01:57 +09:00
ahci_ceva.c ata: Drop commas after OF match table sentinels 2022-03-07 11:49:10 +09:00
ahci_da850.c ata: libahci_platform: Convert to using devm bulk clocks API 2022-09-17 01:39:22 +09:00
ahci_dm816.c ata: libahci_platform: Convert to using devm bulk clocks API 2022-09-17 01:39:22 +09:00
ahci_dwc.c ata: ahci-dwc: Add Baikal-T1 AHCI SATA interface support 2022-09-17 01:40:31 +09:00
ahci_imx.c ata: ahci_imx: Fix compilation warning 2022-10-18 08:02:14 +09:00
ahci_mtk.c ata: libahci_platform: Parse ports-implemented property in resources getter 2022-09-17 01:39:30 +09:00
ahci_mvebu.c Char/Misc and other driver updates for 5.18-rc1 2022-03-28 12:27:35 -07:00
ahci_octeon.c ata: Drop commas after OF match table sentinels 2022-03-07 11:49:10 +09:00
ahci_platform.c ata: ahci: Add DWC AHCI SATA controller support 2022-09-17 01:40:15 +09:00
ahci_qoriq.c ata: ahci_qoriq: Fix compilation warning 2022-10-18 08:02:14 +09:00
ahci_seattle.c
ahci_st.c ata: ahci_st: Fix compilation warning 2022-10-17 22:01:57 +09:00
ahci_sunxi.c ata: Drop commas after OF match table sentinels 2022-03-07 11:49:10 +09:00
ahci_tegra.c ata: ahci_tegra: call tegra_powergate_power_off only when PM domain is not present 2021-04-11 20:35:08 -06:00
ahci_xgene.c ata: ahci_xgene: Fix compilation warning 2022-10-18 08:02:14 +09:00
ata_generic.c ata: ata_generic: Fix misspelling of 'ata_generic_init_one()' 2021-03-30 20:21:26 -06:00
ata_piix.c ata: libata: make ata_host_suspend() *void* 2022-02-19 11:18:35 +09:00
libahci.c ata: libahci: clear pending interrupt status 2023-09-23 11:11:12 +02:00
libahci_platform.c ata: libahci_platform: ahci_platform_find_clk: oops, NULL pointer 2022-12-07 08:36:37 +09:00
libata-acpi.c ata: make transfer mode masks *unsigned int* 2022-06-17 16:35:02 +09:00
libata-core.c ata: libata-scsi: Avoid deadlock on rescan after device resume 2023-06-28 11:12:17 +02:00
libata-eh.c ata: libata-eh: do not clear ATA_PFLAG_EH_PENDING in ata_eh_reset() 2023-10-06 14:56:54 +02:00
libata-pata-timings.c ata: separate PATA timings code from libata-core.c 2020-03-26 10:28:19 -06:00
libata-pmp.c ata: libata: add tracepoints for ATA error handling 2022-01-05 19:33:01 +09:00
libata-sata.c ata: libata: disallow dev-initiated LPM transitions to unsupported states 2023-09-23 11:11:12 +02:00
libata-scsi.c ata: libata-scsi: Avoid deadlock on rescan after device resume 2023-06-28 11:12:17 +02:00
libata-sff.c ata: libata-sff: Fix double word in comments 2022-09-16 23:24:06 +09:00
libata-trace.c ata: libata-sff: tracepoints for HSM state machine 2022-01-05 19:33:01 +09:00
libata-transport.c ata: libata-transport: fix error handling in ata_tdev_add() 2022-11-11 17:26:05 +09:00
libata-transport.h
libata-zpodd.c
libata.h ata: libata-core: Simplify ata_build_rw_tf() 2022-08-26 07:46:08 +09:00
pata_acpi.c ata: make transfer mode masks *unsigned int* 2022-06-17 16:35:02 +09:00
pata_ali.c ata: make transfer mode masks *unsigned int* 2022-06-17 16:35:02 +09:00
pata_amd.c ata: make transfer mode masks *unsigned int* 2022-06-17 16:35:02 +09:00
pata_arasan_cf.c ata: pata_arasan_cf: Use dev_err_probe() instead dev_err() in data_xfer() 2023-09-13 09:42:23 +02:00
pata_artop.c ata: pata_artop: use *switch* in atp8xx_fixup() 2022-02-19 11:18:42 +09:00
pata_atiixp.c ata: pata_atiixp: make static read-only arrays const 2022-01-31 09:58:32 +09:00
pata_atp867x.c ata: pata_atp867x: convert printk() calls 2022-01-05 19:33:02 +09:00
pata_bk3710.c
pata_buddha.c
pata_cmd64x.c ata: pata_cmd64x: convert printk() calls 2022-01-05 19:33:03 +09:00
pata_cmd640.c ata: pata_cmd640: convert printk() calls 2022-01-05 19:33:02 +09:00
pata_cs5520.c ata: libata: make ata_host_suspend() *void* 2022-02-19 11:18:35 +09:00
pata_cs5530.c ata: pata_cs5530: Avoid overwriting initialised field in 'cs5530_sht' 2021-06-16 06:50:25 -06:00
pata_cs5535.c ata: pata_cs5535: Fix W=1 warnings 2022-06-30 08:21:43 +09:00
pata_cs5536.c ata: pata_cs5536: convert printk() calls 2022-01-05 19:33:03 +09:00
pata_cypress.c ata: pata_cypress: convert printk() calls 2022-01-05 19:33:03 +09:00
pata_efar.c
pata_ep93xx.c ata: add/use ata_taskfile::{error|status} fields 2022-02-20 09:06:05 +09:00
pata_falcon.c ata: pata_falcon: fix IO base selection for Q40 2023-09-19 12:28:05 +02:00
pata_ftide010.c ata: pata_ftide010: Add missing MODULE_DESCRIPTION 2023-09-19 12:28:05 +02:00
pata_gayle.c
pata_hpt3x2n.c ata: make transfer mode masks *unsigned int* 2022-06-17 16:35:02 +09:00
pata_hpt3x3.c
pata_hpt37x.c ata: make transfer mode masks *unsigned int* 2022-06-17 16:35:02 +09:00
pata_hpt366.c ata: make transfer mode masks *unsigned int* 2022-06-17 16:35:02 +09:00
pata_icside.c ata: Avoid comma separated statements 2021-01-31 08:05:46 -07:00
pata_imx.c ata: libata: make ata_host_suspend() *void* 2022-02-19 11:18:35 +09:00
pata_isapnp.c
pata_it821x.c ata: fix read_id() ata port operation interface 2022-01-14 15:17:16 +09:00
pata_it8213.c
pata_ixp4xx_cf.c ata: Drop commas after OF match table sentinels 2022-03-07 11:49:10 +09:00
pata_jmicron.c ata: pata_jmicron: Fix incorrectly documented function parameter 2021-03-12 07:28:31 -07:00
pata_legacy.c ata: pata_legacy: fix pdc20230_set_piomode() 2022-10-31 20:27:27 +09:00
pata_macio.c ata: pata_macio: Remove unneeded word in comments 2022-09-16 23:24:06 +09:00
pata_marvell.c ata: pata_marvell: Check the 'bmdma_addr' beforing reading 2022-04-22 08:45:06 +09:00
pata_mpc52xx.c powerpc/mpc5xxx: Switch mpc5xxx_get_bus_frequency() to use fwnode 2022-06-22 12:51:49 +10:00
pata_mpiix.c
pata_netcell.c ata: fix read_id() ata port operation interface 2022-01-14 15:17:16 +09:00
pata_ninja32.c
pata_ns87410.c
pata_ns87415.c ata: pata_ns87415: mark ns87560_tf_read static 2023-08-03 10:24:07 +02:00
pata_octeon_cf.c ata: pata_octeon_cf: Fix refcount leak in octeon_cf_probe 2022-06-06 09:52:17 +09:00
pata_of_platform.c ata: Drop commas after OF match table sentinels 2022-03-07 11:49:10 +09:00
pata_oldpiix.c
pata_opti.c ata: pata_opti: Fix spelling issue of 'val' in 'opti_write_reg()' 2021-03-30 20:21:26 -06:00
pata_optidma.c pata_optidma: fix checking of DMA state 2021-10-12 17:46:59 +09:00
pata_palmld.c ata: palmld: fix return value check in palmld_pata_probe() 2022-10-31 20:28:05 +09:00
pata_pcmcia.c pata_pcmia: add SanDisk High (>8G) CF card to supported list 2020-01-29 20:54:51 -07:00
pata_pdc202xx_old.c ata: pata_pdc202xx_old: make static read-only array pio_timing const 2022-01-31 09:58:32 +09:00
pata_pdc2027x.c ata: make transfer mode masks *unsigned int* 2022-06-17 16:35:02 +09:00
pata_piccolo.c ata: pata_piccolo: 'ata_tosh_init()' is misnamed in its header 2021-03-30 20:21:25 -06:00
pata_platform.c ata: pata_platform: Make use of platform_get_mem_or_io() 2022-01-31 09:58:31 +09:00
pata_pxa.c ata: pata_pxa: Use platform_get_irq() to get the interrupt 2022-03-10 11:17:59 +09:00
pata_radisys.c pata_radisys: fix checking of DMA state 2021-10-12 17:47:02 +09:00
pata_rb532_cf.c ata: rb532_cf: remove redundant codes 2021-06-24 18:49:01 -06:00
pata_rdc.c
pata_rz1000.c ata: pata_rz1000: convert printk() calls 2022-01-05 19:33:03 +09:00
pata_samsung_cf.c ata: add/use ata_taskfile::{error|status} fields 2022-02-20 09:06:05 +09:00
pata_sc1200.c ata: pata_sc1200: sc1200_sht'Avoid overwriting initialised field in ' 2021-06-16 06:50:25 -06:00
pata_sch.c
pata_serverworks.c ata: make transfer mode masks *unsigned int* 2022-06-17 16:35:02 +09:00
pata_sil680.c ata: pata_sil680: fix result type of sil680_sel{dev|reg}() 2022-04-13 12:42:51 +09:00
pata_sis.c ata: make transfer mode masks *unsigned int* 2022-06-17 16:35:02 +09:00
pata_sl82c105.c ata: pata_sl82c105: Fix potential doc-rot 2021-03-30 20:21:25 -06:00
pata_triflex.c ata: libata: make ata_host_suspend() *void* 2022-02-19 11:18:35 +09:00
pata_via.c ata: make transfer mode masks *unsigned int* 2022-06-17 16:35:02 +09:00
pdc_adma.c ata: pdc_adma: Drop pointless VPRINTK() calls and remove disabled NCQ debugging 2022-01-05 19:33:01 +09:00
sata_dwc_460ex.c ata: sata_dwc_460ex: Fix crash due to OOB write 2022-04-04 09:56:34 +09:00
sata_fsl.c ata changes for 5.18-rc1 2022-03-23 14:35:59 -07:00
sata_gemini.c ata: sata_gemini: Add missing MODULE_DESCRIPTION 2023-09-19 12:28:05 +02:00
sata_gemini.h
sata_highbank.c ata: Drop commas after OF match table sentinels 2022-03-07 11:49:10 +09:00
sata_inic162x.c ata: add/use ata_taskfile::{error|status} fields 2022-02-20 09:06:05 +09:00
sata_mv.c ata: sata_mv: Fix incorrect string length computation in mv_dump_mem() 2023-10-06 14:56:53 +02:00
sata_nv.c ata: sata_nv: drop pointless VPRINTK() calls and convert remaining ones 2022-01-05 19:33:02 +09:00
sata_promise.c ata: sata_promise: Drop pointless VPRINTK() calls and convert the remaining ones 2022-01-05 19:33:01 +09:00
sata_promise.h
sata_qstor.c ata: sata_qstor: Drop pointless VPRINTK() calls 2022-01-05 19:33:02 +09:00
sata_rcar.c ata: sata_rcar: Fix compilation warning 2022-10-18 08:01:45 +09:00
sata_sil.c ata: sata_sil: Drop pointless VPRINTK() calls 2022-01-05 19:33:02 +09:00
sata_sil24.c ata: libata: add reset tracepoints 2022-01-04 20:00:57 +09:00
sata_sis.c
sata_svw.c ata: add/use ata_taskfile::{error|status} fields 2022-02-20 09:06:05 +09:00
sata_sx4.c ata: sata_sx4: convert printk() calls 2022-01-05 19:33:03 +09:00
sata_uli.c
sata_via.c
sata_vsc.c ata: add/use ata_taskfile::{error|status} fields 2022-02-20 09:06:05 +09:00
sis.h