Commit 65cb9fda authored by Patrick McHardy's avatar Patrick McHardy

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: default avatarPatrick McHardy <kaber@trash.net>
parent 266d07cb
...@@ -807,8 +807,6 @@ void __nf_ct_refresh_acct(struct nf_conn *ct, ...@@ -807,8 +807,6 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,
NF_CT_ASSERT(ct->timeout.data == (unsigned long)ct); NF_CT_ASSERT(ct->timeout.data == (unsigned long)ct);
NF_CT_ASSERT(skb); NF_CT_ASSERT(skb);
spin_lock_bh(&nf_conntrack_lock);
/* Only update if this is not a fixed timeout */ /* Only update if this is not a fixed timeout */
if (test_bit(IPS_FIXED_TIMEOUT_BIT, &ct->status)) if (test_bit(IPS_FIXED_TIMEOUT_BIT, &ct->status))
goto acct; goto acct;
...@@ -822,11 +820,8 @@ void __nf_ct_refresh_acct(struct nf_conn *ct, ...@@ -822,11 +820,8 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,
/* Only update the timeout if the new timeout is at least /* Only update the timeout if the new timeout is at least
HZ jiffies from the old timeout. Need del_timer for race HZ jiffies from the old timeout. Need del_timer for race
avoidance (may already be dying). */ avoidance (may already be dying). */
if (newtime - ct->timeout.expires >= HZ if (newtime - ct->timeout.expires >= HZ)
&& del_timer(&ct->timeout)) { mod_timer_pending(&ct->timeout, newtime);
ct->timeout.expires = newtime;
add_timer(&ct->timeout);
}
} }
acct: acct:
...@@ -835,13 +830,13 @@ void __nf_ct_refresh_acct(struct nf_conn *ct, ...@@ -835,13 +830,13 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,
acct = nf_conn_acct_find(ct); acct = nf_conn_acct_find(ct);
if (acct) { if (acct) {
spin_lock_bh(&ct->lock);
acct[CTINFO2DIR(ctinfo)].packets++; acct[CTINFO2DIR(ctinfo)].packets++;
acct[CTINFO2DIR(ctinfo)].bytes += acct[CTINFO2DIR(ctinfo)].bytes +=
skb->len - skb_network_offset(skb); skb->len - skb_network_offset(skb);
spin_unlock_bh(&ct->lock);
} }
} }
spin_unlock_bh(&nf_conntrack_lock);
} }
EXPORT_SYMBOL_GPL(__nf_ct_refresh_acct); EXPORT_SYMBOL_GPL(__nf_ct_refresh_acct);
...@@ -853,14 +848,14 @@ bool __nf_ct_kill_acct(struct nf_conn *ct, ...@@ -853,14 +848,14 @@ bool __nf_ct_kill_acct(struct nf_conn *ct,
if (do_acct) { if (do_acct) {
struct nf_conn_counter *acct; struct nf_conn_counter *acct;
spin_lock_bh(&nf_conntrack_lock);
acct = nf_conn_acct_find(ct); acct = nf_conn_acct_find(ct);
if (acct) { if (acct) {
spin_lock_bh(&ct->lock);
acct[CTINFO2DIR(ctinfo)].packets++; acct[CTINFO2DIR(ctinfo)].packets++;
acct[CTINFO2DIR(ctinfo)].bytes += acct[CTINFO2DIR(ctinfo)].bytes +=
skb->len - skb_network_offset(skb); skb->len - skb_network_offset(skb);
spin_unlock_bh(&ct->lock);
} }
spin_unlock_bh(&nf_conntrack_lock);
} }
if (del_timer(&ct->timeout)) { if (del_timer(&ct->timeout)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment