Re: mapping pages into new address spaces
Joshua Haberman <[email protected]>
| Newsgroups | gmane.comp.micro-kernel.l4.l4ka.general |
|---|---|
| Message-ID | <[email protected]> |
On Mon, Sep 11, 2006 at 01:54:45PM +0200, Espen Skoglund wrote: > [Joshua Haberman] > > What I am proposing is to make the second case more like the first. > > Make all MapItem/GrantItem IPCs that come from a thread's pager > > behave like IPCs sent in response to page faults, namely: > > > 1. they are not subject to a thread's acceptor > > 2. they automatically take effect without being explicitly received > > In effect, what you're proposing is to add some special case where L4 > IPC is no longer synchronous. L4 IPC is synchronous for a good > reason. It is *the* major reason why IPC can be implemented > efficiently. Introducing such asynch IPCs also opens up a whole can > of worms in the implementation itself, not to mention the mess you > make out of the API specification. Just treat the pagefault protocol > as regular IPCs. Avoid special cases. This gives you the simplest > and most efficient implementation. I strongly agree with all of this. Synchronous IPC, good performance, a a good API specification, and a lack of special cases are exactly the things that I like about L4. I didn't think of my suggestion as asking for asynchronous IPC, but when you describe it that way, I can see why it is the case. Let's start from scratch and forget what I suggested. There is still what I would consider a small but important gap in the current API. There is no way for a pager to proactively (ie. not in response to a page fault) map pages into the address space of one of its threads in a way that: 1. is not subject to the thread's acceptor 2. can complete even if the thread is not waiting for an IPC Compare this with unmapping. A thread can unmap at any time using the Unmap system call. The target threads are not involved. Why shouldn't there be a similar system call for mapping? There may be cases where it is important to prevent page faults by mapping memory in advance. Performance is one reason, but there could be other scenarios as well. Imagine that you want a pager to manage its own memory space. It could obtain memory by commanding the thread that actually has the memory to map pages. This pager must never fault, because its pager (the dumb program that maps on command) doesn't have the page tables. > > The one downside of this is that it counts on the thread to set its > > acceptor properly, or the pager's fpage will go to the wrong place. > > It seems like a pager should have complete control over its threads' > > address spaces, and be able to map things wherever it wants, > > whenever it wants to. > > If the thread sets its acceptor to the entire address space, how can > the pager's fpage go to the wrong place? If the programmer is not > able to set the acceptor to L4_CompleteAddressSpace then he should > seriously consider to take up gardening, news reporting, accounting, > or some such instead. This isn't about programmers and their talent, it is about division of responsibility in an inter-process protocol. I want my pager to expose an interface to its constituent threads that lets them request memory. I want to be able to guarantee that this memory is mapped before the call returns, and will not generate page faults. But my threads do not want to accept mappings into this region from just any process, only their pager. To provide this using the current API, I must require my clients to set and reset their acceptor every time they call this memory allocation API. If they do not do this, their request will be fulfilled incorrectly. This makes my API less robust. I don't think you would accept publishing APIs to L4 itself that said something like "you must save your UTCB before the call, overwrite it with X, and restore it after the call returns." In the same way, I don't want to put a requirement like this on the interface I expose to my clients. Josh