pub struct RingProducer<M> { /* private fields */ }Expand description
Producer (driver) side of a packed virtqueue.
The producer submits buffer chains for the device to process and polls for completions. This is typically used by the driver/guest side.
§Lifecycle
1.Submit: Call submit_available or
submit_one to make buffers available to device
2. Notify: If SubmitResult::notify is true, signal the device
3. Poll: Call poll_used to check for completions
4. Process: Handle completed buffers and reuse descriptor IDs
Implementations§
Source§impl<M: MemOps> RingProducer<M>
impl<M: MemOps> RingProducer<M>
Sourcepub fn new(layout: Layout, mem: M) -> Self
pub fn new(layout: Layout, mem: M) -> Self
Create a new producer from a memory layout and accessor.
Sourcepub fn submit_one(
&mut self,
addr: u64,
len: u32,
writable: bool,
) -> Result<u16, RingError>
pub fn submit_one( &mut self, addr: u64, len: u32, writable: bool, ) -> Result<u16, RingError>
Fast path: submit exactly one descriptor
This is more efficient than submit_available
for single-buffer submissions as it avoids chain iteration overhead.
§Arguments
addr- physical address of the bufferlen- Length of the buffer in byteswritable- If true, device writes to buffer; if false, device reads
§Returns
The descriptor ID assigned to this buffer, for matching with completions.
§Errors
RingError::WouldBlock- No free descriptor slotsRingError::OutOfMemory- No free descriptor IDs (internal error)RingError::InvalidState- ID tracking corrupted (internal error)RingError::MemError- Backend memory error while publishing the descriptor
Sourcepub fn submit_available_with_notify(
&mut self,
chain: &BufferChain,
) -> Result<SubmitResult, RingError>
pub fn submit_available_with_notify( &mut self, chain: &BufferChain, ) -> Result<SubmitResult, RingError>
Submit a buffer chain to the ring, returning whether to notify the device.
Sourcepub fn submit_one_with_notify(
&mut self,
addr: u64,
len: u32,
writable: bool,
) -> Result<SubmitResult, RingError>
pub fn submit_one_with_notify( &mut self, addr: u64, len: u32, writable: bool, ) -> Result<SubmitResult, RingError>
Submit a single-buffer descriptor with notification check.
Sourcepub fn submit_available(
&mut self,
chain: &BufferChain,
) -> Result<u16, RingError>
pub fn submit_available( &mut self, chain: &BufferChain, ) -> Result<u16, RingError>
Submit a buffer chain to the ring.
Writes all descriptors in the chain to the ring, linking them with NEXT flags. The head descriptor is written last with release semantics to ensure atomicity of the chain.
§Arguments
chain- The buffer chain to submit
§Returns
The descriptor ID assigned to this chain. All descriptors in the chain share this ID for correlation during completion.
§Errors
RingError::EmptyChain- Chain has no buffersRingError::WouldBlock- Not enough free descriptor slotsRingError::OutOfMemory- No free descriptor IDs (internal error)RingError::InvalidState- ID tracking or descriptor-table state is corruptedRingError::MemError- Backend memory error while publishing descriptors
Sourcepub fn poll_used(&mut self) -> Result<UsedBuffer, RingError>
pub fn poll_used(&mut self) -> Result<UsedBuffer, RingError>
Poll the ring for a used buffer.
Checks if the device has marked any buffers as used. If so, returns the completion information and reclaims the descriptor(s).
§Returns
Ok(UsedBuffer)- A buffer chain was completedErr(RingError::WouldBlock)- No completions available
Sourcepub fn num_inflight(&self) -> usize
pub fn num_inflight(&self) -> usize
Get number of inflight (submitted but not yet used) descriptors.
Sourcepub fn desc_table(&self) -> &DescTable
pub fn desc_table(&self) -> &DescTable
Get descriptor table reference
Sourcepub fn avail_cursor(&self) -> RingCursor
pub fn avail_cursor(&self) -> RingCursor
Get a snapshot of the current available cursor position.
Used for batch operations to track the cursor before submitting multiple chains, enabling proper event suppression checks.
Sourcepub fn used_cursor(&self) -> RingCursor
pub fn used_cursor(&self) -> RingCursor
Get a snapshot of the current used cursor position.
Used for setting up DESC mode event suppression at specific positions.
Sourcepub fn should_notify_since(&self, old: RingCursor) -> Result<bool, RingError>
pub fn should_notify_since(&self, old: RingCursor) -> Result<bool, RingError>
Check if device should be notified given a cursor snapshot from before batch start.
This is used for batching: record cursor before first submit, then after all submits call this to determine if notification is needed based on event suppression.
§Arguments
old- Cursor position snapshot taken before batch started
Sourcepub fn disable_used_notifications(&mut self) -> Result<(), RingError>
pub fn disable_used_notifications(&mut self) -> Result<(), RingError>
Driver disables used-buffer notifications from device to driver.
Sourcepub fn enable_used_notifications(&mut self) -> Result<(), RingError>
pub fn enable_used_notifications(&mut self) -> Result<(), RingError>
Driver enables used-buffer notifications from device to driver.
Sourcepub fn enable_used_notifications_desc(
&mut self,
off: u16,
wrap: bool,
) -> Result<(), RingError>
pub fn enable_used_notifications_desc( &mut self, off: u16, wrap: bool, ) -> Result<(), RingError>
Driver enables descriptor-specific used notifications (EVENT_IDX / DESC mode).
This tells the device: “Interrupt me when you reach used index (off, wrap)”.
This enables batching on the device side - it can complete multiple requests before triggering an interrupt.
Sourcepub fn enable_used_notifications_for_next(&mut self) -> Result<(), RingError>
pub fn enable_used_notifications_for_next(&mut self) -> Result<(), RingError>
Convenience: enable DESC mode for “next used cursor” like Linux enable_cb_prepare.
Sourcepub fn reset_prefilled(&mut self, ids: &[u16])
pub fn reset_prefilled(&mut self, ids: &[u16])
Reset the ring to the “N slots submitted, none completed” state.
ids contains the descriptor IDs that are in-flight.
Sets cursors, counters, and id_num accordingly. The chain lengths are all set to 1.