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
next prev parent 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).