Subject: Re: Problems with ccd (960413)
To: Charles M. Hannum <mycroft@mit.edu>
From: Justin T. Gibbs <gibbs@freefall.freebsd.org>
List: current-users
Date: 05/15/1996 19:07:30
>
>Noriyuki Soda <soda@sra.co.jp> writes:
>
>> 
>> 1. change scsi_scsi_cmd(,... SCSI_NOSLEEP) behavior into returning
>>   EWOULDBLOCK (or something like that), when (*sc_link->adapter->scsi_cmd)()
>>   returns TRY_AGAIN_LATOR. 
>>   (if SCSI_NOSLEEP is not specified,
>>    or if (*sc_link->adapter->scsi_cmd)() doesn't return TRY_AGAIN_LATOR,
>>    then scsi_scsi_cmd() behaves as it is.)
>> 
>> 2. sdstart(), ststart() and cdstart() check return value of
>>   scsi_scsi_cmd(), and these remove `struct buf' from sc->buf_queue,
>>   only if scsi_scsi_cmd() does not return EWOULDBLOCK.
>>   That is, if scsi_scsi_cmd() returns EWOULDBLOCK, we leave
>>   sc->buf_queue as it is, and immediately returns from xxstart().
>>   (xxstart() continues to use SCSI_NOSLEEP.)
>> 
>> This fix seems to be easy to implement, and doesn't change traditional
>> behavior of xxstart(). (xxstart() can be called from interrupt)
>
>By itself, this isn't sufficient, because you wouldn't be guaranteed
>to notify the higher-level driver when a slot (SCB) becomes available.
>(Consider the case where other devices are currently hogging all the
>slots.  There won't be a call to scsi_done() for that device, so its
>start routine won't be called again unless someone queues another I/O
>operation.)

Yup.  Peter Dufault has implemented a round robin scheduling scheme for
all devices attached to the same controller.  I was planning to use his
code to solve this problem (although his intention was to use it for adding
rtprio support to the SCSI system and also fix the resource fairness
problem for competing devices with a large number of tags).

>Additionally, the behaviour suggested in item 2 would require either
>disallowing the start routine from ever sleeping (meaning that it
>would always have to use SCSI_NOSLEEP), or adding an additional lock
>to prevent another process entering the start routine (from the
>strategy routine) and trying to start the same buffer.

Hmmm, yuck.  You could work around this by guarding against the
queue being empty.  The only real restraint here is that the
transactions are queued in the same order as the buffers (tape writes
won't work otherwise), but you don't care if the buffer you pull off
the queue is the same one that you looked at before you slept.  This
becomes even less of a problem with the round robin scheduler since
you could always reserve your resources before you pick the final
device start routine to call (that start routine only sending one
command).

--
Justin T. Gibbs
===========================================
  FreeBSD: Turning PCs into workstations
===========================================