Skip to content

Commit

Permalink
Initial kernel-side pager prep (#232)
Browse files Browse the repository at this point in the history
* Working on pager.

* Fix stalling bugs in queue.

* Remove some debug code.

* Working on pager inflight tracking.

* Fix build after rebase.
  • Loading branch information
dbittman authored Jan 3, 2025
1 parent 72babc2 commit c98c41b
Show file tree
Hide file tree
Showing 23 changed files with 545 additions and 159 deletions.
10 changes: 7 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/bin/netmgr/src/client_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub async fn handle_client_request(
handle: &HandleRef,
id: u32,
request: TxRequest,
) -> Result<(), QueueError> {
) -> Result<(), std::io::Error> {
println!("got txreq {:?}", request);
let reply = match request {
TxRequest::Echo(incoming_data) => {
Expand Down
5 changes: 4 additions & 1 deletion src/bin/pager/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@ edition = "2021"
twizzler-abi = { path = "../../lib/twizzler-abi" }
twizzler-object = { path = "../../lib/twizzler-object" }
twizzler-queue = { path = "../../lib/twizzler-queue" }
twizzler-async = { path = "../../lib/twizzler-async" }
#twizzler-async = { path = "../../lib/twizzler-async" }
twizzler-driver = { path = "../../lib/twizzler-driver" }
twizzler-runtime = { path = "../../rt" }
nvme = { path = "../../lib/nvme-rs" }
tickv = { version = "1.0.0" }
async-trait = "0.1.66"
volatile = "0.5"
async-io = "*"
async-executor = "*"
futures = "*"
28 changes: 18 additions & 10 deletions src/bin/pager/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use std::{collections::BTreeMap, time::Duration};
use std::{collections::BTreeMap, sync::OnceLock, time::Duration};

use async_executor::{Executor, Task};
use async_io::Timer;
use futures::executor::block_on;
use tickv::{success_codes::SuccessCode, ErrorCode};
use twizzler_abi::pager::{
CompletionToKernel, CompletionToPager, KernelCompletionData, RequestFromKernel,
Expand All @@ -23,6 +26,8 @@ struct Foo {
}

extern crate twizzler_runtime;
pub static EXECUTOR: OnceLock<Executor> = OnceLock::new();

fn main() {
let idstr = std::env::args().nth(1).unwrap();
let kidstr = std::env::args().nth(2).unwrap();
Expand Down Expand Up @@ -52,38 +57,41 @@ fn main() {
let kqueue = twizzler_queue::Queue::<RequestFromPager, CompletionToPager>::from(kobject);
let sq = twizzler_queue::QueueSender::new(kqueue);

let ex = EXECUTOR.get_or_init(|| Executor::new());

let num_threads = 2;
for _ in 0..(num_threads - 1) {
std::thread::spawn(|| twizzler_async::run(std::future::pending::<()>()));
std::thread::spawn(|| block_on(ex.run(std::future::pending::<()>())));
}

twizzler_async::Task::spawn(async move {
ex.spawn(async move {
loop {
let timeout = twizzler_async::Timer::after(Duration::from_millis(1000));
println!("pager submitting request");
let timeout = Timer::after(Duration::from_millis(1000));
println!(" pager: submitting request");
let res = sq.submit_and_wait(RequestFromPager::new(
twizzler_abi::pager::PagerRequest::EchoReq,
));
let x = res.await;
println!("pager got {:?} in response", x);
println!(" pager: got {:?} in response", x);
timeout.await;
break;
// TODO: do some other stuff?
std::future::pending::<()>().await;
}
})
.detach();

twizzler_async::Task::spawn(async move {
ex.spawn(async move {
loop {
let (id, request) = rq.receive().await.unwrap();
println!("got req from kernel: {} {:?}", id, request);
println!(" pager: got req from kernel: {} {:?}", id, request);
let reply = handle_request(request).await;
if let Some(reply) = reply {
rq.complete(id, reply).await.unwrap();
}
}
})
.detach();
twizzler_async::run(std::future::pending::<()>());
block_on(ex.run(std::future::pending::<()>()));
}

static mut RAND_STATE: u32 = 0;
Expand Down
4 changes: 2 additions & 2 deletions src/bin/pager/src/nvme/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::{
sync::{Arc, Mutex, OnceLock, RwLock},
};

use async_executor::Task;
use nvme::{
admin::{CreateIOCompletionQueue, CreateIOSubmissionQueue},
ds::{
Expand All @@ -16,7 +17,6 @@ use nvme::{
hosted::memory::{PhysicalPageCollection, PrpMode},
nvm::{ReadDword13, WriteDword13},
};
use twizzler_async::Task;
use twizzler_driver::{
dma::{DmaOptions, DmaPool, DMA_PAGE_SIZE},
request::{Requester, SubmitRequest, SubmitSummaryWithResponses},
Expand Down Expand Up @@ -144,7 +144,7 @@ pub async fn init_controller(ctrl: &mut Arc<NvmeController>) {

let req2 = req.clone();
let ctrl2 = ctrl.clone();
let task = Task::spawn(async move {
let task = super::super::EXECUTOR.get().unwrap().spawn(async move {
loop {
let _i = int.next().await;
//println!("got interrupt");
Expand Down
7 changes: 4 additions & 3 deletions src/bin/pager/src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::{
sync::Arc,
};

use futures::executor::block_on;
use tickv::{success_codes::SuccessCode, ErrorCode, FlashController};
use twizzler_object::ObjID;

Expand All @@ -32,7 +33,7 @@ impl FlashController<BLOCK_SIZE> for Storage {
offset: usize,
buf: &mut [u8; BLOCK_SIZE],
) -> Result<(), tickv::ErrorCode> {
twizzler_async::block_on(self.nvme.read_page(region_number as u64 * 8, buf, offset))
block_on(self.nvme.read_page(region_number as u64 * 8, buf, offset))
.map_err(|_| tickv::ErrorCode::ReadFail)
}

Expand All @@ -42,7 +43,7 @@ impl FlashController<BLOCK_SIZE> for Storage {
let start = (address / BLOCK_SIZE) * SECTORS_TO_BLOCK;
let thislen = min(BLOCK_SIZE - offset, buf.len());

twizzler_async::block_on(self.nvme.write_page(start as u64, &buf[0..thislen], offset))
block_on(self.nvme.write_page(start as u64, &buf[0..thislen], offset))
.map_err(|_| tickv::ErrorCode::WriteFail)?;

buf = &buf[thislen..buf.len()];
Expand All @@ -52,7 +53,7 @@ impl FlashController<BLOCK_SIZE> for Storage {
}

fn erase_region(&self, region_number: usize) -> Result<(), tickv::ErrorCode> {
twizzler_async::block_on(self.nvme.write_page(
block_on(self.nvme.write_page(
(region_number * SECTORS_TO_BLOCK) as u64,
&[0xffu8; BLOCK_SIZE],
0,
Expand Down
1 change: 1 addition & 0 deletions src/kernel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ limine = "0.2.0"
twizzler-queue-raw = { version = "*", path = "../lib/twizzler-queue-raw", default-features = false }
#syscall_encode = { version = "0.1.2" }
volatile = "0.5"
stable-vec = { version = "0.4", default-features = false, features = [] }
# for crypto
p256 = { version = "0.13.2", default-features = false, features = ["ecdsa"] }
log = "*"
Expand Down
9 changes: 8 additions & 1 deletion src/kernel/src/condvar.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use alloc::vec::Vec;

use intrusive_collections::{intrusive_adapter, KeyAdapter, RBTree};
use twizzler_abi::{object::ObjID, thread::ExecutionState};

Expand Down Expand Up @@ -65,7 +67,13 @@ impl CondVar {
pub fn signal(&self) {
let mut inner = self.inner.lock();
let mut node = inner.queue.front_mut();
let mut threads_to_wake = Vec::new();
while let Some(t) = node.remove() {
threads_to_wake.push(t);
}

drop(inner);
for t in threads_to_wake {
schedule_thread(t);
}
}
Expand Down Expand Up @@ -96,7 +104,6 @@ mod tests {

#[kernel_test]
fn test_condvar() {
//logln!("a: {}", crate::interrupt::disable());
let lock = Arc::new(Spinlock::new(0));
let cv = Arc::new(CondVar::new());
let cv2 = cv.clone();
Expand Down
11 changes: 11 additions & 0 deletions src/kernel/src/idcounter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,17 @@ impl SimpleId {
}
}

impl From<u32> for SimpleId {
fn from(value: u32) -> Self {
Self { id: value as u64 }
}
}
impl From<u64> for SimpleId {
fn from(value: u64) -> Self {
Self { id: value }
}
}

impl IdCounter {
pub const fn new() -> Self {
Self {
Expand Down
26 changes: 0 additions & 26 deletions src/kernel/src/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -388,29 +388,3 @@ macro_rules! emerglogln {
$crate::emerglog!(concat!($fmt, "\n"), $($arg)*)
};
}

use log::{Level, Metadata, Record};

struct SimpleLogger;

impl log::Log for SimpleLogger {
fn enabled(&self, metadata: &Metadata) -> bool {
metadata.level() <= Level::Info
}

fn log(&self, record: &Record) {
if self.enabled(record.metadata()) {
logln!("{} - {}", record.level(), record.args());
}
}

fn flush(&self) {}
}

use log::{LevelFilter, SetLoggerError};

static LOGGER: SimpleLogger = SimpleLogger;

pub fn init() {
let _ = log::set_logger(&LOGGER).map(|()| log::set_max_level(LevelFilter::Info));
}
12 changes: 10 additions & 2 deletions src/kernel/src/machine/pc/serial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ impl SerialPort {
// Enable DLAB
self.write_reg(Self::LINE_CTRL, 0x80);

// Set maximum speed to 38400 bps by configuring DLL and DLM
self.write_reg(Self::DATA, 0x03);
// Set maximum speed to 115200 bps by configuring DLL and DLM
self.write_reg(Self::DATA, 0x01);
self.write_reg(Self::INT_EN, 0x00);

// Disable DLAB and set data word length to 8 bits
Expand Down Expand Up @@ -193,6 +193,11 @@ lazy_static! {
serial_port.init();
SimpleLock::new(serial_port)
};
static ref SERIAL2: SimpleLock<SerialPort> = {
let mut serial_port = unsafe { SerialPort::new(0x2f8) };
serial_port.init();
SimpleLock::new(serial_port)
};
}

pub fn late_init() {
Expand Down Expand Up @@ -225,5 +230,8 @@ pub fn write(data: &[u8], _flags: crate::log::KernelConsoleWriteFlags) {
let _ = SERIAL1
.lock()
.write_str(core::str::from_utf8_unchecked(data));
let _ = SERIAL2
.lock()
.write_str(core::str::from_utf8_unchecked(data));
}
}
1 change: 0 additions & 1 deletion src/kernel/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ pub fn is_test_mode() -> bool {

fn kernel_main<B: BootInfo>(boot_info: &mut B) -> ! {
arch::init(boot_info);
log::init();
logln!("[kernel] boot with cmd `{}'", boot_info.get_cmd_line());
let cmdline = boot_info.get_cmd_line();
for opt in cmdline.split(" ") {
Expand Down
Loading

0 comments on commit c98c41b

Please sign in to comment.