Next Previous Contents

49. IDE HDs performance optimization via hdparm

With the invention of IDE hard drives, which replaced the classic MFM, RLL, and even ESDI HDs of the past, things got much easier and cheaper. Unlike IDE, SCSI usually operates at top performance where as IDE must be tuned for the system the IDE HD is installed into. The command to do this with Linux is HDPARM.

With IDE HDs, you can configure (read the hdparm man page for a full list of feature with better descriptions):

- multicount - The number of sectors the HD can transfer per system interupt. Default is 1 and the max depends on your HD.

- I/O support - The data transfer mode the HD operates in. The default is 16bit though you can put it into 32bit mode if the IDE controller supports it.

- unmaskirq - This allows the OS to listen to other interrupts while a data transfer is taking place. Though this can speed things up, this can make your system unstable if you have a poor IDE chipset. Read the man page for more details.

- using_dma - With new UltraDMA (UDMA) hard drives and supporting UDMA controllers. UDMA is a technique to let the IDE chipset transfer data directly from HD to memory without bothering the CPU. Because of this, you can greatly reduce CPU utilization for big IDE transfers.

NOTE: I've tried using this parameter in the past and it ALWAYS has crashed the machine (P-II 400Mhz with IBM 16.8GB UDMA HDs). Your milage will vary.

Anyway, first, lets get an idea of what HDPARM see's for /dev/hda (my first IDE HD): Notice that I use "-I" to get the current HD setup settings:


                /sbin/hdparm -I /dev/hda

                /dev/hda:
                 Model=DW CCA1300H0, FwRev=911.E922, SerialNo=DWW-2T27
                 Config={ HardSect NotMFM HdSw>15uSec SpinMotCtl Fixed DTR>5Mbs FmtGapReq }
                 RawCHS=2100/16/63, TrkSize=57600, SectSize=600, ECCbytes=4
                 BuffType=3(DualPortCache), BuffSize=128kB, MaxMultSect=16, MultSect=16
                 DblWordIO=no, maxPIO=1(medium), DMA=yes, maxDMA=2(fast)
                 CurCHS=2100/16/63, CurSects=2116800, LBA=yes, LBAsects=2116800
                 tDMA={min:150,rec:150}, DMA modes: sword0 mword0 mword1 
                 IORDY=on/off, tPIO={min:380,w/IORDY:180}, PIO modes: mode3 

What does all this mean? Ok:

Line 1 - Its a Western Digitial drive with a model# of CCA1300H0 with the serial# (why is WD reversed? Dunno.. it doesn't that with the "/sbin/hdparm -i" command. Eh...)

- Line 2 - This lists the HDs technical abilities. This isn't the forum to describe them but if you are curious, email me.

- Line 3 - CHS stands for Cylinder, Head, Sectors and describes the HDs geometry. It also tells you the technical aspects of the geometries.

- Line 4 - Tells you the HDs caching system, the size of the cache, the HD's maximum number of sectors or BLOCKs per interrupt, and the current BLOCKs per intertupt setting.

- Line 5 - The HD is in 16bit mode, the current PIO or Programmed I/O data transfer mode is Mode1. I'm not sure what the (medium) means though. It also says that this drive DOES support DMA and the max supported *DMA* mode is Mode2.

- Line 6 - This tells you what Linux is using for the HD geometry (yes, it can be different than the actual HD's geometry). It also counts the total number of HD sectors, the HD is running in Logical Block Addressing (LBA) mode, and the total number of LBA blocks.

NOTE: LBA mode is critical for HDs bigger than 528MB to be properly used.

- Line 5 - This mentions the technical DMA timing requirements and the possible DMA modes.

- Line 6 - Mentions that this drive supports the legacy IORDY ISA line, the IORDY timing requirements, and finally, the maximum supported PIO mode.

Whew! Get all that? Hehehe.. don't worry about it. All you'll really care about is the 16/32bit mode, the PIO mode, and the DMA mode. Ok, so what settings is my drive currently using? Lets see:


                /sbin/hdparm -v /dev/hda 

                        /dev/hda:
                         multcount    =  0 (off)
                         I/O support  =  0 (default 16-bit)
                         unmaskirq    =  0 (off)
                         using_dma    =  0 (off)
                         keepsettings =  0 (off)
                         nowerr       =  0 (off)
                         readonly     =  0 (off)
                         readahead    =  8 (on)
                         geometry     = 525/64/63, sectors = 2116800, start = 0

So, you can see that multicount is OFF, 32Bit mode is ON, etc.

* Before you make any changes, do a quick NON-DESTRUCTIVE (ie. this won't hurt any of your data, etc) benchmark of your HD by doing:


                /sbin/hdparm -t -T /dev/hda

                        /dev/hda:
                         Timing buffer-cache reads:   32 MB in  1.82 seconds =17.58 MB/sec
                         Timing buffered disk reads:  16 MB in  7.27 seconds = 2.20 MB/sec

As you can see, the top figure is really a benchmark of all of the system's memory, caching, etc. (This is slow since this is only a 486-160). The second benchmark is the actual HD's read performance. Again.. this is VERY slow since I only have a Mode1 IDE controller in this system. Doh! Also, if your system has 8MB or less memory, the benchmarking might not work for you.

- Ok, so lets TUNE this thing!

NOTE: As you start trying to use these HDPARM commands, your system might freeze (crash). If it does, you can pretty much count on that your system not being able to run with that option. I too have done this a few times and everything came back up after a RESET. Your milage will vary and you might lose data though I have been lucky. So, first, read item #1!!!

1. Be VERY sure you have a good tape, CD-R, etc backup of your machine first. Reading the hdparm man page warns that some of these settings on a not-so-well IDE subsystems destroy your HD's data. So, YOU'VE BEEN WARNED!

2. Ok, turn on 32bit transfers on your first HD by typing in "/sbin/hdparm -c3 /dev/hda". Once that is turned on, benchmark your HD again with the "/sbin/hdparm -t -T /dev/hda". Any improvement?

NOTE: On my 486 system with the lame IDE controller, I didn't see much.

3. Next, turn on the HD's blocking mode if it isn't currently already set. To do this, get the max blocking mode using "/sbin/hdparm -I /dev/hda" and then enter in the MaxMultSect number into the command (example here is 16):


                                "/sbin/hdparm -m16 /dev/hda".  

After this setting, rebenchmark your HD.

NOTE: As mentioned in the hdparm man page, some drives will actually run SLOWER with higher BLOCK modes. Because of this, I recommend that you try multiple sizes and then re-benchmark the HD.

4. Lastly, for those of you with Mode3/4 IDE controllers with EIDE or UDMA HDs, enable the Mode3 or Mode4 PIO and UDMA mode if it isn't already set.

NOTE: This is where it begins to get risky. I truly recommend that you read the hdparm man page on the -d, -p, and -X options.

If you are ready to try it, run the command:


                                        "/sbin/hdparm -d1 -X34 /dev/hda"

Now re-run the system benchmark and see what performance differences you've gained. Once you have found the optimal performance and stability settings, you need to make sure that the settings are restored upon a HD reset and also a system reboot. To do this, I recommend to APPEND the following lines to your /etc/rc.d/rc.local file. Please note the top line is ONLY an example and will need to be replaced with your optimal settings:


#Enable the kernel to perform optimal IDE I/O
/sbin/hdparm -d1 -X34 /dev/hda

#Save the HDPARM settings over a HD reset
/sbin/hdparm -k1 /dev/hda


Next Previous Contents