From: drew@hazelrah.cs.colorado.edu (Drew Eckhardt) Subject: Seagate scatter / gather patches Date: Thu, 28 Jan 1993 00:01:42 GMT
Ok, here's the first installment of the Seagate patches, This one
implements scatter-gather (I saw a 4X speed improvement). As far
as CPU usage and "hanging" - things should improve if your filesystems
aren't too fragmented.
Note that the current Seagate routines will not transfer >
~500-600K/sec. If your disk is faster than this, you'll have to
format at something greater than a 1:1 interleave if you want to
see the same four-fold performance increase.
I have another patch on the way that will allow the use of the
Seagate's hardware handshaking, it will be posted "RSN" (the
definition of RSN being somewhere between a few hours and six months).
It should rectify the maximum transfer rate restriction.
Here are some figures for your perusal :
IOZONE results (using recommended file sizes, minix filesystems).
To reduce buffer cache size (and therefore required filesize under
IOZONE), I loaded the memory by running X11R5 + 3 xterms + xman + xload +
xsysinfo + twm.
System : i386-33, 8M main memory, 64K cache
SCSI host : Seagate ST02
Software : Linux .99.3
Disk : /dev/sda3 Seagate 296N, 3:1 interleave
Writing the 3 Megabyte file, 'iozone.tmp'...50.610000 seconds
Reading the file...62.110000 seconds
IOZONE performance measurements:
62156 bytes/second for writing the file
50647 bytes/second for reading the file
Software : Linux .99.4 + Seagate Scatter / Gather patches
Disk : /dev/sda3 Seagate 296N, 3:1 interleave
Writing the 3 Megabyte file, 'iozone.tmp'...12.840000 seconds
Reading the file...16.120000 seconds
IOZONE performance measurements:
244994 bytes/second for writing the file
195144 bytes/second for reading the file
And, as a baseline :
Software : Linux .99.4 + Seagate Scatter / Gather patches
Disk : /dev/hda2 Seagate 1144A 1:1 interleave
Writing the 3 Megabyte file, 'iozone.tmp'...7.500000 seconds
Reading the file...15.520000 seconds
IOZONE performance measurements:
419430 bytes/second for writing the file
202688 bytes/second for reading the file
Software : Linux .99.3
The patch :
*** 1.1 1993/01/27 20:33:13
--- linux/kernel/blk_drv/scsi/seagate.c 1993/01/27 22:16:53
***************
*** 225,230 ****
--- 225,233 ----
static unsigned char current_target, current_lun;
static unsigned char *current_cmnd, *current_data;
+ static int current_nobuffs;
+ static struct scatterlist *current_buffer;
+
static int current_bufflen;
static void (*done_fn)(Scsi_Cmnd *) = NULL;
static Scsi_Cmnd * SCint = NULL;
***************
*** 353,358 ****
--- 356,363 ----
{
int len;
unsigned char *data;
+ struct scatterlist *buffer;
+ int nobuffs;
int clock;
int temp;
Scsi_Cmnd * SCtmp;
***************
*** 371,379 ****
unsigned char message = 0;
register unsigned char status_read;
- len=bufflen;
- data=(unsigned char *) buff;
-
incommand = 0;
st0x_aborted = 0;
--- 376,381 ----
***************
*** 455,463 ****
hostno, temp);
return (DID_BAD_INTR << 16);
}
! data=current_data; /* WDE add */
cmnd=current_cmnd; /* WDE add */
len=current_bufflen; /* WDE add */
/*
* We have determined that we have been selected. At this point,
--- 457,468 ----
hostno, temp);
return (DID_BAD_INTR << 16);
}
!
! buffer=current_buffer;
cmnd=current_cmnd; /* WDE add */
+ data=current_data; /* WDE add */
len=current_bufflen; /* WDE add */
+ nobuffs=current_nobuffs;
/*
* We have determined that we have been selected. At this point,
***************
*** 606,611 ****
--- 611,629 ----
}
return retcode(st0x_aborted);
}
+
+ /* Establish current pointers. Take into account scatter / gather */
+
+ if ((nobuffs = SCint->use_sg)) {
+ buffer = (struct scatterlist *) SCint->buffer;
+ len = buffer->length;
+ data = (unsigned char *) buffer->address;
+ } else {
+ buffer = NULL;
+ len = SCint->bufflen;
+ data = (unsigned char *) SCint->buffer;
+ }
+
}
CONTROL = BASE_CMD | CMD_DRVR_ENABLE |
***************
*** 748,753 ****
--- 766,779 ----
/* clobbered */
"ebx", "ecx", "edi", "esi");
+ if (!len && nobuffs) {
+ --nobuffs;
+ ++buffer;
+ len = buffer->length;
+ data = (unsigned char *) buffer->address;
+ }
+
+
break;
case REQ_DATAIN :
***************
*** 811,816 ****
--- 837,850 ----
"0" (data), "1" (len) :
/* clobbered */
"ebx", "ecx", "edi", "esi");
+
+ if (!len && nobuffs) {
+ --nobuffs;
+ ++buffer;
+ len = buffer->length;
+ data = (unsigned char *) buffer->address;
+ }
+
break;
case REQ_CMDOUT :
***************
*** 858,864 ****
--- 892,901 ----
case DISCONNECT :
should_reconnect = 1;
current_data = data; /* WDE add */
+ current_buffer = buffer;
current_bufflen = len; /* WDE add */
+ current_nobuffs = nobuffs;
+
#if (DEBUG & (PHASE_RESELECT | PHASE_MSGIN))
printk("scsi%d : disconnected.\n", hostno);
done=1;
***************
*** 877,891 ****
done=1;
break;
case SAVE_POINTERS :
! current_data = data; /* WDE mod */
current_bufflen = len; /* WDE add */
#if (DEBUG & PHASE_MSGIN)
printk("scsi%d : pointers saved.\n", hostno);
#endif
break;
case RESTORE_POINTERS:
! data=current_data; /* WDE mod */
cmnd=current_cmnd;
#if (DEBUG & PHASE_MSGIN)
printk("scsi%d : pointers restored.\n", hostno);
#endif
--- 914,933 ----
done=1;
break;
case SAVE_POINTERS :
! current_buffer = buffer;
current_bufflen = len; /* WDE add */
+ current_data = data; /* WDE mod */
+ current_nobuffs = nobuffs;
#if (DEBUG & PHASE_MSGIN)
printk("scsi%d : pointers saved.\n", hostno);
#endif
break;
case RESTORE_POINTERS:
! buffer=current_buffer;
cmnd=current_cmnd;
+ data=current_data; /* WDE mod */
+ len=current_bufflen;
+ nobuffs=current_nobuffs;
#if (DEBUG & PHASE_MSGIN)
printk("scsi%d : pointers restored.\n", hostno);
#endif
-- Boycott AT&T for their absurd anti-BSDI lawsuit. | Drew Eckhardt Condemn Colorado for Amendment Two. | drew@cs.colorado.edu Use Linux, the fast, flexible, and free 386 unix |