drtio: increase robustness for longer payloads

This commit is contained in:
mwojcik 2023-11-02 14:48:52 +08:00
parent 4a34777b97
commit b76f634686
4 changed files with 84 additions and 40 deletions

View File

@ -19,6 +19,46 @@ impl From<IoError> for Error {
} }
} }
#[derive(PartialEq, Clone, Copy, Debug)]
#[repr(u8)]
pub enum PayloadStatus {
Middle = 0,
First = 1,
Last = 2,
FirstAndLast = 3,
}
impl From<u8> for PayloadStatus {
fn from(value: u8) -> PayloadStatus {
match value {
0 => PayloadStatus::Middle,
1 => PayloadStatus::First,
2 => PayloadStatus::Last,
3 => PayloadStatus::FirstAndLast,
_ => unreachable!(),
}
}
}
impl PayloadStatus {
pub fn is_first(self) -> bool {
self == PayloadStatus::First || self == PayloadStatus::FirstAndLast
}
pub fn is_last(self) -> bool {
self == PayloadStatus::Last || self == PayloadStatus::FirstAndLast
}
pub fn from_status(first: bool, last: bool) -> PayloadStatus {
match (first, last) {
(true, true) => PayloadStatus::FirstAndLast,
(true, false) => PayloadStatus::First,
(false, true) => PayloadStatus::Last,
(false, false) => PayloadStatus::Middle,
}
}
}
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
pub enum Packet { pub enum Packet {
EchoRequest, EchoRequest,
@ -159,7 +199,7 @@ pub enum Packet {
DmaAddTraceRequest { DmaAddTraceRequest {
destination: u8, destination: u8,
id: u32, id: u32,
last: bool, status: PayloadStatus,
length: u16, length: u16,
trace: [u8; MASTER_PAYLOAD_MAX_SIZE], trace: [u8; MASTER_PAYLOAD_MAX_SIZE],
}, },
@ -192,7 +232,7 @@ pub enum Packet {
SubkernelAddDataRequest { SubkernelAddDataRequest {
destination: u8, destination: u8,
id: u32, id: u32,
last: bool, status: PayloadStatus,
length: u16, length: u16,
data: [u8; MASTER_PAYLOAD_MAX_SIZE], data: [u8; MASTER_PAYLOAD_MAX_SIZE],
}, },
@ -228,7 +268,7 @@ pub enum Packet {
SubkernelMessage { SubkernelMessage {
destination: u8, destination: u8,
id: u32, id: u32,
last: bool, status: PayloadStatus,
length: u16, length: u16,
data: [u8; MASTER_PAYLOAD_MAX_SIZE], data: [u8; MASTER_PAYLOAD_MAX_SIZE],
}, },
@ -391,14 +431,14 @@ impl Packet {
0xb0 => { 0xb0 => {
let destination = reader.read_u8()?; let destination = reader.read_u8()?;
let id = reader.read_u32()?; let id = reader.read_u32()?;
let last = reader.read_bool()?; let status = PayloadStatus::from(reader.read_u8()?);
let length = reader.read_u16()?; let length = reader.read_u16()?;
let mut trace: [u8; MASTER_PAYLOAD_MAX_SIZE] = [0; MASTER_PAYLOAD_MAX_SIZE]; let mut trace: [u8; MASTER_PAYLOAD_MAX_SIZE] = [0; MASTER_PAYLOAD_MAX_SIZE];
reader.read_exact(&mut trace[0..length as usize])?; reader.read_exact(&mut trace[0..length as usize])?;
Packet::DmaAddTraceRequest { Packet::DmaAddTraceRequest {
destination: destination, destination: destination,
id: id, id: id,
last: last, status: status,
length: length as u16, length: length as u16,
trace: trace, trace: trace,
} }
@ -432,14 +472,14 @@ impl Packet {
0xc0 => { 0xc0 => {
let destination = reader.read_u8()?; let destination = reader.read_u8()?;
let id = reader.read_u32()?; let id = reader.read_u32()?;
let last = reader.read_bool()?; let status = PayloadStatus::from(reader.read_u8()?);
let length = reader.read_u16()?; let length = reader.read_u16()?;
let mut data: [u8; MASTER_PAYLOAD_MAX_SIZE] = [0; MASTER_PAYLOAD_MAX_SIZE]; let mut data: [u8; MASTER_PAYLOAD_MAX_SIZE] = [0; MASTER_PAYLOAD_MAX_SIZE];
reader.read_exact(&mut data[0..length as usize])?; reader.read_exact(&mut data[0..length as usize])?;
Packet::SubkernelAddDataRequest { Packet::SubkernelAddDataRequest {
destination: destination, destination: destination,
id: id, id: id,
last: last, status: status,
length: length as u16, length: length as u16,
data: data, data: data,
} }
@ -482,14 +522,14 @@ impl Packet {
0xcb => { 0xcb => {
let destination = reader.read_u8()?; let destination = reader.read_u8()?;
let id = reader.read_u32()?; let id = reader.read_u32()?;
let last = reader.read_bool()?; let status = PayloadStatus::from(reader.read_u8()?);
let length = reader.read_u16()?; let length = reader.read_u16()?;
let mut data: [u8; MASTER_PAYLOAD_MAX_SIZE] = [0; MASTER_PAYLOAD_MAX_SIZE]; let mut data: [u8; MASTER_PAYLOAD_MAX_SIZE] = [0; MASTER_PAYLOAD_MAX_SIZE];
reader.read_exact(&mut data[0..length as usize])?; reader.read_exact(&mut data[0..length as usize])?;
Packet::SubkernelMessage { Packet::SubkernelMessage {
destination: destination, destination: destination,
id: id, id: id,
last: last, status: status,
length: length as u16, length: length as u16,
data: data, data: data,
} }
@ -713,14 +753,14 @@ impl Packet {
Packet::DmaAddTraceRequest { Packet::DmaAddTraceRequest {
destination, destination,
id, id,
last, status,
trace, trace,
length, length,
} => { } => {
writer.write_u8(0xb0)?; writer.write_u8(0xb0)?;
writer.write_u8(destination)?; writer.write_u8(destination)?;
writer.write_u32(id)?; writer.write_u32(id)?;
writer.write_bool(last)?; writer.write_u8(status as u8)?;
// trace may be broken down to fit within drtio aux memory limit // trace may be broken down to fit within drtio aux memory limit
// will be reconstructed by satellite // will be reconstructed by satellite
writer.write_u16(length)?; writer.write_u16(length)?;
@ -771,14 +811,14 @@ impl Packet {
Packet::SubkernelAddDataRequest { Packet::SubkernelAddDataRequest {
destination, destination,
id, id,
last, status,
data, data,
length, length,
} => { } => {
writer.write_u8(0xc0)?; writer.write_u8(0xc0)?;
writer.write_u8(destination)?; writer.write_u8(destination)?;
writer.write_u32(id)?; writer.write_u32(id)?;
writer.write_bool(last)?; writer.write_u8(status as u8)?;
writer.write_u16(length)?; writer.write_u16(length)?;
writer.write_all(&data[0..length as usize])?; writer.write_all(&data[0..length as usize])?;
} }
@ -822,14 +862,14 @@ impl Packet {
Packet::SubkernelMessage { Packet::SubkernelMessage {
destination, destination,
id, id,
last, status,
data, data,
length, length,
} => { } => {
writer.write_u8(0xcb)?; writer.write_u8(0xcb)?;
writer.write_u8(destination)?; writer.write_u8(destination)?;
writer.write_u32(id)?; writer.write_u32(id)?;
writer.write_bool(last)?; writer.write_u8(status as u8)?;
writer.write_u16(length)?; writer.write_u16(length)?;
writer.write_all(&data[0..length as usize])?; writer.write_all(&data[0..length as usize])?;
} }

View File

@ -13,8 +13,10 @@ pub mod drtio {
use ksupport::{resolve_channel_name, ASYNC_ERROR_BUSY, ASYNC_ERROR_COLLISION, ASYNC_ERROR_SEQUENCE_ERROR, use ksupport::{resolve_channel_name, ASYNC_ERROR_BUSY, ASYNC_ERROR_COLLISION, ASYNC_ERROR_SEQUENCE_ERROR,
SEEN_ASYNC_ERRORS}; SEEN_ASYNC_ERRORS};
use libasync::{delay, task}; use libasync::{delay, task};
use libboard_artiq::{drtioaux::Error, drtioaux_async, drtioaux_async::Packet, use libboard_artiq::{drtioaux::Error,
drtioaux_proto::MASTER_PAYLOAD_MAX_SIZE}; drtioaux_async,
drtioaux_async::Packet,
drtioaux_proto::{PayloadStatus, MASTER_PAYLOAD_MAX_SIZE}};
use libboard_zynq::time::Milliseconds; use libboard_zynq::time::Milliseconds;
use log::{error, info, warn}; use log::{error, info, warn};
@ -61,11 +63,11 @@ pub mod drtio {
Packet::SubkernelMessage { Packet::SubkernelMessage {
id, id,
destination: from, destination: from,
last, status,
length, length,
data, data,
} => { } => {
subkernel::message_handle_incoming(id, last, length as usize, &data).await; subkernel::message_handle_incoming(id, status, length as usize, &data).await;
// acknowledge receiving part of the message // acknowledge receiving part of the message
let _lock = aux_mutex.async_lock().await; let _lock = aux_mutex.async_lock().await;
drtioaux_async::send(linkno, &Packet::SubkernelMessageAck { destination: from }) drtioaux_async::send(linkno, &Packet::SubkernelMessageAck { destination: from })
@ -463,7 +465,7 @@ pub mod drtio {
reply_handler_f: HandlerF, reply_handler_f: HandlerF,
) -> Result<(), &'static str> ) -> Result<(), &'static str>
where where
PacketF: Fn(&[u8; MASTER_PAYLOAD_MAX_SIZE], bool, usize) -> Packet, PacketF: Fn(&[u8; MASTER_PAYLOAD_MAX_SIZE], PayloadStatus, usize) -> Packet,
HandlerF: Fn(&Packet) -> Result<(), &'static str>, HandlerF: Fn(&Packet) -> Result<(), &'static str>,
{ {
let mut i = 0; let mut i = 0;
@ -474,10 +476,12 @@ pub mod drtio {
} else { } else {
data.len() - i data.len() - i
} as usize; } as usize;
let first = i == 0;
let last = i + len == data.len(); let last = i + len == data.len();
slice[..len].clone_from_slice(&data[i..i + len]); slice[..len].clone_from_slice(&data[i..i + len]);
i += len; i += len;
let packet = packet_f(&slice, last, len); let status = PayloadStatus::from_status(first, last);
let packet = packet_f(&slice, status, len);
let reply = aux_transact(aux_mutex, linkno, &packet, timer).await?; let reply = aux_transact(aux_mutex, linkno, &packet, timer).await?;
reply_handler_f(&reply)?; reply_handler_f(&reply)?;
} }
@ -498,10 +502,10 @@ pub mod drtio {
aux_mutex, aux_mutex,
timer, timer,
trace, trace,
|slice, last, len| Packet::DmaAddTraceRequest { |slice, status, len| Packet::DmaAddTraceRequest {
id: id, id: id,
destination: destination, destination: destination,
last: last, status: status,
length: len as u16, length: len as u16,
trace: *slice, trace: *slice,
}, },
@ -655,10 +659,10 @@ pub mod drtio {
aux_mutex, aux_mutex,
timer, timer,
data, data,
|slice, last, len| Packet::SubkernelAddDataRequest { |slice, status, len| Packet::SubkernelAddDataRequest {
id: id, id: id,
destination: destination, destination: destination,
last: last, status: status,
length: len as u16, length: len as u16,
data: *slice, data: *slice,
}, },
@ -742,10 +746,10 @@ pub mod drtio {
aux_mutex, aux_mutex,
timer, timer,
message, message,
|slice, last, len| Packet::SubkernelMessage { |slice, status, len| Packet::SubkernelMessage {
destination: destination, destination: destination,
id: id, id: id,
last: last, status: status,
length: len as u16, length: len as u16,
data: *slice, data: *slice,
}, },

View File

@ -1,6 +1,6 @@
use alloc::{collections::btree_map::BTreeMap, vec::Vec}; use alloc::{collections::btree_map::BTreeMap, vec::Vec};
use libboard_artiq::pl::csr; use libboard_artiq::{drtioaux_proto::PayloadStatus, pl::csr};
use libcortex_a9::cache::dcci_slice; use libcortex_a9::cache::dcci_slice;
const ALIGNMENT: usize = 64; const ALIGNMENT: usize = 64;
@ -50,10 +50,10 @@ impl Manager {
} }
} }
pub fn add(&mut self, id: u32, last: bool, trace: &[u8], trace_len: usize) -> Result<(), Error> { pub fn add(&mut self, id: u32, status: PayloadStatus, trace: &[u8], trace_len: usize) -> Result<(), Error> {
let entry = match self.entries.get_mut(&id) { let entry = match self.entries.get_mut(&id) {
Some(entry) => { Some(entry) => {
if entry.complete { if entry.complete || status.is_first() {
// replace entry // replace entry
self.entries.remove(&id); self.entries.remove(&id);
self.entries.insert( self.entries.insert(
@ -83,7 +83,7 @@ impl Manager {
}; };
entry.trace.extend(&trace[0..trace_len]); entry.trace.extend(&trace[0..trace_len]);
if last { if status.is_last() {
entry.trace.push(0); entry.trace.push(0);
let data_len = entry.trace.len(); let data_len = entry.trace.len();

View File

@ -162,7 +162,7 @@ fn process_aux_packet(
&drtioaux::Packet::SubkernelMessage { &drtioaux::Packet::SubkernelMessage {
destination: destination, destination: destination,
id: kernel_manager.get_current_id().unwrap(), id: kernel_manager.get_current_id().unwrap(),
last: meta.last, status: meta.status,
length: meta.len as u16, length: meta.len as u16,
data: data_slice, data: data_slice,
}, },
@ -494,12 +494,12 @@ fn process_aux_packet(
drtioaux::Packet::DmaAddTraceRequest { drtioaux::Packet::DmaAddTraceRequest {
destination: _destination, destination: _destination,
id, id,
last, status,
length, length,
trace, trace,
} => { } => {
forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer); forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer);
let succeeded = dma_manager.add(id, last, &trace, length as usize).is_ok(); let succeeded = dma_manager.add(id, status, &trace, length as usize).is_ok();
drtioaux::send(0, &drtioaux::Packet::DmaAddTraceReply { succeeded: succeeded }) drtioaux::send(0, &drtioaux::Packet::DmaAddTraceReply { succeeded: succeeded })
} }
drtioaux::Packet::DmaRemoveTraceRequest { drtioaux::Packet::DmaRemoveTraceRequest {
@ -527,12 +527,12 @@ fn process_aux_packet(
drtioaux::Packet::SubkernelAddDataRequest { drtioaux::Packet::SubkernelAddDataRequest {
destination: _destination, destination: _destination,
id, id,
last, status,
length, length,
data, data,
} => { } => {
forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer); forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer);
let succeeded = kernel_manager.add(id, last, &data, length as usize).is_ok(); let succeeded = kernel_manager.add(id, status, &data, length as usize).is_ok();
drtioaux::send(0, &drtioaux::Packet::SubkernelAddDataReply { succeeded: succeeded }) drtioaux::send(0, &drtioaux::Packet::SubkernelAddDataReply { succeeded: succeeded })
} }
drtioaux::Packet::SubkernelLoadRunRequest { drtioaux::Packet::SubkernelLoadRunRequest {
@ -562,7 +562,7 @@ fn process_aux_packet(
drtioaux::send( drtioaux::send(
0, 0,
&drtioaux::Packet::SubkernelException { &drtioaux::Packet::SubkernelException {
last: meta.last, last: meta.status.is_last(),
length: meta.len, length: meta.len,
data: data_slice, data: data_slice,
}, },
@ -571,12 +571,12 @@ fn process_aux_packet(
drtioaux::Packet::SubkernelMessage { drtioaux::Packet::SubkernelMessage {
destination, destination,
id: _id, id: _id,
last, status,
length, length,
data, data,
} => { } => {
forward!(_routing_table, destination, *_rank, _repeaters, &packet, timer); forward!(_routing_table, destination, *_rank, _repeaters, &packet, timer);
kernel_manager.message_handle_incoming(last, length as usize, &data); kernel_manager.message_handle_incoming(status, length as usize, &data);
drtioaux::send( drtioaux::send(
0, 0,
&drtioaux::Packet::SubkernelMessageAck { &drtioaux::Packet::SubkernelMessageAck {
@ -596,7 +596,7 @@ fn process_aux_packet(
&drtioaux::Packet::SubkernelMessage { &drtioaux::Packet::SubkernelMessage {
destination: *_rank, destination: *_rank,
id: kernel_manager.get_current_id().unwrap(), id: kernel_manager.get_current_id().unwrap(),
last: meta.last, status: meta.status,
length: meta.len as u16, length: meta.len as u16,
data: data_slice, data: data_slice,
}, },