Commit 65cb9fda32be613216f601a330b311c3bd7a8436
1 parent
266d07cb1c
Exists in
master
and in
7 other branches
netfilter: nf_conntrack: use mod_timer_pending() for conntrack refresh
Use mod_timer_pending() instead of atomic sequence of del_timer()/ add_timer(). mod_timer_pending() does not rearm an inactive timer, so we don't need the conntrack lock anymore to make sure we don't accidentally rearm a timer of a conntrack which is in the process of being destroyed. With this change, we don't need to take the global lock anymore at all, counter updates can be performed under the per-conntrack lock. Signed-off-by: Patrick McHardy <kaber@trash.net>
Showing 1 changed file with 6 additions and 11 deletions Side-by-side Diff
net/netfilter/nf_conntrack_core.c
... | ... | @@ -807,8 +807,6 @@ |
807 | 807 | NF_CT_ASSERT(ct->timeout.data == (unsigned long)ct); |
808 | 808 | NF_CT_ASSERT(skb); |
809 | 809 | |
810 | - spin_lock_bh(&nf_conntrack_lock); | |
811 | - | |
812 | 810 | /* Only update if this is not a fixed timeout */ |
813 | 811 | if (test_bit(IPS_FIXED_TIMEOUT_BIT, &ct->status)) |
814 | 812 | goto acct; |
... | ... | @@ -822,11 +820,8 @@ |
822 | 820 | /* Only update the timeout if the new timeout is at least |
823 | 821 | HZ jiffies from the old timeout. Need del_timer for race |
824 | 822 | avoidance (may already be dying). */ |
825 | - if (newtime - ct->timeout.expires >= HZ | |
826 | - && del_timer(&ct->timeout)) { | |
827 | - ct->timeout.expires = newtime; | |
828 | - add_timer(&ct->timeout); | |
829 | - } | |
823 | + if (newtime - ct->timeout.expires >= HZ) | |
824 | + mod_timer_pending(&ct->timeout, newtime); | |
830 | 825 | } |
831 | 826 | |
832 | 827 | acct: |
833 | 828 | |
834 | 829 | |
... | ... | @@ -835,13 +830,13 @@ |
835 | 830 | |
836 | 831 | acct = nf_conn_acct_find(ct); |
837 | 832 | if (acct) { |
833 | + spin_lock_bh(&ct->lock); | |
838 | 834 | acct[CTINFO2DIR(ctinfo)].packets++; |
839 | 835 | acct[CTINFO2DIR(ctinfo)].bytes += |
840 | 836 | skb->len - skb_network_offset(skb); |
837 | + spin_unlock_bh(&ct->lock); | |
841 | 838 | } |
842 | 839 | } |
843 | - | |
844 | - spin_unlock_bh(&nf_conntrack_lock); | |
845 | 840 | } |
846 | 841 | EXPORT_SYMBOL_GPL(__nf_ct_refresh_acct); |
847 | 842 | |
848 | 843 | |
849 | 844 | |
850 | 845 | |
... | ... | @@ -853,14 +848,14 @@ |
853 | 848 | if (do_acct) { |
854 | 849 | struct nf_conn_counter *acct; |
855 | 850 | |
856 | - spin_lock_bh(&nf_conntrack_lock); | |
857 | 851 | acct = nf_conn_acct_find(ct); |
858 | 852 | if (acct) { |
853 | + spin_lock_bh(&ct->lock); | |
859 | 854 | acct[CTINFO2DIR(ctinfo)].packets++; |
860 | 855 | acct[CTINFO2DIR(ctinfo)].bytes += |
861 | 856 | skb->len - skb_network_offset(skb); |
857 | + spin_unlock_bh(&ct->lock); | |
862 | 858 | } |
863 | - spin_unlock_bh(&nf_conntrack_lock); | |
864 | 859 | } |
865 | 860 | |
866 | 861 | if (del_timer(&ct->timeout)) { |