All of lore.kernel.org
 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 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.