1 ================ 2 Shadow Variables 3 ================ 4 5 Shadow variables are a simple way for livepatc 6 additional "shadow" data with existing data st 7 allocated separately from parent data structur 8 unmodified. The shadow variable API described 9 to allocate/add and remove/free shadow variabl 10 11 The implementation introduces a global, in-ker 12 associates pointers to parent objects and a nu 13 shadow data. The numeric identifier is a simp 14 used to describe shadow variable version, clas 15 specifically, the parent pointer serves as the 16 numeric id subsequently filters hashtable quer 17 variables may attach to the same parent object 18 identifier distinguishes between them. 19 20 21 1. Brief API summary 22 ==================== 23 24 (See the full API usage docbook notes in livep 25 26 A hashtable references all shadow variables. 27 stored and retrieved through a <obj, id> pair. 28 29 * The klp_shadow variable data structure encap 30 meta-data and shadow-data: 31 32 - meta-data 33 34 - obj - pointer to parent object 35 - id - data identifier 36 37 - data[] - storage for shadow data 38 39 It is important to note that the klp_shadow_al 40 klp_shadow_get_or_alloc() are zeroing the vari 41 They also allow to call a custom constructor f 42 value is needed. Callers should provide whatev 43 is required. 44 45 Note that the constructor is called under klp_ 46 to do actions that can be done only once when 47 48 * klp_shadow_get() - retrieve a shadow variabl 49 - search hashtable for <obj, id> pair 50 51 * klp_shadow_alloc() - allocate and add a new 52 - search hashtable for <obj, id> pair 53 54 - if exists 55 56 - WARN and return NULL 57 58 - if <obj, id> doesn't already exist 59 60 - allocate a new shadow variable 61 - initialize the variable using a custom c 62 - add <obj, id> to the global hashtable 63 64 * klp_shadow_get_or_alloc() - get existing or 65 - search hashtable for <obj, id> pair 66 67 - if exists 68 69 - return existing shadow variable 70 71 - if <obj, id> doesn't already exist 72 73 - allocate a new shadow variable 74 - initialize the variable using a custom c 75 - add <obj, id> pair to the global hashtab 76 77 * klp_shadow_free() - detach and free a <obj, 78 - find and remove a <obj, id> reference from 79 80 - if found 81 82 - call destructor function if defined 83 - free shadow variable 84 85 * klp_shadow_free_all() - detach and free all 86 - find and remove any <_, id> references fro 87 88 - if found 89 90 - call destructor function if defined 91 - free shadow variable 92 93 94 2. Use cases 95 ============ 96 97 (See the example shadow variable livepatch mod 98 for full working demonstrations.) 99 100 For the following use-case examples, consider 101 ("mac80211: fix AP powersave TX vs. wakeup ra 102 spinlock to net/mac80211/sta_info.h :: struct 103 example can be considered a stand-alone livepa 104 fix. 105 106 107 Matching parent's lifecycle 108 --------------------------- 109 110 If parent data structures are frequently creat 111 be easiest to align their shadow variables lif 112 allocation and release functions. In this cas 113 structure is typically allocated, initialized, 114 manner. Shadow variable allocation and setup 115 part of the parent's initialization and should 116 parent "goes live" (ie, any shadow variable ge 117 for this <obj, id> pair.) 118 119 For commit 1d147bfa6429, when a parent sta_inf 120 allocate a shadow copy of the ps_lock pointer, 121 122 #define PS_LOCK 1 123 struct sta_info *sta_info_alloc(struct ieee8 124 const u8 *ad 125 { 126 struct sta_info *sta; 127 spinlock_t *ps_lock; 128 129 /* Parent structure is created */ 130 sta = kzalloc(sizeof(*sta) + hw->sta_d 131 132 /* Attach a corresponding shadow varia 133 ps_lock = klp_shadow_alloc(sta, PS_LOC 134 NULL, NULL) 135 if (!ps_lock) 136 goto shadow_fail; 137 spin_lock_init(ps_lock); 138 ... 139 140 When requiring a ps_lock, query the shadow var 141 for a specific struct sta_info::: 142 143 void ieee80211_sta_ps_deliver_wakeup(struct 144 { 145 spinlock_t *ps_lock; 146 147 /* sync with ieee80211_tx_h_unicast_ps 148 ps_lock = klp_shadow_get(sta, PS_LOCK) 149 if (ps_lock) 150 spin_lock(ps_lock); 151 ... 152 153 When the parent sta_info structure is freed, f 154 variable:: 155 156 void sta_info_free(struct ieee80211_local *l 157 { 158 klp_shadow_free(sta, PS_LOCK, NULL); 159 kfree(sta); 160 ... 161 162 163 In-flight parent objects 164 ------------------------ 165 166 Sometimes it may not be convenient or possible 167 variables alongside their parent objects. Or 168 require shadow variables for only a subset of 169 In these cases, the klp_shadow_get_or_alloc() 170 shadow variables to parents already in-flight. 171 172 For commit 1d147bfa6429, a good spot to alloca 173 inside ieee80211_sta_ps_deliver_wakeup():: 174 175 int ps_lock_shadow_ctor(void *obj, void *sha 176 { 177 spinlock_t *lock = shadow_data; 178 179 spin_lock_init(lock); 180 return 0; 181 } 182 183 #define PS_LOCK 1 184 void ieee80211_sta_ps_deliver_wakeup(struct 185 { 186 spinlock_t *ps_lock; 187 188 /* sync with ieee80211_tx_h_unicast_ps 189 ps_lock = klp_shadow_get_or_alloc(sta, 190 sizeof(*ps_lock), GFP_ 191 ps_lock_shadow_ctor, N 192 193 if (ps_lock) 194 spin_lock(ps_lock); 195 ... 196 197 This usage will create a shadow variable, only 198 will use one that was already created for this 199 200 Like the previous use-case, the shadow spinloc 201 A shadow variable can be freed just before its 202 or even when the shadow variable itself is no 203 204 205 Other use-cases 206 --------------- 207 208 Shadow variables can also be used as a flag in 209 structure was allocated by new, livepatched co 210 doesn't matter what data value the shadow vari 211 suggests how to handle the parent object. 212 213 214 3. References 215 ============= 216 217 * https://github.com/dynup/kpatch 218 219 The livepatch implementation is based on the 220 variables. 221 222 * http://files.mkgnu.net/files/dynamos/doc/pap 223 224 Dynamic and Adaptive Updates of Non-Quiescen 225 Operating System Kernels (Kritis Makris, Kyu 226 a datatype update technique called "shadow d
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.