Message ID | 2860814445452DE8+20240924022437.119730-1-yushengjin@uniontech.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [v2] net/bridge: Optimizing read-write locks in ebtables.c | expand |
Hi yushengjin, kernel test robot noticed the following build errors: [auto build test ERROR on netfilter-nf/main] [also build test ERROR on horms-ipvs/master linus/master v6.11 next-20240924] [cannot apply to nf-next/master] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/yushengjin/net-bridge-Optimizing-read-write-locks-in-ebtables-c/20240924-102547 base: https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf.git main patch link: https://lore.kernel.org/r/2860814445452DE8%2B20240924022437.119730-1-yushengjin%40uniontech.com patch subject: [PATCH v2] net/bridge: Optimizing read-write locks in ebtables.c config: sh-allmodconfig (https://download.01.org/0day-ci/archive/20240924/202409241543.F99I82u3-lkp@intel.com/config) compiler: sh4-linux-gcc (GCC) 14.1.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240924/202409241543.F99I82u3-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202409241543.F99I82u3-lkp@intel.com/ All errors (new ones prefixed by >>): In file included from include/asm-generic/percpu.h:7, from ./arch/sh/include/generated/asm/percpu.h:1, from include/linux/irqflags.h:19, from arch/sh/include/asm/cmpxchg-irq.h:5, from arch/sh/include/asm/cmpxchg.h:20, from arch/sh/include/asm/atomic.h:19, from include/linux/atomic.h:7, from include/asm-generic/bitops/atomic.h:5, from arch/sh/include/asm/bitops.h:23, from include/linux/bitops.h:68, from include/linux/thread_info.h:27, from include/asm-generic/preempt.h:5, from ./arch/sh/include/generated/asm/preempt.h:1, from include/linux/preempt.h:79, from include/linux/spinlock.h:56, from include/linux/mmzone.h:8, from include/linux/gfp.h:7, from include/linux/umh.h:4, from include/linux/kmod.h:9, from net/bridge/netfilter/ebtables.c:14: net/bridge/netfilter/ebtables.c: In function 'get_counters': >> net/bridge/netfilter/ebtables.c:1006:30: error: 'ebt_recseq' undeclared (first use in this function); did you mean 'xt_recseq'? 1006 | s = &per_cpu(ebt_recseq, cpu); | ^~~~~~~~~~ include/linux/percpu-defs.h:219:54: note: in definition of macro '__verify_pcpu_ptr' 219 | const void __percpu *__vpp_verify = (typeof((ptr) + 0))NULL; \ | ^~~ include/linux/percpu-defs.h:263:49: note: in expansion of macro 'VERIFY_PERCPU_PTR' 263 | #define per_cpu_ptr(ptr, cpu) ({ (void)(cpu); VERIFY_PERCPU_PTR(ptr); }) | ^~~~~~~~~~~~~~~~~ include/linux/percpu-defs.h:269:35: note: in expansion of macro 'per_cpu_ptr' 269 | #define per_cpu(var, cpu) (*per_cpu_ptr(&(var), cpu)) | ^~~~~~~~~~~ net/bridge/netfilter/ebtables.c:1006:22: note: in expansion of macro 'per_cpu' 1006 | s = &per_cpu(ebt_recseq, cpu); | ^~~~~~~ net/bridge/netfilter/ebtables.c:1006:30: note: each undeclared identifier is reported only once for each function it appears in 1006 | s = &per_cpu(ebt_recseq, cpu); | ^~~~~~~~~~ include/linux/percpu-defs.h:219:54: note: in definition of macro '__verify_pcpu_ptr' 219 | const void __percpu *__vpp_verify = (typeof((ptr) + 0))NULL; \ | ^~~ include/linux/percpu-defs.h:263:49: note: in expansion of macro 'VERIFY_PERCPU_PTR' 263 | #define per_cpu_ptr(ptr, cpu) ({ (void)(cpu); VERIFY_PERCPU_PTR(ptr); }) | ^~~~~~~~~~~~~~~~~ include/linux/percpu-defs.h:269:35: note: in expansion of macro 'per_cpu_ptr' 269 | #define per_cpu(var, cpu) (*per_cpu_ptr(&(var), cpu)) | ^~~~~~~~~~~ net/bridge/netfilter/ebtables.c:1006:22: note: in expansion of macro 'per_cpu' 1006 | s = &per_cpu(ebt_recseq, cpu); | ^~~~~~~ net/bridge/netfilter/ebtables.c: In function 'do_replace_finish': net/bridge/netfilter/ebtables.c:1111:42: error: 'ebt_recseq' undeclared (first use in this function); did you mean 'xt_recseq'? 1111 | seqcount_t *s = &per_cpu(ebt_recseq, cpu); | ^~~~~~~~~~ include/linux/percpu-defs.h:219:54: note: in definition of macro '__verify_pcpu_ptr' 219 | const void __percpu *__vpp_verify = (typeof((ptr) + 0))NULL; \ | ^~~ include/linux/percpu-defs.h:263:49: note: in expansion of macro 'VERIFY_PERCPU_PTR' 263 | #define per_cpu_ptr(ptr, cpu) ({ (void)(cpu); VERIFY_PERCPU_PTR(ptr); }) | ^~~~~~~~~~~~~~~~~ include/linux/percpu-defs.h:269:35: note: in expansion of macro 'per_cpu_ptr' 269 | #define per_cpu(var, cpu) (*per_cpu_ptr(&(var), cpu)) | ^~~~~~~~~~~ net/bridge/netfilter/ebtables.c:1111:34: note: in expansion of macro 'per_cpu' 1111 | seqcount_t *s = &per_cpu(ebt_recseq, cpu); | ^~~~~~~ vim +1006 net/bridge/netfilter/ebtables.c 987 988 989 static void get_counters(const struct ebt_counter *oldcounters, 990 struct ebt_counter *counters, unsigned int nentries) 991 { 992 int i, cpu; 993 struct ebt_counter *counter_base; 994 seqcount_t *s; 995 996 /* counters of cpu 0 */ 997 memcpy(counters, oldcounters, 998 sizeof(struct ebt_counter) * nentries); 999 1000 /* add other counters to those of cpu 0 */ 1001 for_each_possible_cpu(cpu) { 1002 1003 if (cpu == 0) 1004 continue; 1005 > 1006 s = &per_cpu(ebt_recseq, cpu); 1007 counter_base = COUNTER_BASE(oldcounters, nentries, cpu); 1008 for (i = 0; i < nentries; i++) { 1009 u64 bcnt, pcnt; 1010 unsigned int start; 1011 1012 do { 1013 start = read_seqcount_begin(s); 1014 bcnt = counter_base[i].bcnt; 1015 pcnt = counter_base[i].pcnt; 1016 } while (read_seqcount_retry(s, start)); 1017 1018 ADD_COUNTER(counters[i], bcnt, pcnt); 1019 cond_resched(); 1020 } 1021 } 1022 } 1023
在 24/9/2024 下午3:43, kernel test robot 写道: > Hi yushengjin, > > kernel test robot noticed the following build errors: > > [auto build test ERROR on netfilter-nf/main] > [also build test ERROR on horms-ipvs/master linus/master v6.11 next-20240924] > [cannot apply to nf-next/master] > [If your patch is applied to the wrong git tree, kindly drop us a note. > And when submitting patch, we suggest to use '--base' as documented in > https://git-scm.com/docs/git-format-patch#_base_tree_information] > > url:https://github.com/intel-lab-lkp/linux/commits/yushengjin/net-bridge-Optimizing-read-write-locks-in-ebtables-c/20240924-102547 > base:https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf.git main > patch link:https://lore.kernel.org/r/2860814445452DE8%2B20240924022437.119730-1-yushengjin%40uniontech.com > patch subject: [PATCH v2] net/bridge: Optimizing read-write locks in ebtables.c > config: sh-allmodconfig (https://download.01.org/0day-ci/archive/20240924/202409241543.F99I82u3-lkp@intel.com/config) > compiler: sh4-linux-gcc (GCC) 14.1.0 > reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240924/202409241543.F99I82u3-lkp@intel.com/reproduce) > > If you fix the issue in a separate patch/commit (i.e. not just a new version of > the same patch/commit), kindly add following tags > | Reported-by: kernel test robot<lkp@intel.com> > | Closes:https://lore.kernel.org/oe-kbuild-all/202409241543.F99I82u3-lkp@intel.com/ > > All errors (new ones prefixed by >>): > > In file included from include/asm-generic/percpu.h:7, > from ./arch/sh/include/generated/asm/percpu.h:1, > from include/linux/irqflags.h:19, > from arch/sh/include/asm/cmpxchg-irq.h:5, > from arch/sh/include/asm/cmpxchg.h:20, > from arch/sh/include/asm/atomic.h:19, > from include/linux/atomic.h:7, > from include/asm-generic/bitops/atomic.h:5, > from arch/sh/include/asm/bitops.h:23, > from include/linux/bitops.h:68, > from include/linux/thread_info.h:27, > from include/asm-generic/preempt.h:5, > from ./arch/sh/include/generated/asm/preempt.h:1, > from include/linux/preempt.h:79, > from include/linux/spinlock.h:56, > from include/linux/mmzone.h:8, > from include/linux/gfp.h:7, > from include/linux/umh.h:4, > from include/linux/kmod.h:9, > from net/bridge/netfilter/ebtables.c:14: > net/bridge/netfilter/ebtables.c: In function 'get_counters': >>> net/bridge/netfilter/ebtables.c:1006:30: error: 'ebt_recseq' undeclared (first use in this function); did you mean 'xt_recseq'? > 1006 | s = &per_cpu(ebt_recseq, cpu); > | ^~~~~~~~~~ > include/linux/percpu-defs.h:219:54: note: in definition of macro '__verify_pcpu_ptr' > 219 | const void __percpu *__vpp_verify = (typeof((ptr) + 0))NULL; \ > | ^~~ > include/linux/percpu-defs.h:263:49: note: in expansion of macro 'VERIFY_PERCPU_PTR' > 263 | #define per_cpu_ptr(ptr, cpu) ({ (void)(cpu); VERIFY_PERCPU_PTR(ptr); }) > | ^~~~~~~~~~~~~~~~~ > include/linux/percpu-defs.h:269:35: note: in expansion of macro 'per_cpu_ptr' > 269 | #define per_cpu(var, cpu) (*per_cpu_ptr(&(var), cpu)) > | ^~~~~~~~~~~ > net/bridge/netfilter/ebtables.c:1006:22: note: in expansion of macro 'per_cpu' > 1006 | s = &per_cpu(ebt_recseq, cpu); > | ^~~~~~~ > net/bridge/netfilter/ebtables.c:1006:30: note: each undeclared identifier is reported only once for each function it appears in > 1006 | s = &per_cpu(ebt_recseq, cpu); > | ^~~~~~~~~~ > include/linux/percpu-defs.h:219:54: note: in definition of macro '__verify_pcpu_ptr' > 219 | const void __percpu *__vpp_verify = (typeof((ptr) + 0))NULL; \ > | ^~~ > include/linux/percpu-defs.h:263:49: note: in expansion of macro 'VERIFY_PERCPU_PTR' > 263 | #define per_cpu_ptr(ptr, cpu) ({ (void)(cpu); VERIFY_PERCPU_PTR(ptr); }) > | ^~~~~~~~~~~~~~~~~ > include/linux/percpu-defs.h:269:35: note: in expansion of macro 'per_cpu_ptr' > 269 | #define per_cpu(var, cpu) (*per_cpu_ptr(&(var), cpu)) > | ^~~~~~~~~~~ > net/bridge/netfilter/ebtables.c:1006:22: note: in expansion of macro 'per_cpu' > 1006 | s = &per_cpu(ebt_recseq, cpu); > | ^~~~~~~ > net/bridge/netfilter/ebtables.c: In function 'do_replace_finish': > net/bridge/netfilter/ebtables.c:1111:42: error: 'ebt_recseq' undeclared (first use in this function); did you mean 'xt_recseq'? > 1111 | seqcount_t *s = &per_cpu(ebt_recseq, cpu); > | ^~~~~~~~~~ > include/linux/percpu-defs.h:219:54: note: in definition of macro '__verify_pcpu_ptr' > 219 | const void __percpu *__vpp_verify = (typeof((ptr) + 0))NULL; \ > | ^~~ > include/linux/percpu-defs.h:263:49: note: in expansion of macro 'VERIFY_PERCPU_PTR' > 263 | #define per_cpu_ptr(ptr, cpu) ({ (void)(cpu); VERIFY_PERCPU_PTR(ptr); }) > | ^~~~~~~~~~~~~~~~~ > include/linux/percpu-defs.h:269:35: note: in expansion of macro 'per_cpu_ptr' > 269 | #define per_cpu(var, cpu) (*per_cpu_ptr(&(var), cpu)) > | ^~~~~~~~~~~ > net/bridge/netfilter/ebtables.c:1111:34: note: in expansion of macro 'per_cpu' > 1111 | seqcount_t *s = &per_cpu(ebt_recseq, cpu); > | ^~~~~~~ > > > vim +1006 net/bridge/netfilter/ebtables.c > > 987 > 988 > 989 static void get_counters(const struct ebt_counter *oldcounters, > 990 struct ebt_counter *counters, unsigned int nentries) > 991 { > 992 int i, cpu; > 993 struct ebt_counter *counter_base; > 994 seqcount_t *s; > 995 > 996 /* counters of cpu 0 */ > 997 memcpy(counters, oldcounters, > 998 sizeof(struct ebt_counter) * nentries); > 999 > 1000 /* add other counters to those of cpu 0 */ > 1001 for_each_possible_cpu(cpu) { > 1002 > 1003 if (cpu == 0) > 1004 continue; > 1005 >> 1006 s = &per_cpu(ebt_recseq, cpu); > 1007 counter_base = COUNTER_BASE(oldcounters, nentries, cpu); > 1008 for (i = 0; i < nentries; i++) { > 1009 u64 bcnt, pcnt; > 1010 unsigned int start; > 1011 > 1012 do { > 1013 start = read_seqcount_begin(s); > 1014 bcnt = counter_base[i].bcnt; > 1015 pcnt = counter_base[i].pcnt; > 1016 } while (read_seqcount_retry(s, start)); > 1017 > 1018 ADD_COUNTER(counters[i], bcnt, pcnt); > 1019 cond_resched(); > 1020 } > 1021 } > 1022 } > 1023 Sorry, it's my fault, I will test it again. > -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
Hi yushengjin, kernel test robot noticed the following build errors: [auto build test ERROR on netfilter-nf/main] [also build test ERROR on horms-ipvs/master linus/master v6.11 next-20240924] [cannot apply to nf-next/master] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/yushengjin/net-bridge-Optimizing-read-write-locks-in-ebtables-c/20240924-102547 base: https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf.git main patch link: https://lore.kernel.org/r/2860814445452DE8%2B20240924022437.119730-1-yushengjin%40uniontech.com patch subject: [PATCH v2] net/bridge: Optimizing read-write locks in ebtables.c config: mips-bmips_stb_defconfig (https://download.01.org/0day-ci/archive/20240924/202409241627.NkoKxMEE-lkp@intel.com/config) compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project 8663a75fa2f31299ab8d1d90288d9df92aadee88) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240924/202409241627.NkoKxMEE-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202409241627.NkoKxMEE-lkp@intel.com/ All errors (new ones prefixed by >>): In file included from net/bridge/netfilter/ebtables.c:17: In file included from include/linux/netfilter/x_tables.h:6: In file included from include/linux/netdevice.h:38: In file included from include/net/net_namespace.h:43: In file included from include/linux/skbuff.h:17: In file included from include/linux/bvec.h:10: In file included from include/linux/highmem.h:8: In file included from include/linux/cacheflush.h:5: In file included from arch/mips/include/asm/cacheflush.h:13: In file included from include/linux/mm.h:2232: include/linux/vmstat.h:517:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion] 517 | return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_" | ~~~~~~~~~~~ ^ ~~~ >> net/bridge/netfilter/ebtables.c:1006:16: error: use of undeclared identifier 'ebt_recseq'; did you mean 'xt_recseq'? 1006 | s = &per_cpu(ebt_recseq, cpu); | ^~~~~~~~~~ | xt_recseq include/linux/percpu-defs.h:269:43: note: expanded from macro 'per_cpu' 269 | #define per_cpu(var, cpu) (*per_cpu_ptr(&(var), cpu)) | ^ include/linux/percpu-defs.h:235:20: note: expanded from macro 'per_cpu_ptr' 235 | __verify_pcpu_ptr(ptr); \ | ^ include/linux/percpu-defs.h:219:47: note: expanded from macro '__verify_pcpu_ptr' 219 | const void __percpu *__vpp_verify = (typeof((ptr) + 0))NULL; \ | ^ include/linux/netfilter/x_tables.h:346:29: note: 'xt_recseq' declared here 346 | DECLARE_PER_CPU(seqcount_t, xt_recseq); | ^ >> net/bridge/netfilter/ebtables.c:1006:16: error: use of undeclared identifier 'ebt_recseq'; did you mean 'xt_recseq'? 1006 | s = &per_cpu(ebt_recseq, cpu); | ^~~~~~~~~~ | xt_recseq include/linux/percpu-defs.h:269:43: note: expanded from macro 'per_cpu' 269 | #define per_cpu(var, cpu) (*per_cpu_ptr(&(var), cpu)) | ^ include/linux/percpu-defs.h:236:20: note: expanded from macro 'per_cpu_ptr' 236 | SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu))); \ | ^ include/linux/percpu-defs.h:231:23: note: expanded from macro 'SHIFT_PERCPU_PTR' 231 | RELOC_HIDE((typeof(*(__p)) __kernel __force *)(__p), (__offset)) | ^ include/linux/compiler.h:177:31: note: expanded from macro 'RELOC_HIDE' 177 | __ptr = (unsigned long) (ptr); \ | ^ include/linux/netfilter/x_tables.h:346:29: note: 'xt_recseq' declared here 346 | DECLARE_PER_CPU(seqcount_t, xt_recseq); | ^ >> net/bridge/netfilter/ebtables.c:1006:16: error: use of undeclared identifier 'ebt_recseq'; did you mean 'xt_recseq'? 1006 | s = &per_cpu(ebt_recseq, cpu); | ^~~~~~~~~~ | xt_recseq include/linux/percpu-defs.h:269:43: note: expanded from macro 'per_cpu' 269 | #define per_cpu(var, cpu) (*per_cpu_ptr(&(var), cpu)) | ^ include/linux/percpu-defs.h:236:20: note: expanded from macro 'per_cpu_ptr' 236 | SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu))); \ | ^ include/linux/percpu-defs.h:231:49: note: expanded from macro 'SHIFT_PERCPU_PTR' 231 | RELOC_HIDE((typeof(*(__p)) __kernel __force *)(__p), (__offset)) | ^ include/linux/compiler.h:177:31: note: expanded from macro 'RELOC_HIDE' 177 | __ptr = (unsigned long) (ptr); \ | ^ include/linux/netfilter/x_tables.h:346:29: note: 'xt_recseq' declared here 346 | DECLARE_PER_CPU(seqcount_t, xt_recseq); | ^ >> net/bridge/netfilter/ebtables.c:1006:16: error: use of undeclared identifier 'ebt_recseq'; did you mean 'xt_recseq'? 1006 | s = &per_cpu(ebt_recseq, cpu); | ^~~~~~~~~~ | xt_recseq include/linux/percpu-defs.h:269:43: note: expanded from macro 'per_cpu' 269 | #define per_cpu(var, cpu) (*per_cpu_ptr(&(var), cpu)) | ^ include/linux/percpu-defs.h:236:20: note: expanded from macro 'per_cpu_ptr' 236 | SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu))); \ | ^ include/linux/percpu-defs.h:231:23: note: expanded from macro 'SHIFT_PERCPU_PTR' 231 | RELOC_HIDE((typeof(*(__p)) __kernel __force *)(__p), (__offset)) | ^ include/linux/compiler.h:178:13: note: expanded from macro 'RELOC_HIDE' 178 | (typeof(ptr)) (__ptr + (off)); }) | ^ include/linux/netfilter/x_tables.h:346:29: note: 'xt_recseq' declared here 346 | DECLARE_PER_CPU(seqcount_t, xt_recseq); | ^ >> net/bridge/netfilter/ebtables.c:1006:16: error: use of undeclared identifier 'ebt_recseq'; did you mean 'xt_recseq'? 1006 | s = &per_cpu(ebt_recseq, cpu); | ^~~~~~~~~~ | xt_recseq include/linux/percpu-defs.h:269:43: note: expanded from macro 'per_cpu' 269 | #define per_cpu(var, cpu) (*per_cpu_ptr(&(var), cpu)) | ^ include/linux/percpu-defs.h:236:20: note: expanded from macro 'per_cpu_ptr' 236 | SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu))); \ | ^ include/linux/percpu-defs.h:231:49: note: expanded from macro 'SHIFT_PERCPU_PTR' 231 | RELOC_HIDE((typeof(*(__p)) __kernel __force *)(__p), (__offset)) | ^ include/linux/compiler.h:178:13: note: expanded from macro 'RELOC_HIDE' 178 | (typeof(ptr)) (__ptr + (off)); }) | ^ include/linux/netfilter/x_tables.h:346:29: note: 'xt_recseq' declared here 346 | DECLARE_PER_CPU(seqcount_t, xt_recseq); | ^ net/bridge/netfilter/ebtables.c:1111:28: error: use of undeclared identifier 'ebt_recseq'; did you mean 'xt_recseq'? 1111 | seqcount_t *s = &per_cpu(ebt_recseq, cpu); | ^~~~~~~~~~ | xt_recseq include/linux/percpu-defs.h:269:43: note: expanded from macro 'per_cpu' 269 | #define per_cpu(var, cpu) (*per_cpu_ptr(&(var), cpu)) | ^ include/linux/percpu-defs.h:235:20: note: expanded from macro 'per_cpu_ptr' 235 | __verify_pcpu_ptr(ptr); \ | ^ include/linux/percpu-defs.h:219:47: note: expanded from macro '__verify_pcpu_ptr' 219 | const void __percpu *__vpp_verify = (typeof((ptr) + 0))NULL; \ | ^ include/linux/netfilter/x_tables.h:346:29: note: 'xt_recseq' declared here 346 | DECLARE_PER_CPU(seqcount_t, xt_recseq); | ^ net/bridge/netfilter/ebtables.c:1111:28: error: use of undeclared identifier 'ebt_recseq'; did you mean 'xt_recseq'? 1111 | seqcount_t *s = &per_cpu(ebt_recseq, cpu); | ^~~~~~~~~~ | xt_recseq include/linux/percpu-defs.h:269:43: note: expanded from macro 'per_cpu' 269 | #define per_cpu(var, cpu) (*per_cpu_ptr(&(var), cpu)) | ^ include/linux/percpu-defs.h:236:20: note: expanded from macro 'per_cpu_ptr' 236 | SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu))); \ | ^ include/linux/percpu-defs.h:231:23: note: expanded from macro 'SHIFT_PERCPU_PTR' 231 | RELOC_HIDE((typeof(*(__p)) __kernel __force *)(__p), (__offset)) | ^ include/linux/compiler.h:177:31: note: expanded from macro 'RELOC_HIDE' 177 | __ptr = (unsigned long) (ptr); \ | ^ include/linux/netfilter/x_tables.h:346:29: note: 'xt_recseq' declared here 346 | DECLARE_PER_CPU(seqcount_t, xt_recseq); | ^ net/bridge/netfilter/ebtables.c:1111:28: error: use of undeclared identifier 'ebt_recseq'; did you mean 'xt_recseq'? 1111 | seqcount_t *s = &per_cpu(ebt_recseq, cpu); | ^~~~~~~~~~ | xt_recseq include/linux/percpu-defs.h:269:43: note: expanded from macro 'per_cpu' 269 | #define per_cpu(var, cpu) (*per_cpu_ptr(&(var), cpu)) | ^ include/linux/percpu-defs.h:236:20: note: expanded from macro 'per_cpu_ptr' 236 | SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu))); \ | ^ include/linux/percpu-defs.h:231:49: note: expanded from macro 'SHIFT_PERCPU_PTR' 231 | RELOC_HIDE((typeof(*(__p)) __kernel __force *)(__p), (__offset)) | ^ include/linux/compiler.h:177:31: note: expanded from macro 'RELOC_HIDE' 177 | __ptr = (unsigned long) (ptr); \ | ^ include/linux/netfilter/x_tables.h:346:29: note: 'xt_recseq' declared here 346 | DECLARE_PER_CPU(seqcount_t, xt_recseq); | ^ net/bridge/netfilter/ebtables.c:1111:28: error: use of undeclared identifier 'ebt_recseq'; did you mean 'xt_recseq'? 1111 | seqcount_t *s = &per_cpu(ebt_recseq, cpu); | ^~~~~~~~~~ | xt_recseq include/linux/percpu-defs.h:269:43: note: expanded from macro 'per_cpu' 269 | #define per_cpu(var, cpu) (*per_cpu_ptr(&(var), cpu)) | ^ include/linux/percpu-defs.h:236:20: note: expanded from macro 'per_cpu_ptr' 236 | SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu))); \ | ^ include/linux/percpu-defs.h:231:23: note: expanded from macro 'SHIFT_PERCPU_PTR' 231 | RELOC_HIDE((typeof(*(__p)) __kernel __force *)(__p), (__offset)) | ^ include/linux/compiler.h:178:13: note: expanded from macro 'RELOC_HIDE' 178 | (typeof(ptr)) (__ptr + (off)); }) | ^ include/linux/netfilter/x_tables.h:346:29: note: 'xt_recseq' declared here 346 | DECLARE_PER_CPU(seqcount_t, xt_recseq); | ^ net/bridge/netfilter/ebtables.c:1111:28: error: use of undeclared identifier 'ebt_recseq'; did you mean 'xt_recseq'? 1111 | seqcount_t *s = &per_cpu(ebt_recseq, cpu); | ^~~~~~~~~~ | xt_recseq include/linux/percpu-defs.h:269:43: note: expanded from macro 'per_cpu' 269 | #define per_cpu(var, cpu) (*per_cpu_ptr(&(var), cpu)) | ^ include/linux/percpu-defs.h:236:20: note: expanded from macro 'per_cpu_ptr' 236 | SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu))); \ vim +1006 net/bridge/netfilter/ebtables.c 987 988 989 static void get_counters(const struct ebt_counter *oldcounters, 990 struct ebt_counter *counters, unsigned int nentries) 991 { 992 int i, cpu; 993 struct ebt_counter *counter_base; 994 seqcount_t *s; 995 996 /* counters of cpu 0 */ 997 memcpy(counters, oldcounters, 998 sizeof(struct ebt_counter) * nentries); 999 1000 /* add other counters to those of cpu 0 */ 1001 for_each_possible_cpu(cpu) { 1002 1003 if (cpu == 0) 1004 continue; 1005 > 1006 s = &per_cpu(ebt_recseq, cpu); 1007 counter_base = COUNTER_BASE(oldcounters, nentries, cpu); 1008 for (i = 0; i < nentries; i++) { 1009 u64 bcnt, pcnt; 1010 unsigned int start; 1011 1012 do { 1013 start = read_seqcount_begin(s); 1014 bcnt = counter_base[i].bcnt; 1015 pcnt = counter_base[i].pcnt; 1016 } while (read_seqcount_retry(s, start)); 1017 1018 ADD_COUNTER(counters[i], bcnt, pcnt); 1019 cond_resched(); 1020 } 1021 } 1022 } 1023
diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h index fd533552a062..15aad1e479d7 100644 --- a/include/linux/netfilter_bridge/ebtables.h +++ b/include/linux/netfilter_bridge/ebtables.h @@ -93,7 +93,6 @@ struct ebt_table { char name[EBT_TABLE_MAXNAMELEN]; struct ebt_replace_kernel *table; unsigned int valid_hooks; - rwlock_t lock; /* the data used by the kernel */ struct ebt_table_info *private; struct nf_hook_ops *ops; diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 3e67d4aff419..d7db7380fcbb 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -204,11 +204,14 @@ unsigned int ebt_do_table(void *priv, struct sk_buff *skb, const char *base; const struct ebt_table_info *private; struct xt_action_param acpar; + unsigned int addend; acpar.state = state; acpar.hotdrop = false; - read_lock_bh(&table->lock); + local_bh_disable(); + addend = xt_write_recseq_begin(); + private = table->private; cb_base = COUNTER_BASE(private->counters, private->nentries, smp_processor_id()); @@ -229,10 +232,8 @@ unsigned int ebt_do_table(void *priv, struct sk_buff *skb, if (EBT_MATCH_ITERATE(point, ebt_do_match, skb, &acpar) != 0) goto letscontinue; - if (acpar.hotdrop) { - read_unlock_bh(&table->lock); - return NF_DROP; - } + if (acpar.hotdrop) + goto drop_out; ADD_COUNTER(*(counter_base + i), skb->len, 1); @@ -251,13 +252,13 @@ unsigned int ebt_do_table(void *priv, struct sk_buff *skb, verdict = t->u.target->target(skb, &acpar); } if (verdict == EBT_ACCEPT) { - read_unlock_bh(&table->lock); + xt_write_recseq_end(addend); + local_bh_enable(); return NF_ACCEPT; } - if (verdict == EBT_DROP) { - read_unlock_bh(&table->lock); - return NF_DROP; - } + if (verdict == EBT_DROP) + goto drop_out; + if (verdict == EBT_RETURN) { letsreturn: if (WARN(sp == 0, "RETURN on base chain")) { @@ -278,10 +279,8 @@ unsigned int ebt_do_table(void *priv, struct sk_buff *skb, if (verdict == EBT_CONTINUE) goto letscontinue; - if (WARN(verdict < 0, "bogus standard verdict\n")) { - read_unlock_bh(&table->lock); - return NF_DROP; - } + if (WARN(verdict < 0, "bogus standard verdict\n")) + goto drop_out; /* jump to a udc */ cs[sp].n = i + 1; @@ -290,10 +289,8 @@ unsigned int ebt_do_table(void *priv, struct sk_buff *skb, i = 0; chaininfo = (struct ebt_entries *) (base + verdict); - if (WARN(chaininfo->distinguisher, "jump to non-chain\n")) { - read_unlock_bh(&table->lock); - return NF_DROP; - } + if (WARN(chaininfo->distinguisher, "jump to non-chain\n")) + goto drop_out; nentries = chaininfo->nentries; point = (struct ebt_entry *)chaininfo->data; @@ -309,10 +306,15 @@ unsigned int ebt_do_table(void *priv, struct sk_buff *skb, if (chaininfo->policy == EBT_RETURN) goto letsreturn; if (chaininfo->policy == EBT_ACCEPT) { - read_unlock_bh(&table->lock); + xt_write_recseq_end(addend); + local_bh_enable(); return NF_ACCEPT; } - read_unlock_bh(&table->lock); + +drop_out: + xt_write_recseq_end(addend); + local_bh_enable(); + return NF_DROP; } @@ -983,12 +985,48 @@ static int translate_table(struct net *net, const char *name, return ret; } -/* called under write_lock */ + static void get_counters(const struct ebt_counter *oldcounters, struct ebt_counter *counters, unsigned int nentries) { int i, cpu; struct ebt_counter *counter_base; + seqcount_t *s; + + /* counters of cpu 0 */ + memcpy(counters, oldcounters, + sizeof(struct ebt_counter) * nentries); + + /* add other counters to those of cpu 0 */ + for_each_possible_cpu(cpu) { + + if (cpu == 0) + continue; + + s = &per_cpu(ebt_recseq, cpu); + counter_base = COUNTER_BASE(oldcounters, nentries, cpu); + for (i = 0; i < nentries; i++) { + u64 bcnt, pcnt; + unsigned int start; + + do { + start = read_seqcount_begin(s); + bcnt = counter_base[i].bcnt; + pcnt = counter_base[i].pcnt; + } while (read_seqcount_retry(s, start)); + + ADD_COUNTER(counters[i], bcnt, pcnt); + cond_resched(); + } + } +} + + +static void get_old_counters(const struct ebt_counter *oldcounters, + struct ebt_counter *counters, unsigned int nentries) +{ + int i, cpu; + struct ebt_counter *counter_base; /* counters of cpu 0 */ memcpy(counters, oldcounters, @@ -1013,6 +1051,7 @@ static int do_replace_finish(struct net *net, struct ebt_replace *repl, /* used to be able to unlock earlier */ struct ebt_table_info *table; struct ebt_table *t; + unsigned int cpu; /* the user wants counters back * the check on the size is done later, when we have the lock @@ -1050,6 +1089,8 @@ static int do_replace_finish(struct net *net, struct ebt_replace *repl, goto free_unlock; } + local_bh_disable(); + /* we have the mutex lock, so no danger in reading this pointer */ table = t->private; /* make sure the table can only be rmmod'ed if it contains no rules */ @@ -1058,15 +1099,31 @@ static int do_replace_finish(struct net *net, struct ebt_replace *repl, goto free_unlock; } else if (table->nentries && !newinfo->nentries) module_put(t->me); - /* we need an atomic snapshot of the counters */ - write_lock_bh(&t->lock); - if (repl->num_counters) - get_counters(t->private->counters, counterstmp, - t->private->nentries); + smp_wmb(); t->private = newinfo; - write_unlock_bh(&t->lock); + smp_mb(); + + local_bh_enable(); + + // wait for even ebt_recseq on all cpus + for_each_possible_cpu(cpu) { + seqcount_t *s = &per_cpu(ebt_recseq, cpu); + u32 seq = raw_read_seqcount(s); + + if (seq & 1) { + do { + cond_resched(); + cpu_relax(); + } while (seq == raw_read_seqcount(s)); + } + } + mutex_unlock(&ebt_mutex); + + if (repl->num_counters) + get_old_counters(table->counters, counterstmp, table->nentries); + /* so, a user can change the chains while having messed up her counter * allocation. Only reason why this is done is because this way the lock * is held only once, while this doesn't bring the kernel into a @@ -1093,6 +1150,7 @@ static int do_replace_finish(struct net *net, struct ebt_replace *repl, return 0; free_unlock: + local_bh_enable(); mutex_unlock(&ebt_mutex); free_iterate: EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size, @@ -1235,7 +1293,6 @@ int ebt_register_table(struct net *net, const struct ebt_table *input_table, goto free_chainstack; table->private = newinfo; - rwlock_init(&table->lock); mutex_lock(&ebt_mutex); list_for_each_entry(t, &ebt_net->tables, list) { if (strcmp(t->name, table->name) == 0) { @@ -1382,6 +1439,7 @@ static int do_update_counters(struct net *net, const char *name, int i, ret; struct ebt_counter *tmp; struct ebt_table *t; + unsigned int addend; if (num_counters == 0) return -EINVAL; @@ -1405,14 +1463,16 @@ static int do_update_counters(struct net *net, const char *name, goto unlock_mutex; } - /* we want an atomic add of the counters */ - write_lock_bh(&t->lock); + local_bh_disable(); + addend = xt_write_recseq_begin(); /* we add to the counters of the first cpu */ for (i = 0; i < num_counters; i++) ADD_COUNTER(t->private->counters[i], tmp[i].bcnt, tmp[i].pcnt); - write_unlock_bh(&t->lock); + xt_write_recseq_end(addend); + local_bh_enable(); + ret = 0; unlock_mutex: mutex_unlock(&ebt_mutex); @@ -1530,9 +1590,7 @@ static int copy_counters_to_user(struct ebt_table *t, if (!counterstmp) return -ENOMEM; - write_lock_bh(&t->lock); get_counters(oldcounters, counterstmp, nentries); - write_unlock_bh(&t->lock); if (copy_to_user(user, counterstmp, array_size(nentries, sizeof(struct ebt_counter))))
When conducting WRK testing, the CPU usage rate of the testing machine was 100%. forwarding through a bridge, if the network load is too high, it may cause abnormal load on the ebt_do_table of the kernel ebtable module, leading to excessive soft interrupts and sometimes even directly causing CPU soft deadlocks. After analysis, it was found that the code of ebtables had not been optimized for a long time, and the read-write locks inside still existed. However, other arp/ip/ip6 tables had already been optimized a lot, and performance bottlenecks in read-write locks had been discovered a long time ago. Ref link: https://lore.kernel.org/lkml/20090428092411.5331c4a1@nehalam/ So I referred to arp/ip/ip6 modification methods to optimize the read-write lock in ebtables.c. test method: 1) Test machine creates bridge : ``` bash brctl addbr br-a brctl addbr br-b brctl addif br-a enp1s0f0 enp1s0f1 brctl addif br-b enp130s0f0 enp130s0f1 ifconfig br-a up ifconfig br-b up ``` 2) Testing with another machine: ``` bash ulimit -n 2048 ./wrk -t48 -c2000 -d6000 -R10000 -s request.lua http://4.4.4.2:80/4k.html & ./wrk -t48 -c2000 -d6000 -R10000 -s request.lua http://5.5.5.2:80/4k.html & ``` Suggested-by: Eric Dumazet <edumazet@google.com> Signed-off-by: yushengjin <yushengjin@uniontech.com> Link: https://lore.kernel.org/all/CANn89iJCBRCM3aHDy-7gxWu_+agXC9M1R=hwFuh2G9RSLu_6bg@mail.gmail.com/ --- include/linux/netfilter_bridge/ebtables.h | 1 - net/bridge/netfilter/ebtables.c | 124 ++++++++++++++++------ 2 files changed, 91 insertions(+), 34 deletions(-)