Skip to content

Commit 600164b

Browse files
committed
refactor(queue): update calculations in the avail ring
Replace numbers with more descriptive `size_of` methods. Signed-off-by: Egor Lazarchuk <[email protected]>
1 parent aaab09e commit 600164b

File tree

1 file changed

+12
-22
lines changed

1 file changed

+12
-22
lines changed

src/vmm/src/devices/virtio/queue.rs

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -398,33 +398,23 @@ impl Queue {
398398
// In a naive notation, that would be:
399399
// `descriptor_table[avail_ring[next_avail]]`.
400400
//
401-
// First, we compute the byte-offset (into `self.avail_ring`) of the index of the next
402-
// available descriptor. `self.avail_ring` stores the address of a `struct
403-
// virtq_avail`, as defined by the VirtIO spec:
404-
//
405-
// ```C
406-
// struct virtq_avail {
407-
// le16 flags;
408-
// le16 idx;
409-
// le16 ring[QUEUE_SIZE];
410-
// le16 used_event
401+
// Avail ring has layout:
402+
// struct AvailRing {
403+
// flags: u16,
404+
// idx: u16,
405+
// ring: [u16; <queue size>],
406+
// used_event: u16,
411407
// }
412-
// ```
413-
//
414-
// We use `self.next_avail` to store the position, in `ring`, of the next available
415-
// descriptor index, with a twist: we always only increment `self.next_avail`, so the
416-
// actual position will be `self.next_avail % self.actual_size()`.
417-
// We are now looking for the offset of `ring[self.next_avail % self.actual_size()]`.
418-
// `ring` starts after `flags` and `idx` (4 bytes into `struct virtq_avail`), and holds
419-
// 2-byte items, so the offset will be:
420-
let index_offset = 4 + 2 * (self.next_avail.0 % self.actual_size());
408+
// We calculate offset into `ring` field.
409+
let desc_index_offset = std::mem::size_of::<u16>()
410+
+ std::mem::size_of::<u16>()
411+
+ std::mem::size_of::<u16>() * usize::from(self.next_avail.0 % self.actual_size());
412+
let desc_index_address = self.avail_ring.unchecked_add(usize_to_u64(desc_index_offset));
421413

422414
// `self.is_valid()` already performed all the bound checks on the descriptor table
423415
// and virtq rings, so it's safe to unwrap guest memory reads and to use unchecked
424416
// offsets.
425-
let desc_index: u16 = mem
426-
.read_obj(self.avail_ring.unchecked_add(u64::from(index_offset)))
427-
.unwrap();
417+
let desc_index: u16 = mem.read_obj(desc_index_address).unwrap();
428418

429419
DescriptorChain::checked_new(mem, self.desc_table, self.actual_size(), desc_index).map(
430420
|dc| {

0 commit comments

Comments
 (0)