gwsystems / composite

A component-based OS

Home Page:composite.seas.gwu.edu

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Possibility of moving retyping facilities to the user level

hungry-foolish opened this issue · comments

Is there any possibility to move the retyping facilities to the user level, and have a trusted user-level component take care of the retyping operations? Each time we retype, we call that component, and the component retypes for us, and the kernel integrity is guaranteed by both the kernel and the user-level component.

Pros:

  • Further simplify the kernel. Something is only tolerated in the kernel if it cannot be moved outside.
  • Different retyping policies can be used, i.e., if some application only allows static allocation, we can ban retyping once and for all, and the complexity of retyping system is completely gone. This is true for embedded applications.

Cons:

  • We need to keep track of the reference counters on pages to know how many times they are mapped in. This may lead to the problem that every map/unmap operation must call the component to update the reference counters. This may be mitigated by amortized operations (each call retypes many pages instead of one), but will hurt microbenchmark.
  • We need to guarantee concurrency and correct stack management, or we risk relying on a unreliable scheduler (and possibly a capability manager).
  • How to keep the integrity of the kernel-user complex is not clear. If it is possible to guarantee kernel integrity by the kernel itself, why involve a user-level component?

@gparmer @WenyuanShao @ryuxin

As I read this, my initial thought was, this is worthless to do at user-level as we'd have more inter-leavings between kernel and user. That would essentially require complex logic or "big kernel locks" kind that beats the whole idea. But, that is not true I think. As I thought about it a little bit further, I realized we have a fixed state-machine that dictate the retyping and simplifies it a lot.

Retyping, I think has a strict state-machine. In my understanding, it goes like this:

KERNEL <-> UNTYPED <-> USER.

Given that, I'd think that it would be fairly easy to push it to the user-level for the most part. Except for changing the actual pgtbl flags (the bits/flags on a pg frame) and updating the pgtbl (cr3 reg).

Plus, because the user-level is by design of Composite responsible for memory management, I'd think it would be fairly straight-forward to handle interleavings between kernel and user in updating the data-structures required for retyping.
The thoughts I presented so far does not consider multi-core execution.

It just makes life slightly more complicated with it, of course. But given that we have a state-machine and that the actual update is going through the kernel, I think we can handle that.
Like you said, unless we're running a system that just deals with dynamic memory and does a whole lot of malloc/free, I don't think it would hurt performance to have locks for handling retyping that will also take care of multi-core. Perhaps this is a big assumption and will come out in the contribution. Like you said, most embedded systems do static allocations and this would work very well there.

Liveness tracking/quiescence tracking are really for resources and not the actual pages (right?), the retyping logic does not necessarily need to worry about that.

All of the map/unmap operations should go through a "memory management" component by design if we dictate it to be. Reference counting of what? Perhaps you mean for like "grant"/"revoke"? If multiple components map (are granted) those pages, I'd think the complexity in managing that chain and revocation would be much better placed at user-level to avoid "unbounded" revocation and the complexity.

IMO this is a good idea and I'm interested in this discussion to gain more knowledge and other perspectives.
I'm sorry to just jump in on a discussion uninvited BTW. :)