Compare commits

...

1 Commits

Author SHA1 Message Date
Astro 4158906122 eth: collect some stats 2020-07-30 19:19:43 +02:00
3 changed files with 66 additions and 8 deletions

View File

@ -160,6 +160,7 @@ pub fn main_core0() {
flash = flash_io.stop(); flash = flash_io.stop();
} }
if false {
let core1 = boot::Core1::start(false); let core1 = boot::Core1::start(false);
let (mut core1_req, rx) = sync_channel!(usize, 10); let (mut core1_req, rx) = sync_channel!(usize, 10);
@ -174,20 +175,21 @@ pub fn main_core0() {
} }
}); });
core1.disable(); core1.disable();
}
let eth = zynq::eth::Eth::default(HWADDR.clone()); let eth = zynq::eth::Eth::default(HWADDR.clone());
println!("Eth on"); println!("Eth on");
const RX_LEN: usize = 4096; const RX_LEN: usize = 8192;
// Number of transmission buffers (minimum is two because with // Number of transmission buffers (minimum is two because with
// one, duplicate packet transmission occurs) // one, duplicate packet transmission occurs)
const TX_LEN: usize = 4096; const TX_LEN: usize = 8192;
let eth = eth.start_rx(RX_LEN); let eth = eth.start_rx(RX_LEN);
let mut eth = eth.start_tx(TX_LEN); let mut eth = eth.start_tx(TX_LEN);
let ethernet_addr = EthernetAddress(HWADDR); let ethernet_addr = EthernetAddress(HWADDR);
// IP stack // IP stack
let local_addr = IpAddress::v4(192, 168, 1, 51); let local_addr = IpAddress::v4(192, 168, 1, 54);
let mut ip_addrs = [IpCidr::new(local_addr, 24)]; let mut ip_addrs = [IpCidr::new(local_addr, 24)];
let routes = Routes::new(BTreeMap::new()); let routes = Routes::new(BTreeMap::new());
let neighbor_cache = NeighborCache::new(BTreeMap::new()); let neighbor_cache = NeighborCache::new(BTreeMap::new());
@ -228,7 +230,7 @@ pub fn main_core0() {
}); });
let stats_rx = stats.clone(); let stats_rx = stats.clone();
task::spawn(async move { task::spawn(async move {
while let Ok(stream) = TcpStream::accept(TCP_PORT+1, 0x10_0000, 0x10_0000).await { while let Ok(stream) = TcpStream::accept(TCP_PORT+1, 4096, 4096).await {
let stats_rx = stats_rx.clone(); let stats_rx = stats_rx.clone();
task::spawn(async move { task::spawn(async move {
loop { loop {
@ -262,7 +264,16 @@ pub fn main_core0() {
} }
}); });
Sockets::run(&mut iface, || { let mut last_stats_time = 0;
Sockets::run(&mut iface, |iface| {
let t = timer.get_time().0;
if t - last_stats_time >= 1000 {
let stats = &mut iface.device_mut().stats;
info!("eth stats: {:?}", stats);
stats.reset();
last_stats_time = t;
}
Instant::from_millis(timer.get_time().0 as i64) Instant::from_millis(timer.get_time().0 as i64)
}) })
} }

View File

@ -43,11 +43,11 @@ impl Sockets {
/// iface /// iface
pub fn run<'b, 'c, 'e, D: for<'d> Device<'d>>( pub fn run<'b, 'c, 'e, D: for<'d> Device<'d>>(
iface: &mut EthernetInterface<'b, 'c, 'e, D>, iface: &mut EthernetInterface<'b, 'c, 'e, D>,
mut get_time: impl FnMut() -> Instant, mut get_time: impl FnMut(&mut EthernetInterface<'b, 'c, 'e, D>) -> Instant,
) -> ! { ) -> ! {
task::block_on(async { task::block_on(async {
loop { loop {
let instant = get_time(); let instant = get_time(iface);
Self::instance().poll(iface, instant); Self::instance().poll(iface, instant);
task::r#yield().await; task::r#yield().await;
} }

View File

@ -140,11 +140,43 @@ fn calculate_tx_divisors(tx_clock: u32) -> (u8, u8) {
result result
} }
#[derive(Debug)]
pub struct EthStats {
frame_recd: usize,
no_frame_recd: usize,
rx_idle: usize,
tx_send: usize,
tx_overflow: usize,
}
impl EthStats {
pub fn new() -> Self {
EthStats {
frame_recd: 0,
no_frame_recd: 0,
rx_idle: 0,
tx_send: 0,
tx_overflow: 0,
}
}
pub fn reset(&mut self) {
*self = EthStats {
frame_recd: 0,
no_frame_recd: 0,
rx_idle: 0,
tx_send: 0,
tx_overflow: 0,
};
}
}
pub struct Eth<GEM: Gem, RX, TX> { pub struct Eth<GEM: Gem, RX, TX> {
rx: RX, rx: RX,
tx: TX, tx: TX,
inner: EthInner<GEM>, inner: EthInner<GEM>,
phy: Phy, phy: Phy,
pub stats: EthStats,
} }
impl Eth<Gem0, (), ()> { impl Eth<Gem0, (), ()> {
@ -303,6 +335,7 @@ impl<GEM: Gem> Eth<GEM, (), ()> {
inner.configure(macaddr); inner.configure(macaddr);
let phy = Phy::find(&mut inner).expect("phy"); let phy = Phy::find(&mut inner).expect("phy");
info!("Eth: found PHY {}", phy.name());
phy.reset(&mut inner); phy.reset(&mut inner);
phy.restart_autoneg(&mut inner); phy.restart_autoneg(&mut inner);
@ -311,6 +344,7 @@ impl<GEM: Gem> Eth<GEM, (), ()> {
tx: (), tx: (),
inner, inner,
phy, phy,
stats: EthStats::new(),
} }
} }
} }
@ -322,6 +356,7 @@ impl<GEM: Gem, RX, TX> Eth<GEM, RX, TX> {
tx: self.tx, tx: self.tx,
inner: self.inner, inner: self.inner,
phy: self.phy, phy: self.phy,
stats: self.stats,
}; };
let list_addr = new_self.rx.list_addr(); let list_addr = new_self.rx.list_addr();
assert!(list_addr & 0b11 == 0); assert!(list_addr & 0b11 == 0);
@ -341,6 +376,7 @@ impl<GEM: Gem, RX, TX> Eth<GEM, RX, TX> {
tx: tx::DescList::new(tx_size), tx: tx::DescList::new(tx_size),
inner: self.inner, inner: self.inner,
phy: self.phy, phy: self.phy,
stats: self.stats,
}; };
let list_addr = &new_self.tx.list_addr(); let list_addr = &new_self.tx.list_addr();
assert!(list_addr & 0b11 == 0); assert!(list_addr & 0b11 == 0);
@ -387,16 +423,19 @@ impl<GEM: Gem, TX> Eth<GEM, rx::DescList, TX> {
let result = self.rx.recv_next(); let result = self.rx.recv_next();
match result { match result {
Ok(None) => { Ok(None) => {
self.stats.no_frame_recd += 1;
// No packet, clear status bit // No packet, clear status bit
GEM::regs().rx_status.write( GEM::regs().rx_status.write(
regs::RxStatus::zeroed() regs::RxStatus::zeroed()
.frame_recd(true) .frame_recd(true)
); );
} }
Ok(Some(_)) => self.stats.frame_recd += 1,
_ => {} _ => {}
} }
result result
} else { } else {
self.stats.rx_idle += 1;
self.inner.check_link_change(&self.phy); self.inner.check_link_change(&self.phy);
Ok(None) Ok(None)
} }
@ -405,7 +444,13 @@ impl<GEM: Gem, TX> Eth<GEM, rx::DescList, TX> {
impl<GEM: Gem, RX> Eth<GEM, RX, tx::DescList> { impl<GEM: Gem, RX> Eth<GEM, RX, tx::DescList> {
pub fn send<'s: 'p, 'p>(&'s mut self, length: usize) -> Option<tx::PktRef<'p>> { pub fn send<'s: 'p, 'p>(&'s mut self, length: usize) -> Option<tx::PktRef<'p>> {
self.tx.send(GEM::regs(), length) let result = self.tx.send(GEM::regs(), length);
if result.is_some() {
self.stats.tx_send += 1;
} else {
self.stats.tx_overflow += 1;
}
result
} }
} }
@ -432,6 +477,7 @@ impl<'a, GEM: Gem> smoltcp::phy::Device<'a> for &mut Eth<GEM, rx::DescList, tx::
fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> { fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> {
match self.rx.recv_next() { match self.rx.recv_next() {
Ok(Some(pktref)) => { Ok(Some(pktref)) => {
self.stats.frame_recd += 1;
let tx_token = tx::Token { let tx_token = tx::Token {
regs: GEM::regs(), regs: GEM::regs(),
desc_list: &mut self.tx, desc_list: &mut self.tx,
@ -439,6 +485,7 @@ impl<'a, GEM: Gem> smoltcp::phy::Device<'a> for &mut Eth<GEM, rx::DescList, tx::
Some((pktref, tx_token)) Some((pktref, tx_token))
} }
Ok(None) => { Ok(None) => {
self.stats.rx_idle += 1;
self.inner.check_link_change(&self.phy); self.inner.check_link_change(&self.phy);
None None
} }