8

How do I make CentOS run SATA drives at 3Gb/s at boot?

Background:

I'm having an issue with a motherboard that claims to support 6Gb/s SATA transfer speeds, but when using 4 drives on it, in a software RAID 10 with heavy disk IO, some of the SATA links start throwing kernel errors, ie. ata1.00: failed command: WRITE FPDMA QUEUED. But it's a different drive each time, not always ata1, and running extended test on each disk individually produces no errors.

When the errors occur, the Kernel/OS (CentOS 6.2) eventually resets the link several times, and when it continues to fail, then it changes the link speed to 3Gb/s. Once that happens, the errors stop for that drive for the remainder of the session.

What I'd like to do is tell the OS to set the SATA links to 3Gb/s to start with on boot, since I don't think the motherboard's SATA bus can handle all 4 drives at 6Gb/s. I couldn't find an option in the Motherboard's BIOS to change the link speed.

Questions:

  1. How would I go about doing that? ie. a config file?

  2. Can it be done while the system is running with the RAID array assembled and root partition mounted, or do I need to boot from a rescue CD?

  3. Will this result in any data loss? I have backups of course, but reinstalling/restoring is several hours of work that I'd like to avoid if possible.

1
  • Just note to anybody looking for this via Google: random hang or freeze of a storage device is often caused by poor motherboard (or other storage device controller hardware) implementation which advertises e.g. 6 Gbps SATA link compatibility but randomly hangs when lots of traffic is actually transmitted at that speed. In most cases the hardware can still work correctly if the link speed is reduced in half (6 Gbps advertised usually works as 3 Gbps link even in worst case). One usually has to slow down the whole controller instead of individual devices because the issue is caused by controller May 13, 2022 at 14:19

4 Answers 4

8

There is nothing at runtime unfortunately (there is /sys/class/ata_link which contains read only infomation).

However at boot it seems you can setup parameters forcing values that you want. The documentation for this is here: https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html

Specifically 
    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.

From the looks of things the kernel parameter libata.force=3.0G should work..

With regards to data loss, probably not -- but frankly since the SATA vendors clearly haven't honored the SATA spec correctly (or its buggy or whatever) then who knows.

3
  • Thanks for your answer- I'm still a bit confused, where does libata.force=3.0G go? And is the G supposed to be at the end?
    – Nick
    Jun 19, 2012 at 23:26
  • +1 for the helpful reference, but the answer wasn't entirely complete.
    – Nick
    Jun 20, 2012 at 6:48
  • Note that the correct syntax would be libata.force=3.0Gbps but documentation also says "As long as there's no ambiguity shortcut notation is allowed. For example, both 1.5 and 1.5G would work for 1.5Gbps." May 13, 2022 at 14:21
7

MIfe's answer here was a good clue (+1 for helpful reference), but not entirely complete.

To set the SATA links to 3Gb/s:

  1. Edit /boot/grub/grub.conf

  2. Find the line that starts with kernel. On mine, it was:

    kernel /vmlinuz-2.6.32-220.17.1.el6.x86_64 ro root=/dev/mapper/vg_lago-host rd_NO_LUKS LANG=en_US.UTF-8...

  3. Add libata.force=3.0 into that kernel line somewhere.

  4. Reboot

After doing the above, I am now able to run IO intensive operations like copying virtual machine images from one part of the disk to another without getting any more WRITE FPDMA QUEUED errors.

1
  • Note that the correct syntax would be libata.force=3.0Gbps but documentation also says "As long as there's no ambiguity shortcut notation is allowed. For example, both 1.5 and 1.5G would work for 1.5Gbps." May 13, 2022 at 14:14
2

As someone might stumble over this question just as I just did: A very simple solution to the problem could be to exchange the SATA cable. I moved an SSD from 2014 into a 2018-ish system and used the old, unshielded cable to connect it. I got exactly the errors and problems described here. They were all completely gone after I exchanged the cable to a modern shielded one.

I could even see in /var/log/syslog that the SATA controller tried to reset the link speed to 1.5 GB and still failed communicating with the disk. Without any configuration change, it worked absolutely flawlessly with the new cable attached.

So, before applying some configuration changes, you might just try a simple solution approach.

0

Downgrading it to 3Gbps may not be possible this way, but it should be possible to downgrade the links to 1.5Gbps. Unless you've got 10k drives or those are SSDs, they won't be able to saturate the 150MB/s link anyway...

Most hard drives can be forced to negotiate lower speed using jumpers. Google for "Sata 1 jumpers your drive model"

1
  • It looks like the OS or Kernel is downgrading the speed from 6 to 3 when it detects write errors occurring, so there must be some OS-level setting for this. The question is, how do I set this so it starts out at 3, without having to fall back to 3 when errors occur.
    – Nick
    Jun 19, 2012 at 23:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .