netfilter: x_tables: don't use seqlock when fetching old counters
after previous commit xt_replace_table will wait until all cpus had even seqcount (i.e., no cpu is accessing old ruleset). Add a 'old' counter retrival version that doesn't synchronize counters. Its not needed, the old counters are not in use anymore at this point. This speeds up table replacement on busy systems with large tables (and many cores). Cc: Dan Williams <dcbw@redhat.com> Cc: Eric Dumazet <edumazet@google.com> Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
80055dab5d
commit
d13e7b2e65
|
@ -634,6 +634,25 @@ static void get_counters(const struct xt_table_info *t,
|
|||
}
|
||||
}
|
||||
|
||||
static void get_old_counters(const struct xt_table_info *t,
|
||||
struct xt_counters counters[])
|
||||
{
|
||||
struct arpt_entry *iter;
|
||||
unsigned int cpu, i;
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
i = 0;
|
||||
xt_entry_foreach(iter, t->entries, t->size) {
|
||||
struct xt_counters *tmp;
|
||||
|
||||
tmp = xt_get_per_cpu_counter(&iter->counters, cpu);
|
||||
ADD_COUNTER(counters[i], tmp->bcnt, tmp->pcnt);
|
||||
++i;
|
||||
}
|
||||
cond_resched();
|
||||
}
|
||||
}
|
||||
|
||||
static struct xt_counters *alloc_counters(const struct xt_table *table)
|
||||
{
|
||||
unsigned int countersize;
|
||||
|
@ -910,8 +929,7 @@ static int __do_replace(struct net *net, const char *name,
|
|||
(newinfo->number <= oldinfo->initial_entries))
|
||||
module_put(t->me);
|
||||
|
||||
/* Get the old counters, and synchronize with replace */
|
||||
get_counters(oldinfo, counters);
|
||||
get_old_counters(oldinfo, counters);
|
||||
|
||||
/* Decrease module usage counts and free resource */
|
||||
loc_cpu_old_entry = oldinfo->entries;
|
||||
|
|
|
@ -781,6 +781,26 @@ get_counters(const struct xt_table_info *t,
|
|||
}
|
||||
}
|
||||
|
||||
static void get_old_counters(const struct xt_table_info *t,
|
||||
struct xt_counters counters[])
|
||||
{
|
||||
struct ipt_entry *iter;
|
||||
unsigned int cpu, i;
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
i = 0;
|
||||
xt_entry_foreach(iter, t->entries, t->size) {
|
||||
const struct xt_counters *tmp;
|
||||
|
||||
tmp = xt_get_per_cpu_counter(&iter->counters, cpu);
|
||||
ADD_COUNTER(counters[i], tmp->bcnt, tmp->pcnt);
|
||||
++i; /* macro does multi eval of i */
|
||||
}
|
||||
|
||||
cond_resched();
|
||||
}
|
||||
}
|
||||
|
||||
static struct xt_counters *alloc_counters(const struct xt_table *table)
|
||||
{
|
||||
unsigned int countersize;
|
||||
|
@ -1070,8 +1090,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
|
|||
(newinfo->number <= oldinfo->initial_entries))
|
||||
module_put(t->me);
|
||||
|
||||
/* Get the old counters, and synchronize with replace */
|
||||
get_counters(oldinfo, counters);
|
||||
get_old_counters(oldinfo, counters);
|
||||
|
||||
/* Decrease module usage counts and free resource */
|
||||
xt_entry_foreach(iter, oldinfo->entries, oldinfo->size)
|
||||
|
|
|
@ -800,6 +800,25 @@ get_counters(const struct xt_table_info *t,
|
|||
}
|
||||
}
|
||||
|
||||
static void get_old_counters(const struct xt_table_info *t,
|
||||
struct xt_counters counters[])
|
||||
{
|
||||
struct ip6t_entry *iter;
|
||||
unsigned int cpu, i;
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
i = 0;
|
||||
xt_entry_foreach(iter, t->entries, t->size) {
|
||||
const struct xt_counters *tmp;
|
||||
|
||||
tmp = xt_get_per_cpu_counter(&iter->counters, cpu);
|
||||
ADD_COUNTER(counters[i], tmp->bcnt, tmp->pcnt);
|
||||
++i;
|
||||
}
|
||||
cond_resched();
|
||||
}
|
||||
}
|
||||
|
||||
static struct xt_counters *alloc_counters(const struct xt_table *table)
|
||||
{
|
||||
unsigned int countersize;
|
||||
|
@ -1090,8 +1109,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
|
|||
(newinfo->number <= oldinfo->initial_entries))
|
||||
module_put(t->me);
|
||||
|
||||
/* Get the old counters, and synchronize with replace */
|
||||
get_counters(oldinfo, counters);
|
||||
get_old_counters(oldinfo, counters);
|
||||
|
||||
/* Decrease module usage counts and free resource */
|
||||
xt_entry_foreach(iter, oldinfo->entries, oldinfo->size)
|
||||
|
|
Loading…
Reference in New Issue