IDE from current bk tree, UDMA and two channels...
Quoted 6 lines · I wrote:
Unfortunately ATA/ATAPIv7 says that single interrupt is triggered after command is done and all data transfered, and we do not play with select bit. But we play with nIEN bit of disk. Do you see any reason why this should cause spurious interrupt? (system is using XT-PIC, FYI)
OK. As I am using only one device on each channel, I commented out ata_irq_enable(drive, 1) in ide-disk.c when issuing command, and removed disabling irq in ide_do_request in ide.c when we do not issue command to the drive, and spurious interrupts disappeared. So now I'm getting only half of IRQs for channel 0, and system still works as before ;-)
Unfortunately, problem is still here: when kernel was in idedisk_do_request performed on channel 0, IRQ for channel 1 arrived, and this irq found channel 1 DMA engine ready, but drive had DRQ set... oops. Shortly after that IRQ for channel 1 arrived again, but as it was unexpected, nothing happened.
I hope that i845 is not simplex device, but first (unexpected) IRQ arrived just when channel 0 code wrote new value to its IDE_SELECT_REG register. Now I even disconnected DVD drive, so it is simple two masters, two channels configuration, but it still happens.
And as always, something else: ata_error does:
OUT_BYTE(WIN_NOP, ch->ports[IDE_CONTROL_OFFSET])
I'd say that it should use 0x00 instead of WIN_NOP, and also that comment above OUT_BYTE(0x04, ch->ports[IDE_CONTROL_OFFSET]) is bogus. Command register is IDE_COMMAND, not IDE_CONTROL ;-)
Best regards,
Petr Vandrovec [email protected]
Quoted 9 lines · Petr Vandrovec
Quoted 5 lines · I wrote:
Unfortunately ATA/ATAPIv7 says that single interrupt is triggered after command is done and all data transfered, and we do not play with select bit. But we play with nIEN bit of disk. Do you see any reason why this should cause spurious interrupt? (system is using XT-PIC, FYI)
Quoted 6 lines
OK. As I am using only one device on each channel, I commented out
ata_irq_enable(drive, 1)inide-disk.cwhen issuing command, and removed disabling irq inide_do_requestinide.cwhen we do not issue command to the drive, and spurious interrupts disappeared. So now I'm getting only half of IRQs for channel 0, and system still works as before ;-)
Well OK this was my next idea, but apparently you already did the experient on your own. Thanks for the result. I'm still scratching my head and I have already observed this before myself.
It's always funny to see what happens when one stops a driver from deliberately disabling IRQs for eons of jiffies :-).
Quoted 5 lines
Unfortunately, problem is still here: when kernel was in
idedisk_do_request
performed on channel 0, IRQ for channel 1 arrived, and this irq found channel 1 DMA engine ready, but drive had DRQ set... oops. Shortly after that IRQ for channel 1 arrived again, but as it was unexpected, nothing happened.I hope that i845 is not simplex device, but first (unexpected) IRQ arrived just when channel 0 code wrote new value to its
IDE_SELECT_REGregister. Now I even disconnected DVD drive, so it is simple two masters, two channels configuration, but it still happens.
One idea and one experiment I was already thinking about is
to change do_ide_request to actually *not* select delibreately which device do handle. (The big for loop found there...) One can instead search for a device on the channel which is matching
the queue for which do_ide_request() was called.
for (unit = 0; unit < MAX_DEVICES; ++unit) {
....
if (tmp->queue == q) {
drive = tmp;
break; }
}
if (!drive)
BUG();
Just please forget temporarly that there is a mechanism for "sleeping".
It is bogous anyway (doesn give time back to anybody) and the only
consumer of it is ide-cd (easly removed there) and ide-tape.c (don't care the driver was never usable in 2.5.xx)
Quoted 7 lines
And as always, something else:
ata_errordoes:
OUT_BYTE(WIN_NOP, ch->ports[IDE_CONTROL_OFFSET])I'd say that it should use
0x00instead ofWIN_NOP, and also tha comment aboveOUT_BYTE(0x04, ch->ports[IDE_CONTROL_OFFSET])is bogus. Command register isIDE_COMMAND, notIDE_CONTROL;-)
Yes I know already about this I will remove the comment. (Must have forgotten about it.)
Quoted 19 lines · Marcin Dalecki
Quoted 10 lines
Unfortunately, problem is still here: when kernel was in
idedisk_do_requestperformed on channel 0, IRQ for channel 1 arrived, and this irq found channel 1 DMA engine ready, but drive had DRQ set... oops. Shortly after that IRQ for channel 1 arrived again, but as it was unexpected, nothing happened.I hope that i845 is not simplex device, but first (unexpected) IRQ arrived just when channel 0 code wrote new value to its
IDE_SELECT_REGregister. Now I even disconnected DVD drive, so it is simple two masters, two channels configuration, but it still happens.One idea and one experiment I was already thinking about is to change
do_ide_requestto actually *not* select delibreately which device do handle. (The big for loop found there...)
One can instead search for a device on the channel which is matching the queue for whichdo_ide_request()was called.for (unit = 0; unit <
MAX_DEVICES; ++unit) {
....
Quoted 7 lines
if (tmp->queue == q) { drive = tmp; break;}
}
if (!drive)
BUG();
hey that sucks :-)
seriously, the better way to do this would be to change the q->queuedata to be a pointer to drive instead of the channel.
that would work, but I think it would seriously starve the other device on the same channel.
Signature · 1 line
Jens Axboe
Quoted 24 lines · Jens Axboe
Quoted 13 lines · Marcin Dalecki
Quoted 5 lines
Unfortunately, problem is still here: when kernel was in
idedisk_do_request
performed on channel 0, IRQ for channel 1 arrived, and this irq found channel 1 DMA engine ready, but drive had DRQ set... oops. Shortly after that IRQ for channel 1 arrived again, but as it was unexpected, nothing happened.I hope that i845 is not simplex device, but first (unexpected) IRQ arrived just when channel 0 code wrote new value to its
IDE_SELECT_REGregister. Now I even disconnected DVD drive, so it is simple two masters, two channels configuration, but it still happens.One idea and one experiment I was already thinking about is
to changedo_ide_requestto actually *not* select delibreately which device do handle. (The big for loop found there...) One can instead search for a device on the channel which is matching
the queue for whichdo_ide_request()was called.for (unit = 0; unit <
MAX_DEVICES; ++unit) {
....Quoted 7 lines
if (tmp->queue == q) { drive = tmp; break;}
}
if (!drive)
BUG();
Quoted 1 line
hey that sucks :-)
Since IDE 111 not any more...
Quoted 2 lines
seriously, the better way to do this would be to change the
q->queuedatato be a pointer to drive instead of the channel.
... becouse this is already *done* there :-).
Quoted 2 lines
that would work, but I think it would seriously starve the other device on the same channel.
We starve anyway, becouse the kernel isn't real time and we can't
guarantee "sleeping" for some maximum time and comming back.
We don't reschedule the kernel during this kind of "sleeping".
And we can't know that a command on the "mate" will not take extraordinary amounts of time. It's only a problem if mixing travan tapes with disks on a channel.
Quoted 3 lines · Marcin Dalecki
Quoted 1 line
hey that sucks :-)
Since IDE 111 not any more...
Yeah I just saw that 110 was the 'broken' solution, 111 made it right. Good.
Quoted 4 lines
Quoted 2 lines
seriously, the better way to do this would be to change the
q->queuedatato be a pointer to drive instead of the channel.... becouse this is already *done* there :-).
:-)
Quoted 9 lines
Quoted 2 lines
that would work, but I think it would seriously starve the other device on the same channel.
We starve anyway, becouse the kernel isn't real time and we can't guarantee "sleeping" for some maximum time and comming back. We don't reschedule the kernel during this kind of "sleeping". And we can't know that a command on the "mate" will not take extraordinary amounts of time. It's only a problem if mixing travan tapes with disks on a channel.
I'm thinking about the alternation of the devices so one device can't starve the other device off the channel.
Signature · 1 line
Jens Axboe
Quoted 10 lines · Jens Axboe
Quoted 8 lines
Quoted 2 lines
that would work, but I think it would seriously starve the other device on the same channel.
We starve anyway, becouse the kernel isn't real time and we can't
guarantee "sleeping" for some maximum time and comming back.
We don't reschedule the kernel during this kind of "sleeping".
And we can't know that a command on the "mate" will not take extraordinary amounts of time. It's only a problem if mixing travan tapes with disks on a channel.
Quoted 2 lines
I'm thinking about the alternation of the devices so one device can't starve the other device off the channel.
Ah so you are thinking about two equally powered devices competing for the channel. Something I would call the "sumo fight" situation. Well disks didn't use the "sleeping" mechanism at all anyway and the chances someone would do cp from CD-ROM to CD-ROM are low.
Finally I think that the proper granularity of scheduling requests to
the drive is, well, the request layer. The queue processing layer should
handle this becouse otherwise we would have two "competing" optimization
mechanisms. And there we are indeed able to actually relinquish some CPU time. If you look at an request processing optimization as a low pass signal filter it's immediately obvious that the effects of chaining them
can be, well at least "counter intuitive".
Quoted 21 lines · Marcin Dalecki
Quoted 11 lines · Jens Axboe
Quoted 9 lines
Quoted 2 lines
that would work, but I think it would seriously starve the other device on the same channel.
We starve anyway, becouse the kernel isn't real time and we can't guarantee "sleeping" for some maximum time and comming back. We don't reschedule the kernel during this kind of "sleeping". And we can't know that a command on the "mate" will not take extraordinary amounts of time. It's only a problem if mixing travan tapes with disks on a channel.
Quoted 2 lines
I'm thinking about the alternation of the devices so one device can't starve the other device off the channel.
Ah so you are thinking about two equally powered devices competing for the channel. Something I would call the "sumo fight" situation. Well disks didn't use the "sleeping" mechanism at all anyway and the chances someone would do cp from CD-ROM to CD-ROM are low.
Quoted 7 lines
Finally I think that the proper granularity of scheduling requests to the drive is, well, the request layer. The queue processing layer should handle this becouse otherwise we would have two "competing" optimization mechanisms. And there we are indeed able to actually relinquish some CPU time. If you look at an request processing optimization as a low pass signal filter it's immediately obvious that the effects of chaining them can be, well at least "counter intuitive".
Actually, I'm thinking of a much simple scenario: basically any two devices on the same channel, both with pending requests on the queue. This could be a hard drive and a cd writer, for instance. If you have 60 requests pending for the hard drive, queue gets unplugged, you start the first one. Correct me if I'm wrong, but now you pass back the drive to the request handler when the first request completes, and you select a new request from that very same drive without considering device starvation? Any run of the cd writer queue would do nothing, since it would just find the channel busy.
This sort of thing cannot be solved at the block layer. The two queues are independent seen from that layer, the channel-busy dependency cannot be solved there.
Signature · 1 line
Jens Axboe