Skip to content

Commit 163b256

Browse files
author
Sebastien Boeuf
committed
virtio-queue: Add helpers for accessing queue information
These helpers are meant to help crate's consumers getting and setting information about the queue. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
1 parent 26fcb56 commit 163b256

File tree

4 files changed

+86
-0
lines changed

4 files changed

+86
-0
lines changed

crates/virtio-queue/src/lib.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,9 @@ pub trait QueueStateT: for<'a> QueueStateGuard<'a> {
154154
/// Read the `idx` field from the available ring.
155155
fn avail_idx<M: GuestMemory>(&self, mem: &M, order: Ordering) -> Result<Wrapping<u16>, Error>;
156156

157+
/// Read the `idx` field from the used ring.
158+
fn used_idx<M: GuestMemory>(&self, mem: &M, order: Ordering) -> Result<Wrapping<u16>, Error>;
159+
157160
/// Put a used descriptor head into the used ring.
158161
fn add_used<M: GuestMemory>(&mut self, mem: &M, head_index: u16, len: u32)
159162
-> Result<(), Error>;
@@ -179,6 +182,12 @@ pub trait QueueStateT: for<'a> QueueStateGuard<'a> {
179182
/// Return the index of the next entry in the available ring.
180183
fn next_avail(&self) -> u16;
181184

185+
/// Return the index for the next descriptor in the used ring.
186+
fn next_used(&self) -> u16;
187+
182188
/// Set the index of the next entry in the available ring.
183189
fn set_next_avail(&mut self, next_avail: u16);
190+
191+
/// Set the index for the next descriptor in the used ring.
192+
fn set_next_used(&mut self, next_used: u16);
184193
}

crates/virtio-queue/src/queue.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,14 @@ impl<M: GuestAddressSpace, S: QueueStateT> Queue<M, S> {
197197
self.state.avail_idx(self.mem.memory().deref(), order)
198198
}
199199

200+
/// Reads the `idx` field from the used ring.
201+
///
202+
/// # Arguments
203+
/// * `order` - the memory ordering used to access the `idx` field from memory.
204+
pub fn used_idx(&self, order: Ordering) -> Result<Wrapping<u16>, Error> {
205+
self.state.used_idx(self.mem.memory().deref(), order)
206+
}
207+
200208
/// Put a used descriptor head into the used ring.
201209
///
202210
/// # Arguments
@@ -236,20 +244,39 @@ impl<M: GuestAddressSpace, S: QueueStateT> Queue<M, S> {
236244
self.state.next_avail()
237245
}
238246

247+
/// Returns the index for the next descriptor in the used ring.
248+
pub fn next_used(&self) -> u16 {
249+
self.state.next_used()
250+
}
251+
239252
/// Set the index of the next entry in the available ring.
240253
///
241254
/// # Arguments
242255
/// * `next_avail` - the index of the next available ring entry.
243256
pub fn set_next_avail(&mut self, next_avail: u16) {
244257
self.state.set_next_avail(next_avail);
245258
}
259+
260+
/// Sets the index for the next descriptor in the used ring.
261+
///
262+
/// # Arguments
263+
/// * `next_used` - the index of the next used ring entry.
264+
pub fn set_next_used(&mut self, next_used: u16) {
265+
self.state.set_next_used(next_used);
266+
}
246267
}
247268

248269
impl<M: GuestAddressSpace> Queue<M, QueueState> {
249270
/// A consuming iterator over all available descriptor chain heads offered by the driver.
250271
pub fn iter(&mut self) -> Result<AvailIter<'_, M::T>, Error> {
251272
self.state.iter(self.mem.memory())
252273
}
274+
275+
/// Set the queue to "ready", and update desc_table, avail_ring and
276+
/// used_ring addresses based on the AccessPlatform handler.
277+
pub fn enable(&mut self, set: bool) {
278+
self.state.enable(set)
279+
}
253280
}
254281

255282
#[cfg(test)]

crates/virtio-queue/src/state.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,28 @@ impl QueueState {
149149
.map(Wrapping)
150150
.map_err(Error::GuestMemory)
151151
}
152+
153+
/// Set the queue to "ready", and update desc_table, avail_ring and
154+
/// used_ring addresses based on the AccessPlatform handler.
155+
pub fn enable(&mut self, set: bool) {
156+
self.ready = set;
157+
158+
if set {
159+
// Translate address of descriptor table and vrings.
160+
if let Some(access_platform) = &self.access_platform {
161+
self.desc_table =
162+
GuestAddress(access_platform.translate(self.desc_table.0, 0).unwrap());
163+
self.avail_ring =
164+
GuestAddress(access_platform.translate(self.avail_ring.0, 0).unwrap());
165+
self.used_ring =
166+
GuestAddress(access_platform.translate(self.used_ring.0, 0).unwrap());
167+
}
168+
} else {
169+
self.desc_table = GuestAddress(0);
170+
self.avail_ring = GuestAddress(0);
171+
self.used_ring = GuestAddress(0);
172+
}
173+
}
152174
}
153175

154176
impl<'a> QueueStateGuard<'a> for QueueState {
@@ -311,6 +333,14 @@ impl QueueStateT for QueueState {
311333
.map_err(Error::GuestMemory)
312334
}
313335

336+
fn used_idx<M: GuestMemory>(&self, mem: &M, order: Ordering) -> Result<Wrapping<u16>, Error> {
337+
let addr = self.used_ring.unchecked_add(2);
338+
339+
mem.load(addr, order)
340+
.map(Wrapping)
341+
.map_err(Error::GuestMemory)
342+
}
343+
314344
fn add_used<M: GuestMemory>(
315345
&mut self,
316346
mem: &M,
@@ -415,7 +445,15 @@ impl QueueStateT for QueueState {
415445
self.next_avail.0
416446
}
417447

448+
fn next_used(&self) -> u16 {
449+
self.next_used.0
450+
}
451+
418452
fn set_next_avail(&mut self, next_avail: u16) {
419453
self.next_avail = Wrapping(next_avail);
420454
}
455+
456+
fn set_next_used(&mut self, next_used: u16) {
457+
self.next_used = Wrapping(next_used);
458+
}
421459
}

crates/virtio-queue/src/state_sync.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ impl QueueStateT for QueueStateSync {
107107
self.lock_state().avail_idx(mem, order)
108108
}
109109

110+
fn used_idx<M: GuestMemory>(&self, mem: &M, order: Ordering) -> Result<Wrapping<u16>, Error> {
111+
self.lock_state().used_idx(mem, order)
112+
}
113+
110114
fn add_used<M: GuestMemory>(
111115
&mut self,
112116
mem: &M,
@@ -132,9 +136,17 @@ impl QueueStateT for QueueStateSync {
132136
self.lock_state().next_avail()
133137
}
134138

139+
fn next_used(&self) -> u16 {
140+
self.lock_state().next_used()
141+
}
142+
135143
fn set_next_avail(&mut self, next_avail: u16) {
136144
self.lock_state().set_next_avail(next_avail);
137145
}
146+
147+
fn set_next_used(&mut self, next_used: u16) {
148+
self.lock_state().set_next_used(next_used);
149+
}
138150
}
139151

140152
#[cfg(test)]

0 commit comments

Comments
 (0)