Skip to content

Commit 24b36f0

Browse files
Eric Dumazetkaber
authored andcommitted
netfilter: {ip,ip6,arp}_tables: dont block bottom half more than necessary
We currently disable BH for the whole duration of get_counters() On machines with a lot of cpus and large tables, this might be too long. We can disable preemption during the whole function, and disable BH only while fetching counters for the current cpu. Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: Patrick McHardy <kaber@trash.net>
1 parent 7df0884 commit 24b36f0

File tree

3 files changed

+18
-12
lines changed

3 files changed

+18
-12
lines changed

net/ipv4/netfilter/arp_tables.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,7 @@ static void get_counters(const struct xt_table_info *t,
710710
struct arpt_entry *iter;
711711
unsigned int cpu;
712712
unsigned int i;
713-
unsigned int curcpu;
713+
unsigned int curcpu = get_cpu();
714714

715715
/* Instead of clearing (by a previous call to memset())
716716
* the counters and using adds, we set the counters
@@ -720,14 +720,16 @@ static void get_counters(const struct xt_table_info *t,
720720
* if new softirq were to run and call ipt_do_table
721721
*/
722722
local_bh_disable();
723-
curcpu = smp_processor_id();
724-
725723
i = 0;
726724
xt_entry_foreach(iter, t->entries[curcpu], t->size) {
727725
SET_COUNTER(counters[i], iter->counters.bcnt,
728726
iter->counters.pcnt);
729727
++i;
730728
}
729+
local_bh_enable();
730+
/* Processing counters from other cpus, we can let bottom half enabled,
731+
* (preemption is disabled)
732+
*/
731733

732734
for_each_possible_cpu(cpu) {
733735
if (cpu == curcpu)
@@ -741,7 +743,7 @@ static void get_counters(const struct xt_table_info *t,
741743
}
742744
xt_info_wrunlock(cpu);
743745
}
744-
local_bh_enable();
746+
put_cpu();
745747
}
746748

747749
static struct xt_counters *alloc_counters(const struct xt_table *table)

net/ipv4/netfilter/ip_tables.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -884,7 +884,7 @@ get_counters(const struct xt_table_info *t,
884884
struct ipt_entry *iter;
885885
unsigned int cpu;
886886
unsigned int i;
887-
unsigned int curcpu;
887+
unsigned int curcpu = get_cpu();
888888

889889
/* Instead of clearing (by a previous call to memset())
890890
* the counters and using adds, we set the counters
@@ -894,14 +894,16 @@ get_counters(const struct xt_table_info *t,
894894
* if new softirq were to run and call ipt_do_table
895895
*/
896896
local_bh_disable();
897-
curcpu = smp_processor_id();
898-
899897
i = 0;
900898
xt_entry_foreach(iter, t->entries[curcpu], t->size) {
901899
SET_COUNTER(counters[i], iter->counters.bcnt,
902900
iter->counters.pcnt);
903901
++i;
904902
}
903+
local_bh_enable();
904+
/* Processing counters from other cpus, we can let bottom half enabled,
905+
* (preemption is disabled)
906+
*/
905907

906908
for_each_possible_cpu(cpu) {
907909
if (cpu == curcpu)
@@ -915,7 +917,7 @@ get_counters(const struct xt_table_info *t,
915917
}
916918
xt_info_wrunlock(cpu);
917919
}
918-
local_bh_enable();
920+
put_cpu();
919921
}
920922

921923
static struct xt_counters *alloc_counters(const struct xt_table *table)

net/ipv6/netfilter/ip6_tables.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -897,7 +897,7 @@ get_counters(const struct xt_table_info *t,
897897
struct ip6t_entry *iter;
898898
unsigned int cpu;
899899
unsigned int i;
900-
unsigned int curcpu;
900+
unsigned int curcpu = get_cpu();
901901

902902
/* Instead of clearing (by a previous call to memset())
903903
* the counters and using adds, we set the counters
@@ -907,14 +907,16 @@ get_counters(const struct xt_table_info *t,
907907
* if new softirq were to run and call ipt_do_table
908908
*/
909909
local_bh_disable();
910-
curcpu = smp_processor_id();
911-
912910
i = 0;
913911
xt_entry_foreach(iter, t->entries[curcpu], t->size) {
914912
SET_COUNTER(counters[i], iter->counters.bcnt,
915913
iter->counters.pcnt);
916914
++i;
917915
}
916+
local_bh_enable();
917+
/* Processing counters from other cpus, we can let bottom half enabled,
918+
* (preemption is disabled)
919+
*/
918920

919921
for_each_possible_cpu(cpu) {
920922
if (cpu == curcpu)
@@ -928,7 +930,7 @@ get_counters(const struct xt_table_info *t,
928930
}
929931
xt_info_wrunlock(cpu);
930932
}
931-
local_bh_enable();
933+
put_cpu();
932934
}
933935

934936
static struct xt_counters *alloc_counters(const struct xt_table *table)

0 commit comments

Comments
 (0)