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);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !device.irq() {
|
let ours = device.irq();
|
||||||
continue;
|
// 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) {
|
if let Err(err) = irq_file.write(&mut irq) {
|
||||||
error!("ac97d: failed to acknowledge IRQ: {err}");
|
error!("ac97d: failed to acknowledge IRQ: {err}");
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !ours {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
readiness_based
|
readiness_based
|
||||||
.poll_all_requests(&mut device)
|
.poll_all_requests(&mut device)
|
||||||
.unwrap_or_else(|err| {
|
.unwrap_or_else(|err| {
|
||||||
|
|||||||
@@ -79,10 +79,15 @@ fn daemon(daemon: daemon::Daemon) -> ! {
|
|||||||
let mut irq = [0; 8];
|
let mut irq = [0; 8];
|
||||||
irq_file.read(&mut irq).unwrap();
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
irq_file.write(&mut irq).unwrap();
|
|
||||||
|
|
||||||
readiness_based
|
readiness_based
|
||||||
.poll_all_requests(&mut device)
|
.poll_all_requests(&mut device)
|
||||||
|
|||||||
@@ -86,9 +86,13 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
|
|||||||
Source::Irq => {
|
Source::Irq => {
|
||||||
let mut irq = [0; 8];
|
let mut irq = [0; 8];
|
||||||
irq_file.irq_handle().read(&mut irq).unwrap();
|
irq_file.irq_handle().read(&mut irq).unwrap();
|
||||||
if scheme.adapter_mut().handle_irq() {
|
let ours = scheme.adapter_mut().handle_irq();
|
||||||
irq_file.irq_handle().write(&mut irq).unwrap();
|
// 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.adapter_mut().handle_events();
|
||||||
scheme.tick().unwrap();
|
scheme.tick().unwrap();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,9 +73,13 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
|
|||||||
Source::Irq => {
|
Source::Irq => {
|
||||||
let mut irq = [0; 8];
|
let mut irq = [0; 8];
|
||||||
irq_file.read(&mut irq).unwrap();
|
irq_file.read(&mut irq).unwrap();
|
||||||
if scheme.adapter().irq() {
|
let ours = scheme.adapter().irq();
|
||||||
irq_file.write(&mut irq).unwrap();
|
// 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();
|
scheme.tick().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,10 +99,13 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
|
|||||||
Source::Irq => {
|
Source::Irq => {
|
||||||
let mut irq = [0; 8];
|
let mut irq = [0; 8];
|
||||||
irq_file.irq_handle().read(&mut irq).unwrap();
|
irq_file.irq_handle().read(&mut irq).unwrap();
|
||||||
//TODO: This may be causing spurious interrupts
|
let ours = unsafe { scheme.adapter_mut().irq() };
|
||||||
if unsafe { scheme.adapter_mut().irq() } {
|
// The kernel masks the IRQ line on delivery and only re-arms
|
||||||
irq_file.irq_handle().write(&mut irq).unwrap();
|
// 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();
|
scheme.tick().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,10 +99,13 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
|
|||||||
Source::Irq => {
|
Source::Irq => {
|
||||||
let mut irq = [0; 8];
|
let mut irq = [0; 8];
|
||||||
irq_file.irq_handle().read(&mut irq).unwrap();
|
irq_file.irq_handle().read(&mut irq).unwrap();
|
||||||
//TODO: This may be causing spurious interrupts
|
let ours = unsafe { scheme.adapter_mut().irq() };
|
||||||
if unsafe { scheme.adapter_mut().irq() } {
|
// The kernel masks the IRQ line on delivery and only re-arms
|
||||||
irq_file.irq_handle().write(&mut irq).unwrap();
|
// 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();
|
scheme.tick().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user