1439e7271SJoe Lawrence================ 2439e7271SJoe LawrenceShadow Variables 3439e7271SJoe Lawrence================ 4439e7271SJoe Lawrence 5439e7271SJoe LawrenceShadow variables are a simple way for livepatch modules to associate 6439e7271SJoe Lawrenceadditional "shadow" data with existing data structures. Shadow data is 7439e7271SJoe Lawrenceallocated separately from parent data structures, which are left 8439e7271SJoe Lawrenceunmodified. The shadow variable API described in this document is used 919205da6SPetr Mladekto allocate/add and remove/free shadow variables to/from their parents. 10439e7271SJoe Lawrence 11439e7271SJoe LawrenceThe implementation introduces a global, in-kernel hashtable that 12439e7271SJoe Lawrenceassociates pointers to parent objects and a numeric identifier of the 13439e7271SJoe Lawrenceshadow data. The numeric identifier is a simple enumeration that may be 14439e7271SJoe Lawrenceused to describe shadow variable version, class or type, etc. More 15439e7271SJoe Lawrencespecifically, the parent pointer serves as the hashtable key while the 16439e7271SJoe Lawrencenumeric id subsequently filters hashtable queries. Multiple shadow 17439e7271SJoe Lawrencevariables may attach to the same parent object, but their numeric 18439e7271SJoe Lawrenceidentifier distinguishes between them. 19439e7271SJoe Lawrence 20439e7271SJoe Lawrence 21439e7271SJoe Lawrence1. Brief API summary 22439e7271SJoe Lawrence==================== 23439e7271SJoe Lawrence 24439e7271SJoe Lawrence(See the full API usage docbook notes in livepatch/shadow.c.) 25439e7271SJoe Lawrence 26439e7271SJoe LawrenceA hashtable references all shadow variables. These references are 27439e7271SJoe Lawrencestored and retrieved through a <obj, id> pair. 28439e7271SJoe Lawrence 29439e7271SJoe Lawrence* The klp_shadow variable data structure encapsulates both tracking 30439e7271SJoe Lawrence meta-data and shadow-data: 3189e33ea7SMauro Carvalho Chehab 32439e7271SJoe Lawrence - meta-data 3389e33ea7SMauro Carvalho Chehab 34439e7271SJoe Lawrence - obj - pointer to parent object 35439e7271SJoe Lawrence - id - data identifier 3689e33ea7SMauro Carvalho Chehab 37439e7271SJoe Lawrence - data[] - storage for shadow data 38439e7271SJoe Lawrence 39439e7271SJoe LawrenceIt is important to note that the klp_shadow_alloc() and 40e91c2518SPetr Mladekklp_shadow_get_or_alloc() are zeroing the variable by default. 41e91c2518SPetr MladekThey also allow to call a custom constructor function when a non-zero 42e91c2518SPetr Mladekvalue is needed. Callers should provide whatever mutual exclusion 43e91c2518SPetr Mladekis required. 44e91c2518SPetr Mladek 45e91c2518SPetr MladekNote that the constructor is called under klp_shadow_lock spinlock. It allows 46e91c2518SPetr Mladekto do actions that can be done only once when a new variable is allocated. 47439e7271SJoe Lawrence 48439e7271SJoe Lawrence* klp_shadow_get() - retrieve a shadow variable data pointer 49439e7271SJoe Lawrence - search hashtable for <obj, id> pair 50439e7271SJoe Lawrence 51439e7271SJoe Lawrence* klp_shadow_alloc() - allocate and add a new shadow variable 52439e7271SJoe Lawrence - search hashtable for <obj, id> pair 5389e33ea7SMauro Carvalho Chehab 54439e7271SJoe Lawrence - if exists 5589e33ea7SMauro Carvalho Chehab 56439e7271SJoe Lawrence - WARN and return NULL 5789e33ea7SMauro Carvalho Chehab 58439e7271SJoe Lawrence - if <obj, id> doesn't already exist 5989e33ea7SMauro Carvalho Chehab 60439e7271SJoe Lawrence - allocate a new shadow variable 61e91c2518SPetr Mladek - initialize the variable using a custom constructor and data when provided 62439e7271SJoe Lawrence - add <obj, id> to the global hashtable 63439e7271SJoe Lawrence 64439e7271SJoe Lawrence* klp_shadow_get_or_alloc() - get existing or alloc a new shadow variable 65439e7271SJoe Lawrence - search hashtable for <obj, id> pair 6689e33ea7SMauro Carvalho Chehab 67439e7271SJoe Lawrence - if exists 6889e33ea7SMauro Carvalho Chehab 69439e7271SJoe Lawrence - return existing shadow variable 7089e33ea7SMauro Carvalho Chehab 71439e7271SJoe Lawrence - if <obj, id> doesn't already exist 7289e33ea7SMauro Carvalho Chehab 73439e7271SJoe Lawrence - allocate a new shadow variable 74e91c2518SPetr Mladek - initialize the variable using a custom constructor and data when provided 75439e7271SJoe Lawrence - add <obj, id> pair to the global hashtable 76439e7271SJoe Lawrence 77439e7271SJoe Lawrence* klp_shadow_free() - detach and free a <obj, id> shadow variable 78439e7271SJoe Lawrence - find and remove a <obj, id> reference from global hashtable 7989e33ea7SMauro Carvalho Chehab 803b2c77d0SPetr Mladek - if found 8189e33ea7SMauro Carvalho Chehab 823b2c77d0SPetr Mladek - call destructor function if defined 833b2c77d0SPetr Mladek - free shadow variable 84439e7271SJoe Lawrence 85e368cd72SDavid Vernet* klp_shadow_free_all() - detach and free all <_, id> shadow variables 86e368cd72SDavid Vernet - find and remove any <_, id> references from global hashtable 8789e33ea7SMauro Carvalho Chehab 883b2c77d0SPetr Mladek - if found 8989e33ea7SMauro Carvalho Chehab 903b2c77d0SPetr Mladek - call destructor function if defined 913b2c77d0SPetr Mladek - free shadow variable 92439e7271SJoe Lawrence 93439e7271SJoe Lawrence 94439e7271SJoe Lawrence2. Use cases 95439e7271SJoe Lawrence============ 96439e7271SJoe Lawrence 97439e7271SJoe Lawrence(See the example shadow variable livepatch modules in samples/livepatch/ 98439e7271SJoe Lawrencefor full working demonstrations.) 99439e7271SJoe Lawrence 100439e7271SJoe LawrenceFor the following use-case examples, consider commit 1d147bfa6429 101439e7271SJoe Lawrence("mac80211: fix AP powersave TX vs. wakeup race"), which added a 102439e7271SJoe Lawrencespinlock to net/mac80211/sta_info.h :: struct sta_info. Each use-case 103439e7271SJoe Lawrenceexample can be considered a stand-alone livepatch implementation of this 104439e7271SJoe Lawrencefix. 105439e7271SJoe Lawrence 106439e7271SJoe Lawrence 107439e7271SJoe LawrenceMatching parent's lifecycle 108439e7271SJoe Lawrence--------------------------- 109439e7271SJoe Lawrence 110439e7271SJoe LawrenceIf parent data structures are frequently created and destroyed, it may 111439e7271SJoe Lawrencebe easiest to align their shadow variables lifetimes to the same 112439e7271SJoe Lawrenceallocation and release functions. In this case, the parent data 113439e7271SJoe Lawrencestructure is typically allocated, initialized, then registered in some 114439e7271SJoe Lawrencemanner. Shadow variable allocation and setup can then be considered 115439e7271SJoe Lawrencepart of the parent's initialization and should be completed before the 116439e7271SJoe Lawrenceparent "goes live" (ie, any shadow variable get-API requests are made 117439e7271SJoe Lawrencefor this <obj, id> pair.) 118439e7271SJoe Lawrence 119439e7271SJoe LawrenceFor commit 1d147bfa6429, when a parent sta_info structure is allocated, 12089e33ea7SMauro Carvalho Chehaballocate a shadow copy of the ps_lock pointer, then initialize it:: 121439e7271SJoe Lawrence 122439e7271SJoe Lawrence #define PS_LOCK 1 123439e7271SJoe Lawrence struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, 124439e7271SJoe Lawrence const u8 *addr, gfp_t gfp) 125439e7271SJoe Lawrence { 126439e7271SJoe Lawrence struct sta_info *sta; 127439e7271SJoe Lawrence spinlock_t *ps_lock; 128439e7271SJoe Lawrence 129439e7271SJoe Lawrence /* Parent structure is created */ 130439e7271SJoe Lawrence sta = kzalloc(sizeof(*sta) + hw->sta_data_size, gfp); 131439e7271SJoe Lawrence 132439e7271SJoe Lawrence /* Attach a corresponding shadow variable, then initialize it */ 133e91c2518SPetr Mladek ps_lock = klp_shadow_alloc(sta, PS_LOCK, sizeof(*ps_lock), gfp, 134e91c2518SPetr Mladek NULL, NULL); 135439e7271SJoe Lawrence if (!ps_lock) 136439e7271SJoe Lawrence goto shadow_fail; 137439e7271SJoe Lawrence spin_lock_init(ps_lock); 138439e7271SJoe Lawrence ... 139439e7271SJoe Lawrence 140439e7271SJoe LawrenceWhen requiring a ps_lock, query the shadow variable API to retrieve one 14189e33ea7SMauro Carvalho Chehabfor a specific struct sta_info::: 142439e7271SJoe Lawrence 143439e7271SJoe Lawrence void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) 144439e7271SJoe Lawrence { 145439e7271SJoe Lawrence spinlock_t *ps_lock; 146439e7271SJoe Lawrence 147439e7271SJoe Lawrence /* sync with ieee80211_tx_h_unicast_ps_buf */ 148439e7271SJoe Lawrence ps_lock = klp_shadow_get(sta, PS_LOCK); 149439e7271SJoe Lawrence if (ps_lock) 150439e7271SJoe Lawrence spin_lock(ps_lock); 151439e7271SJoe Lawrence ... 152439e7271SJoe Lawrence 153439e7271SJoe LawrenceWhen the parent sta_info structure is freed, first free the shadow 15489e33ea7SMauro Carvalho Chehabvariable:: 155439e7271SJoe Lawrence 156439e7271SJoe Lawrence void sta_info_free(struct ieee80211_local *local, struct sta_info *sta) 157439e7271SJoe Lawrence { 1583b2c77d0SPetr Mladek klp_shadow_free(sta, PS_LOCK, NULL); 159439e7271SJoe Lawrence kfree(sta); 160439e7271SJoe Lawrence ... 161439e7271SJoe Lawrence 162439e7271SJoe Lawrence 163439e7271SJoe LawrenceIn-flight parent objects 164439e7271SJoe Lawrence------------------------ 165439e7271SJoe Lawrence 166439e7271SJoe LawrenceSometimes it may not be convenient or possible to allocate shadow 167439e7271SJoe Lawrencevariables alongside their parent objects. Or a livepatch fix may 168a5907065SBhaskar Chowdhuryrequire shadow variables for only a subset of parent object instances. 169a5907065SBhaskar ChowdhuryIn these cases, the klp_shadow_get_or_alloc() call can be used to attach 170439e7271SJoe Lawrenceshadow variables to parents already in-flight. 171439e7271SJoe Lawrence 172439e7271SJoe LawrenceFor commit 1d147bfa6429, a good spot to allocate a shadow spinlock is 17389e33ea7SMauro Carvalho Chehabinside ieee80211_sta_ps_deliver_wakeup():: 174439e7271SJoe Lawrence 175e91c2518SPetr Mladek int ps_lock_shadow_ctor(void *obj, void *shadow_data, void *ctor_data) 176e91c2518SPetr Mladek { 177e91c2518SPetr Mladek spinlock_t *lock = shadow_data; 178e91c2518SPetr Mladek 179e91c2518SPetr Mladek spin_lock_init(lock); 180e91c2518SPetr Mladek return 0; 181e91c2518SPetr Mladek } 182e91c2518SPetr Mladek 183439e7271SJoe Lawrence #define PS_LOCK 1 184439e7271SJoe Lawrence void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) 185439e7271SJoe Lawrence { 186439e7271SJoe Lawrence spinlock_t *ps_lock; 187439e7271SJoe Lawrence 188439e7271SJoe Lawrence /* sync with ieee80211_tx_h_unicast_ps_buf */ 189439e7271SJoe Lawrence ps_lock = klp_shadow_get_or_alloc(sta, PS_LOCK, 190e91c2518SPetr Mladek sizeof(*ps_lock), GFP_ATOMIC, 191e91c2518SPetr Mladek ps_lock_shadow_ctor, NULL); 192e91c2518SPetr Mladek 193439e7271SJoe Lawrence if (ps_lock) 194439e7271SJoe Lawrence spin_lock(ps_lock); 195439e7271SJoe Lawrence ... 196439e7271SJoe Lawrence 197439e7271SJoe LawrenceThis usage will create a shadow variable, only if needed, otherwise it 198439e7271SJoe Lawrencewill use one that was already created for this <obj, id> pair. 199439e7271SJoe Lawrence 200439e7271SJoe LawrenceLike the previous use-case, the shadow spinlock needs to be cleaned up. 201439e7271SJoe LawrenceA shadow variable can be freed just before its parent object is freed, 202439e7271SJoe Lawrenceor even when the shadow variable itself is no longer required. 203439e7271SJoe Lawrence 204439e7271SJoe Lawrence 205439e7271SJoe LawrenceOther use-cases 206439e7271SJoe Lawrence--------------- 207439e7271SJoe Lawrence 208439e7271SJoe LawrenceShadow variables can also be used as a flag indicating that a data 209439e7271SJoe Lawrencestructure was allocated by new, livepatched code. In this case, it 210439e7271SJoe Lawrencedoesn't matter what data value the shadow variable holds, its existence 211439e7271SJoe Lawrencesuggests how to handle the parent object. 212439e7271SJoe Lawrence 213439e7271SJoe Lawrence 214439e7271SJoe Lawrence3. References 215439e7271SJoe Lawrence============= 216439e7271SJoe Lawrence 217439e7271SJoe Lawrence* https://github.com/dynup/kpatch 21889e33ea7SMauro Carvalho Chehab 219439e7271SJoe Lawrence The livepatch implementation is based on the kpatch version of shadow 220439e7271SJoe Lawrence variables. 221439e7271SJoe Lawrence 222439e7271SJoe Lawrence* http://files.mkgnu.net/files/dynamos/doc/papers/dynamos_eurosys_07.pdf 22389e33ea7SMauro Carvalho Chehab 224439e7271SJoe Lawrence Dynamic and Adaptive Updates of Non-Quiescent Subsystems in Commodity 225439e7271SJoe Lawrence Operating System Kernels (Kritis Makris, Kyung Dong Ryu 2007) presented 226439e7271SJoe Lawrence a datatype update technique called "shadow data structures". 227