Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: nft_set_pipapo: Use nested-BH locking for nft_pipapo_scratch

nft_pipapo_scratch is a per-CPU variable and relies on disabled BH for
its locking. Without per-CPU locking in local_bh_disable() on PREEMPT_RT
this data structure requires explicit locking.

Add a local_lock_t to the data structure and use local_lock_nested_bh() for
locking. This change adds only lockdep coverage and does not alter the
functional behaviour for !PREEMPT_RT.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Florian Westphal <fw@strlen.de>

authored by

Sebastian Andrzej Siewior and committed by
Florian Westphal
456010c8 6aa67d57

+11
+5
net/netfilter/nft_set_pipapo.c
··· 429 429 scratch = *raw_cpu_ptr(m->scratch); 430 430 if (unlikely(!scratch)) 431 431 goto out; 432 + __local_lock_nested_bh(&scratch->bh_lock); 432 433 433 434 map_index = scratch->map_index; 434 435 ··· 466 465 last); 467 466 if (b < 0) { 468 467 scratch->map_index = map_index; 468 + __local_unlock_nested_bh(&scratch->bh_lock); 469 469 local_bh_enable(); 470 470 471 471 return NULL; ··· 486 484 * *next* bitmap (not initial) for the next packet. 487 485 */ 488 486 scratch->map_index = map_index; 487 + __local_unlock_nested_bh(&scratch->bh_lock); 489 488 local_bh_enable(); 490 489 return e; 491 490 } ··· 501 498 data += NFT_PIPAPO_GROUPS_PADDING(f); 502 499 } 503 500 501 + __local_unlock_nested_bh(&scratch->bh_lock); 504 502 out: 505 503 local_bh_enable(); 506 504 return NULL; ··· 1219 1215 } 1220 1216 1221 1217 pipapo_free_scratch(clone, i); 1218 + local_lock_init(&scratch->bh_lock); 1222 1219 *per_cpu_ptr(clone->scratch, i) = scratch; 1223 1220 } 1224 1221
+2
net/netfilter/nft_set_pipapo.h
··· 124 124 125 125 /** 126 126 * struct nft_pipapo_scratch - percpu data used for lookup and matching 127 + * @bh_lock: PREEMPT_RT local spinlock 127 128 * @map_index: Current working bitmap index, toggled between field matches 128 129 * @__map: store partial matching results during lookup 129 130 */ 130 131 struct nft_pipapo_scratch { 132 + local_lock_t bh_lock; 131 133 u8 map_index; 132 134 unsigned long __map[]; 133 135 };
+4
net/netfilter/nft_set_pipapo_avx2.c
··· 1163 1163 if (unlikely(!scratch)) 1164 1164 return NULL; 1165 1165 1166 + __local_lock_nested_bh(&scratch->bh_lock); 1166 1167 map_index = scratch->map_index; 1167 1168 map = NFT_PIPAPO_LT_ALIGN(&scratch->__map[0]); 1168 1169 res = map + (map_index ? m->bsize_max : 0); ··· 1229 1228 if (ret < 0) { 1230 1229 scratch->map_index = map_index; 1231 1230 kernel_fpu_end(); 1231 + __local_unlock_nested_bh(&scratch->bh_lock); 1232 1232 return NULL; 1233 1233 } 1234 1234 ··· 1243 1241 1244 1242 scratch->map_index = map_index; 1245 1243 kernel_fpu_end(); 1244 + __local_unlock_nested_bh(&scratch->bh_lock); 1246 1245 return e; 1247 1246 } 1248 1247 ··· 1253 1250 } 1254 1251 1255 1252 kernel_fpu_end(); 1253 + __local_unlock_nested_bh(&scratch->bh_lock); 1256 1254 return NULL; 1257 1255 } 1258 1256