@@ -21,7 +21,6 @@ use crate::ip::cpu;
21
21
use crate :: ip:: ncpus;
22
22
use crate :: ip:: processorid_t;
23
23
use crate :: mac;
24
- use crate :: mac:: mac_rx_barrier;
25
24
use crate :: mac:: ChecksumOffloadCapabs ;
26
25
use crate :: mac:: MacClient ;
27
26
use crate :: mac:: MacEmul ;
@@ -37,6 +36,7 @@ use crate::mac::mac_capab_lso_t;
37
36
use crate :: mac:: mac_getinfo;
38
37
use crate :: mac:: mac_hw_emul;
39
38
use crate :: mac:: mac_private_minor;
39
+ use crate :: mac:: mac_rx_barrier;
40
40
use crate :: route:: Route ;
41
41
use crate :: route:: RouteCache ;
42
42
use crate :: route:: RouteKey ;
@@ -98,6 +98,7 @@ use opte::ddi::sync::KMutexGuard;
98
98
use opte:: ddi:: sync:: KRwLock ;
99
99
use opte:: ddi:: sync:: KRwLockReadGuard ;
100
100
use opte:: ddi:: sync:: KRwLockType ;
101
+ use opte:: ddi:: sync:: KRwLockWriteGuard ;
101
102
use opte:: ddi:: time:: Interval ;
102
103
use opte:: ddi:: time:: Periodic ;
103
104
use opte:: engine:: NetworkImpl ;
@@ -356,13 +357,13 @@ pub struct XdeDev {
356
357
routes : RouteCache ,
357
358
358
359
// Each port has its own copy of XDE_DEVS.
359
- port_map : KMutex < DevMap > ,
360
+ port_map : KMutex < Arc < DevMap > > ,
360
361
}
361
362
362
363
#[ repr( C ) ]
363
364
struct UnderlayDev {
364
365
stream : DlsStream ,
365
- ports_map : Vec < KMutex < DevMap > > ,
366
+ ports_map : Vec < KMutex < Arc < DevMap > > > ,
366
367
}
367
368
368
369
impl core:: fmt:: Debug for UnderlayDev {
@@ -808,7 +809,7 @@ fn create_xde(req: &CreateXdeReq) -> Result<NoResp, OpteError> {
808
809
u2 : underlay. u2 . clone ( ) ,
809
810
underlay_capab : underlay. shared_props ,
810
811
routes : RouteCache :: default ( ) ,
811
- port_map : KMutex :: new ( DevMap :: default ( ) ) ,
812
+ port_map : KMutex :: new ( Arc :: new ( DevMap :: new ( ) ) ) ,
812
813
} ) ;
813
814
let xde_ref =
814
815
Arc :: get_mut ( & mut xde) . expect ( "only one instance of XDE exists" ) ;
@@ -880,28 +881,7 @@ fn create_xde(req: &CreateXdeReq) -> Result<NoResp, OpteError> {
880
881
}
881
882
882
883
_ = 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) ;
905
885
906
886
Ok ( NoResp :: default ( ) )
907
887
}
@@ -964,32 +944,37 @@ fn delete_xde(req: &DeleteXdeReq) -> Result<NoResp, OpteError> {
964
944
}
965
945
} ;
966
946
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 ( ) ) ;
969
961
970
- // Update all ports's maps.
971
- // TODO: not clone the WHOLE THING each time.
962
+ // Update all ports' maps.
972
963
for port in devs. iter ( ) {
973
964
let mut map = port. port_map . lock ( ) ;
974
- * map = devs . clone ( ) ;
965
+ * map = new_map . clone ( ) ;
975
966
}
976
967
977
968
// 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 ( ) ;
989
976
}
990
977
}
991
-
992
- Ok ( NoResp :: default ( ) )
993
978
}
994
979
995
980
#[ unsafe( no_mangle) ]
@@ -1064,11 +1049,6 @@ fn clear_xde_underlay() -> Result<NoResp, OpteError> {
1064
1049
// Because there are no ports and we hold the write/management lock, no
1065
1050
// one else will have or try to clone the Stream handle.
1066
1051
1067
- // TEST
1068
- if let Ok ( mch) = u. stream . mac_client_handle ( ) { unsafe {
1069
- mac_rx_barrier ( mch) ;
1070
- } }
1071
-
1072
1052
// 2. Close the open stream handle.
1073
1053
// The only other hold on this `DlsStream` is via `u.siphon`, which
1074
1054
// we just dropped. The `expect` asserts that we have consumed them
@@ -1207,7 +1187,7 @@ fn create_underlay_port(
1207
1187
let cpus = unsafe { ncpus } as usize ;
1208
1188
let mut ports_map = Vec :: with_capacity ( cpus) ;
1209
1189
for _ in 0 ..cpus {
1210
- ports_map. push ( KMutex :: new ( DevMap :: new ( ) ) ) ;
1190
+ ports_map. push ( KMutex :: new ( DevMap :: new ( ) . into ( ) ) ) ;
1211
1191
}
1212
1192
1213
1193
let stream = Arc :: new ( UnderlayDev { stream, ports_map } ) ;
@@ -1572,7 +1552,7 @@ fn guest_loopback_probe(
1572
1552
#[ unsafe( no_mangle) ]
1573
1553
fn guest_loopback (
1574
1554
src_dev : & XdeDev ,
1575
- devs : & KMutexGuard < DevMap > ,
1555
+ devs : & KMutexGuard < Arc < DevMap > > ,
1576
1556
mut pkt : MsgBlk ,
1577
1557
vni : Vni ,
1578
1558
) {
0 commit comments