Page-pin packet memory for cuda (#4250)

* Page-pin packet memory for cuda

Bring back recyclers and pin offset buffers

* Add packet recycler to streamer

* Add set_pinnable to sigverify vecs to pin them

* Add packets reset test

* Add test for recycler and reduce the gc lock critical section
* Add comments/tests to cuda_runtime

* Add recycler to recv_blobs path.

* Add trace/names for debug and PacketsRecycler to bench-streamer

* Predict realloc and unpin beforehand.

* Add helper to reserve and pin

* Cap buffered packets length

* Call cuda wrapper functions
This commit is contained in:
sakridge
2019-06-27 09:32:32 +02:00
committed by GitHub
parent 44a572416d
commit fbea9d8621
13 changed files with 613 additions and 56 deletions

View File

@@ -1,5 +1,7 @@
//! The `packet` module defines data structures and methods to pull data from the network.
use crate::cuda_runtime::PinnedVec;
use crate::recvmmsg::{recv_mmsg, NUM_RCVMMSGS};
use crate::recycler::{Recycler, Reset};
use crate::result::{Error, Result};
use bincode;
use byteorder::{ByteOrder, LittleEndian};
@@ -16,6 +18,7 @@ use std::fmt;
use std::io;
use std::io::Cursor;
use std::io::Write;
use std::mem;
use std::mem::size_of;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, UdpSocket};
use std::ops::{Deref, DerefMut};
@@ -124,21 +127,61 @@ impl Meta {
#[derive(Debug, Clone)]
pub struct Packets {
pub packets: Vec<Packet>,
pub packets: PinnedVec<Packet>,
recycler: Option<PacketsRecycler>,
}
impl Drop for Packets {
fn drop(&mut self) {
if let Some(ref recycler) = self.recycler {
let old = mem::replace(&mut self.packets, PinnedVec::default());
recycler.recycle(old)
}
}
}
impl Reset for Packets {
fn reset(&mut self) {
self.packets.resize(0, Packet::default());
}
}
impl Reset for PinnedVec<Packet> {
fn reset(&mut self) {
self.resize(0, Packet::default());
}
}
//auto derive doesn't support large arrays
impl Default for Packets {
fn default() -> Packets {
let packets = PinnedVec::with_capacity(NUM_RCVMMSGS);
Packets {
packets: Vec::with_capacity(NUM_RCVMMSGS),
packets,
recycler: None,
}
}
}
pub type PacketsRecycler = Recycler<PinnedVec<Packet>>;
impl Packets {
pub fn new(packets: Vec<Packet>) -> Self {
Self { packets }
let packets = PinnedVec::from_vec(packets);
Self {
packets,
recycler: None,
}
}
pub fn new_with_recycler(recycler: PacketsRecycler, size: usize, name: &'static str) -> Self {
let mut packets = recycler.allocate(name);
packets.reserve_and_pin(size);
Packets {
packets,
recycler: Some(recycler),
}
}
pub fn set_addr(&mut self, addr: &SocketAddr) {
@@ -516,9 +559,8 @@ impl Blob {
}
// other side of store_packets
pub fn load_packets(&self) -> Vec<Packet> {
pub fn load_packets(&self, packets: &mut PinnedVec<Packet>) {
// rough estimate
let mut packets: Vec<Packet> = Vec::with_capacity(self.size() / PACKET_DATA_SIZE);
let mut pos = 0;
let size_len = bincode::serialized_size(&0usize).unwrap() as usize;
@@ -538,7 +580,6 @@ impl Blob {
pos += size;
packets.push(packet);
}
packets
}
pub fn recv_blob(socket: &UdpSocket, r: &SharedBlob) -> io::Result<()> {
@@ -652,7 +693,7 @@ mod tests {
// test that the address is actually being updated
let send_addr = socketaddr!([127, 0, 0, 1], 123);
let packets = vec![Packet::default()];
let mut msgs = Packets { packets };
let mut msgs = Packets::new(packets);
msgs.set_addr(&send_addr);
assert_eq!(SocketAddr::from(msgs.packets[0].meta.addr()), send_addr);
}
@@ -678,7 +719,7 @@ mod tests {
assert_eq!(recvd, p.packets.len());
for m in p.packets {
for m in &p.packets {
assert_eq!(m.meta.size, PACKET_DATA_SIZE);
assert_eq!(m.meta.addr(), saddr);
}
@@ -810,10 +851,12 @@ mod tests {
let blobs = packets_to_blobs(&packets[..]);
let reconstructed_packets: Vec<Packet> =
blobs.iter().flat_map(|b| b.load_packets()).collect();
let mut reconstructed_packets = PinnedVec::default();
blobs
.iter()
.for_each(|b| b.load_packets(&mut reconstructed_packets));
assert_eq!(reconstructed_packets, packets);
assert_eq!(reconstructed_packets[..], packets[..]);
}
#[test]
@@ -862,4 +905,13 @@ mod tests {
b.sign(&k);
assert!(b.verify());
}
#[test]
fn test_packets_reset() {
let mut packets = Packets::default();
packets.packets.resize(10, Packet::default());
assert_eq!(packets.packets.len(), 10);
packets.reset();
assert_eq!(packets.packets.len(), 0);
}
}