Skip to content

Commit cf8bb5b

Browse files
committed
refactor(pvirtq): use bitfields for RingIdx
1 parent 06380c9 commit cf8bb5b

File tree

1 file changed

+39
-40
lines changed

1 file changed

+39
-40
lines changed

src/drivers/virtio/virtqueue/packed.rs

Lines changed: 39 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -35,27 +35,26 @@ use super::{
3535
use crate::arch::mm::paging::{BasePageSize, PageSize};
3636
use crate::mm::device_alloc::DeviceAlloc;
3737

38-
#[derive(Default, PartialEq, Eq, Clone, Copy, Debug)]
39-
struct RingIdx {
40-
off: u16,
41-
wrap: u8,
42-
}
43-
4438
trait RingIndexRange {
45-
fn wrapping_contains(&self, item: &RingIdx) -> bool;
39+
fn wrapping_contains(&self, item: &EventSuppressDesc) -> bool;
4640
}
4741

48-
impl RingIndexRange for ops::Range<RingIdx> {
49-
fn wrapping_contains(&self, item: &RingIdx) -> bool {
50-
let ops::Range { start, end } = self;
51-
52-
if start.wrap == end.wrap {
53-
item.wrap == start.wrap && start.off <= item.off && item.off < end.off
54-
} else if item.wrap == start.wrap {
55-
start.off <= item.off
42+
impl RingIndexRange for ops::Range<EventSuppressDesc> {
43+
fn wrapping_contains(&self, item: &EventSuppressDesc) -> bool {
44+
let start_off = self.start.desc_event_off();
45+
let start_wrap = self.start.desc_event_wrap();
46+
let end_off = self.end.desc_event_off();
47+
let end_wrap = self.end.desc_event_wrap();
48+
let item_off = item.desc_event_off();
49+
let item_wrap = item.desc_event_wrap();
50+
51+
if start_wrap == end_wrap {
52+
item_wrap == start_wrap && start_off <= item_off && item_off < end_off
53+
} else if item_wrap == start_wrap {
54+
start_off <= item_off
5655
} else {
57-
debug_assert!(item.wrap == end.wrap);
58-
item.off < end.off
56+
debug_assert!(item_wrap == end_wrap);
57+
item_off < end_off
5958
}
6059
}
6160
}
@@ -117,7 +116,7 @@ impl DescriptorRing {
117116
fn push_batch(
118117
&mut self,
119118
tkn_lst: impl IntoIterator<Item = TransferToken<pvirtq::Desc>>,
120-
) -> Result<RingIdx, VirtqError> {
119+
) -> Result<EventSuppressDesc, VirtqError> {
121120
// Catch empty push, in order to allow zero initialized first_ctrl_settings struct
122121
// which will be overwritten in the first iteration of the for-loop
123122

@@ -148,13 +147,13 @@ impl DescriptorRing {
148147
first_ctrl_settings.1,
149148
first_ctrl_settings.2,
150149
);
151-
Ok(RingIdx {
152-
off: self.write_index,
153-
wrap: self.drv_wc.into(),
154-
})
150+
151+
Ok(EventSuppressDesc::new()
152+
.with_desc_event_off(self.write_index)
153+
.with_desc_event_wrap(self.drv_wc.into()))
155154
}
156155

157-
fn push(&mut self, tkn: TransferToken<pvirtq::Desc>) -> Result<RingIdx, VirtqError> {
156+
fn push(&mut self, tkn: TransferToken<pvirtq::Desc>) -> Result<EventSuppressDesc, VirtqError> {
158157
self.push_batch([tkn])
159158
}
160159

@@ -435,13 +434,11 @@ impl DrvNotif {
435434
}
436435

437436
/// Enables a notification by the device for a specific descriptor.
438-
fn enable_specific(&mut self, idx: RingIdx) {
437+
fn enable_specific(&mut self, desc: EventSuppressDesc) {
439438
// Check if VIRTIO_F_RING_EVENT_IDX has been negotiated
440439
if self.f_notif_idx {
441440
self.raw.flags = EventSuppressFlags::new().with_desc_event_flags(RingEventFlags::Desc);
442-
self.raw.desc = EventSuppressDesc::new()
443-
.with_desc_event_off(idx.off)
444-
.with_desc_event_wrap(idx.wrap);
441+
self.raw.desc = desc;
445442
}
446443
}
447444
}
@@ -458,7 +455,7 @@ impl DevNotif {
458455
self.raw.flags.desc_event_flags() == RingEventFlags::Enable
459456
}
460457

461-
fn notif_specific(&self) -> Option<RingIdx> {
458+
fn notif_specific(&self) -> Option<EventSuppressDesc> {
462459
if !self.f_notif_idx {
463460
return None;
464461
}
@@ -467,10 +464,7 @@ impl DevNotif {
467464
return None;
468465
}
469466

470-
let off = self.raw.desc.desc_event_off();
471-
let wrap = self.raw.desc.desc_event_wrap();
472-
473-
Some(RingIdx { off, wrap })
467+
Some(self.raw.desc)
474468
}
475469
}
476470

@@ -492,7 +486,7 @@ pub struct PackedVq {
492486
/// The virtqueues index. This identifies the virtqueue to the
493487
/// device and is unique on a per device basis.
494488
index: u16,
495-
last_next: Cell<RingIdx>,
489+
last_next: Cell<EventSuppressDesc>,
496490
}
497491

498492
// Public interface of PackedVq
@@ -537,8 +531,8 @@ impl Virtq for PackedVq {
537531
if self.dev_event.is_notif() || notif_specific {
538532
let notification_data = NotificationData::new()
539533
.with_vqn(self.index)
540-
.with_next_off(next_idx.off)
541-
.with_next_wrap(next_idx.wrap);
534+
.with_next_off(next_idx.desc_event_off())
535+
.with_next_wrap(next_idx.desc_event_wrap());
542536
self.notif_ctrl.notify_dev(notification_data);
543537
self.last_next.set(next_idx);
544538
}
@@ -572,8 +566,8 @@ impl Virtq for PackedVq {
572566
if self.dev_event.is_notif() | notif_specific {
573567
let notification_data = NotificationData::new()
574568
.with_vqn(self.index)
575-
.with_next_off(next_idx.off)
576-
.with_next_wrap(next_idx.wrap);
569+
.with_next_off(next_idx.desc_event_off())
570+
.with_next_wrap(next_idx.desc_event_wrap());
577571
self.notif_ctrl.notify_dev(notification_data);
578572
self.last_next.set(next_idx);
579573
}
@@ -593,13 +587,18 @@ impl Virtq for PackedVq {
593587
self.drv_event.enable_specific(next_idx);
594588
}
595589

596-
let notif_specific = self.dev_event.notif_specific() == Some(self.last_next.get());
590+
// FIXME: impl PartialEq for EventSuppressDesc in virtio-spec instead of converting into bits.
591+
let notif_specific = self
592+
.dev_event
593+
.notif_specific()
594+
.map(EventSuppressDesc::into_bits)
595+
== Some(self.last_next.get().into_bits());
597596

598597
if self.dev_event.is_notif() || notif_specific {
599598
let notification_data = NotificationData::new()
600599
.with_vqn(self.index)
601-
.with_next_off(next_idx.off)
602-
.with_next_wrap(next_idx.wrap);
600+
.with_next_off(next_idx.desc_event_off())
601+
.with_next_wrap(next_idx.desc_event_wrap());
603602
self.notif_ctrl.notify_dev(notification_data);
604603
self.last_next.set(next_idx);
605604
}

0 commit comments

Comments
 (0)