perf(e1000e): agrupa el doorbell RDT y elimina MMIO redundante en RX - #752
Merged
Conversation
El camino RX no agrupaba ningun acceso MMIO por paquete: cada frame recibido pagaba su propio round-trip completo, sin importar cuantos llegaran en la misma rafaga. Bajo QEMU (el objetivo de pruebas habitual de este driver) cada acceso MMIO tipicamente dispara una VM exit completa, asi que esta sobrecarga por-paquete domina el coste real de mover los bytes. Cambios en drivers/src/net/e1000e.rs, todos en el camino RX: - receive() cachea RDH una sola vez por llamada en vez de releerlo por MMIO en cada iteracion del bucle de drenaje (hasta 2 lecturas por iteracion antes). process_rx_slot ya no relee RDH: el invariante lo garantiza quien llama. - El doorbell RDT se difiere (rx_doorbell_dirty) y se agrupa con flush_rx_doorbell(), llamado una vez por rafaga en poll_with_irq_hint (tras iface.poll()) y en NetScheme::recv(). Se elimina tambien la lectura de flush sincrona que seguia a cada escritura de RDT. - ensure_rx_armed_if_link_up ya no relee STATUS por MMIO cuando el enlace ya se sabe activo (se invoca en cada poll). - La invalidacion de cache del buffer RX usa la longitud real del frame en vez de BUF_SIZE completo (2048B) — nada lee mas alla de esa longitud. Nuevo test rx_doorbell_is_batched_not_rung_per_packet que verifica el agrupamiento explicitamente. Los 13 tests existentes (RX, TX, coherency bench) siguen en verde; cargo build (no_std real) y clippy limpios. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GFLBAPffWxDbLjrj9TEoW4
There was a problem hiding this comment.
Pull request overview
This PR optimizes the e1000e RX fast path by reducing per-packet MMIO round-trips (particularly important under QEMU where MMIO often triggers VM-exits) and by tightening DMA cache invalidation to only the bytes actually read.
Changes:
- Cache RDH once per
receive()call and remove per-slot RDH MMIO reads inprocess_rx_slot. - Defer/batch RX RDT doorbell writes via
rx_doorbell_dirty+flush_rx_doorbell(), called once per poll burst and inNetScheme::recv(). - Reduce RX buffer cache invalidation from
BUF_SIZEto the actual frame fragment length; add a test to assert doorbell batching behavior.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| drivers/src/net/e1000e.rs | Batches RX doorbell writes, reduces redundant MMIO reads, and narrows DMA sync ranges; adds a regression test for batching. |
| docs/README-e1000e-bugs.md | Documents the diagnosed RX MMIO batching issue and the applied performance fixes/verification. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
El camino RX no agrupaba ningun acceso MMIO por paquete: cada frame recibido pagaba su propio round-trip completo, sin importar cuantos llegaran en la misma rafaga. Bajo QEMU (el objetivo de pruebas habitual de este driver) cada acceso MMIO tipicamente dispara una VM exit completa, asi que esta sobrecarga por-paquete domina el coste real de mover los bytes.
Cambios en drivers/src/net/e1000e.rs, todos en el camino RX:
Nuevo test rx_doorbell_is_batched_not_rung_per_packet que verifica el agrupamiento explicitamente. Los 13 tests existentes (RX, TX, coherency bench) siguen en verde; cargo build (no_std real) y clippy limpios.
Claude-Session: https://claude.ai/code/session_01GFLBAPffWxDbLjrj9TEoW4