Skip to content

Added support for endpoint thresholds and budget limits#6

Open
Yermin9 wants to merge 2 commits intomasterfrom
threshold_rfc
Open

Added support for endpoint thresholds and budget limits#6
Yermin9 wants to merge 2 commits intomasterfrom
threshold_rfc

Conversation

@Yermin9
Copy link
Copy Markdown
Owner

@Yermin9 Yermin9 commented Apr 3, 2023

No description provided.

@Indanz
Copy link
Copy Markdown

Indanz commented Nov 16, 2023

Please split the one commit into multiple ones: One for threshold, one for limit, and another one for the new system calls. That makes reviewing a lot easier. The current code needs some cleaning up.

For the threshold check the main costs seems to be updateTimestamp. But if that is done before taking the kernel lock anyway for other reasons, the extra overhead for this feature will be minimal. See discussion of seL4#844. But it depends on what time model MCS is going to use.

I think the fastpath shouldn't use the expensive available_budget_check() call, but only look at the current refill, same as round-robin does.

@Yermin9
Copy link
Copy Markdown
Owner Author

Yermin9 commented Jan 26, 2024

My apologies for taking a while, but I've now split this up into separate commits for Thresholds, Budget Limits and the new System call.

Comment thread include/object/endpoint.h Outdated
void receiveIPC(tcb_t *thread, cap_t cap, bool_t isBlocking, cap_t replyCPtr);
void reorderEP(endpoint_t *epptr, tcb_t *thread);

void setThreshold(endpoint_t * epptr, time_t threshold, bool_t budgetLimit);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

budgetLimit should be part of the other commit.

Comment thread include/object/endpoint.h Outdated
void replyFromKernel_error(tcb_t *thread);
void replyFromKernel_success_empty(tcb_t *thread);

void replyFromKernel_success_empty(tcb_t *thread); No newline at end of file
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please avoid unnecessary whitespace changes like these.

Comment thread libsel4/include/interfaces/sel4.xml Outdated
</error>
</method>

<method id="EndpointSetThreshold" name="Endpoint_SetThreshold" manual_name="Endpoint Set Threshold" manual_label="cnode__endpoint_setThreshold">
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be an endpoint operation, not a cnode operation, that just overly complicates the API for no reason.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, the reason it is implemented as a CNode operation is probably because any invocation on an endpoint is treated as an IPC call, not a syscall.

With that limitation in mind, I think we should make it a reply object property and invocation instead.

Copy link
Copy Markdown

@Indanz Indanz Jul 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reply objects have the same problem as endpoints, all invocations are treated as replies to an IPC call.

With the current kernel syscall+method decoding mess, there is no clean way to add endpoint, reply or notification methods.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you stated, I think I made it a Cnode operation because all endpoint operations are treated as IPC calls.

With the limitations on reply objects as well, what do you suggest?

Comment thread src/fastpath/fastpath.c
Comment on lines +168 to +166
/* Perform addition, checking for overflow as we go */
if (unlikely(getMaxTicksToUs() - NODE_STATE(ksConsumed) < threshold)) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This overflow should be impossible by design, ksConsumed > getMaxTicksToUs() should be impossible.

Comment thread src/object/endpoint.c

#ifdef CONFIG_KERNEL_MCS
void setThreshold(endpoint_t * epptr, time_t threshold, bool_t budgetLimit) {
/* Add the kernel WCET to the passed threshold value, unless we were passed 0*/
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment is in the wrong place, but why add WCET? A fastpath invocation should take nowhere near WCET time.

I'd assure that the threshold is at least WCET instead. Users need to measure the call time to tweak this setting anyway, don't make it harder by changing the value randomly.

Comment thread src/object/objecttype.c
commitTime();

/* Yield and wait for sufficient budget */
if(!merge_until_budget(NODE_STATE(ksCurThread)->tcbSchedContext,endpoint_ptr_get_epThreshold(ep_ptr) + 2u * getKernelWcetTicks())) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't add WCET everywhere please. The threshold value should be twice WCET already.

Please write a test for sel4test that checks that the budget works as expected and use that to test your implementation. E.g. configure a task with a certain budget/period and check if IPC calls fail and succeed when they should.

Comment thread src/api/syscall.c
Comment on lines +332 to +341
/* The EXCEPTION_NONE_THRESHOLD_RESTART check is necessary,
* because for IPC threshold behaviour, we actually do want to set ThreadState_Restart
*/
if (unlikely(
thread_state_get_tsType(thread->tcbState) == ThreadState_Restart)) {
thread_state_get_tsType(thread->tcbState) == ThreadState_Restart
&& status != EXCEPTION_NONE_THRESHOLD_RESTART
)) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original code was already obtuse, but with this change it gets even harder to understand what's happening.

It would make more sense if the code that sets the task to ThreadState_Restart would set it to ThreadState_Running instead if that's what's wanted (and also call replyFromKernel_success_empty()). Then this code can be removed altogether.

@Indanz
Copy link
Copy Markdown

Indanz commented Jan 26, 2024

My apologies for taking a while, but I've now split this up into separate commits for Thresholds, Budget Limits and the new System call.

No problem and thanks.

I recommend focussing on the threshold feature first and leaving the others for now, or have them in a separate PR to ease review. At least I'm ignoring the limit and new syscall features, because I don't agree with them.

@Yermin9
Copy link
Copy Markdown
Owner Author

Yermin9 commented Jul 29, 2025

I should have the time now to follow this through.
I've started by rebasing onto master, discarded the budgetLimit commits and removed any stray budgetLimit references.

@Indanz
Copy link
Copy Markdown

Indanz commented Jul 29, 2025

I should have the time now to follow this through. I've started by rebasing onto master, discarded the budgetLimit commits and removed any stray budgetLimit references.

I'm working on a simplified version at the moment, so don't spend too much time on it. Should have something up this week. Trying to keep the good bits of your commits though and would greatly appreciate your feedback. There's probably a reason for everything you did, which I don't know, so I might be oversimplifying things too much.

As you stated, I think I made it a Cnode operation because all endpoint operations are treated as IPC calls.
With the limitations on reply objects as well, what do you suggest?

If people didn't spend decades verifying the current code, I'd suggest to cleanup the syscall/invocation decoding code to something less messy and horrible. Then there would be no assumptions on which objects which syscalls are done, and adding a new invocation would be easy without slowing down everything else.

As it is, I think I prefer either an endpoint or Reply invocation that requires both an endpoint and Reply cap. Then we can use the permissions on the reply cap to limit this call, as you would need something like read permission for the endpoint and write for the reply. Wherever I put it, it will slow down everything, but hopefully it can be limited to one extra if-check in a slow path somewhere.

The other gnarl is how to bypass handleInvocation's trailing code messing things up.

@Indanz
Copy link
Copy Markdown

Indanz commented Jul 30, 2025

WIP can be found at: Indanz#2

Early version, haven't compiled it yet. I went for making it a reply invocation as I can do a quick check on the call argument, limiting the damage. This check can be avoided altogether for the fastpath, as the fastpath only handles endpoint calls and ReplyRecv syscalls.

I fixed some other problems by improving the mainline kernel, not sure if that's being too optimistic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants