forked from M-Labs/artiq
run idle kernel on flash
This commit is contained in:
parent
468ace0e6d
commit
ea0a8a99d3
|
@ -29,9 +29,10 @@ extern crate riscv;
|
||||||
extern crate tar_no_std;
|
extern crate tar_no_std;
|
||||||
|
|
||||||
use alloc::collections::BTreeMap;
|
use alloc::collections::BTreeMap;
|
||||||
use core::cell::RefCell;
|
use core::cell::{RefCell, Cell};
|
||||||
use core::convert::TryFrom;
|
use core::convert::TryFrom;
|
||||||
use smoltcp::wire::HardwareAddress;
|
use smoltcp::wire::HardwareAddress;
|
||||||
|
use urc::Urc;
|
||||||
|
|
||||||
use board_misoc::{csr, ident, clock, spiflash, config, net_settings, pmp, boot};
|
use board_misoc::{csr, ident, clock, spiflash, config, net_settings, pmp, boot};
|
||||||
#[cfg(has_ethmac)]
|
#[cfg(has_ethmac)]
|
||||||
|
@ -196,6 +197,7 @@ fn startup() {
|
||||||
|
|
||||||
let ddma_mutex = sched::Mutex::new();
|
let ddma_mutex = sched::Mutex::new();
|
||||||
let subkernel_mutex = sched::Mutex::new();
|
let subkernel_mutex = sched::Mutex::new();
|
||||||
|
let restart_idle = Urc::new(Cell::new(false));
|
||||||
|
|
||||||
let mut scheduler = sched::Scheduler::new(interface);
|
let mut scheduler = sched::Scheduler::new(interface);
|
||||||
let io = scheduler.io();
|
let io = scheduler.io();
|
||||||
|
@ -205,15 +207,18 @@ fn startup() {
|
||||||
}
|
}
|
||||||
|
|
||||||
rtio_mgt::startup(&io, &aux_mutex, &drtio_routing_table, &up_destinations, &ddma_mutex, &subkernel_mutex);
|
rtio_mgt::startup(&io, &aux_mutex, &drtio_routing_table, &up_destinations, &ddma_mutex, &subkernel_mutex);
|
||||||
|
{
|
||||||
io.spawn(4096, mgmt::thread);
|
let restart_idle = restart_idle.clone();
|
||||||
|
io.spawn(4096, move |io| { mgmt::thread(io, &restart_idle) });
|
||||||
|
}
|
||||||
{
|
{
|
||||||
let aux_mutex = aux_mutex.clone();
|
let aux_mutex = aux_mutex.clone();
|
||||||
let drtio_routing_table = drtio_routing_table.clone();
|
let drtio_routing_table = drtio_routing_table.clone();
|
||||||
let up_destinations = up_destinations.clone();
|
let up_destinations = up_destinations.clone();
|
||||||
let ddma_mutex = ddma_mutex.clone();
|
let ddma_mutex = ddma_mutex.clone();
|
||||||
let subkernel_mutex = subkernel_mutex.clone();
|
let subkernel_mutex = subkernel_mutex.clone();
|
||||||
io.spawn(32768, move |io| { session::thread(io, &aux_mutex, &drtio_routing_table, &up_destinations, &ddma_mutex, &subkernel_mutex) });
|
let restart_idle = restart_idle.clone();
|
||||||
|
io.spawn(32768, move |io| { session::thread(io, &aux_mutex, &drtio_routing_table, &up_destinations, &ddma_mutex, &subkernel_mutex, &restart_idle) });
|
||||||
}
|
}
|
||||||
#[cfg(any(has_rtio_moninj, has_drtio))]
|
#[cfg(any(has_rtio_moninj, has_drtio))]
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
use log::{self, LevelFilter};
|
use log::{self, LevelFilter};
|
||||||
|
use core::cell::Cell;
|
||||||
|
|
||||||
use io::{Write, ProtoWrite, Error as IoError};
|
use io::{Write, ProtoWrite, Error as IoError};
|
||||||
use board_misoc::{config, spiflash};
|
use board_misoc::{config, spiflash};
|
||||||
use logger_artiq::BufferLogger;
|
use logger_artiq::BufferLogger;
|
||||||
use mgmt_proto::*;
|
use mgmt_proto::*;
|
||||||
use sched::{Io, TcpListener, TcpStream, Error as SchedError};
|
use sched::{Io, TcpListener, TcpStream, Error as SchedError};
|
||||||
|
use urc::Urc;
|
||||||
|
|
||||||
impl From<SchedError> for Error<SchedError> {
|
impl From<SchedError> for Error<SchedError> {
|
||||||
fn from(value: SchedError) -> Error<SchedError> {
|
fn from(value: SchedError) -> Error<SchedError> {
|
||||||
|
@ -12,7 +14,7 @@ impl From<SchedError> for Error<SchedError> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn worker(io: &Io, stream: &mut TcpStream) -> Result<(), Error<SchedError>> {
|
fn worker(io: &Io, stream: &mut TcpStream, restart_idle: &Urc<Cell<bool>>) -> Result<(), Error<SchedError>> {
|
||||||
read_magic(stream)?;
|
read_magic(stream)?;
|
||||||
Write::write_all(stream, "e".as_bytes())?;
|
Write::write_all(stream, "e".as_bytes())?;
|
||||||
info!("new connection from {}", stream.remote_endpoint());
|
info!("new connection from {}", stream.remote_endpoint());
|
||||||
|
@ -84,7 +86,13 @@ fn worker(io: &Io, stream: &mut TcpStream) -> Result<(), Error<SchedError>> {
|
||||||
}
|
}
|
||||||
Request::ConfigWrite { ref key, ref value } => {
|
Request::ConfigWrite { ref key, ref value } => {
|
||||||
match config::write(key, value) {
|
match config::write(key, value) {
|
||||||
Ok(_) => Reply::Success.write_to(stream),
|
Ok(_) => {
|
||||||
|
if key == "idle_kernel" {
|
||||||
|
io.until(|| !restart_idle.get())?;
|
||||||
|
restart_idle.set(true);
|
||||||
|
}
|
||||||
|
Reply::Success.write_to(stream)
|
||||||
|
},
|
||||||
Err(_) => Reply::Error.write_to(stream)
|
Err(_) => Reply::Error.write_to(stream)
|
||||||
}?;
|
}?;
|
||||||
}
|
}
|
||||||
|
@ -117,16 +125,17 @@ fn worker(io: &Io, stream: &mut TcpStream) -> Result<(), Error<SchedError>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn thread(io: Io) {
|
pub fn thread(io: Io, restart_idle: &Urc<Cell<bool>>) {
|
||||||
let listener = TcpListener::new(&io, 8192);
|
let listener = TcpListener::new(&io, 8192);
|
||||||
listener.listen(1380).expect("mgmt: cannot listen");
|
listener.listen(1380).expect("mgmt: cannot listen");
|
||||||
info!("management interface active");
|
info!("management interface active");
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let stream = listener.accept().expect("mgmt: cannot accept").into_handle();
|
let stream = listener.accept().expect("mgmt: cannot accept").into_handle();
|
||||||
|
let restart_idle = restart_idle.clone();
|
||||||
io.spawn(4096, move |io| {
|
io.spawn(4096, move |io| {
|
||||||
let mut stream = TcpStream::from_handle(&io, stream);
|
let mut stream = TcpStream::from_handle(&io, stream);
|
||||||
match worker(&io, &mut stream) {
|
match worker(&io, &mut stream, &restart_idle) {
|
||||||
Ok(()) => (),
|
Ok(()) => (),
|
||||||
Err(Error::Io(IoError::UnexpectedEnd)) => (),
|
Err(Error::Io(IoError::UnexpectedEnd)) => (),
|
||||||
Err(err) => error!("aborted: {}", err)
|
Err(err) => error!("aborted: {}", err)
|
||||||
|
|
|
@ -839,7 +839,7 @@ fn flash_kernel_worker(io: &Io, aux_mutex: &Mutex,
|
||||||
routing_table: &drtio_routing::RoutingTable,
|
routing_table: &drtio_routing::RoutingTable,
|
||||||
up_destinations: &Urc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
up_destinations: &Urc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
||||||
ddma_mutex: &Mutex, subkernel_mutex: &Mutex, congress: &mut Congress,
|
ddma_mutex: &Mutex, subkernel_mutex: &Mutex, congress: &mut Congress,
|
||||||
config_key: &str) -> Result<(), Error<SchedError>> {
|
config_key: &str, restart_idle: Option<&Urc<Cell<bool>>>) -> Result<(), Error<SchedError>> {
|
||||||
let mut session = Session::new(congress);
|
let mut session = Session::new(congress);
|
||||||
|
|
||||||
config::read(config_key, |result| {
|
config::read(config_key, |result| {
|
||||||
|
@ -859,12 +859,17 @@ fn flash_kernel_worker(io: &Io, aux_mutex: &Mutex,
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
kern_run(&mut session)?;
|
kern_run(&mut session)?;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if !rpc_queue::empty() {
|
if !rpc_queue::empty() {
|
||||||
unexpected!("unexpected background RPC in flash kernel")
|
unexpected!("unexpected background RPC in flash kernel")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(r_idle) = restart_idle {
|
||||||
|
if r_idle.get() {
|
||||||
|
return Err(Error::KernelNotFound)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if mailbox::receive() != 0 {
|
if mailbox::receive() != 0 {
|
||||||
if process_kern_message(io, aux_mutex, routing_table, up_destinations, ddma_mutex, subkernel_mutex, None, &mut session)? {
|
if process_kern_message(io, aux_mutex, routing_table, up_destinations, ddma_mutex, subkernel_mutex, None, &mut session)? {
|
||||||
return Ok(())
|
return Ok(())
|
||||||
|
@ -897,7 +902,7 @@ fn respawn<F>(io: &Io, handle: &mut Option<ThreadHandle>, f: F)
|
||||||
pub fn thread(io: Io, aux_mutex: &Mutex,
|
pub fn thread(io: Io, aux_mutex: &Mutex,
|
||||||
routing_table: &Urc<RefCell<drtio_routing::RoutingTable>>,
|
routing_table: &Urc<RefCell<drtio_routing::RoutingTable>>,
|
||||||
up_destinations: &Urc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
up_destinations: &Urc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
||||||
ddma_mutex: &Mutex, subkernel_mutex: &Mutex) {
|
ddma_mutex: &Mutex, subkernel_mutex: &Mutex, restart_idle: &Urc<Cell<bool>>) {
|
||||||
let listener = TcpListener::new(&io, 65535);
|
let listener = TcpListener::new(&io, 65535);
|
||||||
listener.listen(1381).expect("session: cannot listen");
|
listener.listen(1381).expect("session: cannot listen");
|
||||||
info!("accepting network sessions");
|
info!("accepting network sessions");
|
||||||
|
@ -910,7 +915,7 @@ pub fn thread(io: Io, aux_mutex: &Mutex,
|
||||||
let mut congress = congress.borrow_mut();
|
let mut congress = congress.borrow_mut();
|
||||||
info!("running startup kernel");
|
info!("running startup kernel");
|
||||||
match flash_kernel_worker(&io, &aux_mutex, &routing_table, &up_destinations,
|
match flash_kernel_worker(&io, &aux_mutex, &routing_table, &up_destinations,
|
||||||
ddma_mutex, subkernel_mutex, &mut congress, "startup_kernel") {
|
ddma_mutex, subkernel_mutex, &mut congress, "startup_kernel", None) {
|
||||||
Ok(()) =>
|
Ok(()) =>
|
||||||
info!("startup kernel finished"),
|
info!("startup kernel finished"),
|
||||||
Err(Error::KernelNotFound) =>
|
Err(Error::KernelNotFound) =>
|
||||||
|
@ -994,11 +999,13 @@ pub fn thread(io: Io, aux_mutex: &Mutex,
|
||||||
let congress = congress.clone();
|
let congress = congress.clone();
|
||||||
let ddma_mutex = ddma_mutex.clone();
|
let ddma_mutex = ddma_mutex.clone();
|
||||||
let subkernel_mutex = subkernel_mutex.clone();
|
let subkernel_mutex = subkernel_mutex.clone();
|
||||||
|
let restart_idle = restart_idle.clone();
|
||||||
|
restart_idle.set(false);
|
||||||
respawn(&io, &mut kernel_thread, move |io| {
|
respawn(&io, &mut kernel_thread, move |io| {
|
||||||
let routing_table = routing_table.borrow();
|
let routing_table = routing_table.borrow();
|
||||||
let mut congress = congress.borrow_mut();
|
let mut congress = congress.borrow_mut();
|
||||||
match flash_kernel_worker(&io, &aux_mutex, &routing_table, &up_destinations,
|
match flash_kernel_worker(&io, &aux_mutex, &routing_table, &up_destinations,
|
||||||
&ddma_mutex, &subkernel_mutex, &mut *congress, "idle_kernel") {
|
&ddma_mutex, &subkernel_mutex, &mut *congress, "idle_kernel", Some(&restart_idle)) {
|
||||||
Ok(()) =>
|
Ok(()) =>
|
||||||
info!("idle kernel finished, standing by"),
|
info!("idle kernel finished, standing by"),
|
||||||
Err(Error::Protocol(host::Error::Io(
|
Err(Error::Protocol(host::Error::Io(
|
||||||
|
@ -1010,7 +1017,9 @@ pub fn thread(io: Io, aux_mutex: &Mutex,
|
||||||
}
|
}
|
||||||
Err(Error::KernelNotFound) => {
|
Err(Error::KernelNotFound) => {
|
||||||
info!("no idle kernel found");
|
info!("no idle kernel found");
|
||||||
while io.relinquish().is_ok() {}
|
loop {
|
||||||
|
if !io.relinquish().is_ok() || restart_idle.get() { break; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("idle kernel aborted: {}", err);
|
error!("idle kernel aborted: {}", err);
|
||||||
|
|
Loading…
Reference in New Issue