[lkml]   [2009]   [Jun]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
    Patch in this message
    SubjectRe: [bug] __nf_ct_refresh_acct(): WARNING: at lib/list_debug.c:30 __list_add+0x7d/0xad()
    Patrick McHardy wrote:
    > Eric Dumazet wrote:
    >> IPS_CONFIRMED_BIT is set under nf_conntrack_lock (in
    >> __nf_conntrack_confirm()),
    >> we probably want to add a synchronisation under ct->lock as well,
    >> or __nf_ct_refresh_acct() could set ct->timeout.expires to extra_jiffies,
    >> while a different cpu could confirm the conntrack.
    > Before the conntrack is confirmed, it is exclusively handled by a
    > single CPU. I agree that we need to make sure the IPS_CONFIRMED_BIT
    > is visible before we add the conntrack to the hash table since the
    > lookup is lockless, but simply moving the set_bit before the hash
    > insertion should be fine I think.

    A slightly changed version which moves hash insertion to the end
    and adds a comment about ordering. This make sure the timer is
    actually running before the conntrack can be found be other CPUs.

    diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
    index 5f72b94..e2cc707 100644
    --- a/net/netfilter/nf_conntrack_core.c
    +++ b/net/netfilter/nf_conntrack_core.c
    @@ -425,7 +425,6 @@ __nf_conntrack_confirm(struct sk_buff *skb)
    /* Remove from unconfirmed list */

    - __nf_conntrack_hash_insert(ct, hash, repl_hash);
    /* Timer relative to confirmation time, not original
    setting time, otherwise we'd get timer wrap in
    weird delay cases. */
    @@ -433,8 +432,15 @@ __nf_conntrack_confirm(struct sk_buff *skb)
    set_bit(IPS_CONFIRMED_BIT, &ct->status);
    + /* Since the lookup is lockless, hash insertion must be after starting the
    + * timer and setting the CONFIRMED bit. The RCU barriers guarantee that no
    + * other CPU can find the conntrack before the above stores are visible.
    + */
    + __nf_conntrack_hash_insert(ct, hash, repl_hash);
    NF_CT_STAT_INC(net, insert);
    help = nfct_help(ct);
    if (help && help->helper)
    nf_conntrack_event_cache(IPCT_HELPER, ct);
     \ /
      Last update: 2009-06-17 13:55    [W:0.045 / U:2.652 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site