Describes the kernel-side issues that must be considered when writing device drivers.
This document explains the impact of data paging on kernel side code.
Intended Audience:
This document is intended for device driver writers.
Certain exported and internal APIs access the address space of the current thread and are subject to restrictions on their use enforced by assertions in the code. The restrictions are these:
The APIs may only be called from thread context.
They may not be called while any mutexes are held. There are two particularly important cases when mutexes are often held:
The APIs may not be called when the system lock is held. There are two particularly important cases when the system lock is often held:
When publish and subscribe is writing large binary properties to user space, and
When the multiple memory model uses DThread::FastWrite to write to user space.
The APIs concerned are these:
Certain exported and internal APIs access the address space of another thread and are subject to restrictions on their use enforced by assertions in the code. The restrictions are these:
The APIs may not be called when any mutexes are held. One particularly important case of this is when undertakers are completed and handles written to user space.
The APIs concerned are these:
In non-paged code it is usual for a thread to have an asynchronous request outstanding and to complete it by calling Kern::RequestComplete(). This technique is not safe in data paged code as it involves writing a status value back into the thread's address space, but this memory might be paged out and violate the thread's performance guarantees or cause a mutex order violation.
Instead, you should use the TClientRequest object to write the request status within the context of the client thread in the following way.
Create a TClientRequest object by calling Kern::CreateClientRequest().
Call the SetStatus() function of the TClientRequest object to set the client's request status.
Call Kern::QueueRequestComplete() to signal the client thread that the request has been queued for completion.
When the client thread next runs, the TRequestStatus value is written back to it.
The TRequestStatus can now be reused, or destroyed by a call to Kern::DestroyRequest().
In non-paged code it is common for a client thread to send a message to a server and write it into the address space of the server. When data paging is enabled, this creates the same risk of page faults as the completion of asynchronous requests and can be mitigated by the same techniques as above. In addition, descriptor information (type, length and maximum length) is read by temporarily switching to the client's address space, creating additional risk of page faults.
When data paging is enabled, messages to servers must be pre-parsed and their type, length and maximum length stored in the message structure. This involves change to the kernel code but does not impact on user-side code.
The kernel maintains a queue of user-input events which is read by the window server. The introduction of data paging involved a change to the kernel code which responds to the user-side API UserSver::RequestEvent(). No change to user-side code is involved.
Copyright ©2010 Nokia Corporation and/or its subsidiary(-ies).
All rights
reserved. Unless otherwise stated, these materials are provided under the terms of the Eclipse Public License
v1.0.