Skip to content

Commit 527d89f

Browse files
committed
Don't leak ports / promisc handlers.
1 parent facc7e3 commit 527d89f

File tree

1 file changed

+31
-51
lines changed

1 file changed

+31
-51
lines changed

xde/src/xde.rs

Lines changed: 31 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ use crate::ip::cpu;
2121
use crate::ip::ncpus;
2222
use crate::ip::processorid_t;
2323
use crate::mac;
24-
use crate::mac::mac_rx_barrier;
2524
use crate::mac::ChecksumOffloadCapabs;
2625
use crate::mac::MacClient;
2726
use crate::mac::MacEmul;
@@ -37,6 +36,7 @@ use crate::mac::mac_capab_lso_t;
3736
use crate::mac::mac_getinfo;
3837
use crate::mac::mac_hw_emul;
3938
use crate::mac::mac_private_minor;
39+
use crate::mac::mac_rx_barrier;
4040
use crate::route::Route;
4141
use crate::route::RouteCache;
4242
use crate::route::RouteKey;
@@ -98,6 +98,7 @@ use opte::ddi::sync::KMutexGuard;
9898
use opte::ddi::sync::KRwLock;
9999
use opte::ddi::sync::KRwLockReadGuard;
100100
use opte::ddi::sync::KRwLockType;
101+
use opte::ddi::sync::KRwLockWriteGuard;
101102
use opte::ddi::time::Interval;
102103
use opte::ddi::time::Periodic;
103104
use opte::engine::NetworkImpl;
@@ -356,13 +357,13 @@ pub struct XdeDev {
356357
routes: RouteCache,
357358

358359
// Each port has its own copy of XDE_DEVS.
359-
port_map: KMutex<DevMap>,
360+
port_map: KMutex<Arc<DevMap>>,
360361
}
361362

362363
#[repr(C)]
363364
struct UnderlayDev {
364365
stream: DlsStream,
365-
ports_map: Vec<KMutex<DevMap>>,
366+
ports_map: Vec<KMutex<Arc<DevMap>>>,
366367
}
367368

368369
impl core::fmt::Debug for UnderlayDev {
@@ -808,7 +809,7 @@ fn create_xde(req: &CreateXdeReq) -> Result<NoResp, OpteError> {
808809
u2: underlay.u2.clone(),
809810
underlay_capab: underlay.shared_props,
810811
routes: RouteCache::default(),
811-
port_map: KMutex::new(DevMap::default()),
812+
port_map: KMutex::new(Arc::new(DevMap::new())),
812813
});
813814
let xde_ref =
814815
Arc::get_mut(&mut xde).expect("only one instance of XDE exists");
@@ -880,28 +881,7 @@ fn create_xde(req: &CreateXdeReq) -> Result<NoResp, OpteError> {
880881
}
881882

882883
_ = devs.insert(xde);
883-
884-
// Update all ports's maps.
885-
// TODO: not clone the WHOLE THING each time.
886-
for port in devs.iter() {
887-
let mut map = port.port_map.lock();
888-
*map = devs.clone();
889-
}
890-
891-
// Update all underlays' maps.
892-
// TODO: not clone the WHOLE THING each time.
893-
{
894-
let underlay_ = state.underlay.lock();
895-
let underlay = underlay_.as_ref().unwrap();
896-
let ports =
897-
[&underlay.u1.stream.ports_map, &underlay.u2.stream.ports_map];
898-
for port in ports {
899-
for map in port {
900-
let mut map = map.lock();
901-
*map = devs.clone();
902-
}
903-
}
904-
}
884+
refresh_maps(devs);
905885

906886
Ok(NoResp::default())
907887
}
@@ -964,32 +944,37 @@ fn delete_xde(req: &DeleteXdeReq) -> Result<NoResp, OpteError> {
964944
}
965945
};
966946

967-
// Remove the xde device entry.
968-
_ = devs.remove(&req.xde_devname);
947+
// Remove the xde device entry. Clear its devmap to break any cycles.
948+
if let Some(xde) = devs.remove(&req.xde_devname) {
949+
let mut pmap = xde.port_map.lock();
950+
*pmap = DevMap::new().into();
951+
}
952+
refresh_maps(devs);
953+
954+
Ok(NoResp::default())
955+
}
956+
957+
// NOTE: mut not used but effectively guaranteering writelock from ioctl.
958+
fn refresh_maps(devs: KRwLockWriteGuard<DevMap>) {
959+
let state = get_xde_state();
960+
let new_map = Arc::new(devs.clone());
969961

970-
// Update all ports's maps.
971-
// TODO: not clone the WHOLE THING each time.
962+
// Update all ports' maps.
972963
for port in devs.iter() {
973964
let mut map = port.port_map.lock();
974-
*map = devs.clone();
965+
*map = new_map.clone();
975966
}
976967

977968
// Update all underlays' maps.
978-
// TODO: not clone the WHOLE THING each time.
979-
{
980-
let underlay_ = state.underlay.lock();
981-
let underlay = underlay_.as_ref().unwrap();
982-
let ports =
983-
[&underlay.u1.stream.ports_map, &underlay.u2.stream.ports_map];
984-
for port in ports {
985-
for map in port {
986-
let mut map = map.lock();
987-
*map = devs.clone();
988-
}
969+
let underlay_ = state.underlay.lock();
970+
let underlay = underlay_.as_ref().unwrap();
971+
let ports = [&underlay.u1.stream.ports_map, &underlay.u2.stream.ports_map];
972+
for port in ports {
973+
for map in port {
974+
let mut map = map.lock();
975+
*map = new_map.clone();
989976
}
990977
}
991-
992-
Ok(NoResp::default())
993978
}
994979

995980
#[unsafe(no_mangle)]
@@ -1064,11 +1049,6 @@ fn clear_xde_underlay() -> Result<NoResp, OpteError> {
10641049
// Because there are no ports and we hold the write/management lock, no
10651050
// one else will have or try to clone the Stream handle.
10661051

1067-
// TEST
1068-
if let Ok(mch) = u.stream.mac_client_handle() {unsafe {
1069-
mac_rx_barrier(mch);
1070-
}}
1071-
10721052
// 2. Close the open stream handle.
10731053
// The only other hold on this `DlsStream` is via `u.siphon`, which
10741054
// we just dropped. The `expect` asserts that we have consumed them
@@ -1207,7 +1187,7 @@ fn create_underlay_port(
12071187
let cpus = unsafe { ncpus } as usize;
12081188
let mut ports_map = Vec::with_capacity(cpus);
12091189
for _ in 0..cpus {
1210-
ports_map.push(KMutex::new(DevMap::new()));
1190+
ports_map.push(KMutex::new(DevMap::new().into()));
12111191
}
12121192

12131193
let stream = Arc::new(UnderlayDev { stream, ports_map });
@@ -1572,7 +1552,7 @@ fn guest_loopback_probe(
15721552
#[unsafe(no_mangle)]
15731553
fn guest_loopback(
15741554
src_dev: &XdeDev,
1575-
devs: &KMutexGuard<DevMap>,
1555+
devs: &KMutexGuard<Arc<DevMap>>,
15761556
mut pkt: MsgBlk,
15771557
vni: Vni,
15781558
) {

0 commit comments

Comments
 (0)