On-Demand Paging

>>> Under Construction <<<

Last Updated: August 12, 2010



Table of Contents

Terminolgy
Initialization
Page Faults
Fill Initiation
Fill Complete
Task Resumption

Terminolgy

g_waitingforfill
An OS list that is used to hold the TCBs of tasks that are waiting for a page fill.
g_pendingfill
A variable that holds a reference to the TCB of the thread that is currently be re-filled.
g_pgworker
The process ID of of the thread that will perform the page fills.
pg_callback()
The callback function that is invoked from a driver when the fill is complete.
pg_miss()
The function that is called from chip-specific code to handle a page fault.
TCB
Task Control Block

Initialization

The following declarations will be added.

During OS initialization in sched/os_start.c, the following steps will be performed:

Declarations for g_waitingforfill, g_pgworker, and other internal, private definitions will be provided in sched/pg_internal.h. All public definitions that should be used by the chip-specific code will be available in include/nuttx/page.h and include/nuttx/arch.h.

Page Faults

Page fault exception handling. Page fault handling is performed by the function pg_miss(). This function is called from architecture-specific memory segmentation fault handling logic. This function will perform the following operations:

  1. Sanity checking. This function will ASSERT if the currently executing task is the page fill worker thread. The page fill worker thread is how the the page fault is resolved and all logic associated with the page fill worker must be "locked" and always present in memory.
  2. Block the currently executing task. This function will call up_block_task() to block the task at the head of the ready-to-run list. This should cause an interrupt level context switch to the next highest priority task. The blocked task will be marked with state TSTATE_WAIT_PAGEFILL and will be retained in the g_waitingforfill prioritized task list.
  3. Boost the page fill worker thread priority. Check the priority of the task at the head of the g_waitingforfill list. If the priority of that task is higher than the current priority of the page fill worker thread, then boost the priority of the page fill worker thread to that priority.
  4. Signal the page fill worker thread. Is there a page already being filled? If not then signal the page fill worker thread to start working on the queued page fill requests.

When signaled from pg_miss(), the page fill worker thread will be awakenend and will initiate the fill operation.

Input Parameters. None -- The head of the ready-to-run list is assumed to be that task that caused the exception. The current task context should already be saved in the TCB of that task. No additional inputs are required.

Assumptions.

Locking code in Memory. One way to accomplish this would be a two phase link:

Fill Initiation

The page fill worker thread will be awakened on one of two conditions:

The page fill worker thread will maintain a static variable called _TCB *g_pendingfill. If not fill is in progress, g_pendingfill will be NULL. Otherwise, will point to the TCB of the task which is receiving the fill that is in progess.

When awakened from pg_miss(), no fill will be in progress and g_pendingfill will be NULL. In this case, the page fill worker thread will call pg_startfill(). That function will perform the following operations:

While the fill is in progress, other tasks may execute. If another page fault occurs during this time, the faulting task will be blocked and its TCB will be added (in priority order) to g_waitingforfill. But no action will be taken until the current page fill completes. NOTE: The IDLE task must also be fully locked in memory. The IDLE task cannot be blocked. It the case where all tasks are blocked waiting for a page fill, the IDLE task must still be available to run.

The chip-specific functions, up_allocpage(vaddr, &page) and up_fillpage(page, pg_callback) will be prototyped in include/nuttx/arch.h

Fill Complete

When the chip-specific driver completes the page fill, it will call the pg_callback() that was provided to up_fillpage. pg_callback() will probably be called from driver interrupt-level logic. The driver ill provide the result of the fill as an argument. NOTE: pg_callback() must also be locked in memory.

When pg_callback() is called, it will perform the following operations:

Task Resumption

When the page fill worker thread is awakened and g_pendingfill is non-NULL (and other state variables are in concurrence), the page fill thread will know that is was awakened because of a page fill completion event. In this case, the page fill worker thread will: