Re: [Xenomai-core] More on Shared interrupts
Anders Blomdell wrote: For the last few days, I have tried to figure out a good way to share interrupts between RT and non-RT domains. This has included looking through Dmitry's patch, correcting bugs and testing what is possible in my specific case. I'll therefore try to summarize at least a few of my thoughts. 1. When looking through Dmitry's patch I get the impression that the iack handler has very little to do with each interrupt (the test 'prev->iack != intr->iack' is a dead giveaway), but is more of a domain-specific function (or perhaps even just a placeholder for the hijacked Linux ack-function). 2. Somewhat inspired by the figure in "Life with Adeos", I have identified the following cases: irq K | --- | ---o| // Linux only ... irq L | ---o| | // RT-only ... irq M | ---o--- | ---o| // Shared between domains ... irq N | ---o---o--- | | // Shared inside single domain ... irq O | ---o---o--- | ---o| // Shared between and inside single domain Xenomai currently handles the K & L cases, Dmitrys patch addresses the N case, with edge triggered interrupts the M (and O after Dmitry's patch) case(s) might be handled by returning RT_INTR_CHAINED | RT_INTR_ENABLE from the interrupt handler, for level triggered interrupt the M and O cases can't be handled. If one looks more closely at the K case (Linux only interrupt), it works by when an interrupt occurs, the call to irq_end is postponed until the Linux interrupt handler has run, i.e. further interrupts are disabled. This can be seen as a lazy version of Philippe's idea of disabling all non-RT interrupts until the RT-domain is idle, i.e. the interrupt is disabled only if it indeed occurs. If this idea should be generalized to the M (and O) case(s), one can't rely on postponing the irq_end call (since the interrupt is still needed in the RT-domain), but has to rely on some function that disables all non-RT hardware that generates interrupts on that irq-line; such a function naturally has to have intimate knowledge of all hardware that can generate interrupts in order to be able to disable those interrupt sources that are non-RT. If we then take Jan's observation about the many (Linux-only) interrupts present in an ordinary PC and add it to Philippe's idea of disabling all non-RT interrupts while executing in the RT-domain, I think that the following is a workable (and fairly efficient) way of handling this: Add hardware dependent enable/disable functions, where the enable is called just before normal execution in a domain starts (i.e. when playing back interrupts, the disable is still in effect), and disable is called when normal domain execution end. This does effectively handle the K case above, with the added benefit that NO non-RT interrupts will occur during RT execution. In the 8259 case, the disable function could look something like: domain_irq_disable(uint irqmask) { if (irqmask & 0xff00 != 0xff00) { irqmask &= ~0x0004; // Cascaded interrupt is still needed outb(irqmask >> 8, PIC_SLAVE_IMR); } outb(irqmask, PIC_MASTER_IMR); } If we should extend this to handle the M (and O) case(s), the disable function could look like: domain_irq_disable(uint irqmask, shared_irq_t *shared[]) { int i; for (i = 0 ; i < MAX_IRQ ; i++) { if (shared[i]) { shared_irq_t *next = shared[i]; irqmask &= ~(1next; } } } if (irqmask & 0xff00 != 0xff00) { irqmask &= ~0x0004; // Cascaded interrupt is still needed outb(irqmask >> 8, PIC_SLAVE_IMR); } outb(irqmask, PIC_MASTER_IMR); } An obvious optimization of the above scheme, is to never call the disable (or enable) function for the RT-domain, since there all interrupt processing is protected by the hardware. Comments, anyone? OK, I have finally got around to do some interrupt timing tests on a PrPMC800 (450 MHz PowerPC/G4) with the following interrupt sources: 3: 10 Khz watchdog interrupt (Linux) 10: 100 Mbit/s ethernet (Linux) 16: mailbox interrupt (RT) + UART (Linux) I have measured interrupt latency, task latency (time from interrupt until a task signalled from interrupt handler has started) and the semaphore latency (time from task semaphore is signalled until task has started). I have tested 4 different ways of handling shared Linux/RT interrupts: 1. When UART interrupt occurs, disable further UART interrupts, signal low priority UART reenable task, return XN_ISR_ENABLE | XN_ISR_CHAINED. In low priority UART reenable task, reenable UART when Linux has handled the interrupt. 2. Disable UART interrupts, and poll them at 1kHz from low priority RT task, and rthal_irq_host_pend them as they occur. 3. Modified Xenomai, where non-RT interrupts are disabled when entering the RT domain, and enabled when entering th
Re: [Xenomai-core] More on Shared interrupts
Anders Blomdell wrote: For the last few days, I have tried to figure out a good way to share interrupts between RT and non-RT domains. This has included looking through Dmitry's patch, correcting bugs and testing what is possible in my specific case. I'll therefore try to summarize at least a few of my thoughts. 1. When looking through Dmitry's patch I get the impression that the iack handler has very little to do with each interrupt (the test 'prev->iack != intr->iack' is a dead giveaway), but is more of a domain-specific function (or perhaps even just a placeholder for the hijacked Linux ack-function). 2. Somewhat inspired by the figure in "Life with Adeos", I have identified the following cases: irq K | --- | ---o| // Linux only ... irq L | ---o| | // RT-only ... irq M | ---o--- | ---o| // Shared between domains ... irq N | ---o---o--- | | // Shared inside single domain ... irq O | ---o---o--- | ---o| // Shared between and inside single domain Xenomai currently handles the K & L cases, Dmitrys patch addresses the N case, with edge triggered interrupts the M (and O after Dmitry's patch) case(s) might be handled by returning RT_INTR_CHAINED | RT_INTR_ENABLE from the interrupt handler, for level triggered interrupt the M and O cases can't be handled. If one looks more closely at the K case (Linux only interrupt), it works by when an interrupt occurs, the call to irq_end is postponed until the Linux interrupt handler has run, i.e. further interrupts are disabled. This can be seen as a lazy version of Philippe's idea of disabling all non-RT interrupts until the RT-domain is idle, i.e. the interrupt is disabled only if it indeed occurs. If this idea should be generalized to the M (and O) case(s), one can't rely on postponing the irq_end call (since the interrupt is still needed in the RT-domain), but has to rely on some function that disables all non-RT hardware that generates interrupts on that irq-line; such a function naturally has to have intimate knowledge of all hardware that can generate interrupts in order to be able to disable those interrupt sources that are non-RT. If we then take Jan's observation about the many (Linux-only) interrupts present in an ordinary PC and add it to Philippe's idea of disabling all non-RT interrupts while executing in the RT-domain, I think that the following is a workable (and fairly efficient) way of handling this: Add hardware dependent enable/disable functions, where the enable is called just before normal execution in a domain starts (i.e. when playing back interrupts, the disable is still in effect), and disable is called when normal domain execution end. This does effectively handle the K case above, with the added benefit that NO non-RT interrupts will occur during RT execution. In the 8259 case, the disable function could look something like: domain_irq_disable(uint irqmask) { if (irqmask & 0xff00 != 0xff00) { irqmask &= ~0x0004; // Cascaded interrupt is still needed outb(irqmask >> 8, PIC_SLAVE_IMR); } outb(irqmask, PIC_MASTER_IMR); } If we should extend this to handle the M (and O) case(s), the disable function could look like: domain_irq_disable(uint irqmask, shared_irq_t *shared[]) { int i; for (i = 0 ; i < MAX_IRQ ; i++) { if (shared[i]) { shared_irq_t *next = shared[i]; irqmask &= ~(1next; } } } if (irqmask & 0xff00 != 0xff00) { irqmask &= ~0x0004; // Cascaded interrupt is still needed outb(irqmask >> 8, PIC_SLAVE_IMR); } outb(irqmask, PIC_MASTER_IMR); } An obvious optimization of the above scheme, is to never call the disable (or enable) function for the RT-domain, since there all interrupt processing is protected by the hardware. Comments, anyone? OK, I have finally got around to do some interrupt timing tests on a PrPMC800 (450 MHz PowerPC/G4) with the following interrupt sources: 3: 10 Khz watchdog interrupt (Linux) 10: 100 Mbit/s ethernet (Linux) 16: mailbox interrupt (RT) + UART (Linux) I have measured interrupt latency, task latency (time from interrupt until a task signalled from interrupt handler has started) and the semaphore latency (time from task semaphore is signalled until task has started). I have tested 4 different ways of handling shared Linux/RT interrupts: 1. When UART interrupt occurs, disable further UART interrupts, signal low priority UART reenable task, return XN_ISR_ENABLE | XN_ISR_CHAINED. In low priority UART reenable task, reenable UART when Linux has handled the interrupt. 2. Disable UART interrupts, and poll them at 1kHz from low priority RT task, and rthal_irq_host_pend them as they occur. 3. Modified Xenomai, where non-RT interrupts are disabled when entering the RT domain, and enabled when entering th
Re: [Xenomai-core] More on Shared interrupts
Jan Kiszka wrote: Anders Blomdell wrote: For the last few days, I have tried to figure out a good way to share interrupts between RT and non-RT domains. This has included looking through Dmitry's patch, correcting bugs and testing what is possible in my specific case. I'll therefore try to summarize at least a few of my thoughts. 1. When looking through Dmitry's patch I get the impression that the iack handler has very little to do with each interrupt (the test 'prev->iack != intr->iack' is a dead giveaway), but is more of a domain-specific function (or perhaps even just a placeholder for the hijacked Linux ack-function). 2. Somewhat inspired by the figure in "Life with Adeos", I have identified the following cases: irq K | --- | ---o| // Linux only ... irq L | ---o| | // RT-only ... irq M | ---o--- | ---o| // Shared between domains ... irq N | ---o---o--- | | // Shared inside single domain ... irq O | ---o---o--- | ---o| // Shared between and inside single domain Xenomai currently handles the K & L cases, Dmitrys patch addresses the N case, with edge triggered interrupts the M (and O after Dmitry's patch) case(s) might be handled by returning RT_INTR_CHAINED | RT_INTR_ENABLE from the interrupt handler, for level triggered interrupt the M and O cases can't be handled. I guess you mean it the other way around: for the edge-triggered cross-domain case we would actually have to loop over both the RT and the Linux handlers until we are sure, that the IRQ line was released once. I obviously has misunderstood edge triggered :-( Luckily, I never saw such a scenario which were unavoidable (it hits you with ISA hardware which tend to have nice IRQ jumpers or other means - it's just that you often cannot divide several controllers on the same extension card IRQ-wise apart). If one looks more closely at the K case (Linux only interrupt), it works by when an interrupt occurs, the call to irq_end is postponed until the Linux interrupt handler has run, i.e. further interrupts are disabled. This can be seen as a lazy version of Philippe's idea of disabling all non-RT interrupts until the RT-domain is idle, i.e. the interrupt is disabled only if it indeed occurs. If this idea should be generalized to the M (and O) case(s), one can't rely on postponing the irq_end call (since the interrupt is still needed in the RT-domain), but has to rely on some function that disables all non-RT hardware that generates interrupts on that irq-line; such a function naturally has to have intimate knowledge of all hardware that can generate interrupts in order to be able to disable those interrupt sources that are non-RT. If we then take Jan's observation about the many (Linux-only) interrupts present in an ordinary PC and add it to Philippe's idea of disabling all non-RT interrupts while executing in the RT-domain, I think that the following is a workable (and fairly efficient) way of handling this: Add hardware dependent enable/disable functions, where the enable is called just before normal execution in a domain starts (i.e. when playing back interrupts, the disable is still in effect), and disable is called when normal domain execution end. This does effectively handle the K case above, with the added benefit that NO non-RT interrupts will occur during RT execution. In the 8259 case, the disable function could look something like: domain_irq_disable(uint irqmask) { if (irqmask & 0xff00 != 0xff00) { irqmask &= ~0x0004; // Cascaded interrupt is still needed outb(irqmask >> 8, PIC_SLAVE_IMR); } outb(irqmask, PIC_MASTER_IMR); } If we should extend this to handle the M (and O) case(s), the disable function could look like: domain_irq_disable(uint irqmask, shared_irq_t *shared[]) { int i; for (i = 0 ; i < MAX_IRQ ; i++) { if (shared[i]) { shared_irq_t *next = shared[i]; irqmask &= ~(1next; } This obviously means that all non-RT IRQ handlers sharing a line with the RT domain would have to be registered in that shared[]-list. This gets close to my old suggestion. Just raises the question how to organise these interface, both on the RT and the Linux side. } } if (irqmask & 0xff00 != 0xff00) { irqmask &= ~0x0004; // Cascaded interrupt is still needed outb(irqmask >> 8, PIC_SLAVE_IMR); } outb(irqmask, PIC_MASTER_IMR); } An obvious optimization of the above scheme, is to never call the disable (or enable) function for the RT-domain, since there all interrupt processing is protected by the hardware. Another point is to avoid that looping over disable handlers for IRQs of the K case. Otherwise, too many device-specific disable handlers had to be implemented even if only a single Linux device hogs a RT IRQ. You only have to spin over those IRQ that are actually shared across domains (probably just a few in most cases), those IRQ that s
Re: [Xenomai-core] More on Shared interrupts
Jan Kiszka wrote: Anders Blomdell wrote: For the last few days, I have tried to figure out a good way to share interrupts between RT and non-RT domains. This has included looking through Dmitry's patch, correcting bugs and testing what is possible in my specific case. I'll therefore try to summarize at least a few of my thoughts. 1. When looking through Dmitry's patch I get the impression that the iack handler has very little to do with each interrupt (the test 'prev->iack != intr->iack' is a dead giveaway), but is more of a domain-specific function (or perhaps even just a placeholder for the hijacked Linux ack-function). 2. Somewhat inspired by the figure in "Life with Adeos", I have identified the following cases: irq K | --- | ---o| // Linux only ... irq L | ---o| | // RT-only ... irq M | ---o--- | ---o| // Shared between domains ... irq N | ---o---o--- | | // Shared inside single domain ... irq O | ---o---o--- | ---o| // Shared between and inside single domain Xenomai currently handles the K & L cases, Dmitrys patch addresses the N case, with edge triggered interrupts the M (and O after Dmitry's patch) case(s) might be handled by returning RT_INTR_CHAINED | RT_INTR_ENABLE from the interrupt handler, for level triggered interrupt the M and O cases can't be handled. I guess you mean it the other way around: for the edge-triggered cross-domain case we would actually have to loop over both the RT and the Linux handlers until we are sure, that the IRQ line was released once. I obviously has misunderstood edge triggered :-( Luckily, I never saw such a scenario which were unavoidable (it hits you with ISA hardware which tend to have nice IRQ jumpers or other means - it's just that you often cannot divide several controllers on the same extension card IRQ-wise apart). If one looks more closely at the K case (Linux only interrupt), it works by when an interrupt occurs, the call to irq_end is postponed until the Linux interrupt handler has run, i.e. further interrupts are disabled. This can be seen as a lazy version of Philippe's idea of disabling all non-RT interrupts until the RT-domain is idle, i.e. the interrupt is disabled only if it indeed occurs. If this idea should be generalized to the M (and O) case(s), one can't rely on postponing the irq_end call (since the interrupt is still needed in the RT-domain), but has to rely on some function that disables all non-RT hardware that generates interrupts on that irq-line; such a function naturally has to have intimate knowledge of all hardware that can generate interrupts in order to be able to disable those interrupt sources that are non-RT. If we then take Jan's observation about the many (Linux-only) interrupts present in an ordinary PC and add it to Philippe's idea of disabling all non-RT interrupts while executing in the RT-domain, I think that the following is a workable (and fairly efficient) way of handling this: Add hardware dependent enable/disable functions, where the enable is called just before normal execution in a domain starts (i.e. when playing back interrupts, the disable is still in effect), and disable is called when normal domain execution end. This does effectively handle the K case above, with the added benefit that NO non-RT interrupts will occur during RT execution. In the 8259 case, the disable function could look something like: domain_irq_disable(uint irqmask) { if (irqmask & 0xff00 != 0xff00) { irqmask &= ~0x0004; // Cascaded interrupt is still needed outb(irqmask >> 8, PIC_SLAVE_IMR); } outb(irqmask, PIC_MASTER_IMR); } If we should extend this to handle the M (and O) case(s), the disable function could look like: domain_irq_disable(uint irqmask, shared_irq_t *shared[]) { int i; for (i = 0 ; i < MAX_IRQ ; i++) { if (shared[i]) { shared_irq_t *next = shared[i]; irqmask &= ~(1next; } This obviously means that all non-RT IRQ handlers sharing a line with the RT domain would have to be registered in that shared[]-list. This gets close to my old suggestion. Just raises the question how to organise these interface, both on the RT and the Linux side. } } if (irqmask & 0xff00 != 0xff00) { irqmask &= ~0x0004; // Cascaded interrupt is still needed outb(irqmask >> 8, PIC_SLAVE_IMR); } outb(irqmask, PIC_MASTER_IMR); } An obvious optimization of the above scheme, is to never call the disable (or enable) function for the RT-domain, since there all interrupt processing is protected by the hardware. Another point is to avoid that looping over disable handlers for IRQs of the K case. Otherwise, too many device-specific disable handlers had to be implemented even if only a single Linux device hogs a RT IRQ. You only have to spin over those IRQ that are actually shared across domains (probably just a few in most cases), those IRQ that s
Re: [Xenomai-core] More on Shared interrupts
Anders Blomdell wrote: > For the last few days, I have tried to figure out a good way to share > interrupts between RT and non-RT domains. This has included looking > through Dmitry's patch, correcting bugs and testing what is possible in > my specific case. I'll therefore try to summarize at least a few of my > thoughts. > > 1. When looking through Dmitry's patch I get the impression that the > iack handler has very little to do with each interrupt (the test > 'prev->iack != intr->iack' is a dead giveaway), but is more of a > domain-specific function (or perhaps even just a placeholder for the > hijacked Linux ack-function). > > > 2. Somewhat inspired by the figure in "Life with Adeos", I have > identified the following cases: > > irq K | --- | ---o| // Linux only > ... > irq L | ---o| | // RT-only > ... > irq M | ---o--- | ---o| // Shared between domains > ... > irq N | ---o---o--- | | // Shared inside single domain > ... > irq O | ---o---o--- | ---o| // Shared between and inside single > domain > > Xenomai currently handles the K & L cases, Dmitrys patch addresses the N > case, with edge triggered interrupts the M (and O after Dmitry's patch) > case(s) might be handled by returning RT_INTR_CHAINED | RT_INTR_ENABLE > from the interrupt handler, for level triggered interrupt the M and O > cases can't be handled. I guess you mean it the other way around: for the edge-triggered cross-domain case we would actually have to loop over both the RT and the Linux handlers until we are sure, that the IRQ line was released once. Luckily, I never saw such a scenario which were unavoidable (it hits you with ISA hardware which tend to have nice IRQ jumpers or other means - it's just that you often cannot divide several controllers on the same extension card IRQ-wise apart). > > If one looks more closely at the K case (Linux only interrupt), it works > by when an interrupt occurs, the call to irq_end is postponed until the > Linux interrupt handler has run, i.e. further interrupts are disabled. > This can be seen as a lazy version of Philippe's idea of disabling all > non-RT interrupts until the RT-domain is idle, i.e. the interrupt is > disabled only if it indeed occurs. > > If this idea should be generalized to the M (and O) case(s), one can't > rely on postponing the irq_end call (since the interrupt is still needed > in the RT-domain), but has to rely on some function that disables all > non-RT hardware that generates interrupts on that irq-line; such a > function naturally has to have intimate knowledge of all hardware that > can generate interrupts in order to be able to disable those interrupt > sources that are non-RT. > > If we then take Jan's observation about the many (Linux-only) interrupts > present in an ordinary PC and add it to Philippe's idea of disabling all > non-RT interrupts while executing in the RT-domain, I think that the > following is a workable (and fairly efficient) way of handling this: > > Add hardware dependent enable/disable functions, where the enable is > called just before normal execution in a domain starts (i.e. when > playing back interrupts, the disable is still in effect), and disable is > called when normal domain execution end. This does effectively handle > the K case above, with the added benefit that NO non-RT interrupts will > occur during RT execution. > > In the 8259 case, the disable function could look something like: > > domain_irq_disable(uint irqmask) { > if (irqmask & 0xff00 != 0xff00) { > irqmask &= ~0x0004; // Cascaded interrupt is still needed > outb(irqmask >> 8, PIC_SLAVE_IMR); > } > outb(irqmask, PIC_MASTER_IMR); > } > > If we should extend this to handle the M (and O) case(s), the disable > function could look like: > > domain_irq_disable(uint irqmask, shared_irq_t *shared[]) { > int i; > > for (i = 0 ; i < MAX_IRQ ; i++) { > if (shared[i]) { > shared_irq_t *next = shared[i]; > irqmask &= ~(1< while (next) { > next->disable(); > next = next->next; > } This obviously means that all non-RT IRQ handlers sharing a line with the RT domain would have to be registered in that shared[]-list. This gets close to my old suggestion. Just raises the question how to organise these interface, both on the RT and the Linux side. > } > } > if (irqmask & 0xff00 != 0xff00) { > irqmask &= ~0x0004; // Cascaded interrupt is still needed > outb(irqmask >> 8, PIC_SLAVE_IMR); > } > outb(irqmask, PIC_MASTER_IMR); > } > > An obvious optimization of the above scheme, is to never call the > disable (or enable) function for the RT-domain, since there all > interrupt processing is protected by the hardware. Another point is to avoid that looping over disable handlers for IRQs of the K case. Otherwise, too many device-specific disable handlers had to be implemented e
Re: [Xenomai-core] More on Shared interrupts
Anders Blomdell wrote: > For the last few days, I have tried to figure out a good way to share > interrupts between RT and non-RT domains. This has included looking > through Dmitry's patch, correcting bugs and testing what is possible in > my specific case. I'll therefore try to summarize at least a few of my > thoughts. > > 1. When looking through Dmitry's patch I get the impression that the > iack handler has very little to do with each interrupt (the test > 'prev->iack != intr->iack' is a dead giveaway), but is more of a > domain-specific function (or perhaps even just a placeholder for the > hijacked Linux ack-function). > > > 2. Somewhat inspired by the figure in "Life with Adeos", I have > identified the following cases: > > irq K | --- | ---o| // Linux only > ... > irq L | ---o| | // RT-only > ... > irq M | ---o--- | ---o| // Shared between domains > ... > irq N | ---o---o--- | | // Shared inside single domain > ... > irq O | ---o---o--- | ---o| // Shared between and inside single > domain > > Xenomai currently handles the K & L cases, Dmitrys patch addresses the N > case, with edge triggered interrupts the M (and O after Dmitry's patch) > case(s) might be handled by returning RT_INTR_CHAINED | RT_INTR_ENABLE > from the interrupt handler, for level triggered interrupt the M and O > cases can't be handled. I guess you mean it the other way around: for the edge-triggered cross-domain case we would actually have to loop over both the RT and the Linux handlers until we are sure, that the IRQ line was released once. Luckily, I never saw such a scenario which were unavoidable (it hits you with ISA hardware which tend to have nice IRQ jumpers or other means - it's just that you often cannot divide several controllers on the same extension card IRQ-wise apart). > > If one looks more closely at the K case (Linux only interrupt), it works > by when an interrupt occurs, the call to irq_end is postponed until the > Linux interrupt handler has run, i.e. further interrupts are disabled. > This can be seen as a lazy version of Philippe's idea of disabling all > non-RT interrupts until the RT-domain is idle, i.e. the interrupt is > disabled only if it indeed occurs. > > If this idea should be generalized to the M (and O) case(s), one can't > rely on postponing the irq_end call (since the interrupt is still needed > in the RT-domain), but has to rely on some function that disables all > non-RT hardware that generates interrupts on that irq-line; such a > function naturally has to have intimate knowledge of all hardware that > can generate interrupts in order to be able to disable those interrupt > sources that are non-RT. > > If we then take Jan's observation about the many (Linux-only) interrupts > present in an ordinary PC and add it to Philippe's idea of disabling all > non-RT interrupts while executing in the RT-domain, I think that the > following is a workable (and fairly efficient) way of handling this: > > Add hardware dependent enable/disable functions, where the enable is > called just before normal execution in a domain starts (i.e. when > playing back interrupts, the disable is still in effect), and disable is > called when normal domain execution end. This does effectively handle > the K case above, with the added benefit that NO non-RT interrupts will > occur during RT execution. > > In the 8259 case, the disable function could look something like: > > domain_irq_disable(uint irqmask) { > if (irqmask & 0xff00 != 0xff00) { > irqmask &= ~0x0004; // Cascaded interrupt is still needed > outb(irqmask >> 8, PIC_SLAVE_IMR); > } > outb(irqmask, PIC_MASTER_IMR); > } > > If we should extend this to handle the M (and O) case(s), the disable > function could look like: > > domain_irq_disable(uint irqmask, shared_irq_t *shared[]) { > int i; > > for (i = 0 ; i < MAX_IRQ ; i++) { > if (shared[i]) { > shared_irq_t *next = shared[i]; > irqmask &= ~(1< while (next) { > next->disable(); > next = next->next; > } This obviously means that all non-RT IRQ handlers sharing a line with the RT domain would have to be registered in that shared[]-list. This gets close to my old suggestion. Just raises the question how to organise these interface, both on the RT and the Linux side. > } > } > if (irqmask & 0xff00 != 0xff00) { > irqmask &= ~0x0004; // Cascaded interrupt is still needed > outb(irqmask >> 8, PIC_SLAVE_IMR); > } > outb(irqmask, PIC_MASTER_IMR); > } > > An obvious optimization of the above scheme, is to never call the > disable (or enable) function for the RT-domain, since there all > interrupt processing is protected by the hardware. Another point is to avoid that looping over disable handlers for IRQs of the K case. Otherwise, too many device-specific disable handlers had to be implemented e