[1511] in linux-scsi channel archive
Re: elevator sorting for the scsi subsystem.
daemon@ATHENA.MIT.EDU (Dario_Ballabio@milano.europe.dg.co)
Wed Mar 5 06:53:52 1997
Date: Wed, 5 Mar 1997 11:44:05 +0100
From: Dario_Ballabio@milano.europe.dg.com
To: linux-scsi@vger.rutgers.edu, lnz@dandelion.com
%UATTACH
> This discussion raised several interesting points:
>
> 1) we have to understand how and why the kernel queues to a scsi devices
> batches of commands where there is at least a write request and there
> are overlapping requests inside the batch;
>
> 2) the "sawtooth" in ll_rw_blk doubles the average seek distance
> compared to an equivalent elevator sorting implementation;
>
> 3) if Q is the device queue depth, any kernel optimization totally
> relies on the tagging feature whenever the number of outstanding
> requests is non greater than Q.
>
> 1) Might or might not be a bug, it needs to be understood better. It
> is a rare event, if sometimes it would show up here and there in
> the world and it would cause a disk corruption, we would surely
> call it an "unlikely transient hardware error" (I'm thinking about
> "intelligent" disk controllers and buggy tag implementations on
> the drives).
>
> 2) There is space for future improvements.
>
> 3) This point can be defined by a suitable benchmark. I know exactely
> what a software implementation of the elevator sorting can provide.
> I'm doing random reads, 512 bytes each, over 960000 sectors. The
> unsorted average seek distance is 320000 sectors. If the device
> queue depth is 15 and there are 15 processes doing the above work,
> the elevator sorted average seek distance is 67000 sectors. The
> gain in term of seek reduction is 5:1. In this condition no sort
> is performed by ll_rw_blk. I would like to see results of the
> above benchmark using SIMPLE QUEUE TAGS first and ORDERED QUEUE
> TAGS next for all the operations. This allows us to evaluate out
> of any discussion the benefits of the current implementation
> where all the optimization is left to the scsi drive.
>
> Anybody willing to perform such a benchmark and let us know the
> results?
>
> db
I run the benchmark that I suggested and I'll show the results.
I did 500 random reads over 960000 sectors on the FUJITSU drive (/dev/sdb).
There were 30 simoultaneous processes doing fully independent random reads
over the sdb drive. The activation script is:
date
>result
for i in 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10
do
disktest /dev/sdb scsi520 500 512 100 r 960000 >>result &
done
sleep 5
killall -USR2 disktest
wait
date
The diskest program takes as arguments:
- the device;
- an (unused) config file;
- number of operations;
- percentage of reads;
- operation lenght in bytes;
- either r (random) or s (sequential);
- number of sectors to seek on.
All the processes wait for the USR2 signal before starting.
Here is my configuration:
Kernel logging (proc) started.
Console: 16 point font, 400 scans
Console: colour VGA+ 80x25, 1 virtual console (max 63)
Calibrating delay loop.. ok - 23.91 BogoMIPS
Memory: 14900k/16384k available (620k kernel code, 384k reserved, 480k data)
Swansea University Computer Society NET3.035 for Linux 2.0
NET3: Unix domain sockets 0.13 for Linux NET3.035.
Swansea University Computer Society TCP/IP for NET3.034
IP Protocols: ICMP, UDP, TCP
Checking 386/387 coupling... Hmm, FDIV bug i586 system
Checking 'hlt' instruction... Ok.
Linux version 2.0.29 (root@pc-dario.europe.dg.com) (gcc version 2.7.2.1) #6
Mon Mar 3 09:31:52 MET 1997
Serial driver version 4.13 with no serial options enabled
tty00 at 0x03f8 (irq = 4) is a 16550A
tty01 at 0x02f8 (irq = 3) is a 16550A
PS/2 auxiliary pointing device detected -- driver installed.
Ramdisk driver initialized : 16 ramdisks of 4096K size
Floppy drive(s): fd0 is 1.44M
FDC 0 is an 8272A
Started kswapd v 1.4.2.2
md driver 0.35 MAX_MD_DEV=4, MAX_REAL=8
linear personality registered
raid0 personality registered
EATA0: 2.0B, EISA 0x5c88, IRQ 15, BMST, SG 64, MB 64, tc:n, lc:y, mq:62.
EATA0: SCSI channel 0 enabled, host target ID 7.
EATA1: 2.0B, EISA 0x6c88, IRQ 11, BMST, SG 64, MB 64, tc:n, lc:y, mq:62.
EATA1: SCSI channel 0 enabled, host target ID 7.
EATA/DMA 2.0x: Copyright (C) 1994-1997 Dario Ballabio.
scsi0 : EATA/DMA 2.0x rev. 3.10.00
scsi1 : EATA/DMA 2.0x rev. 3.10.00
scsi : 2 hosts.
Vendor: IBM OEM Model: 0662S08 EE Rev: DG06
Type: Direct-Access ANSI SCSI revision: 02
Detected scsi disk sda at scsi0, channel 0, id 0, lun 0
Vendor: ARCHIVE Model: VIPER 150 25087 Rev: -003
Type: Sequential-Access ANSI SCSI revision: 01
Detected scsi tape st0 at scsi0, channel 0, id 2, lun 0
Vendor: FUJITSU Model: M2624F-512 EO Rev: DG03
Type: Direct-Access ANSI SCSI revision: 02
Detected scsi disk sdb at scsi0, channel 0, id 5, lun 0
EATA0: scsi0, channel 0, id 0, lun 0, cmds/lun 31, linked, untagged.
EATA0: scsi0, channel 0, id 2, lun 0, cmds/lun 2.
EATA0: scsi0, channel 0, id 5, lun 0, cmds/lun 31, linked, untagged.
Vendor: FUJITSU Model: M2624F-512 EO Rev: DG03
Type: Direct-Access ANSI SCSI revision: 02
Detected scsi disk sdc at scsi1, channel 0, id 0, lun 0
Vendor: MICROP Model: 1684-07 HZ Rev: DG03
Type: Direct-Access ANSI SCSI revision: 01 CCS
Detected scsi disk sdd at scsi1, channel 0, id 1, lun 0
Vendor: SEAGATE Model: ST1480 Rev: 5736
Type: Direct-Access ANSI SCSI revision: 02
Detected scsi disk sde at scsi1, channel 0, id 5, lun 0
Vendor: DPT Model: PM3224A - W Rev: 07G0
Type: Processor ANSI SCSI revision: 02
Detected scsi generic sgg at scsi1, channel 0, id 6, lun 0
EATA1: scsi1, channel 0, id 0, lun 0, cmds/lun 20, linked, untagged.
EATA1: scsi1, channel 0, id 1, lun 0, cmds/lun 20, linked.
EATA1: scsi1, channel 0, id 5, lun 0, cmds/lun 20, linked, untagged.
EATA1: scsi1, channel 0, id 6, lun 0, cmds/lun 2.
scsi : detected 1 SCSI tape 5 SCSI disks total.
SCSI device sda: hdwr sector= 512 bytes. Sectors= 1015812 [496 MB] [0.5 GB]
SCSI device sdb: hdwr sector= 512 bytes. Sectors= 1015812 [496 MB] [0.5 GB]
SCSI device sdc: hdwr sector= 512 bytes. Sectors= 1015812 [496 MB] [0.5 GB]
SCSI device sdd: hdwr sector= 512 bytes. Sectors= 663476 [323 MB] [0.3 GB]
SCSI device sde: hdwr sector= 512 bytes. Sectors= 832527 [406 MB] [0.4 GB]
SLIP: version 0.8.4-NET3.019-NEWTTY (dynamic channels, max=256).
CSLIP: code copyright 1989 Regents of the University of California.
SLIP linefill/keepalive option.
eth0: 3c509 at 0x300 tag 1, AUI port, address 00 20 af 0a 19 81, IRQ 5.
3c509.c:1.07 6/15/95 becker@cesdis.gsfc.nasa.gov
Partition check:
sda: sda1 sda2 sda3
sdb: sdb1 sdb2 sdb3
sdc: sdc1
sdd: sdd1
sde: sde1
VFS: Mounted root (ext2 filesystem) readonly.
fc 200 bc 2 ic 2 oc 0 rc 5 rs 0 sc 0 re 0 av 63K as 63K.
Adding Swap: 13996k swap-space
Adding Swap: 14996k swap-space
fc 400 bc 2 ic 2 oc 0 rc 5 rs 0 sc 0 re 0 av 63K as 63K.
fc 600 bc 2 ic 2 oc 0 rc 5 rs 0 sc 0 re 0 av 63K as 63K.
fc 800 bc 3 ic 3 oc 0 rc 9 rs 0 sc 0 re 0 av 106K as 106K.
fc 1000 bc 16 ic 12 oc 0 rc 94 rs 42 sc 3 re 2 av 83K as 61K.
fc 1200 bc 17 ic 13 oc 0 rc 96 rs 44 sc 3 re 3 av 87K as 64K.
fc 1400 bc 21 ic 16 oc 0 rc 104 rs 48 sc 4 re 4 av 89K as 67K.
login: ROOT LOGIN ON tty1
fc 1600 bc 36 ic 21 oc 0 rc 215 rs 117 sc 7 re 12 av 85K as 63K.
fc 1800 bc 100 ic 81 oc 0 rc 1850 rs 1710 sc 36 re 40 av 280K as 36K.
fc 2000 bc 276 ic 257 oc 0 rc 6953 rs 6813 sc 124 re 128 av 307K as 32K.
fc 2200 bc 440 ic 421 oc 0 rc 11709 rs 11569 sc 206 re 210 av 313K as 32K.
fc 2400 bc 572 ic 551 oc 0 rc 15188 rs 15037 sc 269 re 274 av 313K as 32K.
In the above log the undocumented "ls:200" debug option was enabled and
the benchmark was running immediately after boot.
fc number of times that the driver queue to the device has been flushed.
bc number of batches (a batch is counted only if it has 2 or more requests).
ic number of batches including only input scsi commands.
oc number of batches with at least an overlapping write request.
rc total number of requests in bc batches.
rs number of requests (among the rc) that have been sorted.
sc sort count
re reverse sort count
av average seek distance seen by the driver (i.e. before sorting).
as average seek distance after the driver elevator sorting.
You can nitice the following.
- rc/bc = 26.5 = average batch length.
- 15037 batches out of 15188 had to be sorted (or revsorted).
- The average seek distance generated by the benchmark is 320K, while the
seek distance measured by the driver is 313K, i.e. the kernel did not
sort anything. In fact if ll_rw_blk.c would have done some sorting, we would
see here a seek distance much lower than 320K.
- the average seek distance after elevator sorting is 32K, well in line
with the theoric value 10:1 (the benchmark had 30 simoultaneous processes,
30/3 = 10 is the expected seek reduction factor);
Here the results with elevator sorting enabled (boot option lc:y).
...the portion of the "result" file for the first process completed.
Disk Under Test: /dev/sdb
\011Results for drive /dev/sdb:
No. Iterations: 500
IO Size: 512 bytes
No. Reads: 500
Read Pct: 100.0
Actual Read Pct: 100.0
Seek Policy: randomly seek up to bk 960000
Average Seek: 332302.6 bks
Minimum Time: 0.0 mS
Maximum Time: 960.0 mS
Average Time: 493.1 mS
Std Deviation: 196.0 mS
Throughput: 2.0 ios/sec
1.0 kB/sec
...the portion of the "result" file for the last process completed.
Disk Under Test: /dev/sdb
\011Results for drive /dev/sdb:
No. Iterations: 500
IO Size: 512 bytes
No. Reads: 500
Read Pct: 100.0
Actual Read Pct: 100.0
Seek Policy: randomly seek up to bk 960000
Average Seek: 293228.0 bks
Minimum Time: 0.0 mS
Maximum Time: 970.0 mS
Average Time: 485.7 mS
Std Deviation: 197.6 mS
Throughput: 2.1 ios/sec
1.0 kB/sec
The aggregate throughput is 2.0 * 30 = 60 operations/second.
Here the results when elevator sorting is *not* enabled (boot option lc:n).
...the portion of the "result" file for the first process completed.
Disk Under Test: /dev/sdb
\011Results for drive /dev/sdb:
No. Iterations: 500
IO Size: 512 bytes
No. Reads: 500
Read Pct: 100.0
Actual Read Pct: 100.0
Seek Policy: randomly seek up to bk 960000
Average Seek: 322257.1 bks
Minimum Time: 20.0 mS
Maximum Time: 730.0 mS
Average Time: 626.0 mS
Std Deviation: 61.4 mS
Throughput: 1.6 ios/sec
0.8 kB/sec
...the portion of the "result" file for the last process completed.
Disk Under Test: /dev/sdb
\011Results for drive /dev/sdb:
No. Iterations: 500
IO Size: 512 bytes
No. Reads: 500
Read Pct: 100.0
Actual Read Pct: 100.0
Seek Policy: randomly seek up to bk 960000
Average Seek: 327123.7 bks
Minimum Time: 0.0 mS
Maximum Time: 730.0 mS
Average Time: 623.8 mS
Std Deviation: 75.6 mS
Throughput: 1.6 ios/sec
0.8 kB/sec
The aggregate throughput is 1.6 * 30 = 48 operations/second.
I this case the elevator sorting raised the i/o rate from 48 to 60 i/o sec.,
which is a 25% performance improvement.
I run the above benchmark and got the above performance without specifying
any explicit scsi tagging (boot option tc:n).
I run the same test using SIMPLE QUEUE TAGS (boot option tc:y,tm:1) with
and without elevator sorting and the numbers did not change at all.
I run using ORDERED QUEUE TAGS (boot option tc:y,tm:3) and again no change
at all. I did the same test on the other 2 drives supporting the queue tagging:
Vendor: SEAGATE Model: ST1480 Rev: 5736
Vendor: IBM OEM Model: 0662S08 EE Rev: DG06
and again no difference at all using either simple, or ordered or no tagging
at all.
Here enclosed the test program used. It would be useful if somebody
else could show the results in different configurations.
db
begin 664 disktest.tar.gz
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
L8!^<>\MR7^[+?;DO]^6^W)?[<E_NRWVY+_?EOMR7^_*7E_\%NX,L_P!X``"3
`
end