[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <m2gda824cf31004131746o15be77b1n7af6fac42ce25280@mail.gmail.com>
Date: Tue, 13 Apr 2010 17:46:11 -0700
From: Grant Grundler <grundler@...gle.com>
To: Linux IDE mailing list <linux-ide@...r.kernel.org>
Cc: Jeff Garzik <jgarzik@...ox.com>, Tejun Heo <tj@...nel.org>,
LKML <linux-kernel@...r.kernel.org>
Subject: [PATCH] 2.6.34-rc3 Disable R_OK (Early ACK) on SII 3726/4726 PMP
In 2009, While running "cache read" performance test of drives behind
SII PMP we encountered a "all 5 drives" timeout on more than 30% of the
machines under test. This patch reduces the rate by a factor of about 70.
Low enough that we didn't care to further investigate the issue.
Performance impact with any sort of "normal" use was ~2%+ CPU and less
than 1% throughput degradation. Worst case impact (cached read) was
6% IOPS reduction. This is with NCQ off (q=1) but I believe FIS based
switching enabled in the SATA driver.
The patch disables "Early ACK" in the 3726/4726 port multiplier.
"Early ACK" is issued when device sends a FIS to the host (via PMP)
and the PMP sends an ACK immediately back to the device - well before
the host gets the response. Under worst case IOPs load (cached read
test) and more than 2 PMPs connected to a 4-port SATA controller,
I suspect the time to service all of the PMPs is exceeding the PMPs
ability to keep track of outstanding FIS it owes the Host. Reducing
the number of PMPs to 2 (or 1) reduces the frequency by several orders
of magnitude. Kudos to Gwendal for initial debugging of this issue.
[Any errors in the description are mine, not his.]
Patch is currently in production on Google servers.
Signed-off-by: Grant Grundler <grundler@...gle.com>
Signed-off-by: Gwendal Grignou <gwendal@...gle.com>
---
And my apologies in advance for using gmail. Patch appended below
is also attached since I expect gmail will mangle the inlined content.
diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c
index 00305f4..69bb203 100644
--- a/drivers/ata/libata-pmp.c
+++ b/drivers/ata/libata-pmp.c
@@ -235,6 +235,8 @@ static int sata_pmp_configure(struct ata_device
*dev, int print_info)
{
struct ata_port *ap = dev->link->ap;
u32 *gscr = dev->gscr;
+ u16 vendor = sata_pmp_gscr_vendor(gscr);
+ u16 devid = sata_pmp_gscr_devid(gscr);
unsigned int err_mask = 0;
const char *reason;
int nr_ports, rc;
@@ -260,12 +262,28 @@ static int sata_pmp_configure(struct ata_device
*dev, int print_info)
goto fail;
}
+ /* For Sil3726, disable sending Early R_OK */
+ if (vendor == 0x1095 && devid == 0x3726) {
+ u32 reg;
+ err_mask = sata_pmp_read(&ap->link,
SATA_PMP_GSCR_SII_POL, ®);
+ if (err_mask) {
+ rc = -EIO;
+ reason = "failed to read Sil3726 Private Register";
+ goto fail;
+ }
+ reg &= ~0x1;
+ err_mask = sata_pmp_write(&ap->link,
SATA_PMP_GSCR_SII_POL, reg);
+ if (err_mask) {
+ rc = -EIO;
+ reason = "failed to write Sil3726 Private Register";
+ goto fail;
+ }
+ }
+
if (print_info) {
ata_dev_printk(dev, KERN_INFO, "Port Multiplier %s, "
"0x%04x:0x%04x r%d, %d ports, feat 0x%x/0x%x\n",
- sata_pmp_spec_rev_str(gscr),
- sata_pmp_gscr_vendor(gscr),
- sata_pmp_gscr_devid(gscr),
+ sata_pmp_spec_rev_str(gscr), vendor, devid,
sata_pmp_gscr_rev(gscr),
nr_ports, gscr[SATA_PMP_GSCR_FEAT_EN],
gscr[SATA_PMP_GSCR_FEAT]);
diff --git a/include/linux/ata.h b/include/linux/ata.h
index 700c5b9..18fc208 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -386,6 +386,7 @@ enum {
SATA_PMP_GSCR_ERROR_EN = 33,
SATA_PMP_GSCR_FEAT = 64,
SATA_PMP_GSCR_FEAT_EN = 96,
+ SATA_PMP_GSCR_SII_POL = 129, /* VENDOR : Silicon Image 3726/4726 */
SATA_PMP_PSCR_STATUS = 0,
SATA_PMP_PSCR_ERROR = 1,
Download attachment "2.6.18-mv_sata-measure_port_handler-03" of type "application/octet-stream" (4937 bytes)
Powered by blists - more mailing lists