forked from M-Labs/artiq
master: support unsolicited async messages
This commit is contained in:
parent
b1c305fd11
commit
a49ba3e350
|
@ -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)?;
|
||||||
|
|
|
@ -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))]
|
||||||
|
|
Loading…
Reference in New Issue