Skip to content

Commit 3163d43

Browse files
committed
perf(virtio-pci): use weaker memory barriers
1 parent 13b7df7 commit 3163d43

File tree

3 files changed

+43
-36
lines changed

3 files changed

+43
-36
lines changed

Cargo.lock

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ tcp = ["net", "smoltcp", "smoltcp/socket-tcp"]
6363
trace = ["smoltcp?/log", "smoltcp?/verbose"]
6464
udp = ["net", "smoltcp", "smoltcp/socket-udp"]
6565
vga = []
66-
virtio = ["dep:virtio"]
66+
virtio = ["dep:virtio", "dep:mem-barrier"]
6767
virtio-net = ["net", "virtio"]
6868
vsock = ["virtio", "pci"]
6969
warn-prebuilt = []
@@ -123,6 +123,7 @@ hermit-entry = { version = "0.10.6", features = ["kernel"] }
123123
hermit-sync = "0.1"
124124
lock_api = "0.4"
125125
log = { version = "0.4", default-features = false }
126+
mem-barrier = { version = "0.1.0", features = ["nightly"], optional = true }
126127
num_enum = { version = "0.7", default-features = false }
127128
pci-ids = { version = "0.2", optional = true }
128129
pci_types = { version = "0.10" }

src/drivers/virtio/transport/pci.rs

Lines changed: 31 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use alloc::vec::Vec;
1313
use core::ptr::NonNull;
1414
use core::{mem, ptr};
1515

16+
use mem_barrier::{BarrierKind, BarrierType, mem_barrier};
1617
use memory_addresses::PhysAddr;
1718
use pci_types::capability::PciCapability;
1819
use virtio::pci::{
@@ -23,7 +24,6 @@ use virtio::{DeviceStatus, le16, le32};
2324
use volatile::access::ReadOnly;
2425
use volatile::{VolatilePtr, VolatileRef};
2526

26-
use crate::arch::memory_barrier;
2727
use crate::arch::pci::PciConfigRegion;
2828
#[cfg(feature = "console")]
2929
use crate::drivers::console::VirtioConsoleDriver;
@@ -299,7 +299,7 @@ impl ComCfg {
299299

300300
/// Resets the device status field to zero.
301301
pub fn reset_dev(&mut self) {
302-
memory_barrier();
302+
mem_barrier(BarrierKind::Mmio, BarrierType::Write);
303303
self.com_cfg
304304
.as_mut_ptr()
305305
.device_status()
@@ -310,7 +310,7 @@ impl ComCfg {
310310
/// A driver MUST NOT initialize and use the device any further after this.
311311
/// A driver MAY use the device again after a proper reset of the device.
312312
pub fn set_failed(&mut self) {
313-
memory_barrier();
313+
mem_barrier(BarrierKind::Mmio, BarrierType::Write);
314314
self.com_cfg
315315
.as_mut_ptr()
316316
.device_status()
@@ -320,32 +320,29 @@ impl ComCfg {
320320
/// Sets the ACKNOWLEDGE bit in the device status field. This indicates, the
321321
/// OS has notived the device
322322
pub fn ack_dev(&mut self) {
323-
memory_barrier();
324-
self.com_cfg
325-
.as_mut_ptr()
326-
.device_status()
327-
.update(|s| s | DeviceStatus::ACKNOWLEDGE);
323+
self.com_cfg.as_mut_ptr().device_status().update(|s| {
324+
mem_barrier(BarrierKind::Mmio, BarrierType::General);
325+
s | DeviceStatus::ACKNOWLEDGE
326+
});
328327
}
329328

330329
/// Sets the DRIVER bit in the device status field. This indicates, the OS
331330
/// know how to run this device.
332331
pub fn set_drv(&mut self) {
333-
memory_barrier();
334-
self.com_cfg
335-
.as_mut_ptr()
336-
.device_status()
337-
.update(|s| s | DeviceStatus::DRIVER);
332+
self.com_cfg.as_mut_ptr().device_status().update(|s| {
333+
mem_barrier(BarrierKind::Mmio, BarrierType::General);
334+
s | DeviceStatus::DRIVER
335+
});
338336
}
339337

340338
/// Sets the FEATURES_OK bit in the device status field.
341339
///
342340
/// Drivers MUST NOT accept new features after this step.
343341
pub fn features_ok(&mut self) {
344-
memory_barrier();
345-
self.com_cfg
346-
.as_mut_ptr()
347-
.device_status()
348-
.update(|s| s | DeviceStatus::FEATURES_OK);
342+
self.com_cfg.as_mut_ptr().device_status().update(|s| {
343+
mem_barrier(BarrierKind::Mmio, BarrierType::General);
344+
s | DeviceStatus::FEATURES_OK
345+
});
349346
}
350347

351348
/// In order to correctly check feature negotiaten, this function
@@ -355,23 +352,19 @@ impl ComCfg {
355352
/// Re-reads device status to ensure the FEATURES_OK bit is still set:
356353
/// otherwise, the device does not support our subset of features and the device is unusable.
357354
pub fn check_features(&self) -> bool {
358-
memory_barrier();
359-
self.com_cfg
360-
.as_ptr()
361-
.device_status()
362-
.read()
363-
.contains(DeviceStatus::FEATURES_OK)
355+
let status = self.com_cfg.as_ptr().device_status().read();
356+
mem_barrier(BarrierKind::Dma, BarrierType::Read);
357+
status.contains(DeviceStatus::FEATURES_OK)
364358
}
365359

366360
/// Sets the DRIVER_OK bit in the device status field.
367361
///
368362
/// After this call, the device is "live"!
369363
pub fn drv_ok(&mut self) {
370-
memory_barrier();
371-
self.com_cfg
372-
.as_mut_ptr()
373-
.device_status()
374-
.update(|s| s | DeviceStatus::DRIVER_OK);
364+
self.com_cfg.as_mut_ptr().device_status().update(|s| {
365+
mem_barrier(BarrierKind::Mmio, BarrierType::General);
366+
s | DeviceStatus::DRIVER_OK
367+
});
375368
}
376369

377370
/// Returns the features offered by the device.
@@ -382,20 +375,22 @@ impl ComCfg {
382375

383376
// Indicate device to show high 32 bits in device_feature field.
384377
// See Virtio specification v1.1. - 4.1.4.3
385-
memory_barrier();
378+
mem_barrier(BarrierKind::Mmio, BarrierType::Write);
386379
device_feature_select.write(1.into());
387-
memory_barrier();
388380

389381
// read high 32 bits of device features
382+
mem_barrier(BarrierKind::Mmio, BarrierType::General);
390383
let mut device_features = u64::from(device_feature.read().to_ne()) << 32;
391384

392385
// Indicate device to show low 32 bits in device_feature field.
393386
// See Virtio specification v1.1. - 4.1.4.3
387+
mem_barrier(BarrierKind::Mmio, BarrierType::General);
394388
device_feature_select.write(0.into());
395-
memory_barrier();
396389

397390
// read low 32 bits of device features
391+
mem_barrier(BarrierKind::Mmio, BarrierType::General);
398392
device_features |= u64::from(device_feature.read().to_ne());
393+
mem_barrier(BarrierKind::Mmio, BarrierType::Read);
399394

400395
virtio::F::from_bits_retain(u128::from(device_features).into())
401396
}
@@ -412,19 +407,20 @@ impl ComCfg {
412407

413408
// Indicate to device that driver_features field shows low 32 bits.
414409
// See Virtio specification v1.1. - 4.1.4.3
415-
memory_barrier();
410+
mem_barrier(BarrierKind::Mmio, BarrierType::Write);
416411
driver_feature_select.write(0.into());
417-
memory_barrier();
418412

419413
// write low 32 bits of device features
414+
mem_barrier(BarrierKind::Mmio, BarrierType::Write);
420415
driver_feature.write(low.into());
421416

422417
// Indicate to device that driver_features field shows high 32 bits.
423418
// See Virtio specification v1.1. - 4.1.4.3
419+
mem_barrier(BarrierKind::Mmio, BarrierType::Write);
424420
driver_feature_select.write(1.into());
425-
memory_barrier();
426421

427422
// write high 32 bits of device features
423+
mem_barrier(BarrierKind::Mmio, BarrierType::Write);
428424
driver_feature.write(high.into());
429425
}
430426
}

0 commit comments

Comments
 (0)