[PATCH 0/4] devPrivates rework: introduction/RFC
Eamon Walsh
ewalsh at tycho.nsa.gov
Thu Feb 22 15:56:05 PST 2007
RFC/Introduction: devPrivates rework
Background
devPrivates provide a way for driver/module writers to hang private data
from various server objects, such as screen, window, colormap, client,
and device structures.
However, the author has found some problems with the current scheme
while writing security modules that store state in a variety of
different server objects.
Each structure has its own devPrivates field and a separate set of
functions for allocating private space. Each set of functions is
slightly different, and the various structures offer differing features
in terms how much space can be allocated, whether or not the space is
allocated on a per-screen basis, and/or whether an initialization
callback can be provided.
Not all objects in the server have the support. Adding support to a new
structures requires adding a devPrivates member to it, potentially
breaking the ABI. Then, a new set of functions needs to be added to
request private space, which duplicates code and inflates the symbol
export count. Finally, all the places where the structure is allocated
need to be found and changed to allocate enough space to store the
private data after the structure, then set up the pointers properly.
Proposal
The proposal is to make devPrivates support part of the resource system.
Instead of hanging off the structure itself, the private data will
hang off the ResourceRec bucket associated with the structure. A new
RC_PRIVATES class indicates resource types that support devPrivates.
This will allow private data to be associated with any supported server
resource using just one set of common functions.
The proposed interface supports all of the previous devPrivates
features, plus more:
- Choose the amount of space you need.
- Allocate space in a single resource object, in all resources, or just
in resources on a given screen (actually, the latter is generic so
something other than screens could be used as the parent object).
- Supports callbacks which are called just after the private is
allocated and just before it is freed.
- Space can be requested even after resource objects have already been
created. The lookup function allocates the space at lookup time if
necessary. Any privates requested before resource creation are
allocated with the resource bucket in one chunk.
Drawbacks
Drivers must update to new interface before old can be removed.
Since the private data hangs off the resource bucket, there needs to be
an O(1) way to get to the resource bucket from the object itself. Thus
the proposed support requires every supporting structure to have a
pointer-to-ResourceRec as the first field. This breaks ABI and may
break clever code that assumes the first field is something else. This
is why the RC_PRIVATES class is there - to mark which resources have
that field added. The support can be added over time; the initial plan
is to do it for the basic resource types.
Some objects that are not currently resources need to become resources.
These are ScreenRec and ClientRec (they would be owned by
serverClient). The author views this as a benefit.
Resources added on a given screen now need to be added with an
AddResource function that takes an additional argument specifying the
ScreenPtr.
Looking up private data requires a few more pointer dereferences and,
rarely, a function call. The patchset currently does the whole lookup
in the dixLookupPrivate() function, but the common case can be done as
an inline or macro outside of it.
Interface Overview
index = dixRequestPrivate(RESTYPE type, unsigned size, pointer parent);
Requests size bytes of private space on resources of type type on screen
parent (NULL for all screens). Type RC_ANY can be used to get space in
all resources.
ptr = dixLookupPrivate(RESTYPE type, int index, pointer instance);
Returns a pointer to the private data associated with instance.
rc = dixRegisterPrivateInitFunc(RESTYPE type, int index, CallbackProcPtr
callbackfunc, pointer userdata);
rc = dixRegisterPrivateDeleteFunc(RESTYPE type, int index,
CallbackProcPtr callbackfunc, pointer userdata);
Registers callbacks that can be used to initialize the newly allocated
space (zeroed out by default), or cleanup just before the space gets
freed. Users do not free the private pointer themselves! The argument
to the callback is a structure that contains the private pointer, index
number, and resource object.
Memory Allocation Diagrams
Diagrams are available showing how memory is allocated and pointers are
set up. Refer to the following URL's:
Current: http://people.freedesktop.org/~ewalsh/devPrivates_current.png
Proposed: http://people.freedesktop.org/~ewalsh/devPrivates_proposed.png
--
Eamon Walsh <ewalsh at tycho.nsa.gov>
National Security Agency
More information about the xorg
mailing list