Change how synchronization is done on the iptables counters. Use seqcount wrapper instead of depending on reader/writer lock. Signed-off-by: Stephen Hemminger --- a/net/netfilter/x_tables.c 2009-01-30 09:15:52.648542116 -0800 +++ b/net/netfilter/x_tables.c 2009-01-30 09:17:03.669061821 -0800 @@ -577,18 +577,36 @@ int xt_compat_target_to_user(struct xt_e EXPORT_SYMBOL_GPL(xt_compat_target_to_user); #endif +static DEFINE_PER_CPU(seqcount_t, xt_counter_sequence); + +/* Update the counters on the current CPU. preempt must be disabled. */ void xt_add_counter(struct xt_counters *c, unsigned b, unsigned p) { + seqcount_t *seq = &__get_cpu_var(xt_counter_sequence); + + write_seqcount_begin(seq); c->bcnt += b; c->pcnt += p; + write_seqcount_end(seq); } EXPORT_SYMBOL_GPL(xt_add_counter); +/* Fetch counters on other CPU. */ void xt_sum_counter(struct xt_counters *t, int cpu, const struct xt_counters *c) { - t->pcnt += c->pcnt; - t->bcnt += c->bcnt; + seqcount_t *seq = &per_cpu(xt_counter_sequence, cpu); + unsigned start; + struct xt_counters v; + + /* Atomic fetch of counter value */ + do { + start = read_seqcount_begin(seq); + v = *c; + } while (read_seqcount_retry(seq, start)); + + t->pcnt += v.pcnt; + t->bcnt += v.bcnt; } EXPORT_SYMBOL_GPL(xt_sum_counter); -- -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html