aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-01-11 18:43:03 -0500
committerDavid S. Miller <davem@davemloft.net>2011-01-11 18:43:03 -0500
commit60dbb011df9764294284cc3e70f935eaa462e15e (patch)
tree7bf7672001c3fc87850895577f22c0f6dc4c1138
parent4b0ef1f223be4e092632b4152ceec5627ac10f59 (diff)
parent2f46e07995734a363608e974a82fd05d5b610750 (diff)
Merge branch 'master' of git://1984.lsi.us.es/net-2.6
-rw-r--r--include/linux/if_bridge.h2
-rw-r--r--include/linux/netfilter/x_tables.h10
-rw-r--r--net/ipv4/netfilter/arp_tables.c45
-rw-r--r--net/ipv4/netfilter/ip_tables.c45
-rw-r--r--net/ipv6/netfilter/ip6_tables.c45
-rw-r--r--net/netfilter/nf_conntrack_netlink.c14
-rw-r--r--net/netfilter/x_tables.c3
7 files changed, 55 insertions, 109 deletions
diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h
index f7e73c338c40..dd3f20139640 100644
--- a/include/linux/if_bridge.h
+++ b/include/linux/if_bridge.h
@@ -103,7 +103,7 @@ struct __fdb_entry {
103 103
104extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *)); 104extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *));
105 105
106typedef int (*br_should_route_hook_t)(struct sk_buff *skb); 106typedef int br_should_route_hook_t(struct sk_buff *skb);
107extern br_should_route_hook_t __rcu *br_should_route_hook; 107extern br_should_route_hook_t __rcu *br_should_route_hook;
108 108
109#endif 109#endif
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index 742bec051440..6712e713b299 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -472,7 +472,7 @@ extern void xt_free_table_info(struct xt_table_info *info);
472 * necessary for reading the counters. 472 * necessary for reading the counters.
473 */ 473 */
474struct xt_info_lock { 474struct xt_info_lock {
475 spinlock_t lock; 475 seqlock_t lock;
476 unsigned char readers; 476 unsigned char readers;
477}; 477};
478DECLARE_PER_CPU(struct xt_info_lock, xt_info_locks); 478DECLARE_PER_CPU(struct xt_info_lock, xt_info_locks);
@@ -497,7 +497,7 @@ static inline void xt_info_rdlock_bh(void)
497 local_bh_disable(); 497 local_bh_disable();
498 lock = &__get_cpu_var(xt_info_locks); 498 lock = &__get_cpu_var(xt_info_locks);
499 if (likely(!lock->readers++)) 499 if (likely(!lock->readers++))
500 spin_lock(&lock->lock); 500 write_seqlock(&lock->lock);
501} 501}
502 502
503static inline void xt_info_rdunlock_bh(void) 503static inline void xt_info_rdunlock_bh(void)
@@ -505,7 +505,7 @@ static inline void xt_info_rdunlock_bh(void)
505 struct xt_info_lock *lock = &__get_cpu_var(xt_info_locks); 505 struct xt_info_lock *lock = &__get_cpu_var(xt_info_locks);
506 506
507 if (likely(!--lock->readers)) 507 if (likely(!--lock->readers))
508 spin_unlock(&lock->lock); 508 write_sequnlock(&lock->lock);
509 local_bh_enable(); 509 local_bh_enable();
510} 510}
511 511
@@ -516,12 +516,12 @@ static inline void xt_info_rdunlock_bh(void)
516 */ 516 */
517static inline void xt_info_wrlock(unsigned int cpu) 517static inline void xt_info_wrlock(unsigned int cpu)
518{ 518{
519 spin_lock(&per_cpu(xt_info_locks, cpu).lock); 519 write_seqlock(&per_cpu(xt_info_locks, cpu).lock);
520} 520}
521 521
522static inline void xt_info_wrunlock(unsigned int cpu) 522static inline void xt_info_wrunlock(unsigned int cpu)
523{ 523{
524 spin_unlock(&per_cpu(xt_info_locks, cpu).lock); 524 write_sequnlock(&per_cpu(xt_info_locks, cpu).lock);
525} 525}
526 526
527/* 527/*
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 3fac340a28d5..e855fffaed95 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -710,42 +710,25 @@ static void get_counters(const struct xt_table_info *t,
710 struct arpt_entry *iter; 710 struct arpt_entry *iter;
711 unsigned int cpu; 711 unsigned int cpu;
712 unsigned int i; 712 unsigned int i;
713 unsigned int curcpu = get_cpu();
714
715 /* Instead of clearing (by a previous call to memset())
716 * the counters and using adds, we set the counters
717 * with data used by 'current' CPU
718 *
719 * Bottom half has to be disabled to prevent deadlock
720 * if new softirq were to run and call ipt_do_table
721 */
722 local_bh_disable();
723 i = 0;
724 xt_entry_foreach(iter, t->entries[curcpu], t->size) {
725 SET_COUNTER(counters[i], iter->counters.bcnt,
726 iter->counters.pcnt);
727 ++i;
728 }
729 local_bh_enable();
730 /* Processing counters from other cpus, we can let bottom half enabled,
731 * (preemption is disabled)
732 */
733 713
734 for_each_possible_cpu(cpu) { 714 for_each_possible_cpu(cpu) {
735 if (cpu == curcpu) 715 seqlock_t *lock = &per_cpu(xt_info_locks, cpu).lock;
736 continue; 716
737 i = 0; 717 i = 0;
738 local_bh_disable();
739 xt_info_wrlock(cpu);
740 xt_entry_foreach(iter, t->entries[cpu], t->size) { 718 xt_entry_foreach(iter, t->entries[cpu], t->size) {
741 ADD_COUNTER(counters[i], iter->counters.bcnt, 719 u64 bcnt, pcnt;
742 iter->counters.pcnt); 720 unsigned int start;
721
722 do {
723 start = read_seqbegin(lock);
724 bcnt = iter->counters.bcnt;
725 pcnt = iter->counters.pcnt;
726 } while (read_seqretry(lock, start));
727
728 ADD_COUNTER(counters[i], bcnt, pcnt);
743 ++i; 729 ++i;
744 } 730 }
745 xt_info_wrunlock(cpu);
746 local_bh_enable();
747 } 731 }
748 put_cpu();
749} 732}
750 733
751static struct xt_counters *alloc_counters(const struct xt_table *table) 734static struct xt_counters *alloc_counters(const struct xt_table *table)
@@ -759,7 +742,7 @@ static struct xt_counters *alloc_counters(const struct xt_table *table)
759 * about). 742 * about).
760 */ 743 */
761 countersize = sizeof(struct xt_counters) * private->number; 744 countersize = sizeof(struct xt_counters) * private->number;
762 counters = vmalloc(countersize); 745 counters = vzalloc(countersize);
763 746
764 if (counters == NULL) 747 if (counters == NULL)
765 return ERR_PTR(-ENOMEM); 748 return ERR_PTR(-ENOMEM);
@@ -1007,7 +990,7 @@ static int __do_replace(struct net *net, const char *name,
1007 struct arpt_entry *iter; 990 struct arpt_entry *iter;
1008 991
1009 ret = 0; 992 ret = 0;
1010 counters = vmalloc(num_counters * sizeof(struct xt_counters)); 993 counters = vzalloc(num_counters * sizeof(struct xt_counters));
1011 if (!counters) { 994 if (!counters) {
1012 ret = -ENOMEM; 995 ret = -ENOMEM;
1013 goto out; 996 goto out;
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index a846d633b3b6..652efea013dc 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -884,42 +884,25 @@ get_counters(const struct xt_table_info *t,
884 struct ipt_entry *iter; 884 struct ipt_entry *iter;
885 unsigned int cpu; 885 unsigned int cpu;
886 unsigned int i; 886 unsigned int i;
887 unsigned int curcpu = get_cpu();
888
889 /* Instead of clearing (by a previous call to memset())
890 * the counters and using adds, we set the counters
891 * with data used by 'current' CPU.
892 *
893 * Bottom half has to be disabled to prevent deadlock
894 * if new softirq were to run and call ipt_do_table
895 */
896 local_bh_disable();
897 i = 0;
898 xt_entry_foreach(iter, t->entries[curcpu], t->size) {
899 SET_COUNTER(counters[i], iter->counters.bcnt,
900 iter->counters.pcnt);
901 ++i;
902 }
903 local_bh_enable();
904 /* Processing counters from other cpus, we can let bottom half enabled,
905 * (preemption is disabled)
906 */