Re: [PATCH] netfilter: xt_statistic: remove nth_lock spinlock

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, May 26, 2010 at 7:54 PM, Eric Dumazet <eric.dumazet@xxxxxxxxx> wrote:
>
> Signed-off-by: Eric Dumazet <eric.dumazet@xxxxxxxxx>
> ---
> diff --git a/net/netfilter/xt_statistic.c b/net/netfilter/xt_statistic.c
> index 96e62b8..0114d2b 100644
> --- a/net/netfilter/xt_statistic.c
> +++ b/net/netfilter/xt_statistic.c
> @@ -18,8 +18,8 @@
>  #include <linux/netfilter/x_tables.h>
>
>  struct xt_statistic_priv {
> -       uint32_t count;
> -};
> +       atomic_t count;
> +} ____cacheline_aligned_in_smp;
>
>  MODULE_LICENSE("GPL");
>  MODULE_AUTHOR("Patrick McHardy <kaber@xxxxxxxxx>");
> @@ -27,13 +27,12 @@ MODULE_DESCRIPTION("Xtables: statistics-based matching (\"Nth\", random)");
>  MODULE_ALIAS("ipt_statistic");
>  MODULE_ALIAS("ip6t_statistic");
>
> -static DEFINE_SPINLOCK(nth_lock);
> -
>  static bool
>  statistic_mt(const struct sk_buff *skb, struct xt_action_param *par)
>  {
>        const struct xt_statistic_info *info = par->matchinfo;
>        bool ret = info->flags & XT_STATISTIC_INVERT;
> +       int nval, oval;
>
>        switch (info->mode) {
>        case XT_STATISTIC_MODE_RANDOM:
> @@ -41,12 +40,14 @@ statistic_mt(const struct sk_buff *skb, struct xt_action_param *par)
>                        ret = !ret;
>                break;
>        case XT_STATISTIC_MODE_NTH:
> -               spin_lock_bh(&nth_lock);
> -               if (info->master->count++ == info->u.nth.every) {
> -                       info->master->count = 0;
> +               do {
> +                       oval = atomic_read(&info->master->count);
> +                       nval = oval + 1;
> +                       if (nval == info->u.nth.every)
> +                               nval = 0;

these lines should be:
                           if (oval == info->u.nth.every)
                                    nval = 0;
                           else
                                    nval = oval + 1;


> +               } while (atomic_cmpxchg(&info->master->count, oval, nval) != oval);
> +               if (nval == 0)
>                        ret = !ret;
> -               }
> -               spin_unlock_bh(&nth_lock);
>                break;
>        }
>
> @@ -64,7 +65,7 @@ static int statistic_mt_check(const struct xt_mtchk_param *par)
>        info->master = kzalloc(sizeof(*info->master), GFP_KERNEL);
>        if (info->master == NULL)
>                return -ENOMEM;
> -       info->master->count = info->u.nth.count;
> +       atomic_set(&info->master->count, info->u.nth.count);
>
>        return 0;
>  }
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>



-- 
Regards,
Changli Gao(xiaosuo@xxxxxxxxx)
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux