[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