How do I target a specific driver for libata kernel parameter modding?
I'm running a 22-disk setup, 19 of those in a ZFS array, 15 of those backed by three port multipliers attached to SATA controllers driven by the sata_sil24
module. When running full speed (SATA2, 3 Gbps), the operation is pretty quirky. Simple read errors will throw an entire port multiplier into spasms for a long time, sometimes with pretty awful results. Booting with kernel parameter libata.force=1.5G
to force SATA controllers into "legacy" speeds completely fixes all issues with the port multipliers. Thing is, my ZFS pool is backed by a fast cache SSD on my ICH10R controller. Another SSD on this same controller holds the system.
Doing libata.force=1.5G
immediately shaves about 100 MB/s off the transfer rate of my SSDs. For the root drive, that's not such a big deal, but for the ZFS cache SSD, it is. It effectively makes the entire zpool slower for sustained transfers than it would've been without the cache drive. Random access and fs tree lookups, of course still benefit. Listing the module options for sata_sil24
, no such option exists.
How to pass the libata.force=1.5G
parameter on to just the three SATA controllers being backed by the sata_sil24
module?
Ah! I found out!
At http://www.kernel.org/doc/Documentation/kernel-parameters.txt, it states,
libata.force= [LIBATA] Force configurations. The format is comma
separated list of "[ID:]VAL" where ID is
PORT[.DEVICE]. PORT and DEVICE are decimal numbers
matching port, link or device. Basically, it matches
the ATA ID string printed on console by libata. If
the whole ID part is omitted, the last PORT and DEVICE
values are used. If ID hasn't been specified yet, the
configuration applies to all ports, links and devices.
If only DEVICE is omitted, the parameter applies to
the port and all links and devices behind it. DEVICE
number of 0 either selects the first device or the
first fan-out link behind PMP device. It does not
select the host link. DEVICE number of 15 selects the
host link and device attached to it.
The VAL specifies the configuration to force. As long
as there's no ambiguity shortcut notation is allowed.
For example, both 1.5 and 1.5G would work for 1.5Gbps.
The following configurations can be forced.
* Cable type: 40c, 80c, short40c, unk, ign or sata.
Any ID with matching PORT is used.
* SATA link speed limit: 1.5Gbps or 3.0Gbps.
* Transfer mode: pio[0-7], mwdma[0-4] and udma[0-7].
udma[/][16,25,33,44,66,100,133] notation is also
allowed.
* [no]ncq: Turn on or off NCQ.
* nohrst, nosrst, norst: suppress hard, soft
and both resets.
* dump_id: dump IDENTIFY data.
If there are multiple matching configurations changing
the same attribute, the last one is used.
So, the tricky part is finding out which port X and device Y (dmesg ataX.YY) is which controller and drive. I think - that notation matches PORT[.DEVICE], but there's also the W:X:Y:Z notation. I'm guessing ataX.YY :)
Luckily, I just did this mapping manually last week (trying to identify a drive that was throwing spasms and resetting a host controller), so I have an exhaustive list already :) I couldn't find anywhere that the mappings from sdX to ataX.Y or W:X:Y:Z where listed, so I ended up simply yanking out SATA cables and watching which ataX.YY messages appeared in /var/log/messages ;)
So, in my setup, it seems I need to do
libata.force=1:1.5G,2:1.5G,3:1.5G
Gonna have to try that out as soon as my ZFS scrub finishes, and report back :) Awesome! Hope this helps someone else :)