diff mbox

[1/1] sata_mv: Prevent PIO commands to be defered too long if traffic in progress.

Message ID 1255387440-13313-2-git-send-email-gwendal@google.com
State Not Applicable
Delegated to: David Miller
Headers show

Commit Message

Gwendal Grignou Oct. 12, 2009, 10:44 p.m. UTC
Use excl_link when non NCQ commands are defered, to be sure they are processed
as soon as outstanding commands are completed. It prevents some commands to be
defered indifinitely when using a port multiplier.

Signed-off-by: Gwendal Grignou <gwendal@google.com>
---
 drivers/ata/sata_mv.c |   29 +++++++++++++++++++++++++++--
 1 files changed, 27 insertions(+), 2 deletions(-)

Comments

Grant Grundler Oct. 13, 2009, 1:44 a.m. UTC | #1
On Mon, Oct 12, 2009 at 3:44 PM, Gwendal Grignou <gwendal@google.com> wrote:
> Use excl_link when non NCQ commands are defered, to be sure they are processed
> as soon as outstanding commands are completed. It prevents some commands to be
> defered indifinitely when using a port multiplier.
>
> Signed-off-by: Gwendal Grignou <gwendal@google.com>

Reviewed-by: Grant Grundler <grundler@google.com>

thanks,
grant

> ---
>  drivers/ata/sata_mv.c |   29 +++++++++++++++++++++++++++--
>  1 files changed, 27 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
> index 17f9ff9..6f5093b 100644
> --- a/drivers/ata/sata_mv.c
> +++ b/drivers/ata/sata_mv.c
> @@ -1382,6 +1382,25 @@ static int mv_qc_defer(struct ata_queued_cmd *qc)
>         */
>        if (pp->pp_flags & MV_PP_FLAG_DELAYED_EH)
>                return ATA_DEFER_PORT;
> +
> +       /* PIO commands need exclusive link: no other commands [DMA or PIO]
> +        * can run concurrently.
> +        * set excl_link when we want to send a PIO command in DMA mode
> +        * or a non-NCQ command in NCQ mode.
> +        * When we receive a command from that link, and there are no
> +        * outstanding commands, mark a flag to clear excl_link and let
> +        * the command go through.
> +        */
> +       if (unlikely(ap->excl_link)) {
> +               if (link == ap->excl_link) {
> +                       if (ap->nr_active_links)
> +                               return ATA_DEFER_PORT;
> +                       qc->flags |= ATA_QCFLAG_CLEAR_EXCL;
> +                       return 0;
> +               } else
> +                       return ATA_DEFER_PORT;
> +       }
> +
>        /*
>         * If the port is completely idle, then allow the new qc.
>         */
> @@ -1395,8 +1414,14 @@ static int mv_qc_defer(struct ata_queued_cmd *qc)
>         * doesn't allow it.
>         */
>        if ((pp->pp_flags & MV_PP_FLAG_EDMA_EN) &&
> -           (pp->pp_flags & MV_PP_FLAG_NCQ_EN) && ata_is_ncq(qc->tf.protocol))
> -               return 0;
> +           (pp->pp_flags & MV_PP_FLAG_NCQ_EN)) {
> +               if (ata_is_ncq(qc->tf.protocol))
> +                       return 0;
> +               else {
> +                       ap->excl_link = link;
> +                       return ATA_DEFER_PORT;
> +               }
> +       }
>
>        return ATA_DEFER_PORT;
>  }
> --
> 1.5.4.3
>
> --
> 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
>
--
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
Mark Lord Oct. 14, 2009, 12:35 p.m. UTC | #2
Gwendal Grignou wrote:
> Use excl_link when non NCQ commands are defered, to be sure they are processed
> as soon as outstanding commands are completed. It prevents some commands to be
> defered indifinitely when using a port multiplier.
> 
> Signed-off-by: Gwendal Grignou <gwendal@google.com>
..
> Reviewed-by: Grant Grundler <grundler@google.com>
..

Reviewed-by: Mark Lord <mlord@pobox.com>

Looks good to me.  Jeff, please feel free to accept sata_mv patches
directly from Gwendal and/or Grant -- they know the chips as well as I do.

Cheers

Mark
--
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 Oct. 14, 2009, 12:38 p.m. UTC | #3
On 10/12/2009 06:44 PM, Gwendal Grignou wrote:
> Use excl_link when non NCQ commands are defered, to be sure they are processed
> as soon as outstanding commands are completed. It prevents some commands to be
> defered indifinitely when using a port multiplier.
>
> Signed-off-by: Gwendal Grignou<gwendal@google.com>
> ---
>   drivers/ata/sata_mv.c |   29 +++++++++++++++++++++++++++--
>   1 files changed, 27 insertions(+), 2 deletions(-)

An ACK from Mark, too, I hope?

I'll give this a try on a Gen-IIE chip...

	Jeff




--
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 Oct. 16, 2009, 10:26 a.m. UTC | #4
On 10/12/2009 06:44 PM, Gwendal Grignou wrote:
> Use excl_link when non NCQ commands are defered, to be sure they are processed
> as soon as outstanding commands are completed. It prevents some commands to be
> defered indifinitely when using a port multiplier.
>
> Signed-off-by: Gwendal Grignou<gwendal@google.com>
> ---
>   drivers/ata/sata_mv.c |   29 +++++++++++++++++++++++++++--
>   1 files changed, 27 insertions(+), 2 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
diff mbox

Patch

diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 17f9ff9..6f5093b 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -1382,6 +1382,25 @@  static int mv_qc_defer(struct ata_queued_cmd *qc)
 	 */
 	if (pp->pp_flags & MV_PP_FLAG_DELAYED_EH)
 		return ATA_DEFER_PORT;
+
+	/* PIO commands need exclusive link: no other commands [DMA or PIO]
+	 * can run concurrently.
+	 * set excl_link when we want to send a PIO command in DMA mode
+	 * or a non-NCQ command in NCQ mode.
+	 * When we receive a command from that link, and there are no
+	 * outstanding commands, mark a flag to clear excl_link and let
+	 * the command go through.
+	 */
+	if (unlikely(ap->excl_link)) {
+		if (link == ap->excl_link) {
+			if (ap->nr_active_links)
+				return ATA_DEFER_PORT;
+			qc->flags |= ATA_QCFLAG_CLEAR_EXCL;
+			return 0;
+		} else
+			return ATA_DEFER_PORT;
+	}
+
 	/*
 	 * If the port is completely idle, then allow the new qc.
 	 */
@@ -1395,8 +1414,14 @@  static int mv_qc_defer(struct ata_queued_cmd *qc)
 	 * doesn't allow it.
 	 */
 	if ((pp->pp_flags & MV_PP_FLAG_EDMA_EN) &&
-	    (pp->pp_flags & MV_PP_FLAG_NCQ_EN) && ata_is_ncq(qc->tf.protocol))
-		return 0;
+	    (pp->pp_flags & MV_PP_FLAG_NCQ_EN)) {
+		if (ata_is_ncq(qc->tf.protocol))
+			return 0;
+		else {
+			ap->excl_link = link;
+			return ATA_DEFER_PORT;
+		}
+	}
 
 	return ATA_DEFER_PORT;
 }