All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3] libata: support the ata host which implements a queue depth less than 32
@ 2014-07-11  6:10 Kevin Hao
  2014-07-11 11:57 ` Sergei Shtylyov
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Kevin Hao @ 2014-07-11  6:10 UTC (permalink / raw)
  To: linux-ide; +Cc: Tejun Heo, Dan Williams

The sata on fsl mpc8315e is broken after the commit 8a4aeec8d2d6
("libata/ahci: accommodate tag ordered controllers"). The reason is
that the ata controller on this SoC only implement a queue depth of
16. When issuing the commands in tag order, all the commands in tag
16 ~ 31 are mapped to tag 0 unconditionally and then causes the sata
malfunction. It makes no senses to use a 32 queue in software while
the hardware has less queue depth. So consider the queue depth
implemented by the hardware when requesting a command tag.

Fixes: 8a4aeec8d2d6 ("libata/ahci: accommodate tag ordered controllers")
Cc: stable@vger.kernel.org
Signed-off-by: Kevin Hao <haokexin@gmail.com>
---
v3: Use ap->scsi_host->can_queue for the queue depth implemented by hardware.
    Patch 2 in v2 is also dropped due to this change.

v2: Remove the changes for the ata tag helper functions

Hi Tejun,

I didn't get explicit objection for the codes at http://marc.info/?l=linux-ide&m=140478830920334&w=2
So I assume that you are OK wit it. The code in this patch is the same as that,
just add the commit log.

 drivers/ata/libata-core.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 8f3043165048..4792fea79acf 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4728,14 +4728,17 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
 static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
 {
 	struct ata_queued_cmd *qc = NULL;
-	unsigned int i, tag;
+	unsigned int i, tag, max_queue;
+
+	max_queue = ap->scsi_host->can_queue;
+	WARN_ON_ONCE(max_queue > ATA_MAX_QUEUE);
 
 	/* no command while frozen */
 	if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
 		return NULL;
 
-	for (i = 0; i < ATA_MAX_QUEUE; i++) {
-		tag = (i + ap->last_tag + 1) % ATA_MAX_QUEUE;
+	for (i = 0, tag = ap->last_tag + 1; i < max_queue; i++, tag++) {
+		tag = tag < max_queue ? tag : 0;
 
 		/* the last tag is reserved for internal command. */
 		if (tag == ATA_TAG_INTERNAL)
-- 
1.9.3


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

* Re: [PATCH v3] libata: support the ata host which implements a queue depth less than 32
  2014-07-11  6:10 [PATCH v3] libata: support the ata host which implements a queue depth less than 32 Kevin Hao
@ 2014-07-11 11:57 ` Sergei Shtylyov
  2014-07-11 14:47   ` Tejun Heo
  2014-07-12  0:26   ` Kevin Hao
  2014-07-11 14:51 ` Tejun Heo
  2014-07-11 16:28 ` Bartlomiej Zolnierkiewicz
  2 siblings, 2 replies; 10+ messages in thread
From: Sergei Shtylyov @ 2014-07-11 11:57 UTC (permalink / raw)
  To: Kevin Hao, linux-ide; +Cc: Tejun Heo, Dan Williams

Hello.

On 11-07-2014 10:10, Kevin Hao wrote:

> The sata on fsl mpc8315e is broken after the commit 8a4aeec8d2d6
> ("libata/ahci: accommodate tag ordered controllers"). The reason is
> that the ata controller on this SoC only implement a queue depth of
> 16. When issuing the commands in tag order, all the commands in tag
> 16 ~ 31 are mapped to tag 0 unconditionally and then causes the sata
> malfunction. It makes no senses to use a 32 queue in software while
> the hardware has less queue depth. So consider the queue depth
> implemented by the hardware when requesting a command tag.

> Fixes: 8a4aeec8d2d6 ("libata/ahci: accommodate tag ordered controllers")
> Cc: stable@vger.kernel.org
> Signed-off-by: Kevin Hao <haokexin@gmail.com>
> ---
> v3: Use ap->scsi_host->can_queue for the queue depth implemented by hardware.
>      Patch 2 in v2 is also dropped due to this change.

> v2: Remove the changes for the ata tag helper functions

> Hi Tejun,

> I didn't get explicit objection for the codes at http://marc.info/?l=linux-ide&m=140478830920334&w=2
> So I assume that you are OK wit it. The code in this patch is the same as that,
> just add the commit log.

>   drivers/ata/libata-core.c | 9 ++++++---
>   1 file changed, 6 insertions(+), 3 deletions(-)

> diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
> index 8f3043165048..4792fea79acf 100644
> --- a/drivers/ata/libata-core.c
> +++ b/drivers/ata/libata-core.c
> @@ -4728,14 +4728,17 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
>   static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
>   {
>   	struct ata_queued_cmd *qc = NULL;
> -	unsigned int i, tag;
> +	unsigned int i, tag, max_queue;
> +
> +	max_queue = ap->scsi_host->can_queue;
> +	WARN_ON_ONCE(max_queue > ATA_MAX_QUEUE);
>
>   	/* no command while frozen */
>   	if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
>   		return NULL;
>
> -	for (i = 0; i < ATA_MAX_QUEUE; i++) {
> -		tag = (i + ap->last_tag + 1) % ATA_MAX_QUEUE;
> +	for (i = 0, tag = ap->last_tag + 1; i < max_queue; i++, tag++) {
> +		tag = tag < max_queue ? tag : 0;

    Assigning 'tag' back to 'tag' is quite stupid, don't you think? Why not:

		if (tag >= max_queue)
			tag = 0;

MBR, Sergei


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

* Re: [PATCH v3] libata: support the ata host which implements a queue depth less than 32
  2014-07-11 11:57 ` Sergei Shtylyov
@ 2014-07-11 14:47   ` Tejun Heo
  2014-07-12  0:26   ` Kevin Hao
  1 sibling, 0 replies; 10+ messages in thread
From: Tejun Heo @ 2014-07-11 14:47 UTC (permalink / raw)
  To: Sergei Shtylyov; +Cc: Kevin Hao, linux-ide, Dan Williams

On Fri, Jul 11, 2014 at 03:57:01PM +0400, Sergei Shtylyov wrote:
> >-	for (i = 0; i < ATA_MAX_QUEUE; i++) {
> >-		tag = (i + ap->last_tag + 1) % ATA_MAX_QUEUE;
> >+	for (i = 0, tag = ap->last_tag + 1; i < max_queue; i++, tag++) {
> >+		tag = tag < max_queue ? tag : 0;
> 
>    Assigning 'tag' back to 'tag' is quite stupid, don't you think? Why not:
> 
> 		if (tag >= max_queue)
> 			tag = 0;

I don't really mind it and the explicit if block isn't more readable
in any way.

Thanks.

-- 
tejun

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

* Re: [PATCH v3] libata: support the ata host which implements a queue depth less than 32
  2014-07-11  6:10 [PATCH v3] libata: support the ata host which implements a queue depth less than 32 Kevin Hao
  2014-07-11 11:57 ` Sergei Shtylyov
@ 2014-07-11 14:51 ` Tejun Heo
  2014-07-12  0:27   ` Kevin Hao
  2014-07-11 16:28 ` Bartlomiej Zolnierkiewicz
  2 siblings, 1 reply; 10+ messages in thread
From: Tejun Heo @ 2014-07-11 14:51 UTC (permalink / raw)
  To: Kevin Hao; +Cc: linux-ide, Dan Williams

On Fri, Jul 11, 2014 at 02:10:26PM +0800, Kevin Hao wrote:
>  static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
>  {
>  	struct ata_queued_cmd *qc = NULL;
> -	unsigned int i, tag;
> +	unsigned int i, tag, max_queue;
> +
> +	max_queue = ap->scsi_host->can_queue;
> +	WARN_ON_ONCE(max_queue > ATA_MAX_QUEUE);

Let's move the WARN_ON_ONCE() to ata_host_register().  Also, let's
please update the function comment explaining why we're allocating
tags the way we do.

Other than that, it looks good to me.

Thanks.

-- 
tejun

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

* Re: [PATCH v3] libata: support the ata host which implements a queue depth less than 32
  2014-07-11  6:10 [PATCH v3] libata: support the ata host which implements a queue depth less than 32 Kevin Hao
  2014-07-11 11:57 ` Sergei Shtylyov
  2014-07-11 14:51 ` Tejun Heo
@ 2014-07-11 16:28 ` Bartlomiej Zolnierkiewicz
  2014-07-11 16:33   ` Bartlomiej Zolnierkiewicz
  2 siblings, 1 reply; 10+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2014-07-11 16:28 UTC (permalink / raw)
  To: Kevin Hao; +Cc: linux-ide, Tejun Heo, Dan Williams


Hi,

On Friday, July 11, 2014 02:10:26 PM Kevin Hao wrote:
> The sata on fsl mpc8315e is broken after the commit 8a4aeec8d2d6
> ("libata/ahci: accommodate tag ordered controllers"). The reason is
> that the ata controller on this SoC only implement a queue depth of
> 16. When issuing the commands in tag order, all the commands in tag
> 16 ~ 31 are mapped to tag 0 unconditionally and then causes the sata
> malfunction. It makes no senses to use a 32 queue in software while
> the hardware has less queue depth. So consider the queue depth
> implemented by the hardware when requesting a command tag.
> 
> Fixes: 8a4aeec8d2d6 ("libata/ahci: accommodate tag ordered controllers")
> Cc: stable@vger.kernel.org
> Signed-off-by: Kevin Hao <haokexin@gmail.com>
> ---
> v3: Use ap->scsi_host->can_queue for the queue depth implemented by hardware.
>     Patch 2 in v2 is also dropped due to this change.
> 
> v2: Remove the changes for the ata tag helper functions
> 
> Hi Tejun,
> 
> I didn't get explicit objection for the codes at http://marc.info/?l=linux-ide&m=140478830920334&w=2
> So I assume that you are OK wit it. The code in this patch is the same as that,
> just add the commit log.
> 
>  drivers/ata/libata-core.c | 9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
> index 8f3043165048..4792fea79acf 100644
> --- a/drivers/ata/libata-core.c
> +++ b/drivers/ata/libata-core.c
> @@ -4728,14 +4728,17 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
>  static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
>  {
>  	struct ata_queued_cmd *qc = NULL;
> -	unsigned int i, tag;
> +	unsigned int i, tag, max_queue;
> +
> +	max_queue = ap->scsi_host->can_queue;
> +	WARN_ON_ONCE(max_queue > ATA_MAX_QUEUE);

Why not handle this properly by just doing what ata_dev_config_ncq() does and
using

	min(ap->scsi_host->can_queue, ATA_MAX_QUEUE - 1);

for obtaining max_queue?
 
>  	/* no command while frozen */
>  	if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
>  		return NULL;
>  
> -	for (i = 0; i < ATA_MAX_QUEUE; i++) {
> -		tag = (i + ap->last_tag + 1) % ATA_MAX_QUEUE;
> +	for (i = 0, tag = ap->last_tag + 1; i < max_queue; i++, tag++) {
> +		tag = tag < max_queue ? tag : 0;
>  
>  		/* the last tag is reserved for internal command. */
>  		if (tag == ATA_TAG_INTERNAL)

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics


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

* Re: [PATCH v3] libata: support the ata host which implements a queue depth less than 32
  2014-07-11 16:28 ` Bartlomiej Zolnierkiewicz
@ 2014-07-11 16:33   ` Bartlomiej Zolnierkiewicz
  2014-07-12  0:58     ` Kevin Hao
  0 siblings, 1 reply; 10+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2014-07-11 16:33 UTC (permalink / raw)
  To: Kevin Hao; +Cc: linux-ide, Tejun Heo, Dan Williams

On Friday, July 11, 2014 06:28:33 PM Bartlomiej Zolnierkiewicz wrote:
> 
> Hi,
> 
> On Friday, July 11, 2014 02:10:26 PM Kevin Hao wrote:
> > The sata on fsl mpc8315e is broken after the commit 8a4aeec8d2d6
> > ("libata/ahci: accommodate tag ordered controllers"). The reason is
> > that the ata controller on this SoC only implement a queue depth of
> > 16. When issuing the commands in tag order, all the commands in tag
> > 16 ~ 31 are mapped to tag 0 unconditionally and then causes the sata
> > malfunction. It makes no senses to use a 32 queue in software while
> > the hardware has less queue depth. So consider the queue depth
> > implemented by the hardware when requesting a command tag.
> > 
> > Fixes: 8a4aeec8d2d6 ("libata/ahci: accommodate tag ordered controllers")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Kevin Hao <haokexin@gmail.com>
> > ---
> > v3: Use ap->scsi_host->can_queue for the queue depth implemented by hardware.
> >     Patch 2 in v2 is also dropped due to this change.
> > 
> > v2: Remove the changes for the ata tag helper functions
> > 
> > Hi Tejun,
> > 
> > I didn't get explicit objection for the codes at http://marc.info/?l=linux-ide&m=140478830920334&w=2
> > So I assume that you are OK wit it. The code in this patch is the same as that,
> > just add the commit log.
> > 
> >  drivers/ata/libata-core.c | 9 ++++++---
> >  1 file changed, 6 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
> > index 8f3043165048..4792fea79acf 100644
> > --- a/drivers/ata/libata-core.c
> > +++ b/drivers/ata/libata-core.c
> > @@ -4728,14 +4728,17 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
> >  static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
> >  {
> >  	struct ata_queued_cmd *qc = NULL;
> > -	unsigned int i, tag;
> > +	unsigned int i, tag, max_queue;
> > +
> > +	max_queue = ap->scsi_host->can_queue;
> > +	WARN_ON_ONCE(max_queue > ATA_MAX_QUEUE);
> 
> Why not handle this properly by just doing what ata_dev_config_ncq() does and
> using
> 
> 	min(ap->scsi_host->can_queue, ATA_MAX_QUEUE - 1);

actually this should be

	min(ap->scsi_host->can_queue, ATA_MAX_QUEUE);

in this function

> for obtaining max_queue?
>  
> >  	/* no command while frozen */
> >  	if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
> >  		return NULL;
> >  
> > -	for (i = 0; i < ATA_MAX_QUEUE; i++) {
> > -		tag = (i + ap->last_tag + 1) % ATA_MAX_QUEUE;
> > +	for (i = 0, tag = ap->last_tag + 1; i < max_queue; i++, tag++) {
> > +		tag = tag < max_queue ? tag : 0;
> >  
> >  		/* the last tag is reserved for internal command. */
> >  		if (tag == ATA_TAG_INTERNAL)

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics


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

* Re: [PATCH v3] libata: support the ata host which implements a queue depth less than 32
  2014-07-11 11:57 ` Sergei Shtylyov
  2014-07-11 14:47   ` Tejun Heo
@ 2014-07-12  0:26   ` Kevin Hao
  2014-07-12  0:36     ` Sergei Shtylyov
  1 sibling, 1 reply; 10+ messages in thread
From: Kevin Hao @ 2014-07-12  0:26 UTC (permalink / raw)
  To: Sergei Shtylyov; +Cc: linux-ide, Tejun Heo, Dan Williams

[-- Attachment #1: Type: text/plain, Size: 575 bytes --]

On Fri, Jul 11, 2014 at 03:57:01PM +0400, Sergei Shtylyov wrote:
> >-	for (i = 0; i < ATA_MAX_QUEUE; i++) {
> >-		tag = (i + ap->last_tag + 1) % ATA_MAX_QUEUE;
> >+	for (i = 0, tag = ap->last_tag + 1; i < max_queue; i++, tag++) {
> >+		tag = tag < max_queue ? tag : 0;
> 
>    Assigning 'tag' back to 'tag' is quite stupid, don't you think? Why not:
> 
> 		if (tag >= max_queue)
> 			tag = 0;

Since I am an idiot, it is very possible for me to write stupid code.
But I don't believe this is one. I don't think the above code is more readable.

Thanks,
Kevin

[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]

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

* Re: [PATCH v3] libata: support the ata host which implements a queue depth less than 32
  2014-07-11 14:51 ` Tejun Heo
@ 2014-07-12  0:27   ` Kevin Hao
  0 siblings, 0 replies; 10+ messages in thread
From: Kevin Hao @ 2014-07-12  0:27 UTC (permalink / raw)
  To: Tejun Heo; +Cc: linux-ide, Dan Williams

[-- Attachment #1: Type: text/plain, Size: 607 bytes --]

On Fri, Jul 11, 2014 at 10:51:05AM -0400, Tejun Heo wrote:
> On Fri, Jul 11, 2014 at 02:10:26PM +0800, Kevin Hao wrote:
> >  static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
> >  {
> >  	struct ata_queued_cmd *qc = NULL;
> > -	unsigned int i, tag;
> > +	unsigned int i, tag, max_queue;
> > +
> > +	max_queue = ap->scsi_host->can_queue;
> > +	WARN_ON_ONCE(max_queue > ATA_MAX_QUEUE);
> 
> Let's move the WARN_ON_ONCE() to ata_host_register().  Also, let's
> please update the function comment explaining why we're allocating
> tags the way we do.

OK, will do.

Thanks,
Kevin

[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]

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

* Re: [PATCH v3] libata: support the ata host which implements a queue depth less than 32
  2014-07-12  0:26   ` Kevin Hao
@ 2014-07-12  0:36     ` Sergei Shtylyov
  0 siblings, 0 replies; 10+ messages in thread
From: Sergei Shtylyov @ 2014-07-12  0:36 UTC (permalink / raw)
  To: Kevin Hao; +Cc: linux-ide, Tejun Heo, Dan Williams

On 07/12/2014 04:26 AM, Kevin Hao wrote:

>>> -	for (i = 0; i < ATA_MAX_QUEUE; i++) {
>>> -		tag = (i + ap->last_tag + 1) % ATA_MAX_QUEUE;
>>> +	for (i = 0, tag = ap->last_tag + 1; i < max_queue; i++, tag++) {
>>> +		tag = tag < max_queue ? tag : 0;

>>     Assigning 'tag' back to 'tag' is quite stupid, don't you think? Why not:

>> 		if (tag >= max_queue)
>> 			tag = 0;

> Since I am an idiot, it is very possible for me to write stupid code.
> But I don't believe this is one. I don't think the above code is more readable.

    Perhaps I'm an idiot (I even seldom doubt it) but to me it looks like 
clear abuse of the ?: operator. But that's probably just me...

> Thanks,
> Kevin

MBR, Sergei


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

* Re: [PATCH v3] libata: support the ata host which implements a queue depth less than 32
  2014-07-11 16:33   ` Bartlomiej Zolnierkiewicz
@ 2014-07-12  0:58     ` Kevin Hao
  0 siblings, 0 replies; 10+ messages in thread
From: Kevin Hao @ 2014-07-12  0:58 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz; +Cc: linux-ide, Tejun Heo, Dan Williams

[-- Attachment #1: Type: text/plain, Size: 1114 bytes --]

On Fri, Jul 11, 2014 at 06:33:46PM +0200, Bartlomiej Zolnierkiewicz wrote:
> On Friday, July 11, 2014 06:28:33 PM Bartlomiej Zolnierkiewicz wrote:
> > > +	max_queue = ap->scsi_host->can_queue;
> > > +	WARN_ON_ONCE(max_queue > ATA_MAX_QUEUE);
> > 
> > Why not handle this properly by just doing what ata_dev_config_ncq() does and
> > using
> > 
> > 	min(ap->scsi_host->can_queue, ATA_MAX_QUEUE - 1);
> 
> actually this should be
> 
> 	min(ap->scsi_host->can_queue, ATA_MAX_QUEUE);
> 
> in this function
> 
> > for obtaining max_queue?

Actually the ap->scsi_host->can_queue is the max queue supported by the
hardware. It should be a bug if it is greater than ATA_MAX_QUEUE. So we don't
need to use min() to get the max queue here. As pointed out by Tejun, it makes
no sense to do the sanity check for each qc requesting, so I will move the
WARN_ON_ONCE() to ata_host_register().

I have a pending patch to free the command tag reserved by the internal
command. In that patch the above code in ata_dev_config_ncq() will change
to:

  hdepth = ap->scsi_host->can_queue;

Thanks,
Kevin

[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]

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

end of thread, other threads:[~2014-07-12  0:59 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-07-11  6:10 [PATCH v3] libata: support the ata host which implements a queue depth less than 32 Kevin Hao
2014-07-11 11:57 ` Sergei Shtylyov
2014-07-11 14:47   ` Tejun Heo
2014-07-12  0:26   ` Kevin Hao
2014-07-12  0:36     ` Sergei Shtylyov
2014-07-11 14:51 ` Tejun Heo
2014-07-12  0:27   ` Kevin Hao
2014-07-11 16:28 ` Bartlomiej Zolnierkiewicz
2014-07-11 16:33   ` Bartlomiej Zolnierkiewicz
2014-07-12  0:58     ` Kevin Hao

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.