Patchwork [libata,1/1] libata: thaw port after maximum reset retries

login
register
mail settings
Submitter Chaitanya Lala
Date Sept. 11, 2009, 3:27 p.m.
Message ID <20090911152703.GA5222@clala-laptop>
Download mbox | patch
Permalink /patch/33469/
State Not Applicable
Delegated to: David Miller
Headers show

Comments

Chaitanya Lala - Sept. 11, 2009, 3:27 p.m.
The libata error recovery tries to reset a port a number
of times and if unsuccessful, gives up. The code does not
thaw the port before it exits. If the bad disk i.e. the disk
that could not be reset is removed and a healthy disk is
inserted, the new disk does not register, since the port is
frozen. This patch fixes the same.

Signed-off-by: Chaitanya Lala <clala@riverbed.com>
---
 drivers/ata/libata-eh.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)
Tejun Heo - Nov. 9, 2009, 8:17 a.m.
Chaitanya Lala wrote:
> The libata error recovery tries to reset a port a number
> of times and if unsuccessful, gives up. The code does not
> thaw the port before it exits. If the bad disk i.e. the disk
> that could not be reset is removed and a healthy disk is
> inserted, the new disk does not register, since the port is
> frozen. This patch fixes the same.

Sorry about the long delay but has this actually happen?  The
rationale for not thawing there was that if the port was behaving
erratically, it could cause IRQ storm and thus take the whole
controller down and the port can be revived by issuing rescan if the
administrator intends to do so.

Thanks.

Patch

diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 79711b6..724f86f 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -2637,8 +2637,12 @@  int ata_eh_reset(struct ata_link *link, int classify,
 	    sata_scr_read(link, SCR_STATUS, &sstatus))
 		rc = -ERESTART;
 
-	if (rc == -ERESTART || try >= max_tries)
+	if (rc == -ERESTART || try >= max_tries) {
+		/* thaw the port */
+		if (ata_is_host_link(link))
+			ata_eh_thaw_port(ap);
 		goto out;
+	}
 
 	now = jiffies;
 	if (time_before(now, deadline)) {