[Solved] Keeping shared memory in-sync
Posted: Sat Jul 04, 2020 5:55 am
Hello!
I'm in the process of rewriting my virtual memory manager and have run into a hang-up.
Each address space is composed of a page-directory and a bitmap describing allocated pages. Each address-space shares the page tables that identity-map low memory, kernel data+code, kernel ELF sections, etc. Memory is allocated on a first-fit basis, so it's reasonable for an allocation to be fulfilled in a globally shared page table.
If a process allocates memory within one of these globally-shared-tables, then every process will then receive the updated state in the shared page tables. However, only the process that fulfilled the allocation would have the memory marked in its allocation bitmap.
I was banging my head against this for a few days after seeing mismatched states between a process's page-tables and allocation bitmap until I realized what was going on. For now, on task switch, I iterate the shared tables and ensure nothing is out-of-sync, and panic if it is.
I'm trying to come up with a clean way to signal allocations to a shared table, so that every process that shares the table can mark the pages as allocated in its bitmap. A few ideas:
- Each VAS never allocates memory within a shared table unless specifically requested. This seems like punting the problem until future-me needs some shared buffer between processes.
- Within the shared kernel memory, maintain a linked-list of VAS's that refer to shared page tables. Whenever an allocation is fulfilled within a shared page table, iterate each VAS, map in the VAS structure somewhere, and update its allocation bitmap. This seems to require quite a lot of state about which page tables are shared by which VAS. This update could alternatively be performed on a task switch, or when a mismatched allocation state is detected between the page tables and allocation bitmap.
- Within the shared kernel memory, maintain a pointer to the "latest" VAS containing modifications to the shared kernel tables. When an allocation is fulfilled in a shared page table, update the pointer to the VAS that fulfilled the allocation. On task switch (or w/e), update the allocation state to match that of the "latest" VAS's shared tables. This seems fine, but seems to be special-casing the shared kernel memory. It'd be nice if the approach worked for general-purpose IPC shared-memory.
I'm sure this is trod-ground and am curious if anyone has an approach they can share. Thanks!
I'm in the process of rewriting my virtual memory manager and have run into a hang-up.
Each address space is composed of a page-directory and a bitmap describing allocated pages. Each address-space shares the page tables that identity-map low memory, kernel data+code, kernel ELF sections, etc. Memory is allocated on a first-fit basis, so it's reasonable for an allocation to be fulfilled in a globally shared page table.
If a process allocates memory within one of these globally-shared-tables, then every process will then receive the updated state in the shared page tables. However, only the process that fulfilled the allocation would have the memory marked in its allocation bitmap.
I was banging my head against this for a few days after seeing mismatched states between a process's page-tables and allocation bitmap until I realized what was going on. For now, on task switch, I iterate the shared tables and ensure nothing is out-of-sync, and panic if it is.
I'm trying to come up with a clean way to signal allocations to a shared table, so that every process that shares the table can mark the pages as allocated in its bitmap. A few ideas:
- Each VAS never allocates memory within a shared table unless specifically requested. This seems like punting the problem until future-me needs some shared buffer between processes.
- Within the shared kernel memory, maintain a linked-list of VAS's that refer to shared page tables. Whenever an allocation is fulfilled within a shared page table, iterate each VAS, map in the VAS structure somewhere, and update its allocation bitmap. This seems to require quite a lot of state about which page tables are shared by which VAS. This update could alternatively be performed on a task switch, or when a mismatched allocation state is detected between the page tables and allocation bitmap.
- Within the shared kernel memory, maintain a pointer to the "latest" VAS containing modifications to the shared kernel tables. When an allocation is fulfilled in a shared page table, update the pointer to the VAS that fulfilled the allocation. On task switch (or w/e), update the allocation state to match that of the "latest" VAS's shared tables. This seems fine, but seems to be special-casing the shared kernel memory. It'd be nice if the approach worked for general-purpose IPC shared-memory.
I'm sure this is trod-ground and am curious if anyone has an approach they can share. Thanks!