[2854] in linux-scsi channel archive
Re: unchecked_isa_dma, *_EXTRA_DEVS
daemon@ATHENA.MIT.EDU (Eric Youngdale)
Mon Nov 24 02:26:31 1997
Date: Sun, 23 Nov 1997 22:46:53 -0500 (EST)
From: Eric Youngdale <eric@andante.jic.com>
To: Jakub Jelinek <jj@sunsite.ms.mff.cuni.cz>
cc: linux-scsi@vger.rutgers.edu
In-Reply-To: <199711200822.JAA19417@sunsite.ms.mff.cuni.cz>
"The woods are lovely, dark and deep. But I have promises to keep,
And lines to code before I sleep, And lines to code before I sleep."
On Thu, 20 Nov 1997, Jakub Jelinek wrote:
> Hi!
>
> Two questions:
>
> a) Am I right when I think a host with unchecked_isa_dma may appear
> on Intel arch only? If yes, wouldn't make sense to
>
> #ifdef __i386__
> #define unchecked_isadma(host) host->unchecked_isa_dma
> #else
> #define unchecked_isadma(host) 0
> #endif
>
> in hosts.h and thus remove some tests which will never be true on all the
> other platforms?
Actually, I believe it isn't only Intel - other processors have
non-32 bit memory busses.
>
> b) What are the issues for getting rid of *_EXTRA_DEVS? It is a very ugly
> limitation. I'm now writing a disk array driver which will always add at
> least 6 new scsi disks (the minimal configuration of the array), but usually
> much more, up to 30 on some models or more. That makes this impossible to
> be loaded as a module, unless someone sets EXTRA_DEVS manually before :((.
> Where are all the arrays/array members referenced?
> Wouldn't it be possible to
> a) allocate new pointers, copy everything and relink the old ones
> b) keep the old chunks allocated, so that the other CPUs don't reference
> something already non-existant
> c) somehow ensure that all the changes made to those arrays are propagated
> to all arrays for some time.
I agree that it is ugly, but there are some very nasty race
conditions that needed to be solved. Your approach sounds reasonable on
the surface, but how do you define "some time"? I guess you could say
several seconds, but this could be too short in the event that error
recovery is in progress.
It would be possible in *some* cases to fix it so that you just
allocate a new array, copy the contents, and then change the pointer. A
writer mutex on the element would protect against two processes trying to
update the same structure at the same time.
A better approach might be to bury the sd_sizes, sd_hardsizes, and
sd_blocksizes inside of the rscsi_disks structure itself. Thus if you add
new disks, it won't affect any of the existing devices. If we did this,
then I believe the only thing that would need to get resized is
rscsi_disks itself.
Next, I would suggest that a void * be added to the Scsi_Device
structure, and in the sd_attach() this be set to point to the rscsi_disks
element that corresponds to the device in question. If we did this, then
in the interrupt handler there would be no need to dereference rscsi_disks
any longer - it would be able to obtain it directly, and type cast it back
to the real data structure.
The final step to clean up this mess is to do something sort of
along the lines of what you suggest. I would suggest a mutex to protect
against access while we are busy changing things, then we just replicate
the rscsi_disks array, and when it is ready, just drop the new pointer
into rscsi_disks and you should be free to release the old list.
Are you up to this? This is something I have wanted to clean up
for ages, and have never had the time.
-Eric