misc: Use a more relaxed memory model when possible

When a total ordering between multiple atomic variables is not required
then use Ordering::Acquire with atomic loads and Ordering::Release with
atomic stores.

This will improve performance as this does not require a memory fence
on x86_64 which Ordering::SeqCst will use.

Add a comment to the code in the vCPU handling code where it operates on
multiple atomics to explain why Ordering::SeqCst is required.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford
2020-12-01 16:15:26 +00:00
committed by Samuel Ortiz
parent 280d4fb245
commit ffaab46934
11 changed files with 32 additions and 27 deletions

View File

@@ -785,6 +785,11 @@ impl CpuManager {
// We enter a loop because park() could spuriously
// return. We will then park() again unless the
// pause boolean has been toggled.
// Need to use Ordering::SeqCst as we have multiple
// loads and stores to different atomics and we need
// to see them in a consistent order in all threads
if vcpu_pause_signalled.load(Ordering::SeqCst) {
vcpu_run_interrupted.store(true, Ordering::SeqCst);
while vcpu_pause_signalled.load(Ordering::SeqCst) {

View File

@@ -39,7 +39,7 @@ impl InterruptRoute {
}
pub fn enable(&self, vm: &Arc<dyn hypervisor::Vm>) -> Result<()> {
if !self.registered.load(Ordering::SeqCst) {
if !self.registered.load(Ordering::Acquire) {
vm.register_irqfd(&self.irq_fd, self.gsi).map_err(|e| {
io::Error::new(
io::ErrorKind::Other,
@@ -48,14 +48,14 @@ impl InterruptRoute {
})?;
// Update internals to track the irq_fd as "registered".
self.registered.store(true, Ordering::SeqCst);
self.registered.store(true, Ordering::Release);
}
Ok(())
}
pub fn disable(&self, vm: &Arc<dyn hypervisor::Vm>) -> Result<()> {
if self.registered.load(Ordering::SeqCst) {
if self.registered.load(Ordering::Acquire) {
vm.unregister_irqfd(&self.irq_fd, self.gsi).map_err(|e| {
io::Error::new(
io::ErrorKind::Other,
@@ -64,7 +64,7 @@ impl InterruptRoute {
})?;
// Update internals to track the irq_fd as "unregistered".
self.registered.store(false, Ordering::SeqCst);
self.registered.store(false, Ordering::Release);
}
Ok(())