New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Server stub INCOMING_SIZE
larger than necessary?
#4
Comments
I fiddled with this a bit more and confirmed the currently-generated server stubs can end up producing unaligned reads, but maybe that's fine? I was experimenting with a In terms of the size, I think that point is still relevant. I have a small patch locally that changes the incoming size in the example above to calculate the max via a const fn max_incoming_size() -> usize {
let mut max = 0;
if max < ENABLE_CLOCK_RAW_MSG_SIZE {
max = ENABLE_CLOCK_RAW_MSG_SIZE;
}
if max < DISABLE_CLOCK_RAW_MSG_SIZE {
max = DISABLE_CLOCK_RAW_MSG_SIZE;
}
if max < ENTER_RESET_RAW_MSG_SIZE {
max = ENTER_RESET_RAW_MSG_SIZE;
}
if max < LEAVE_RESET_RAW_MSG_SIZE {
max = LEAVE_RESET_RAW_MSG_SIZE;
}
max
}
pub const INCOMING_SIZE: usize = max_incoming_size(); Not the nicest |
Ha, nice catch. Yes, this was a braino on my part when writing the server code generation. I'd happily take your patch, that's roughly what I would have written.
Hmmm it really shouldn't be... or, that is, it should be generating careful unaligned reads, because of the use of |
I think "careful unaligned reads" might be what I'm seeing. I created a dummy task with this idol:
and then poked at the internal implementation in the server stub like this: let buf = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
for i in 0..4 {
// force awkward alignment
let buf = &buf[i..i+server_stub::DUMMY1_MSG_SIZE];
// convert to a repr(packed) &Dummy1Args
let args = server_stub::read_dummy1_msg(buf).unwrap();
// read x and y; y will be read unaligned 3/4 times
let x = args.x;
let y = args.y;
sys_log!("x = {:#x}, y = {:#x}", x, y);
} which compiles to this (comments are my notes, which I believe are correct based on gdb register contents): ; r6 = original buf
; r5 = i
=> 0x8020286 <dummy_srv::main+142>: ldrb r0, [r6, r5] ; load args.x
0x8020288 <dummy_srv::main+144>: strb.w r0, [r7, #-49] ; store args.x
0x802028c <dummy_srv::main+148>: adds r0, r6, r5 ; compute address of args.y
0x802028e <dummy_srv::main+150>: str r4, [sp, #32] ; unrelated?
0x8020290 <dummy_srv::main+152>: ldr.w r0, [r0, #1] ; load args.y; this is an unaligned read if r0 % 4 != 3 One thing that concerned me a bit was https://rust-lang.github.io/rfcs/1240-repr-packed-unsafe-ref.html. If anyone were to take a reference to the fields of an
Compiler codegen is outside my area of expertise, but based on reading that RFC I believe (?) that reading a packed structs fields directly is fine, and the compiler should know that it needs to emit instructions suitable for unaligned loads - it's only taking references that's problematic. |
...overzealous Github. Reopening this to discuss the alignment behavior. |
That's right! This is why the args structs are nested inside the functions, to make them difficult to access and use incorrectly.
I was initially surprised by this, but, reading the LLVM ARM backend, it appears that LLVM assumes that Cortex-M targets (other than M0) support misaligned loads/stores. This is kinda true -- they tend to support them by default though they can be disabled at runtime. Presumably if you did that, you'd need to add a target option ( So, I think this is correct. (And I'm pleased, because loading a misaligned |
This is exactly what I didn't know when I opened the issue! :) Agreed everything looks fine. |
Hi folks - I've been fiddling around with hubris on an stm32f4 discovery board, and was trying to update one of my tasks to use idolatry following the changes made to similar tasks in hubris, and ran into a couple questions: should the generated server's
INCOMING_SIZE
be the max of the message sizes instead of the sum, and what is the proper way to handle alignment when declaring a buffer to be given toidol_runtime::dispatch
?Specifically, I was updating a task that's almost identical to stm32h7-rcc based on this commit in hubris; this bit in particular:
The
INCOMING_SIZE
in the generated server stub iswhich makes
buffer
four times larger than it was before (which I believe is unnecessary based on https://github.com/oxidecomputer/idolatry/blob/ec1047c/runtime/src/lib.rs#L154-L161). The comment is also out of date in terms of alignment, but I'm not sure what the right fix is; in my task I tried keepingbuffer
declared as[0u32; 1]
and adding an assertion that its size matchedidl::INCOMING_SIZE
, which is how I bumped into this question.The text was updated successfully, but these errors were encountered: