aboutsummaryrefslogtreecommitdiff
path: root/embassy-net/src/stack.rs
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2022-12-07 15:55:46 +0100
committerDario Nieuwenhuis <[email protected]>2022-12-13 16:18:39 +0100
commitac74613b5a7be72acd8d5259055963f8b4aba7fd (patch)
treebcc287e4edf65e0bb15cb5ff880aa0319ebf254f /embassy-net/src/stack.rs
parent47747d3b73f392e53ead8ff49cd09fd017df3215 (diff)
net: remove packet pool.
The pool was prone to deadlocks, especially due to having a single pool for rx+tx. If the pool got full with rx'd packets it would deadlock because processing a rx packet requires doing another allocation on the pool, for the possibly tx'd response, before deallocating the rx'd packet. This also allows Device impls to allocate the packet memory in a particular RAM kind, if needed for example to do DMA. The `Device` trait is now token-based, like smoltcp's. In the end, this is better because it allows callers to manage memory however they want (including with a pool if they want to).
Diffstat (limited to 'embassy-net/src/stack.rs')
-rw-r--r--embassy-net/src/stack.rs24
1 files changed, 14 insertions, 10 deletions
diff --git a/embassy-net/src/stack.rs b/embassy-net/src/stack.rs
index 5c4fb0442..21316e485 100644
--- a/embassy-net/src/stack.rs
+++ b/embassy-net/src/stack.rs
@@ -12,7 +12,7 @@ use smoltcp::iface::{Interface, InterfaceBuilder, SocketSet, SocketStorage};
12#[cfg(feature = "medium-ethernet")] 12#[cfg(feature = "medium-ethernet")]
13use smoltcp::iface::{Neighbor, NeighborCache, Route, Routes}; 13use smoltcp::iface::{Neighbor, NeighborCache, Route, Routes};
14#[cfg(feature = "medium-ethernet")] 14#[cfg(feature = "medium-ethernet")]
15use smoltcp::phy::{Device as _, Medium}; 15use smoltcp::phy::Medium;
16#[cfg(feature = "dhcpv4")] 16#[cfg(feature = "dhcpv4")]
17use smoltcp::socket::dhcpv4; 17use smoltcp::socket::dhcpv4;
18use smoltcp::time::Instant as SmolInstant; 18use smoltcp::time::Instant as SmolInstant;
@@ -67,7 +67,7 @@ pub struct Stack<D: Device> {
67} 67}
68 68
69struct Inner<D: Device> { 69struct Inner<D: Device> {
70 device: DeviceAdapter<D>, 70 device: D,
71 link_up: bool, 71 link_up: bool,
72 config: Option<Config>, 72 config: Option<Config>,
73 #[cfg(feature = "dhcpv4")] 73 #[cfg(feature = "dhcpv4")]
@@ -83,7 +83,7 @@ pub(crate) struct SocketStack {
83 83
84impl<D: Device + 'static> Stack<D> { 84impl<D: Device + 'static> Stack<D> {
85 pub fn new<const ADDR: usize, const SOCK: usize, const NEIGH: usize>( 85 pub fn new<const ADDR: usize, const SOCK: usize, const NEIGH: usize>(
86 device: D, 86 mut device: D,
87 config: ConfigStrategy, 87 config: ConfigStrategy,
88 resources: &'static mut StackResources<ADDR, SOCK, NEIGH>, 88 resources: &'static mut StackResources<ADDR, SOCK, NEIGH>,
89 random_seed: u64, 89 random_seed: u64,
@@ -98,8 +98,6 @@ impl<D: Device + 'static> Stack<D> {
98 [0, 0, 0, 0, 0, 0] 98 [0, 0, 0, 0, 0, 0]
99 }; 99 };
100 100
101 let mut device = DeviceAdapter::new(device);
102
103 let mut b = InterfaceBuilder::new(); 101 let mut b = InterfaceBuilder::new();
104 b = b.ip_addrs(&mut resources.addresses[..]); 102 b = b.ip_addrs(&mut resources.addresses[..]);
105 b = b.random_seed(random_seed); 103 b = b.random_seed(random_seed);
@@ -111,7 +109,10 @@ impl<D: Device + 'static> Stack<D> {
111 b = b.routes(Routes::new(&mut resources.routes[..])); 109 b = b.routes(Routes::new(&mut resources.routes[..]));
112 } 110 }
113 111
114 let iface = b.finalize(&mut device); 112 let iface = b.finalize(&mut DeviceAdapter {
113 inner: &mut device,
114 cx: None,
115 });
115 116
116 let sockets = SocketSet::new(&mut resources.sockets[..]); 117 let sockets = SocketSet::new(&mut resources.sockets[..]);
117 118
@@ -155,7 +156,7 @@ impl<D: Device + 'static> Stack<D> {
155 } 156 }
156 157
157 pub fn ethernet_address(&self) -> [u8; 6] { 158 pub fn ethernet_address(&self) -> [u8; 6] {
158 self.with(|_s, i| i.device.device.ethernet_address()) 159 self.with(|_s, i| i.device.ethernet_address())
159 } 160 }
160 161
161 pub fn is_link_up(&self) -> bool { 162 pub fn is_link_up(&self) -> bool {
@@ -238,11 +239,14 @@ impl<D: Device + 'static> Inner<D> {
238 } 239 }
239 240
240 fn poll(&mut self, cx: &mut Context<'_>, s: &mut SocketStack) { 241 fn poll(&mut self, cx: &mut Context<'_>, s: &mut SocketStack) {
241 self.device.device.register_waker(cx.waker());
242 s.waker.register(cx.waker()); 242 s.waker.register(cx.waker());
243 243
244 let timestamp = instant_to_smoltcp(Instant::now()); 244 let timestamp = instant_to_smoltcp(Instant::now());
245 if s.iface.poll(timestamp, &mut self.device, &mut s.sockets).is_err() { 245 let mut smoldev = DeviceAdapter {
246 cx: Some(cx),
247 inner: &mut self.device,
248 };
249 if s.iface.poll(timestamp, &mut smoldev, &mut s.sockets).is_err() {
246 // If poll() returns error, it may not be done yet, so poll again later. 250 // If poll() returns error, it may not be done yet, so poll again later.
247 cx.waker().wake_by_ref(); 251 cx.waker().wake_by_ref();
248 return; 252 return;
@@ -250,7 +254,7 @@ impl<D: Device + 'static> Inner<D> {
250 254
251 // Update link up 255 // Update link up
252 let old_link_up = self.link_up; 256 let old_link_up = self.link_up;
253 self.link_up = self.device.device.link_state() == LinkState::Up; 257 self.link_up = self.device.link_state(cx) == LinkState::Up;
254 258
255 // Print when changed 259 // Print when changed
256 if old_link_up != self.link_up { 260 if old_link_up != self.link_up {