linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jens Axboe <jens.axboe@oracle.com>
To: Brad Campbell <brad@wasp.net.au>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>,
	jeff@garzik.org, tj@kernel.org, linux-ide@vger.kernel.org
Subject: Re: libata bridge limits
Date: Tue, 26 Aug 2008 14:48:16 +0200	[thread overview]
Message-ID: <20080826124816.GA20055@kernel.dk> (raw)
In-Reply-To: <48B3F7C3.6010600@wasp.net.au>

On Tue, Aug 26 2008, Brad Campbell wrote:
> Jens 2 wrote:
> >On Tue, Aug 26 2008, Alan Cox wrote:
> >>>a) Why was this limit put in there? It limits both transfer speed and
> >>>   request size. If it's due to some dodgy drive/bridge, perhaps we
> >>>   should just check for that and only apply the transfer limits when
> >>>   detected (or blacklisted). On the bridge setups I've seen, I've never
> >>>   had problems with killing the limit.
> >>Various old bridges need it - and you can't detect the bridge type.
> >
> >Not generically, but for some devices (like the Mtron) we can.
> >
> >>>b) Put in a whitelist, easy to do for these Mtron drives.
> >>>
> >>>c) Add a parameter to turn it on (or off, depending on the default) for
> >>>   a specific drive.
> >>>
> >>>I'm in favor of a) personally, but I'd like to hear why the check was
> >>>added originally first. Dropping 20-30% of the throughput performance on
> >>>the floor without option seems like a really bad choice.
> 
> The check was originally put there as some nasty bridges caused all sorts 
> of errors when these limits were exceeded, including some random data 
> corruption from memory.
> 
> Those particular bridges were/are still widely available an can't be 
> detected / identified using any other means.

That's a worry, since I don't think we can dynamically switch back in
that case if it has potential data corruption problems.

> >>Can I suggest 
> >>
> >>d) Assume the bridge is ok but teach the SATA error handling code that if
> >>there is a timeout immediately with such a bridge then to flip down to
> >>UDMA5 and knobble the transfer length.
> >
> >That would be nice, assuming that we can rely on safe behaviour (eg not
> >data corrupting badness).
> >
> 
> I was responsible for that original bridge knobble stuff and fortunately I 
> still have the bridges, disks and controllers that triggered the original 
> faults. If someone wants to cook up some code for testing I'd be more than 
> happy to stick this stuff on the bench and beat on it for regression 
> purposes.

Given that this problem should be going away and that it only really
matters on very select devices (like this SSD), I think we should just
add a quick white list for the bridge limits.

Below is a quick'n dirty for that...

diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 79e3a8e..fe8033a 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -2097,9 +2097,70 @@ retry:
 	return rc;
 }
 
+struct ata_blacklist_entry {
+	const char *model_num;
+	const char *model_rev;
+	unsigned long horkage;
+};
+
+static const struct ata_blacklist_entry ata_bridge_whitelist[] = {
+	/*
+	 * The following devices sit behind a bridge, but don't need
+	 * transfer rate or size limits applied.
+	 */
+	{ "Mtron", },
+
+	/* End Marker */
+	{ }
+};
+
+static int strn_pattern_cmp(const char *patt, const char *name, int wildchar)
+{
+	const char *p;
+	int len;
+
+	/*
+	 * check for trailing wildcard: *\0
+	 */
+	p = strchr(patt, wildchar);
+	if (p && ((*(p + 1)) == 0))
+		len = p - patt;
+	else {
+		len = strlen(name);
+		if (!len) {
+			if (!*patt)
+				return 0;
+			return -1;
+		}
+	}
+
+	return strncmp(patt, name, len);
+}
+
+static unsigned int ata_dev_bridge_whitelisted(const struct ata_device *dev)
+{
+	unsigned char model_num[ATA_ID_PROD_LEN + 1];
+	unsigned char model_rev[ATA_ID_FW_REV_LEN + 1];
+	const struct ata_blacklist_entry *ad = ata_bridge_whitelist;
+
+	ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
+	ata_id_c_string(dev->id, model_rev, ATA_ID_FW_REV, sizeof(model_rev));
+
+	while (ad->model_num) {
+		if (!strn_pattern_cmp(ad->model_num, model_num, '*'))
+			return 1;
+		ad++;
+	}
+	return 0;
+}
+
 static inline u8 ata_dev_knobble(struct ata_device *dev)
 {
 	struct ata_port *ap = dev->link->ap;
+
+	if (ata_dev_bridge_whitelisted(dev))
+		return 0;
+
 	return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(dev->id)));
 }
 
@@ -3913,12 +3974,6 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class,
 	return rc;
 }
 
-struct ata_blacklist_entry {
-	const char *model_num;
-	const char *model_rev;
-	unsigned long horkage;
-};
-
 static const struct ata_blacklist_entry ata_device_blacklist [] = {
 	/* Devices with DMA related problems under Linux */
 	{ "WDC AC11000H",	NULL,		ATA_HORKAGE_NODMA },
@@ -4002,29 +4057,6 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
 	{ }
 };
 
-static int strn_pattern_cmp(const char *patt, const char *name, int wildchar)
-{
-	const char *p;
-	int len;
-
-	/*
-	 * check for trailing wildcard: *\0
-	 */
-	p = strchr(patt, wildchar);
-	if (p && ((*(p + 1)) == 0))
-		len = p - patt;
-	else {
-		len = strlen(name);
-		if (!len) {
-			if (!*patt)
-				return 0;
-			return -1;
-		}
-	}
-
-	return strncmp(patt, name, len);
-}
-
 static unsigned long ata_dev_blacklisted(const struct ata_device *dev)
 {
 	unsigned char model_num[ATA_ID_PROD_LEN + 1];

-- 
Jens Axboe


  reply	other threads:[~2008-08-26 12:48 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-08-26  7:28 libata bridge limits Jens Axboe
2008-08-26  9:42 ` Alan Cox
2008-08-26 10:17   ` Jens Axboe
2008-08-26 10:43     ` Tejun Heo
2008-08-26 10:38       ` Alan Cox
2008-08-26 11:23         ` Tejun Heo
2008-08-26 12:25           ` Alan Cox
2008-08-26 12:45             ` Tejun Heo
2008-08-26 17:25       ` Gwendal Grignou
2008-08-26 17:45         ` James Bottomley
2008-08-26 19:25           ` Gwendal Grignou
2008-08-26 20:55             ` James Bottomley
2008-08-26 12:32     ` Brad Campbell
2008-08-26 12:48       ` Jens Axboe [this message]
2008-08-26 12:55         ` Tejun Heo
2008-08-26 13:06           ` Jens Axboe
2008-08-26 13:58             ` Jens Axboe
2008-08-26 14:20               ` Tejun Heo
2008-08-26 14:26                 ` Jens Axboe
2008-08-26 14:25               ` Jens Axboe
2008-08-26 19:36               ` Jeff Garzik
2008-08-26 22:37                 ` Mark Lord
2008-08-27 13:23                 ` Jens Axboe
2008-10-31  5:45                   ` Jeff Garzik

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080826124816.GA20055@kernel.dk \
    --to=jens.axboe@oracle.com \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=brad@wasp.net.au \
    --cc=jeff@garzik.org \
    --cc=linux-ide@vger.kernel.org \
    --cc=tj@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).