Skip to content

Commit b20103e

Browse files
committed
perf(pvirtq): use bitfields for RingIdx
1 parent 9d1e4dd commit b20103e

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
@@ -28,27 +28,26 @@ use super::{
2828
use crate::arch::mm::paging::{BasePageSize, PageSize};
2929
use crate::mm::device_alloc::DeviceAlloc;
3030

31-
#[derive(Default, PartialEq, Eq, Clone, Copy, Debug)]
32-
struct RingIdx {
33-
off: u16,
34-
wrap: u8,
35-
}
36-
3731
trait RingIndexRange {
38-
fn wrapping_contains(&self, item: &RingIdx) -> bool;
32+
fn wrapping_contains(&self, item: &EventSuppressDesc) -> bool;
3933
}
4034

41-
impl RingIndexRange for ops::Range<RingIdx> {
42-
fn wrapping_contains(&self, item: &RingIdx) -> bool {
43-
let ops::Range { start, end } = self;
44-
45-
if start.wrap == end.wrap {
46-
item.wrap == start.wrap && start.off <= item.off && item.off < end.off
47-
} else if item.wrap == start.wrap {
48-
start.off <= item.off
35+
impl RingIndexRange for ops::Range<EventSuppressDesc> {
36+
fn wrapping_contains(&self, item: &EventSuppressDesc) -> bool {
37+
let start_off = self.start.desc_event_off();
38+
let start_wrap = self.start.desc_event_wrap();
39+
let end_off = self.end.desc_event_off();
40+
let end_wrap = self.end.desc_event_wrap();
41+
let item_off = item.desc_event_off();
42+
let item_wrap = item.desc_event_wrap();
43+
44+
if start_wrap == end_wrap {
45+
item_wrap == start_wrap && start_off <= item_off && item_off < end_off
46+
} else if item_wrap == start_wrap {
47+
start_off <= item_off
4948
} else {
50-
debug_assert!(item.wrap == end.wrap);
51-
item.off < end.off
49+
debug_assert!(item_wrap == end_wrap);
50+
item_off < end_off
5251
}
5352
}
5453
}
@@ -110,7 +109,7 @@ impl DescriptorRing {
110109
fn push_batch(
111110
&mut self,
112111
tkn_lst: impl IntoIterator<Item = TransferToken<pvirtq::Desc>>,
113-
) -> Result<RingIdx, VirtqError> {
112+
) -> Result<EventSuppressDesc, VirtqError> {
114113
// Catch empty push, in order to allow zero initialized first_ctrl_settings struct
115114
// which will be overwritten in the first iteration of the for-loop
116115

@@ -141,13 +140,13 @@ impl DescriptorRing {
141140
first_ctrl_settings.1,
142141
first_ctrl_settings.2,
143142
);
144-
Ok(RingIdx {
145-
off: self.write_index,
146-
wrap: self.drv_wc.into(),
147-
})
143+
144+
Ok(EventSuppressDesc::new()
145+
.with_desc_event_off(self.write_index)
146+
.with_desc_event_wrap(self.drv_wc.into()))
148147
}
149148

150-
fn push(&mut self, tkn: TransferToken<pvirtq::Desc>) -> Result<RingIdx, VirtqError> {
149+
fn push(&mut self, tkn: TransferToken<pvirtq::Desc>) -> Result<EventSuppressDesc, VirtqError> {
151150
self.push_batch([tkn])
152151
}
153152

@@ -428,13 +427,11 @@ impl DrvNotif {
428427
}
429428

430429
/// Enables a notification by the device for a specific descriptor.
431-
fn enable_specific(&mut self, idx: RingIdx) {
430+
fn enable_specific(&mut self, desc: EventSuppressDesc) {
432431
// Check if VIRTIO_F_RING_EVENT_IDX has been negotiated
433432
if self.f_notif_idx {
434433
self.raw.flags = EventSuppressFlags::new().with_desc_event_flags(RingEventFlags::Desc);
435-
self.raw.desc = EventSuppressDesc::new()
436-
.with_desc_event_off(idx.off)
437-
.with_desc_event_wrap(idx.wrap);
434+
self.raw.desc = desc;
438435
}
439436
}
440437
}
@@ -451,7 +448,7 @@ impl DevNotif {
451448
self.raw.flags.desc_event_flags() == RingEventFlags::Enable
452449
}
453450

454-
fn notif_specific(&self) -> Option<RingIdx> {
451+
fn notif_specific(&self) -> Option<EventSuppressDesc> {
455452
if !self.f_notif_idx {
456453
return None;
457454
}
@@ -460,10 +457,7 @@ impl DevNotif {
460457
return None;
461458
}
462459

463-
let off = self.raw.desc.desc_event_off();
464-
let wrap = self.raw.desc.desc_event_wrap();
465-
466-
Some(RingIdx { off, wrap })
460+
Some(self.raw.desc)
467461
}
468462
}
469463

@@ -485,7 +479,7 @@ pub struct PackedVq {
485479
/// The virtqueues index. This identifies the virtqueue to the
486480
/// device and is unique on a per device basis.
487481
index: u16,
488-
last_next: Cell<RingIdx>,
482+
last_next: Cell<EventSuppressDesc>,
489483
}
490484

491485
// Public interface of PackedVq
@@ -530,8 +524,8 @@ impl Virtq for PackedVq {
530524
if self.dev_event.is_notif() || notif_specific {
531525
let notification_data = NotificationData::new()
532526
.with_vqn(self.index)
533-
.with_next_off(next_idx.off)
534-
.with_next_wrap(next_idx.wrap);
527+
.with_next_off(next_idx.desc_event_off())
528+
.with_next_wrap(next_idx.desc_event_wrap());
535529
self.notif_ctrl.notify_dev(notification_data);
536530
self.last_next.set(next_idx);
537531
}
@@ -565,8 +559,8 @@ impl Virtq for PackedVq {
565559
if self.dev_event.is_notif() | notif_specific {
566560
let notification_data = NotificationData::new()
567561
.with_vqn(self.index)
568-
.with_next_off(next_idx.off)
569-
.with_next_wrap(next_idx.wrap);
562+
.with_next_off(next_idx.desc_event_off())
563+
.with_next_wrap(next_idx.desc_event_wrap());
570564
self.notif_ctrl.notify_dev(notification_data);
571565
self.last_next.set(next_idx);
572566
}
@@ -586,13 +580,18 @@ impl Virtq for PackedVq {
586580
self.drv_event.enable_specific(next_idx);
587581
}
588582

589-
let notif_specific = self.dev_event.notif_specific() == Some(self.last_next.get());
583+
// FIXME: impl PartialEq for EventSuppressDesc in virtio-spec instead of converting into bits.
584+
let notif_specific = self
585+
.dev_event
586+
.notif_specific()
587+
.map(EventSuppressDesc::into_bits)
588+
== Some(self.last_next.get().into_bits());
590589

591590
if self.dev_event.is_notif() || notif_specific {
592591
let notification_data = NotificationData::new()
593592
.with_vqn(self.index)
594-
.with_next_off(next_idx.off)
595-
.with_next_wrap(next_idx.wrap);
593+
.with_next_off(next_idx.desc_event_off())
594+
.with_next_wrap(next_idx.desc_event_wrap());
596595
self.notif_ctrl.notify_dev(notification_data);
597596
self.last_next.set(next_idx);
598597
}

0 commit comments

Comments
 (0)