Patchwork [#upstream-fixes] libata: no special completion processing for EH commands

login
register
mail settings
Submitter Tejun Heo
Date Dec. 9, 2010, 2:59 p.m.
Message ID <4D00EED4.3020901@kernel.org>
Download mbox | patch
Permalink /patch/74905/
State Not Applicable
Delegated to: David Miller
Headers show

Comments

Tejun Heo - Dec. 9, 2010, 2:59 p.m.
ata_qc_complete() contains special handling for certain commands.  For
example, it schedules EH for device revalidation after certain
configurations are changed.  These shouldn't be applied to EH
commands but they were.

In most cases, it doesn't cause an actual problem because EH doesn't
issue any command which would trigger special handling; however, ACPI
can issue such commands via _GTF which can cause weird interactions.

Restructure ata_qc_complete() such that EH commands are always passed
on to __ata_qc_complete().

stable: Please apply to -stable only after 2.6.38 is released.

Signed-off-by: Tejun Heo <tj@kernel.org>
Reported-by: Kyle McMartin <kyle@mcmartin.ca>
Cc: stable@kernel.org
---
 drivers/ata/libata-core.c |   24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

--
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jeff Garzik - Dec. 24, 2010, 6:39 p.m.
On 12/09/2010 09:59 AM, Tejun Heo wrote:
> ata_qc_complete() contains special handling for certain commands.  For
> example, it schedules EH for device revalidation after certain
> configurations are changed.  These shouldn't be applied to EH
> commands but they were.
>
> In most cases, it doesn't cause an actual problem because EH doesn't
> issue any command which would trigger special handling; however, ACPI
> can issue such commands via _GTF which can cause weird interactions.
>
> Restructure ata_qc_complete() such that EH commands are always passed
> on to __ata_qc_complete().
>
> stable: Please apply to -stable only after 2.6.38 is released.
>
> Signed-off-by: Tejun Heo<tj@kernel.org>
> Reported-by: Kyle McMartin<kyle@mcmartin.ca>
> Cc: stable@kernel.org
> ---
>   drivers/ata/libata-core.c |   24 +++++++++++++++---------
>   1 file changed, 15 insertions(+), 9 deletions(-)

applied


--
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 7f77c67..f23d6d4 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4807,9 +4807,6 @@  static void ata_verify_xfer(struct ata_queued_cmd *qc)
 {
 	struct ata_device *dev = qc->dev;

-	if (ata_tag_internal(qc->tag))
-		return;
-
 	if (ata_is_nodata(qc->tf.protocol))
 		return;

@@ -4858,14 +4855,23 @@  void ata_qc_complete(struct ata_queued_cmd *qc)
 		if (unlikely(qc->err_mask))
 			qc->flags |= ATA_QCFLAG_FAILED;

-		if (unlikely(qc->flags & ATA_QCFLAG_FAILED)) {
-			/* always fill result TF for failed qc */
+		/*
+		 * Finish internal commands without any further processing
+		 * and always with the result TF filled.
+		 */
+		if (unlikely(ata_tag_internal(qc->tag))) {
 			fill_result_tf(qc);
+			__ata_qc_complete(qc);
+			return;
+		}

-			if (!ata_tag_internal(qc->tag))
-				ata_qc_schedule_eh(qc);
-			else
-				__ata_qc_complete(qc);
+		/*
+		 * Non-internal qc has failed.  Fill the result TF and
+		 * summon EH.
+		 */
+		if (unlikely(qc->flags & ATA_QCFLAG_FAILED)) {
+			fill_result_tf(qc);
+			ata_qc_schedule_eh(qc);
 			return;
 		}