diff options
| author | David S. Miller <davem@davemloft.net> | 2011-01-11 18:43:03 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2011-01-11 18:43:03 -0500 |
| commit | 60dbb011df9764294284cc3e70f935eaa462e15e (patch) | |
| tree | 7bf7672001c3fc87850895577f22c0f6dc4c1138 | |
| parent | 4b0ef1f223be4e092632b4152ceec5627ac10f59 (diff) | |
| parent | 2f46e07995734a363608e974a82fd05d5b610750 (diff) | |
Merge branch 'master' of git://1984.lsi.us.es/net-2.6
| -rw-r--r-- | include/linux/if_bridge.h | 2 | ||||
| -rw-r--r-- | include/linux/netfilter/x_tables.h | 10 | ||||
| -rw-r--r-- | net/ipv4/netfilter/arp_tables.c | 45 | ||||
| -rw-r--r-- | net/ipv4/netfilter/ip_tables.c | 45 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 45 | ||||
| -rw-r--r-- | net/netfilter/nf_conntrack_netlink.c | 14 | ||||
| -rw-r--r-- | net/netfilter/x_tables.c | 3 |
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 | ||
| 104 | extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *)); | 104 | extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *)); |
| 105 | 105 | ||
| 106 | typedef int (*br_should_route_hook_t)(struct sk_buff *skb); | 106 | typedef int br_should_route_hook_t(struct sk_buff *skb); |
| 107 | extern br_should_route_hook_t __rcu *br_should_route_hook; | 107 | extern 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 | */ |
| 474 | struct xt_info_lock { | 474 | struct xt_info_lock { |
| 475 | spinlock_t lock; | 475 | seqlock_t lock; |
| 476 | unsigned char readers; | 476 | unsigned char readers; |
| 477 | }; | 477 | }; |
| 478 | DECLARE_PER_CPU(struct xt_info_lock, xt_info_locks); | 478 | DECLARE_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 | ||
| 503 | static inline void xt_info_rdunlock_bh(void) | 503 | static 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 | */ |
| 517 | static inline void xt_info_wrlock(unsigned int cpu) | 517 | static 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 | ||
| 522 | static inline void xt_info_wrunlock(unsigned int cpu) | 522 | static 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 | ||
| 751 | static struct xt_counters *alloc_counters(const struct xt_table *table) | 734 | static 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 | */ | ||
