All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH #upstream-fixes] libata: fix unexpectedly frozen port after ata_eh_reset()
@ 2011-05-25 10:02 Tejun Heo
  2011-05-25 10:33 ` Dave Howorth
  2011-05-25 11:19 ` [PATCH UPDATED " Tejun Heo
  0 siblings, 2 replies; 3+ messages in thread
From: Tejun Heo @ 2011-05-25 10:02 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linux-ide, Bruce Stenning

To work around controllers which can't properly plug events while
reset, ata_eh_reset() clears error states and ATA_PFLAG_EH_PENDING
after reset but before RESET is marked done.  As reset is the final
recovery action and full verification of devices including onlineness
and classfication match is done afterwards, this shouldn't lead to
lost devices or missed hotplug events.

Unfortunately, it forgot to thaw the port when clearing EH_PENDING, so
if the condition happens after resetting an empty port, the port could
be left frozen and EH will end without thawing it, making the port
unresponsive to further hotplug events.

Thaw if the port is frozen after clearing EH_PENDING.  This problem is
reported by Bruce Stenning in the following thread.

  http://thread.gmane.org/gmane.linux.kernel/1123265

stable: I think we should weather this patch a bit longer in -rcX
        before sending it to -stable.  Please wait at least a month
        after this patch makes upstream.  Thanks.

Signed-off-by: Tejun Heo <tj@kernel.org>
Reported-by: Bruce Stenning <b.stenning@indigovision.com>
Cc: stable@kernel.org
---
 drivers/ata/libata-eh.c |   12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index dfb6e9d..094ce48 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -2802,10 +2802,11 @@ int ata_eh_reset(struct ata_link *link, int classify,
 	}
 
 	/*
-	 * Some controllers can't be frozen very well and may set
-	 * spuruious error conditions during reset.  Clear accumulated
-	 * error information.  As reset is the final recovery action,
-	 * nothing is lost by doing this.
+	 * Some controllers can't be frozen very well and may set spuruious
+	 * error conditions during reset.  Clear accumulated error
+	 * information and re-thaw the port if frozen.  As reset is the
+	 * final recovery action and we cross check link onlineness against
+	 * device classification later, no hotplug event is lost by this.
 	 */
 	spin_lock_irqsave(link->ap->lock, flags);
 	memset(&link->eh_info, 0, sizeof(link->eh_info));
@@ -2814,6 +2815,9 @@ int ata_eh_reset(struct ata_link *link, int classify,
 	ap->pflags &= ~ATA_PFLAG_EH_PENDING;
 	spin_unlock_irqrestore(link->ap->lock, flags);
 
+	if (ap->pflags & ATA_PFLAG_FROZEN)
+		ata_eh_thaw_port(ap);
+
 	/*
 	 * Make sure onlineness and classification result correspond.
 	 * Hotplug could have happened during reset and some

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH #upstream-fixes] libata: fix unexpectedly frozen port after ata_eh_reset()
  2011-05-25 10:02 [PATCH #upstream-fixes] libata: fix unexpectedly frozen port after ata_eh_reset() Tejun Heo
@ 2011-05-25 10:33 ` Dave Howorth
  2011-05-25 11:19 ` [PATCH UPDATED " Tejun Heo
  1 sibling, 0 replies; 3+ messages in thread
From: Dave Howorth @ 2011-05-25 10:33 UTC (permalink / raw)
  To: Tejun Heo; +Cc: Jeff Garzik, linux-ide, Bruce Stenning

Tejun Heo wrote:

> -	 * Some controllers can't be frozen very well and may set
> -	 * spuruious error conditions during reset.  Clear accumulated
> -	 * error information.  As reset is the final recovery action,
> -	 * nothing is lost by doing this.
> +	 * Some controllers can't be frozen very well and may set spuruious
> +	 * error conditions during reset.  Clear accumulated error
> +	 * information and re-thaw the port if frozen.  As reset is the
> +	 * final recovery action and we cross check link onlineness against
> +	 * device classification later, no hotplug event is lost by this.

spuruious -> spurious

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH UPDATED #upstream-fixes] libata: fix unexpectedly frozen port after ata_eh_reset()
  2011-05-25 10:02 [PATCH #upstream-fixes] libata: fix unexpectedly frozen port after ata_eh_reset() Tejun Heo
  2011-05-25 10:33 ` Dave Howorth
@ 2011-05-25 11:19 ` Tejun Heo
  1 sibling, 0 replies; 3+ messages in thread
From: Tejun Heo @ 2011-05-25 11:19 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linux-ide, Bruce Stenning, Dave Howorth

To work around controllers which can't properly plug events while
reset, ata_eh_reset() clears error states and ATA_PFLAG_EH_PENDING
after reset but before RESET is marked done.  As reset is the final
recovery action and full verification of devices including onlineness
and classfication match is done afterwards, this shouldn't lead to
lost devices or missed hotplug events.

Unfortunately, it forgot to thaw the port when clearing EH_PENDING, so
if the condition happens after resetting an empty port, the port could
be left frozen and EH will end without thawing it, making the port
unresponsive to further hotplug events.

Thaw if the port is frozen after clearing EH_PENDING.  This problem is
reported by Bruce Stenning in the following thread.

 http://thread.gmane.org/gmane.linux.kernel/1123265

stable: I think we should weather this patch a bit longer in -rcX
	before sending it to -stable.  Please wait at least a month
	after this patch makes upstream.  Thanks.

-v2: Fixed spelling in the comment per Dave Howorth.

Signed-off-by: Tejun Heo <tj@kernel.org>
Reported-by: Bruce Stenning <b.stenning@indigovision.com>
Cc: stable@kernel.org
Cc: Dave Howorth <dhoworth@mrc-lmb.cam.ac.uk>
---
 drivers/ata/libata-eh.c |   12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index dfb6e9d..7f099d6 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -2802,10 +2802,11 @@ int ata_eh_reset(struct ata_link *link, int classify,
 	}
 
 	/*
-	 * Some controllers can't be frozen very well and may set
-	 * spuruious error conditions during reset.  Clear accumulated
-	 * error information.  As reset is the final recovery action,
-	 * nothing is lost by doing this.
+	 * Some controllers can't be frozen very well and may set spurious
+	 * error conditions during reset.  Clear accumulated error
+	 * information and re-thaw the port if frozen.  As reset is the
+	 * final recovery action and we cross check link onlineness against
+	 * device classification later, no hotplug event is lost by this.
 	 */
 	spin_lock_irqsave(link->ap->lock, flags);
 	memset(&link->eh_info, 0, sizeof(link->eh_info));
@@ -2814,6 +2815,9 @@ int ata_eh_reset(struct ata_link *link, int classify,
 	ap->pflags &= ~ATA_PFLAG_EH_PENDING;
 	spin_unlock_irqrestore(link->ap->lock, flags);
 
+	if (ap->pflags & ATA_PFLAG_FROZEN)
+		ata_eh_thaw_port(ap);
+
 	/*
 	 * Make sure onlineness and classification result correspond.
 	 * Hotplug could have happened during reset and some

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2011-05-25 11:19 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-25 10:02 [PATCH #upstream-fixes] libata: fix unexpectedly frozen port after ata_eh_reset() Tejun Heo
2011-05-25 10:33 ` Dave Howorth
2011-05-25 11:19 ` [PATCH UPDATED " Tejun Heo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.