drivers: complete shared-IRQ re-arm sweep (audio, net, graphics)
Continuation of 92924224 — the same conditional-ack bug class found in
six more drivers: a foreign interrupt on a shared INTx line skipped the
write-back ack, leaving the kernel-masked IRQ line dead forever.
- sb16d, ac97d: ack before the not-ours continue
- rtl8139d, rtl8168d, ixgbed: ack unconditionally, tick only when ours
(the stale 'TODO: spurious interrupts' comments removed — the
spurious-interrupt confusion was this bug)
- ihdgd: ack unconditionally, handle_events/tick only when ours
Verified: cargo check -Z build-std --target x86_64-unknown-redox for
sb16d, ac97d, rtl8139d, rtl8168d, ixgbed, ihdgd — clean, no new
warnings. nvmed audited: not affected (per-queue MSI pattern, no
conditional ack).
This commit is contained in:
@@ -149,14 +149,19 @@ fn daemon(daemon: daemon::Daemon, pcid_handle: PciFunctionHandle) -> ! {
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
if !device.irq() {
|
||||
continue;
|
||||
}
|
||||
let ours = device.irq();
|
||||
// The kernel masks the IRQ line on delivery and only re-arms
|
||||
// it on write-back; ack unconditionally or a foreign interrupt
|
||||
// on a shared line leaves the line masked forever.
|
||||
if let Err(err) = irq_file.write(&mut irq) {
|
||||
error!("ac97d: failed to acknowledge IRQ: {err}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
if !ours {
|
||||
continue;
|
||||
}
|
||||
|
||||
readiness_based
|
||||
.poll_all_requests(&mut device)
|
||||
.unwrap_or_else(|err| {
|
||||
|
||||
@@ -79,10 +79,15 @@ fn daemon(daemon: daemon::Daemon) -> ! {
|
||||
let mut irq = [0; 8];
|
||||
irq_file.read(&mut irq).unwrap();
|
||||
|
||||
if !device.irq() {
|
||||
let ours = device.irq();
|
||||
// The kernel masks the IRQ line on delivery and only re-arms
|
||||
// it on write-back; ack unconditionally or a foreign interrupt
|
||||
// on a shared line leaves the line masked forever.
|
||||
irq_file.write(&mut irq).unwrap();
|
||||
|
||||
if !ours {
|
||||
continue;
|
||||
}
|
||||
irq_file.write(&mut irq).unwrap();
|
||||
|
||||
readiness_based
|
||||
.poll_all_requests(&mut device)
|
||||
|
||||
@@ -86,9 +86,13 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
|
||||
Source::Irq => {
|
||||
let mut irq = [0; 8];
|
||||
irq_file.irq_handle().read(&mut irq).unwrap();
|
||||
if scheme.adapter_mut().handle_irq() {
|
||||
irq_file.irq_handle().write(&mut irq).unwrap();
|
||||
let ours = scheme.adapter_mut().handle_irq();
|
||||
// The kernel masks the IRQ line on delivery and only re-arms
|
||||
// it on write-back; ack unconditionally or a foreign interrupt
|
||||
// on a shared line leaves the line masked forever.
|
||||
irq_file.irq_handle().write(&mut irq).unwrap();
|
||||
|
||||
if ours {
|
||||
scheme.adapter_mut().handle_events();
|
||||
scheme.tick().unwrap();
|
||||
}
|
||||
|
||||
@@ -73,9 +73,13 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
|
||||
Source::Irq => {
|
||||
let mut irq = [0; 8];
|
||||
irq_file.read(&mut irq).unwrap();
|
||||
if scheme.adapter().irq() {
|
||||
irq_file.write(&mut irq).unwrap();
|
||||
let ours = scheme.adapter().irq();
|
||||
// The kernel masks the IRQ line on delivery and only re-arms
|
||||
// it on write-back; ack unconditionally or a foreign interrupt
|
||||
// on a shared line leaves the line masked forever.
|
||||
irq_file.write(&mut irq).unwrap();
|
||||
|
||||
if ours {
|
||||
scheme.tick().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,10 +99,13 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
|
||||
Source::Irq => {
|
||||
let mut irq = [0; 8];
|
||||
irq_file.irq_handle().read(&mut irq).unwrap();
|
||||
//TODO: This may be causing spurious interrupts
|
||||
if unsafe { scheme.adapter_mut().irq() } {
|
||||
irq_file.irq_handle().write(&mut irq).unwrap();
|
||||
let ours = unsafe { scheme.adapter_mut().irq() };
|
||||
// The kernel masks the IRQ line on delivery and only re-arms
|
||||
// it on write-back; ack unconditionally or a foreign interrupt
|
||||
// on a shared line leaves the line masked forever.
|
||||
irq_file.irq_handle().write(&mut irq).unwrap();
|
||||
|
||||
if ours {
|
||||
scheme.tick().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,10 +99,13 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
|
||||
Source::Irq => {
|
||||
let mut irq = [0; 8];
|
||||
irq_file.irq_handle().read(&mut irq).unwrap();
|
||||
//TODO: This may be causing spurious interrupts
|
||||
if unsafe { scheme.adapter_mut().irq() } {
|
||||
irq_file.irq_handle().write(&mut irq).unwrap();
|
||||
let ours = unsafe { scheme.adapter_mut().irq() };
|
||||
// The kernel masks the IRQ line on delivery and only re-arms
|
||||
// it on write-back; ack unconditionally or a foreign interrupt
|
||||
// on a shared line leaves the line masked forever.
|
||||
irq_file.irq_handle().write(&mut irq).unwrap();
|
||||
|
||||
if ours {
|
||||
scheme.tick().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user