123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- ================
- Shadow Variables
- ================
- Shadow variables are a simple way for livepatch modules to associate
- additional "shadow" data with existing data structures. Shadow data is
- allocated separately from parent data structures, which are left
- unmodified. The shadow variable API described in this document is used
- to allocate/add and remove/free shadow variables to/from their parents.
- The implementation introduces a global, in-kernel hashtable that
- associates pointers to parent objects and a numeric identifier of the
- shadow data. The numeric identifier is a simple enumeration that may be
- used to describe shadow variable version, class or type, etc. More
- specifically, the parent pointer serves as the hashtable key while the
- numeric id subsequently filters hashtable queries. Multiple shadow
- variables may attach to the same parent object, but their numeric
- identifier distinguishes between them.
- 1. Brief API summary
- ====================
- (See the full API usage docbook notes in livepatch/shadow.c.)
- A hashtable references all shadow variables. These references are
- stored and retrieved through a <obj, id> pair.
- * The klp_shadow variable data structure encapsulates both tracking
- meta-data and shadow-data:
- - meta-data
- - obj - pointer to parent object
- - id - data identifier
- - data[] - storage for shadow data
- It is important to note that the klp_shadow_alloc() and
- klp_shadow_get_or_alloc() are zeroing the variable by default.
- They also allow to call a custom constructor function when a non-zero
- value is needed. Callers should provide whatever mutual exclusion
- is required.
- Note that the constructor is called under klp_shadow_lock spinlock. It allows
- to do actions that can be done only once when a new variable is allocated.
- * klp_shadow_get() - retrieve a shadow variable data pointer
- - search hashtable for <obj, id> pair
- * klp_shadow_alloc() - allocate and add a new shadow variable
- - search hashtable for <obj, id> pair
- - if exists
- - WARN and return NULL
- - if <obj, id> doesn't already exist
- - allocate a new shadow variable
- - initialize the variable using a custom constructor and data when provided
- - add <obj, id> to the global hashtable
- * klp_shadow_get_or_alloc() - get existing or alloc a new shadow variable
- - search hashtable for <obj, id> pair
- - if exists
- - return existing shadow variable
- - if <obj, id> doesn't already exist
- - allocate a new shadow variable
- - initialize the variable using a custom constructor and data when provided
- - add <obj, id> pair to the global hashtable
- * klp_shadow_free() - detach and free a <obj, id> shadow variable
- - find and remove a <obj, id> reference from global hashtable
- - if found
- - call destructor function if defined
- - free shadow variable
- * klp_shadow_free_all() - detach and free all <_, id> shadow variables
- - find and remove any <_, id> references from global hashtable
- - if found
- - call destructor function if defined
- - free shadow variable
- 2. Use cases
- ============
- (See the example shadow variable livepatch modules in samples/livepatch/
- for full working demonstrations.)
- For the following use-case examples, consider commit 1d147bfa6429
- ("mac80211: fix AP powersave TX vs. wakeup race"), which added a
- spinlock to net/mac80211/sta_info.h :: struct sta_info. Each use-case
- example can be considered a stand-alone livepatch implementation of this
- fix.
- Matching parent's lifecycle
- If parent data structures are frequently created and destroyed, it may
- be easiest to align their shadow variables lifetimes to the same
- allocation and release functions. In this case, the parent data
- structure is typically allocated, initialized, then registered in some
- manner. Shadow variable allocation and setup can then be considered
- part of the parent's initialization and should be completed before the
- parent "goes live" (ie, any shadow variable get-API requests are made
- for this <obj, id> pair.)
- For commit 1d147bfa6429, when a parent sta_info structure is allocated,
- allocate a shadow copy of the ps_lock pointer, then initialize it::
-
- struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
- const u8 *addr, gfp_t gfp)
- {
- struct sta_info *sta;
- spinlock_t *ps_lock;
- /* Parent structure is created */
- sta = kzalloc(sizeof
|