From e7c3bf6047246a4612aa2c64ab38b3ea9ecf610c Mon Sep 17 00:00:00 2001 From: Mathias Hall-Andersen Date: Sun, 29 Mar 2020 18:23:51 +0200 Subject: Experiment with locking performance. --- src/wireguard/router/device.rs | 5 +- src/wireguard/router/mod.rs | 2 + src/wireguard/router/mutex.rs | 91 +++++++++++++++++++++++++++++++++++++ src/wireguard/router/peer.rs | 14 +++--- src/wireguard/router/queue.rs | 3 +- src/wireguard/router/receive.rs | 2 +- src/wireguard/router/route.rs | 3 +- src/wireguard/router/send.rs | 5 +- src/wireguard/router/tests/bench.rs | 22 +++++---- 9 files changed, 126 insertions(+), 21 deletions(-) create mode 100644 src/wireguard/router/mutex.rs diff --git a/src/wireguard/router/device.rs b/src/wireguard/router/device.rs index 7c90f22..0fec686 100644 --- a/src/wireguard/router/device.rs +++ b/src/wireguard/router/device.rs @@ -6,7 +6,10 @@ use std::thread; use std::time::Instant; use log; -use spin::{Mutex, RwLock}; + +// TESTING +use super::mutex::*; + use zerocopy::LayoutVerified; use super::anti_replay::AntiReplay; diff --git a/src/wireguard/router/mod.rs b/src/wireguard/router/mod.rs index 7ab291b..16e16b7 100644 --- a/src/wireguard/router/mod.rs +++ b/src/wireguard/router/mod.rs @@ -12,6 +12,8 @@ mod receive; mod send; mod worker; +mod mutex; + #[cfg(test)] mod tests; diff --git a/src/wireguard/router/mutex.rs b/src/wireguard/router/mutex.rs new file mode 100644 index 0000000..aaf0b5e --- /dev/null +++ b/src/wireguard/router/mutex.rs @@ -0,0 +1,91 @@ +/* +use std::sync::Mutex as StdMutex; +use std::sync::MutexGuard; + +use std::sync::RwLock as StdRwLock; +use std::sync::RwLockReadGuard; +use std::sync::RwLockWriteGuard; + +pub struct Mutex { + mutex: StdMutex, +} + +pub struct RwLock { + rwlock: StdRwLock, +} + +impl Mutex { + pub fn new(v: T) -> Mutex { + Mutex { + mutex: StdMutex::new(v), + } + } + + pub fn lock(&self) -> MutexGuard { + self.mutex.lock().unwrap() + } +} + +impl RwLock { + pub fn new(v: T) -> RwLock { + RwLock { + rwlock: StdRwLock::new(v), + } + } + + pub fn read(&self) -> RwLockReadGuard { + self.rwlock.read().unwrap() + } + + pub fn write(&self) -> RwLockWriteGuard { + self.rwlock.write().unwrap() + } +} +*/ + +use spin::Mutex as StdMutex; +use spin::MutexGuard; + +use spin::RwLock as StdRwLock; +use spin::RwLockReadGuard; +use spin::RwLockWriteGuard; + +pub struct Mutex { + mutex: StdMutex, +} + +pub struct RwLock { + rwlock: StdRwLock, +} + +impl Mutex { + pub fn new(v: T) -> Mutex { + Mutex { + mutex: StdMutex::new(v), + } + } + + pub fn lock(&self) -> MutexGuard { + self.mutex.lock() + } + + pub fn try_lock(&self) -> Option> { + self.mutex.try_lock() + } +} + +impl RwLock { + pub fn new(v: T) -> RwLock { + RwLock { + rwlock: StdRwLock::new(v), + } + } + + pub fn read(&self) -> RwLockReadGuard { + self.rwlock.read() + } + + pub fn write(&self) -> RwLockWriteGuard { + self.rwlock.write() + } +} diff --git a/src/wireguard/router/peer.rs b/src/wireguard/router/peer.rs index 67d90d8..6ba9ad1 100644 --- a/src/wireguard/router/peer.rs +++ b/src/wireguard/router/peer.rs @@ -21,12 +21,14 @@ use core::sync::atomic::AtomicBool; use alloc::sync::Arc; +// TESTING +use super::mutex::Mutex; + // TODO: consider no_std alternatives use std::net::{IpAddr, SocketAddr}; use arraydeque::{ArrayDeque, Wrapping}; use log; -use spin::Mutex; pub struct KeyWheel { next: Option>, // next key state (unconfirmed) @@ -111,7 +113,7 @@ impl> DecryptionSta DecryptionState { confirmed: AtomicBool::new(keypair.initiator), keypair: keypair.clone(), - protector: spin::Mutex::new(AntiReplay::new()), + protector: Mutex::new(AntiReplay::new()), death: keypair.birth + REJECT_AFTER_TIME, peer, } @@ -168,15 +170,15 @@ pub fn new_peer>( device, inbound: Queue::new(), outbound: Queue::new(), - enc_key: spin::Mutex::new(None), - endpoint: spin::Mutex::new(None), - keys: spin::Mutex::new(KeyWheel { + enc_key: Mutex::new(None), + endpoint: Mutex::new(None), + keys: Mutex::new(KeyWheel { next: None, current: None, previous: None, retired: vec![], }), - staged_packets: spin::Mutex::new(ArrayDeque::new()), + staged_packets: Mutex::new(ArrayDeque::new()), }), } }; diff --git a/src/wireguard/router/queue.rs b/src/wireguard/router/queue.rs index d5d657a..22882fd 100644 --- a/src/wireguard/router/queue.rs +++ b/src/wireguard/router/queue.rs @@ -1,5 +1,6 @@ +use super::mutex::Mutex; + use arraydeque::ArrayDeque; -use spin::Mutex; use core::mem; use core::sync::atomic::{AtomicUsize, Ordering}; diff --git a/src/wireguard/router/receive.rs b/src/wireguard/router/receive.rs index 15eb8fb..863c973 100644 --- a/src/wireguard/router/receive.rs +++ b/src/wireguard/router/receive.rs @@ -6,11 +6,11 @@ use super::types::Callbacks; use super::{REJECT_AFTER_MESSAGES, SIZE_TAG}; use super::super::{tun, udp, Endpoint}; +use super::mutex::Mutex; use alloc::sync::Arc; use core::sync::atomic::{AtomicBool, Ordering}; use ring::aead::{Aad, LessSafeKey, Nonce, UnboundKey, CHACHA20_POLY1305}; -use spin::Mutex; use zerocopy::{AsBytes, LayoutVerified}; struct Inner> { diff --git a/src/wireguard/router/route.rs b/src/wireguard/router/route.rs index a556010..4afe820 100644 --- a/src/wireguard/router/route.rs +++ b/src/wireguard/router/route.rs @@ -3,7 +3,8 @@ use super::ip::*; // TODO: no_std alternatives use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; -use spin::RwLock; +use super::mutex::RwLock; + use treebitmap::address::Address; use treebitmap::IpLookupTable; use zerocopy::LayoutVerified; diff --git a/src/wireguard/router/send.rs b/src/wireguard/router/send.rs index 7e14209..e14a401 100644 --- a/src/wireguard/router/send.rs +++ b/src/wireguard/router/send.rs @@ -11,9 +11,10 @@ use alloc::sync::Arc; use core::sync::atomic::{AtomicBool, Ordering}; use ring::aead::{Aad, LessSafeKey, Nonce, UnboundKey, CHACHA20_POLY1305}; -use spin::Mutex; use zerocopy::{AsBytes, LayoutVerified}; +use super::mutex::Mutex; + struct Inner> { ready: AtomicBool, buffer: Mutex>, @@ -127,7 +128,7 @@ impl> SequentialJob // send to peer let job = &self.0; - let msg = job.buffer.lock(); + let msg = job.buffer.try_lock().unwrap(); // never contested let xmit = job.peer.send_raw(&msg[..]).is_ok(); // trigger callback (for timers) diff --git a/src/wireguard/router/tests/bench.rs b/src/wireguard/router/tests/bench.rs index f025dc9..b05f6a2 100644 --- a/src/wireguard/router/tests/bench.rs +++ b/src/wireguard/router/tests/bench.rs @@ -80,7 +80,7 @@ fn profiler_start(name: &str) { #[bench] fn bench_router_outbound(b: &mut Bencher) { - // 10 GB transmission per iteration + // 1 GB transmission per iteration const BYTES_PER_ITER: usize = 100 * 1024 * 1024 * 1024; // inner payload of IPv4 packet is 1440 bytes @@ -118,16 +118,20 @@ fn bench_router_outbound(b: &mut Bencher) { #[cfg(feature = "profiler")] profiler_start("outbound"); - // repeatedly transmit 10 GB - b.iter(|| { - opaque.reset(); - while opaque.sent() < BYTES_PER_ITER / packet.len() { - router - .send(msg.to_vec()) - .expect("failed to crypto-route packet"); - } + // repeatedly transmit 1 GB + let summary = b.bench(|bench| { + bench.iter(|| { + opaque.reset(); + while opaque.sent() < BYTES_PER_ITER / packet.len() { + router + .send(msg.to_vec()) + .expect("failed to crypto-route packet"); + } + }) }); + println!("{:?}", summary); + // stop profiler #[cfg(feature = "profiler")] profiler_stop(); -- cgit v1.2.3-59-g8ed1b