From: eric@tantalus.nrl.navy.mil (Eric Youngdale)
Newsgroups: comp.os.linux
Subject: Re: Slow SCSI Disk performance.
Date: 30 Sep 92 02:46:01 GMT
Organization: Naval Research Laboratory

In article <1992Sep30.000233.29248@mnemosyne.cs.du.edu> smace@nyx.cs.du.edu (Scott Mace) writes:
>
>I have noticed that the performance of both of my scsi drives really
>hurts.  With 'iozone' I am registering about 65K/sec.  I beleive that my
>system is transfer 1  1Kblock per revelution (3600 RPM drive).  In dos I
>was getting rates of about 500K per second, this is more like whatit
>should be considering that my disk can to about 7.5 Mbits /sec.  Is
>there any patch to fix this problem, if not are there any "beta" patches
>for this problem, I would be willing to help test them.

	Please, PLEASE.  When you make a report like this, tell us what version
of the kernel you are running, and which host adapter.

	Anyway, now that I have that off my chest, I wanted to mention that we
had to intentionally cripple the I/O speed for Adaptec 1740 series boards
because of silicon bugs in the 1740.  Unfortunately, the I/O speed for *all*
scsi disks was crippled in the process, when these patches went in (0.97 pl6).
I had sent a patch to linus which would un-cripple the I/O speed for all but
the 1740, but they did not make it into 0.98.  I am enclosing these patches at
the end of this message.  I would guess that the I/O speed would roughly double
with these patches inserted.  For the aha1542, the performance increase will be
even more, because I changed some timing values.

-Eric

Patches for 0.97pl6 or 0.98 to improve SCSI disk performance:


*** linux/kernel/blk_drv/scsi/sd.c~	Sat Sep 19 13:07:04 1992
--- linux/kernel/blk_drv/scsi/sd.c	Tue Sep 29 21:40:58 1992
***************
*** 43,49 ****
--- 43,51 ----
  static int the_result;
  
  static char sense_buffer[255];
+ int slow_scsi_io = -1;  /* This is set by aha1542.c, and others, if needed */
  
+ 
  extern int sd_ioctl(struct inode *, struct file *, unsigned long, unsigned long);
  
  static void sd_release(struct inode * inode, struct file * file)
***************
*** 108,119 ****
  
  	if (!result) {
  		CURRENT->nr_sectors -= this_count;
! 		total_count -= this_count;
! 		if(total_count){
! 		  CURRENT->sector += this_count;
! 		  CURRENT->buffer += (this_count << 9);
! 		  do_sd_request();
! 		  return;
  		};
  
  #ifdef DEBUG
--- 110,123 ----
  
  	if (!result) {
  		CURRENT->nr_sectors -= this_count;
! 		if (slow_scsi_io == host) {
! 		  total_count -= this_count;
! 		  if(total_count){
! 		    CURRENT->sector += this_count;
! 		    CURRENT->buffer += (this_count << 9);
! 		    do_sd_request();
! 		    return;
! 		  };
  		};
  
  #ifdef DEBUG
***************
*** 255,264 ****
  		this_count = CURRENT->nr_sectors;
  	else
  		this_count = (BLOCK_SIZE / 512);
  /* This is a temporary hack for the AHA1742. */
! 	if(total_count == 0)
! 	  total_count = this_count;
! 	this_count = 1;  /* Take only 512 bytes at a time */
  
  #ifdef DEBUG
  	printk("sd%d : %s %d/%d 512 byte blocks.\n", MINOR(CURRENT->dev), 
--- 259,272 ----
  		this_count = CURRENT->nr_sectors;
  	else
  		this_count = (BLOCK_SIZE / 512);
+ 
+ 
  /* This is a temporary hack for the AHA1742. */
! 	if(slow_scsi_io == HOST) {
! 	  if(total_count == 0)
! 	    total_count = this_count;
! 	  this_count = 1;  /* Take only 512 bytes at a time */
! 	};
  
  #ifdef DEBUG
  	printk("sd%d : %s %d/%d 512 byte blocks.\n", MINOR(CURRENT->dev), 
*** linux/kernel/blk_drv/scsi/aha1542.c~	Sat Sep 19 13:14:20 1992
--- linux/kernel/blk_drv/scsi/aha1542.c	Tue Sep 29 21:58:45 1992
***************
*** 32,37 ****
--- 32,39 ----
  static struct mailbox mb[2];
  static struct ccb ccb;
  
+ extern int slow_scsi_io;
+ 
  long WAITtimeout, WAITnexttimeout = 3000000;
  
  void (*do_done)(int, int) = NULL;
***************
*** 389,395 ****
  }
  
  /* Query the board to find out if it is a 1542 or a 1740, or whatever. */
! static void aha1542_query()
  {
    static unchar inquiry_cmd[] = {CMD_INQUIRY };
    static unchar inquiry_result[4];
--- 391,397 ----
  }
  
  /* Query the board to find out if it is a 1542 or a 1740, or whatever. */
! static void aha1542_query(int hostnum)
  {
    static unchar inquiry_cmd[] = {CMD_INQUIRY };
    static unchar inquiry_result[4];
***************
*** 397,403 ****
    i = inb(STATUS);
    if (i & DF) {
      i = inb(DATA);
-     printk("Stale data:%x ");
    };
    aha1542_out(inquiry_cmd, 1);
    aha1542_in(inquiry_result, 4);
--- 399,404 ----
***************
*** 406,414 ****
    fail:
      printk("aha1542_detect: query card type\n");
    }
!       aha1542_intr_reset();
!   printk("Inquiry:");
!   for(i=0;i<4;i++) printk("%x ",inquiry_result[i]);
  }
  /* return non-zero on detection */
  int aha1542_detect(int hostnum)
--- 407,424 ----
    fail:
      printk("aha1542_detect: query card type\n");
    }
!   aha1542_intr_reset();
! 
! /* For an AHA1740 series board, we select slower I/O because there is a
!    hardware bug which can lead to wrong blocks being returned.  The slow
!    I/O somehow prevents this.  Once we have drivers for extended mode
!    on the aha1740, this will no longer be required.
! */
! 
!   if (inquiry_result[0] == 0x43) {
!     slow_scsi_io = hostnum;
!     printk("aha1542.c: Slow SCSI disk I/O selected for AHA 174N hardware.\n");
!   };
  }
  /* return non-zero on detection */
  int aha1542_detect(int hostnum)
***************
*** 421,430 ****
  	return 0;
      }
   
      /* Set the Bus on/off-times as not to ruin floppy performens */
      {
! 	static unchar oncmd[] = {CMD_BUSON_TIME, 5};
! 	static unchar offcmd[] = {CMD_BUSOFF_TIME, 9};
  	
  	aha1542_intr_reset();
  	aha1542_out(oncmd, 2);
--- 431,445 ----
  	return 0;
      }
   
+ #if MAX_MEGABYTES > 16
+   printk("Adaptec 1542 disabled for kernels for which MAX_MEGABYTES > 16.\n");
+   return 0;
+ #endif
+ 
      /* Set the Bus on/off-times as not to ruin floppy performens */
      {
! 	static unchar oncmd[] = {CMD_BUSON_TIME, 9};
! 	static unchar offcmd[] = {CMD_BUSOFF_TIME, 5};
  	
  	aha1542_intr_reset();
  	aha1542_out(oncmd, 2);
***************
*** 438,444 ****
  	}
  	aha1542_intr_reset();
      }
!     aha1542_query();
  
      DEB(aha1542_stat());
      setup_mailboxes();
--- 453,459 ----
  	}
  	aha1542_intr_reset();
      }
!     aha1542_query(hostnum);
  
      DEB(aha1542_stat());
      setup_mailboxes();
-- 
Eric Youngdale
eric@tantalus.nrl.navy.mil