forked from M-Labs/artiq
1
0
Fork 0

master: support unsolicited async messages

This commit is contained in:
mwojcik 2024-04-19 16:28:26 +08:00 committed by Sébastien Bourdeauducq
parent b1c305fd11
commit a49ba3e350
2 changed files with 57 additions and 80 deletions

View File

@ -77,8 +77,6 @@ pub enum Packet {
RoutingSetPath { destination: u8, hops: [u8; 32] }, RoutingSetPath { destination: u8, hops: [u8; 32] },
RoutingSetRank { rank: u8 }, RoutingSetRank { rank: u8 },
RoutingRetrievePackets,
RoutingNoPackets,
RoutingAck, RoutingAck,
MonitorRequest { destination: u8, channel: u16, probe: u8 }, MonitorRequest { destination: u8, channel: u16, probe: u8 },
@ -170,8 +168,6 @@ impl Packet {
rank: reader.read_u8()? rank: reader.read_u8()?
}, },
0x32 => Packet::RoutingAck, 0x32 => Packet::RoutingAck,
0x33 => Packet::RoutingRetrievePackets,
0x34 => Packet::RoutingNoPackets,
0x40 => Packet::MonitorRequest { 0x40 => Packet::MonitorRequest {
destination: reader.read_u8()?, destination: reader.read_u8()?,
@ -456,10 +452,6 @@ impl Packet {
}, },
Packet::RoutingAck => Packet::RoutingAck =>
writer.write_u8(0x32)?, writer.write_u8(0x32)?,
Packet::RoutingRetrievePackets =>
writer.write_u8(0x33)?,
Packet::RoutingNoPackets =>
writer.write_u8(0x34)?,
Packet::MonitorRequest { destination, channel, probe } => { Packet::MonitorRequest { destination, channel, probe } => {
writer.write_u8(0x40)?; writer.write_u8(0x40)?;

View File

@ -78,16 +78,6 @@ pub mod drtio {
} }
} }
fn link_has_async_ready(linkno: u8) -> bool {
let linkno = linkno as usize;
let async_ready;
unsafe {
async_ready = (csr::DRTIO[linkno].async_messages_ready_read)() == 1;
(csr::DRTIO[linkno].async_messages_ready_write)(1);
}
async_ready
}
fn recv_aux_timeout(io: &Io, linkno: u8, timeout: u32) -> Result<drtioaux::Packet, Error> { fn recv_aux_timeout(io: &Io, linkno: u8, timeout: u32) -> Result<drtioaux::Packet, Error> {
let max_time = clock::get_ms() + timeout as u64; let max_time = clock::get_ms() + timeout as u64;
loop { loop {
@ -97,6 +87,7 @@ pub mod drtio {
if clock::get_ms() > max_time { if clock::get_ms() > max_time {
return Err(Error::Timeout); return Err(Error::Timeout);
} }
// todo: reinsert handling of async messages
match drtioaux::recv(linkno) { match drtioaux::recv(linkno) {
Ok(Some(packet)) => return Ok(packet), Ok(Some(packet)) => return Ok(packet),
Ok(None) => (), Ok(None) => (),
@ -106,62 +97,51 @@ pub mod drtio {
} }
} }
fn process_async_packets(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, subkernel_mutex: &Mutex, fn process_async_packets(io: &Io, ddma_mutex: &Mutex, subkernel_mutex: &Mutex,
routing_table: &drtio_routing::RoutingTable, linkno: u8) routing_table: &drtio_routing::RoutingTable, linkno: u8, packet: drtioaux::Packet
{ ) -> Option<drtioaux::Packet> {
if link_has_async_ready(linkno) { match packet {
loop { // packets to be consumed locally
let reply = aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::RoutingRetrievePackets); drtioaux::Packet::DmaPlaybackStatus { id, source, destination: 0, error, channel, timestamp } => {
if let Ok(packet) = reply { remote_dma::playback_done(io, ddma_mutex, id, source, error, channel, timestamp);
match packet { None
// packets to be consumed locally },
drtioaux::Packet::DmaPlaybackStatus { id, source, destination: 0, error, channel, timestamp } => { drtioaux::Packet::SubkernelFinished { id, destination: 0, with_exception, exception_src } => {
remote_dma::playback_done(io, ddma_mutex, id, source, error, channel, timestamp); subkernel::subkernel_finished(io, subkernel_mutex, id, with_exception, exception_src);
}, None
drtioaux::Packet::SubkernelFinished { id, destination: 0, with_exception, exception_src } => { },
subkernel::subkernel_finished(io, subkernel_mutex, id, with_exception, exception_src); drtioaux::Packet::SubkernelMessage { id, source: from, destination: 0, status, length, data } => {
}, subkernel::message_handle_incoming(io, subkernel_mutex, id, status, length as usize, &data);
drtioaux::Packet::SubkernelMessage { id, source: from, destination: 0, status, length, data } => { // acknowledge receiving part of the message
subkernel::message_handle_incoming(io, subkernel_mutex, id, status, length as usize, &data); drtioaux::send(linkno,
// acknowledge receiving part of the message &drtioaux::Packet::SubkernelMessageAck { destination: from }
drtioaux::send(linkno, ).unwrap();
&drtioaux::Packet::SubkernelMessageAck { destination: from } None
).unwrap(); },
// give the satellite some time to process the message // routable packets
io.sleep(10).unwrap(); drtioaux::Packet::DmaAddTraceRequest { destination, .. } |
}, drtioaux::Packet::DmaAddTraceReply { destination, .. } |
// routable packets drtioaux::Packet::DmaRemoveTraceRequest { destination, .. } |
drtioaux::Packet::DmaAddTraceRequest { destination, .. } | drtioaux::Packet::DmaRemoveTraceReply { destination, .. } |
drtioaux::Packet::DmaAddTraceReply { destination, .. } | drtioaux::Packet::DmaPlaybackRequest { destination, .. } |
drtioaux::Packet::DmaRemoveTraceRequest { destination, .. } | drtioaux::Packet::DmaPlaybackReply { destination, .. } |
drtioaux::Packet::DmaRemoveTraceReply { destination, .. } | drtioaux::Packet::SubkernelLoadRunRequest { destination, .. } |
drtioaux::Packet::DmaPlaybackRequest { destination, .. } | drtioaux::Packet::SubkernelLoadRunReply { destination, .. } |
drtioaux::Packet::DmaPlaybackReply { destination, .. } | drtioaux::Packet::SubkernelMessage { destination, .. } |
drtioaux::Packet::SubkernelLoadRunRequest { destination, .. } | drtioaux::Packet::SubkernelMessageAck { destination, .. } |
drtioaux::Packet::SubkernelLoadRunReply { destination, .. } | drtioaux::Packet::DmaPlaybackStatus { destination, .. } |
drtioaux::Packet::SubkernelMessage { destination, .. } | drtioaux::Packet::SubkernelFinished { destination, .. } => {
drtioaux::Packet::SubkernelMessageAck { destination, .. } | let dest_link = routing_table.0[destination as usize][0] - 1;
drtioaux::Packet::DmaPlaybackStatus { destination, .. } | if dest_link == linkno {
drtioaux::Packet::SubkernelFinished { destination, .. } => { warn!("[LINK#{}] Re-routed packet would return to the same link, dropping: {:?}", linkno, packet);
let dest_link = routing_table.0[destination as usize][0] - 1; } else if destination == 0 {
if dest_link == linkno { warn!("[LINK#{}] Received invalid routable packet: {:?}", linkno, packet)
warn!("[LINK#{}] Re-routed packet would return to the same link, dropping: {:?}", linkno, packet);
} else if destination == 0 {
warn!("[LINK#{}] Received invalid routable packet: {:?}", linkno, packet)
} else {
drtioaux::send(dest_link, &packet).unwrap();
}
}
drtioaux::Packet::RoutingNoPackets => break,
other => warn!("[LINK#{}] Received an unroutable packet: {:?}", linkno, other)
}
} else { } else {
warn!("[LINK#{}] Error handling async packets ({})", linkno, reply.unwrap_err()); drtioaux::send(dest_link, &packet).unwrap();
return;
} }
None
} }
other => Some(other)
} }
} }
@ -268,12 +248,19 @@ pub mod drtio {
} }
} }
fn process_unsolicited_aux(io: &Io, aux_mutex: &Mutex, linkno: u8) { fn process_unsolicited_aux(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, subkernel_mutex: &Mutex,
routing_table: &drtio_routing::RoutingTable, linkno: u8) {
let _lock = aux_mutex.lock(io).unwrap(); let _lock = aux_mutex.lock(io).unwrap();
match drtioaux::recv(linkno) { loop {
Ok(Some(packet)) => warn!("[LINK#{}] unsolicited aux packet: {:?}", linkno, packet), match drtioaux::recv(linkno) {
Ok(None) => (), Ok(Some(packet)) => {
Err(_) => warn!("[LINK#{}] aux packet error", linkno) if let Some(packet) = process_async_packets(&io, ddma_mutex, subkernel_mutex, routing_table, linkno, packet) {
warn!("[LINK#{}] unsolicited aux packet: {:?}", linkno, packet);
}
},
Ok(None) => return,
Err(_) => { warn!("[LINK#{}] aux packet error", linkno); return }
}
} }
} }
@ -403,8 +390,7 @@ pub mod drtio {
if up_links[linkno as usize] { if up_links[linkno as usize] {
/* link was previously up */ /* link was previously up */
if link_rx_up(linkno) { if link_rx_up(linkno) {
process_async_packets(&io, aux_mutex, ddma_mutex, subkernel_mutex, routing_table, linkno); process_unsolicited_aux(&io, aux_mutex, ddma_mutex, subkernel_mutex, routing_table, linkno);
process_unsolicited_aux(&io, aux_mutex, linkno);
process_local_errors(linkno); process_local_errors(linkno);
} else { } else {
info!("[LINK#{}] link is down", linkno); info!("[LINK#{}] link is down", linkno);
@ -636,7 +622,6 @@ pub mod drtio {
} }
}) })
} }
} }
#[cfg(not(has_drtio))] #[cfg(not(has_drtio))]