Skip to contentSkip to conversation

IDE from current bk tree, UDMA and two channels...

DISCUSSION Petr Vandrovec 3 participants 7 messages Jul 30, 2002 – Aug 1, 2002

lore
Share & tools
lore
#0 lore raw
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]

#1 lore raw
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) 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 ;-)

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_REG register. 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_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 tha comment above OUT_BYTE(0x04, ch->ports[IDE_CONTROL_OFFSET]) is bogus. Command register is IDE_COMMAND, not IDE_CONTROL ;-)

Yes I know already about this I will remove the comment. (Must have forgotten about it.)

#2 lore raw
Quoted 19 lines · Marcin Dalecki
Quoted 10 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_REG register. 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) {
....

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
#3 lore raw
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_REG register. 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) {
....

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->queuedata to 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.

#4 lore raw
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->queuedata to 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
#5 lore raw
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".

#6 lore raw
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