[7742] in linux-scsi channel archive
SCSI queueing status.
daemon@ATHENA.MIT.EDU (Eric Youngdale)
Thu Dec 23 00:58:11 1999
Message-ID: <003c01bf4cdd$f9407e20$7f66420c@zydeco>
From: "Eric Youngdale" <eric@andante.org>
To: <linux-scsi@vger.rutgers.edu>
Cc: "Peter Rival" <frival@zk3.dec.com>,
"Christoph Rohland" <hans-christoph.rohland@sap.com>,
<frankeh@us.ibm.com>, "Tim Waugh" <twaugh@redhat.com>
Date: Thu, 23 Dec 1999 00:37:30 -0000
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="----=_NextPart_000_0030_01BF4CDD.E4FC8120"
This is a multi-part message in MIME format.
------=_NextPart_000_0030_01BF4CDD.E4FC8120
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
I have figured out a couple more of the open issues. I *believe* that this
may correct all of the outstanding issues as of last night (details below),
that is of course assuming that the patches themselves don't break anything.
Also, I am flying a little blind here, as I cannot test live kernels until I
get back home from Christmas, so I don't want to forward patches to Linus
until I get good feedback from a number of people.
I am enclosing cumulative diffs against 2.3.34.
1) The problem with HIGHMEM is that in ll_rw_blk.c we are automatically
getting a bounce buffer, but from this it is impossible to do queue
management to combine requests. I simply added some code to dereference the
thing. The fix is a bit of a hack, but I don't completely understand
HIGHMEM anyways, so this will do for now, I guess.
2) Some people were reporting problems scanning the bus with ppa and imm
host adapters. The problem here was that I was incrementing the host usage
count too soon, and thus hosts that could only queue a single command would
deadlock attempting to scan the bus. I think I have fixed this - it was a
relic of the old way of doing things (and a maintainence problem as well) to
bump the usage count in two separate functions. I moved this over so that
it is all done in the same place now. There is a danger that I missed
something here, and thus there is a slight possibility that usage counts
will get out of synch and the system will wedge.
3) The problem involving > 16 disks was a weird one. The symptom was that
ext2 didn't recognize the superblock, and as a result it went onto the next
filesystem - iso9660 in this case. There were spew messages on the console
complaining about the fact that the disk drive didn't support multi-session.
There were actually two bugs - the first one I had fixed some time ago. I
am not 100% certain that I have fixed the second bug, but I believe the
underlying problem was caused by the incorrect usage of the MINOR() macro in
sd.c. Whether or not this fully corrects the problem, the second thing was
a real bug.
4) I fixed a bug in a previous patch which would have probably led to
spurious messages about running low on DMA memory.
-Eric
------=_NextPart_000_0030_01BF4CDD.E4FC8120
Content-Type: application/octet-stream;
name="linux34.diff"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="linux34.diff"
Index: linux/drivers/scsi/hosts.h=0A=
diff -c linux/drivers/scsi/hosts.h:1.1.1.2 linux/drivers/scsi/hosts.h:1.2=0A=
*** linux/drivers/scsi/hosts.h:1.1.1.2 Sat Dec 18 18:33:45 1999=0A=
--- linux/drivers/scsi/hosts.h Wed Dec 22 02:41:24 1999=0A=
***************=0A=
*** 437,442 ****=0A=
--- 437,444 ----=0A=
struct module * module; /* Used for loadable modules */=0A=
unsigned char scsi_type;=0A=
unsigned char major;=0A=
+ unsigned char min_major; /* Minimum major in range. */ =0A=
+ unsigned char max_major; /* Maximum major in range. */=0A=
unsigned char nr_dev; /* Number currently attached */=0A=
unsigned char dev_noticed; /* Number of devices detected. */=0A=
unsigned char dev_max; /* Current size of arrays */=0A=
***************=0A=
*** 447,453 ****=0A=
void (*finish)(void); /* Perform initialization after attachment =
*/=0A=
int (*attach)(Scsi_Device *); /* Attach devices to arrays */=0A=
void (*detach)(Scsi_Device *);=0A=
! int (*init_command)(Scsi_Cmnd *); /* Used by new queueing =
code. */=0A=
};=0A=
=0A=
extern struct Scsi_Device_Template sd_template;=0A=
--- 449,456 ----=0A=
void (*finish)(void); /* Perform initialization after attachment =
*/=0A=
int (*attach)(Scsi_Device *); /* Attach devices to arrays */=0A=
void (*detach)(Scsi_Device *);=0A=
! int (*init_command)(Scsi_Cmnd *); /* Used by new queueing =
code. =0A=
! Selects command for blkdevs =
*/=0A=
};=0A=
=0A=
extern struct Scsi_Device_Template sd_template;=0A=
Index: linux/drivers/scsi/scsi.c=0A=
diff -c linux/drivers/scsi/scsi.c:1.1.1.4 linux/drivers/scsi/scsi.c:1.3=0A=
*** linux/drivers/scsi/scsi.c:1.1.1.4 Wed Dec 22 10:28:43 1999=0A=
--- linux/drivers/scsi/scsi.c Wed Dec 22 02:41:24 1999=0A=
***************=0A=
*** 1470,1478 ****=0A=
*/=0A=
=0A=
=0A=
- host->host_busy++;=0A=
- device->device_busy++;=0A=
- =0A=
/*=0A=
* Our own function scsi_done (which marks the host as not busy, =
disables=0A=
* the timeout counter, etc) will be called by us or by the=0A=
--- 1470,1475 ----=0A=
***************=0A=
*** 1575,1580 ****=0A=
--- 1572,1580 ----=0A=
* Since serial_number is now 0, the error handler cound detect this=0A=
* situation and avoid to call the the low level driver abort routine.=0A=
* (DB)=0A=
+ *=0A=
+ * FIXME(eric) - I believe that this test is now redundant, =
due to=0A=
+ * the test of the return status of del_timer().=0A=
*/=0A=
if (SCpnt->state =3D=3D SCSI_STATE_TIMEOUT) {=0A=
SCSI_LOG_MLCOMPLETE(1, printk("Ignoring completion of %p due to =
timeout status", SCpnt));=0A=
Index: linux/drivers/scsi/scsi_error.c=0A=
diff -c linux/drivers/scsi/scsi_error.c:1.1.1.4 =
linux/drivers/scsi/scsi_error.c:1.4=0A=
*** linux/drivers/scsi/scsi_error.c:1.1.1.4 Wed Dec 22 10:28:44 1999=0A=
--- linux/drivers/scsi/scsi_error.c Wed Dec 22 02:41:24 1999=0A=
***************=0A=
*** 1778,1783 ****=0A=
--- 1778,1794 ----=0A=
for (SCpnt =3D SCdone; SCpnt !=3D NULL; SCpnt =3D SCdone) {=0A=
SCdone =3D SCpnt->bh_next;=0A=
SCpnt->bh_next =3D NULL;=0A=
+ /*=0A=
+ * Oh, this is a vile hack. scsi_done() expects a =
timer=0A=
+ * to be running on the command. If there isn't, it =
assumes=0A=
+ * that the command has actually timed out, and a timer=0A=
+ * handler is running. That may well be how we got =
into=0A=
+ * this fix, but right now things are stable. We add=0A=
+ * a timer back again so that we can report completion.=0A=
+ * scsi_done() will immediately remove said timer from=0A=
+ * the command, and then process it.=0A=
+ */=0A=
+ scsi_add_timer(SCpnt, 100, scsi_eh_times_out);=0A=
scsi_done(SCpnt);=0A=
}=0A=
=0A=
***************=0A=
*** 1809,1815 ****=0A=
--- 1820,1833 ----=0A=
int rtn;=0A=
DECLARE_MUTEX_LOCKED(sem);=0A=
=0A=
+ /*=0A=
+ * We only listen to signals if the HA was loaded as a module.=0A=
+ * If the HA was compiled into the kernel, then we don't listen=0A=
+ * to any signals.=0A=
+ */=0A=
+ if( host->loaded_as_module ) {=0A=
siginitsetinv(¤t->blocked, SHUTDOWN_SIGS);=0A=
+ }=0A=
=0A=
lock_kernel();=0A=
=0A=
***************=0A=
*** 1844,1853 ****=0A=
--- 1862,1875 ----=0A=
* trying to unload a module.=0A=
*/=0A=
SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler sleeping\n"));=0A=
+ if( host->loaded_as_module ) {=0A=
down_interruptible(&sem);=0A=
=0A=
if (signal_pending(current))=0A=
break;=0A=
+ } else {=0A=
+ down(&sem);=0A=
+ }=0A=
=0A=
SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler waking up\n"));=0A=
=0A=
Index: linux/drivers/scsi/scsi_lib.c=0A=
diff -c linux/drivers/scsi/scsi_lib.c:1.1.1.3 =
linux/drivers/scsi/scsi_lib.c:1.3=0A=
*** linux/drivers/scsi/scsi_lib.c:1.1.1.3 Wed Dec 22 10:28:45 1999=0A=
--- linux/drivers/scsi/scsi_lib.c Wed Dec 22 02:41:24 1999=0A=
***************=0A=
*** 607,612 ****=0A=
--- 607,628 ----=0A=
if (spnt->blk && spnt->major =3D=3D major) {=0A=
return spnt;=0A=
}=0A=
+ /*=0A=
+ * I am still not entirely satisfied with this solution,=0A=
+ * but it is good enough for now. Disks have a number of=0A=
+ * major numbers associated with them, the primary=0A=
+ * 8, which we test above, and a secondary range of 7=0A=
+ * different consecutive major numbers. If this ever=0A=
+ * becomes insufficient, then we could add another function=0A=
+ * to the structure, and generalize this completely.=0A=
+ */=0A=
+ if( spnt->min_major !=3D 0 =0A=
+ && spnt->max_major !=3D 0=0A=
+ && major >=3D spnt->min_major=0A=
+ && major <=3D spnt->max_major )=0A=
+ {=0A=
+ return spnt;=0A=
+ }=0A=
}=0A=
return NULL;=0A=
}=0A=
***************=0A=
*** 742,750 ****=0A=
if (!SCpnt) {=0A=
break;=0A=
}=0A=
- SHpnt->host_busy++;=0A=
- SDpnt->device_busy++;=0A=
}=0A=
=0A=
/*=0A=
* FIXME(eric)=0A=
--- 758,771 ----=0A=
if (!SCpnt) {=0A=
break;=0A=
}=0A=
}=0A=
+ =0A=
+ /*=0A=
+ * Now bump the usage count for both the host and the=0A=
+ * device.=0A=
+ */=0A=
+ SHpnt->host_busy++;=0A=
+ SDpnt->device_busy++;=0A=
=0A=
/*=0A=
* FIXME(eric)=0A=
Index: linux/drivers/scsi/scsi_merge.c=0A=
diff -c linux/drivers/scsi/scsi_merge.c:1.1.1.3 =
linux/drivers/scsi/scsi_merge.c:1.3=0A=
*** linux/drivers/scsi/scsi_merge.c:1.1.1.3 Wed Dec 22 10:28:45 1999=0A=
--- linux/drivers/scsi/scsi_merge.c Wed Dec 22 02:41:25 1999=0A=
***************=0A=
*** 290,295 ****=0A=
--- 290,319 ----=0A=
=0A=
count =3D bh->b_size >> 9;=0A=
sector =3D bh->b_rsector;=0A=
+ #if CONFIG_HIGHMEM=0A=
+ /*=0A=
+ * This is a temporary hack for the time being.=0A=
+ * In some cases, the ll_rw_blk layer is creating=0A=
+ * bounce buffers for us - this implies that we don't=0A=
+ * need to down here, but queue management becomes quite=0A=
+ * difficult otherwise. When the ll_rw_blk layer gets=0A=
+ * cleaned up to handle bounce buffers better, then=0A=
+ * this hack can be cleaned up.=0A=
+ */=0A=
+ if( sector =3D=3D -1 )=0A=
+ {=0A=
+ struct buffer_head * bh_new;=0A=
+ bh_new =3D (struct buffer_head *) bh->b_dev_id;=0A=
+ if( bh_new !=3D NULL )=0A=
+ {=0A=
+ sector =3D bh_new->b_rsector;=0A=
+ }=0A=
+ if( sector =3D=3D -1 )=0A=
+ {=0A=
+ panic("Unable to merge ambiguous block request");=0A=
+ }=0A=
+ }=0A=
+ #endif=0A=
=0A=
/*=0A=
* We come in here in one of two cases. The first is that we=0A=
***************=0A=
*** 765,771 ****=0A=
if( scsi_dma_free_sectors > 30 ) {=0A=
for (this_count =3D 0, bh =3D SCpnt->request.bh;=0A=
bh; bh =3D bh->b_reqnext) {=0A=
! if( scsi_dma_free_sectors < 30 || this_count =3D=3D sectors )=0A=
{=0A=
break;=0A=
}=0A=
--- 789,796 ----=0A=
if( scsi_dma_free_sectors > 30 ) {=0A=
for (this_count =3D 0, bh =3D SCpnt->request.bh;=0A=
bh; bh =3D bh->b_reqnext) {=0A=
! if( scsi_dma_free_sectors - this_count < 30 =0A=
! || this_count =3D=3D sectors )=0A=
{=0A=
break;=0A=
}=0A=
***************=0A=
*** 831,854 ****=0A=
* We always force "_VALID" to 1. Eventually clean this up=0A=
* and get rid of the extra argument.=0A=
*/=0A=
- #if 0=0A=
- /* Old definitions */=0A=
- INITIO(scsi_init_io_, 0, 0, 0)=0A=
- INITIO(scsi_init_io_d, 0, 0, 1)=0A=
- INITIO(scsi_init_io_c, 0, 1, 0)=0A=
- INITIO(scsi_init_io_dc, 0, 1, 1)=0A=
- =0A=
- /* Newer redundant definitions. */=0A=
- INITIO(scsi_init_io_, 1, 0, 0)=0A=
- INITIO(scsi_init_io_d, 1, 0, 1)=0A=
- INITIO(scsi_init_io_c, 1, 1, 0)=0A=
- INITIO(scsi_init_io_dc, 1, 1, 1)=0A=
- #endif=0A=
- =0A=
INITIO(scsi_init_io_v, 1, 0, 0)=0A=
INITIO(scsi_init_io_vd, 1, 0, 1)=0A=
INITIO(scsi_init_io_vc, 1, 1, 0)=0A=
INITIO(scsi_init_io_vdc, 1, 1, 1)=0A=
/*=0A=
* Function: initialize_merge_fn()=0A=
*=0A=
--- 856,866 ----=0A=
* We always force "_VALID" to 1. Eventually clean this up=0A=
* and get rid of the extra argument.=0A=
*/=0A=
INITIO(scsi_init_io_v, 1, 0, 0)=0A=
INITIO(scsi_init_io_vd, 1, 0, 1)=0A=
INITIO(scsi_init_io_vc, 1, 1, 0)=0A=
INITIO(scsi_init_io_vdc, 1, 1, 1)=0A=
+ =0A=
/*=0A=
* Function: initialize_merge_fn()=0A=
*=0A=
***************=0A=
*** 881,901 ****=0A=
* If this host has an unlimited tablesize, then don't bother with a=0A=
* merge manager. The whole point of the operation is to make sure=0A=
* that requests don't grow too large, and this host isn't picky.=0A=
! */=0A=
! if (SHpnt->sg_tablesize =3D=3D SG_ALL) {=0A=
! if (!CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma =
=3D=3D 0) {=0A=
! SDpnt->scsi_init_io_fn =3D scsi_init_io_v;=0A=
! } else if (!CLUSTERABLE_DEVICE(SHpnt, SDpnt) && =
SHpnt->unchecked_isa_dma !=3D 0) {=0A=
! SDpnt->scsi_init_io_fn =3D scsi_init_io_vd;=0A=
! } else if (CLUSTERABLE_DEVICE(SHpnt, SDpnt) && =
SHpnt->unchecked_isa_dma =3D=3D 0) {=0A=
! SDpnt->scsi_init_io_fn =3D scsi_init_io_vc;=0A=
! } else if (CLUSTERABLE_DEVICE(SHpnt, SDpnt) && =
SHpnt->unchecked_isa_dma !=3D 0) {=0A=
! SDpnt->scsi_init_io_fn =3D scsi_init_io_vdc;=0A=
! }=0A=
! return;=0A=
! }=0A=
! /*=0A=
! * Now pick out the correct function.=0A=
*/=0A=
if (!CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma =
=3D=3D 0) {=0A=
q->merge_fn =3D scsi_merge_fn_;=0A=
--- 893,904 ----=0A=
* If this host has an unlimited tablesize, then don't bother with a=0A=
* merge manager. The whole point of the operation is to make sure=0A=
* that requests don't grow too large, and this host isn't picky.=0A=
! *=0A=
! * Note that ll_rw_blk.c is effectively maintaining a segment=0A=
! * count which is only valid if clustering is used, and it obviously=0A=
! * doesn't handle the DMA case. In the end, it=0A=
! * is simply easier to do it ourselves with our own functions=0A=
! * rather than rely upon the default behavior of ll_rw_blk.=0A=
*/=0A=
if (!CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma =
=3D=3D 0) {=0A=
q->merge_fn =3D scsi_merge_fn_;=0A=
Index: linux/drivers/scsi/sd.c=0A=
diff -c linux/drivers/scsi/sd.c:1.1.1.3 linux/drivers/scsi/sd.c:1.4=0A=
*** linux/drivers/scsi/sd.c:1.1.1.3 Wed Dec 22 10:28:46 1999=0A=
--- linux/drivers/scsi/sd.c Wed Dec 22 18:37:56 1999=0A=
***************=0A=
*** 202,207 ****=0A=
--- 202,212 ----=0A=
tag:"sd",=0A=
scsi_type:TYPE_DISK,=0A=
major:SCSI_DISK0_MAJOR,=0A=
+ /*=0A=
+ * Secondary range of majors that this driver handles.=0A=
+ */=0A=
+ min_major:SCSI_DISK1_MAJOR,=0A=
+ max_major:SCSI_DISK7_MAJOR,=0A=
blk:1,=0A=
detect:sd_detect,=0A=
init:sd_init,=0A=
***************=0A=
*** 229,235 ****=0A=
Scsi_Disk *dpnt;=0A=
char nbuff[6];=0A=
=0A=
! devm =3D MINOR(SCpnt->request.rq_dev);=0A=
dev =3D DEVICE_NR(SCpnt->request.rq_dev);=0A=
=0A=
block =3D SCpnt->request.sector;=0A=
--- 234,240 ----=0A=
Scsi_Disk *dpnt;=0A=
char nbuff[6];=0A=
=0A=
! devm =3D SD_PARTITION(SCpnt->request.rq_dev);=0A=
dev =3D DEVICE_NR(SCpnt->request.rq_dev);=0A=
=0A=
block =3D SCpnt->request.sector;=0A=
***************=0A=
*** 561,567 ****=0A=
default:=0A=
break;=0A=
}=0A=
! error_sector -=3D sd[MINOR(SCpnt->request.rq_dev)].start_sect;=0A=
error_sector &=3D ~(block_sectors - 1);=0A=
good_sectors =3D error_sector - SCpnt->request.sector;=0A=
if (good_sectors < 0 || good_sectors >=3D this_count)=0A=
--- 566,572 ----=0A=
default:=0A=
break;=0A=
}=0A=
! error_sector -=3D =
sd[SD_PARTITION(SCpnt->request.rq_dev)].start_sect;=0A=
error_sector &=3D ~(block_sectors - 1);=0A=
good_sectors =3D error_sector - SCpnt->request.sector;=0A=
if (good_sectors < 0 || good_sectors >=3D this_count)=0A=
Index: linux/drivers/scsi/sg.c=0A=
diff -c linux/drivers/scsi/sg.c:1.1.1.4 linux/drivers/scsi/sg.c:1.3=0A=
*** linux/drivers/scsi/sg.c:1.1.1.4 Wed Dec 22 10:28:46 1999=0A=
--- linux/drivers/scsi/sg.c Wed Dec 22 02:41:25 1999=0A=
***************=0A=
*** 101,110 ****=0A=
static void sg_detach(Scsi_Device *);=0A=
=0A=
=0A=
! struct Scsi_Device_Template sg_template =3D {NULL, NULL, "sg", NULL, =
0xff,=0A=
! SCSI_GENERIC_MAJOR, 0, 0, =
0, 0,=0A=
! sg_detect, sg_init,=0A=
! sg_finish, sg_attach, =
sg_detach};=0A=
=0A=
=0A=
typedef struct sg_scatter_hold /* holding area for scsi scatter =
gather info */=0A=
--- 101,117 ----=0A=
static void sg_detach(Scsi_Device *);=0A=
=0A=
=0A=
! struct Scsi_Device_Template sg_template =3D =0A=
! {=0A=
! tag:"sg", =0A=
! scsi_type:0xff,=0A=
! major:SCSI_GENERIC_MAJOR, =0A=
! detect:sg_detect, =0A=
! init:sg_init,=0A=
! finish:sg_finish, =0A=
! attach:sg_attach, =0A=
! detach:sg_detach=0A=
! };=0A=
=0A=
=0A=
typedef struct sg_scatter_hold /* holding area for scsi scatter =
gather info */=0A=
Index: linux/drivers/scsi/st.c=0A=
diff -c linux/drivers/scsi/st.c:1.1.1.3 linux/drivers/scsi/st.c:1.3=0A=
*** linux/drivers/scsi/st.c:1.1.1.3 Wed Dec 22 10:28:48 1999=0A=
--- linux/drivers/scsi/st.c Wed Dec 22 02:41:25 1999=0A=
***************=0A=
*** 147,156 ****=0A=
static void st_detach(Scsi_Device *);=0A=
=0A=
struct Scsi_Device_Template st_template =3D=0A=
! {NULL, "tape", "st", NULL, TYPE_TAPE,=0A=
! SCSI_TAPE_MAJOR, 0, 0, 0, 0,=0A=
! st_detect, st_init,=0A=
! NULL, st_attach, st_detach};=0A=
=0A=
static int st_compression(Scsi_Tape *, int);=0A=
=0A=
--- 147,162 ----=0A=
static void st_detach(Scsi_Device *);=0A=
=0A=
struct Scsi_Device_Template st_template =3D=0A=
! {=0A=
! name:"tape", =0A=
! tag:"st", =0A=
! scsi_type:TYPE_TAPE,=0A=
! major:SCSI_TAPE_MAJOR, =0A=
! detect:st_detect, =0A=
! init:st_init,=0A=
! attach:st_attach, =0A=
! detach:st_detach=0A=
! };=0A=
=0A=
static int st_compression(Scsi_Tape *, int);=0A=
=0A=
------=_NextPart_000_0030_01BF4CDD.E4FC8120--
-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.rutgers.edu