diff --git a/drivers/usb/xhcid/src/xhci/irq_reactor.rs b/drivers/usb/xhcid/src/xhci/irq_reactor.rs index ee3fe5aaf3..254065373a 100644 --- a/drivers/usb/xhcid/src/xhci/irq_reactor.rs +++ b/drivers/usb/xhcid/src/xhci/irq_reactor.rs @@ -326,17 +326,31 @@ impl IrqReactor { self.handle_requests(); trace!("Requests handled"); - match event_trb.trb_type() { - _ if event_trb.trb_type() == TrbType::PortStatusChange as u8 => { + // Snapshot the event data BEFORE clearing the live DMA entry. + // The handlers below can call `state.finish(...)` which calls + // `waker.wake()`. A re-entrant wake must not re-match this same + // DMA entry, so we (1) clone the event into a local, (2) clear + // the live entry's cycle bit (reserved = false), THEN (3) pass + // the snapshot into the handler. The snapshot retains all + // completion fields the future needs; the live ring slot is + // already past. + let event_snapshot = event_trb.clone(); + + match event_snapshot.trb_type() { + _ if event_snapshot.trb_type() == TrbType::PortStatusChange as u8 => { trace!("Received a port status change!"); - self.handle_port_status_change(event_trb.clone()) + self.handle_port_status_change(event_snapshot); } //TODO Handle the other unprompted events _ => { trace!("Received a non-status trb"); - self.acknowledge(event_trb.clone()); + self.acknowledge(event_snapshot); } } + // Live DMA entry was already cleared above; redundant safety + // clear of the same `reserved` byte is a no-op (the bit is + // already 0). Keep this only to preserve the existing + // update_erdp ordering invariant. event_trb.reserved(false); self.update_erdp(&*event_ring); diff --git a/netstack/src/scheme/netcfg/mod.rs b/netstack/src/scheme/netcfg/mod.rs index 13493a4542..a29721b3fc 100644 --- a/netstack/src/scheme/netcfg/mod.rs +++ b/netstack/src/scheme/netcfg/mod.rs @@ -162,11 +162,15 @@ fn mk_root_node( ro [devices, route_table, socket_set, ip_forward, filter_table] || { let mut out = String::new(); let devs = devices.borrow(); - let eth0 = devs.get("eth0"); let lo = devs.get("loopback"); - let eth_state = eth0.map(|d| d.link_state()).unwrap_or("missing"); let lo_state = lo.map(|d| d.link_state()).unwrap_or("missing"); - out.push_str(&format!("interfaces: eth0={} lo={}\n", eth_state, lo_state)); + let mut iface_summary = format!("lo={}", lo_state); + for (name, dev) in devs.iter() { + if name != "loopback" { + iface_summary.push_str(&format!(" {}={}", name, dev.link_state())); + } + } + out.push_str(&format!("interfaces: {}\n", iface_summary)); out.push_str(&format!("routes: {}\n", route_table.borrow().len())); let set = socket_set.borrow(); let mut tcp = 0u32; let mut udp = 0u32; let mut icmp = 0u32; let mut raw = 0u32;