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:
Red Bear OS
2026-07-20 18:48:30 +09:00
parent 9292422458
commit 28afc1fefd
6 changed files with 39 additions and 15 deletions
+8 -3
View File
@@ -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| {
+7 -2
View File
@@ -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)
+6 -2
View File
@@ -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();
}
+6 -2
View File
@@ -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();
}
}
+6 -3
View File
@@ -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();
}
}
+6 -3
View File
@@ -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();
}
}