Re: [PATCH nf-next 1/1] netfilter: nf_tables: Remove the rcu lock for dump functions

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

 



On Thu, Jan 12, 2017 at 6:37 PM,  <fgao@xxxxxxxxxx> wrote:
> From: Feng <fgao@xxxxxxxxxx>
>
> The rcu lock protect is added 3 years ago with the commit
> e688a7f8c6cb7a18aae7e55ccdd175f0ad9e69c0. But I find the dump
> operation is protected by the nfnl_lock in the current codes. The
> dump is a synchronization opertion in the netlink callback function
> which is protected by the nfnl_lock.
>
> BTW, I made some tests for this issue. I used the lockdep_nfnl_is_held
> to check if the dump functions hold the lock at the entry and exit.
> It shows all dump functions holds the nfnl_lock with subsystem id
> NFNL_SUBSYS_NFTABLES.
>
> Signed-off-by: Feng <fgao@xxxxxxxxxx>
> ---
>  net/netfilter/nf_tables_api.c | 42 +++++++++++++++---------------------------
>  1 file changed, 15 insertions(+), 27 deletions(-)
>
> diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
> index a019a87..23a3be5c 100644
> --- a/net/netfilter/nf_tables_api.c
> +++ b/net/netfilter/nf_tables_api.c
> @@ -498,14 +498,13 @@ static int nf_tables_dump_tables(struct sk_buff *skb,
>         struct net *net = sock_net(skb->sk);
>         int family = nfmsg->nfgen_family;
>
> -       rcu_read_lock();
>         cb->seq = net->nft.base_seq;
>
> -       list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
> +       list_for_each_entry(afi, &net->nft.af_info, list) {
>                 if (family != NFPROTO_UNSPEC && family != afi->family)
>                         continue;
>
> -               list_for_each_entry_rcu(table, &afi->tables, list) {
> +               list_for_each_entry(table, &afi->tables, list) {
>                         if (idx < s_idx)
>                                 goto cont;
>                         if (idx > s_idx)
> @@ -527,7 +526,6 @@ static int nf_tables_dump_tables(struct sk_buff *skb,
>                 }
>         }
>  done:
> -       rcu_read_unlock();
>         cb->args[0] = idx;
>         return skb->len;
>  }
> @@ -1089,15 +1087,14 @@ static int nf_tables_dump_chains(struct sk_buff *skb,
>         struct net *net = sock_net(skb->sk);
>         int family = nfmsg->nfgen_family;
>
> -       rcu_read_lock();
>         cb->seq = net->nft.base_seq;
>
> -       list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
> +       list_for_each_entry(afi, &net->nft.af_info, list) {
>                 if (family != NFPROTO_UNSPEC && family != afi->family)
>                         continue;
>
> -               list_for_each_entry_rcu(table, &afi->tables, list) {
> -                       list_for_each_entry_rcu(chain, &table->chains, list) {
> +               list_for_each_entry(table, &afi->tables, list) {
> +                       list_for_each_entry(chain, &table->chains, list) {
>                                 if (idx < s_idx)
>                                         goto cont;
>                                 if (idx > s_idx)
> @@ -1120,7 +1117,6 @@ static int nf_tables_dump_chains(struct sk_buff *skb,
>                 }
>         }
>  done:
> -       rcu_read_unlock();
>         cb->args[0] = idx;
>         return skb->len;
>  }
> @@ -1981,24 +1977,23 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
>         struct net *net = sock_net(skb->sk);
>         int family = nfmsg->nfgen_family;
>
> -       rcu_read_lock();
>         cb->seq = net->nft.base_seq;
>
> -       list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
> +       list_for_each_entry(afi, &net->nft.af_info, list) {
>                 if (family != NFPROTO_UNSPEC && family != afi->family)
>                         continue;
>
> -               list_for_each_entry_rcu(table, &afi->tables, list) {
> +               list_for_each_entry(table, &afi->tables, list) {
>                         if (ctx && ctx->table[0] &&
>                             strcmp(ctx->table, table->name) != 0)
>                                 continue;
>
> -                       list_for_each_entry_rcu(chain, &table->chains, list) {
> +                       list_for_each_entry(chain, &table->chains, list) {
>                                 if (ctx && ctx->chain[0] &&
>                                     strcmp(ctx->chain, chain->name) != 0)
>                                         continue;
>
> -                               list_for_each_entry_rcu(rule, &chain->rules, list) {
> +                               list_for_each_entry(rule, &chain->rules, list) {
>                                         if (!nft_is_active(net, rule))
>                                                 goto cont;
>                                         if (idx < s_idx)
> @@ -2021,8 +2016,6 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
>                 }
>         }
>  done:
> -       rcu_read_unlock();
> -
>         cb->args[0] = idx;
>         return skb->len;
>  }
> @@ -2699,10 +2692,9 @@ static int nf_tables_dump_sets(struct sk_buff *skb, struct netlink_callback *cb)
>         if (cb->args[1])
>                 return skb->len;
>
> -       rcu_read_lock();
>         cb->seq = net->nft.base_seq;
>
> -       list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
> +       list_for_each_entry(afi, &net->nft.af_info, list) {
>                 if (ctx->afi && ctx->afi != afi)
>                         continue;
>
> @@ -2712,7 +2704,7 @@ static int nf_tables_dump_sets(struct sk_buff *skb, struct netlink_callback *cb)
>
>                         cur_family = 0;
>                 }
> -               list_for_each_entry_rcu(table, &afi->tables, list) {
> +               list_for_each_entry(table, &afi->tables, list) {
>                         if (ctx->table && ctx->table != table)
>                                 continue;
>
> @@ -2723,7 +2715,7 @@ static int nf_tables_dump_sets(struct sk_buff *skb, struct netlink_callback *cb)
>                                 cur_table = NULL;
>                         }
>                         idx = 0;
> -                       list_for_each_entry_rcu(set, &table->sets, list) {
> +                       list_for_each_entry(set, &table->sets, list) {
>                                 if (idx < s_idx)
>                                         goto cont;
>                                 if (!nft_is_active(net, set))
> @@ -2750,7 +2742,6 @@ static int nf_tables_dump_sets(struct sk_buff *skb, struct netlink_callback *cb)
>         }
>         cb->args[1] = 1;
>  done:
> -       rcu_read_unlock();
>         return skb->len;
>  }
>
> @@ -4246,15 +4237,14 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb)
>         if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET)
>                 reset = true;
>
> -       rcu_read_lock();
>         cb->seq = net->nft.base_seq;
>
> -       list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
> +       list_for_each_entry(afi, &net->nft.af_info, list) {
>                 if (family != NFPROTO_UNSPEC && family != afi->family)
>                         continue;
>
> -               list_for_each_entry_rcu(table, &afi->tables, list) {
> -                       list_for_each_entry_rcu(obj, &table->objects, list) {
> +               list_for_each_entry(table, &afi->tables, list) {
> +                       list_for_each_entry(obj, &table->objects, list) {
>                                 if (!nft_is_active(net, obj))
>                                         goto cont;
>                                 if (idx < s_idx)
> @@ -4283,8 +4273,6 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb)
>                 }
>         }
>  done:
> -       rcu_read_unlock();
> -
>         cb->args[0] = idx;
>         return skb->len;
>  }
> --
> 1.9.1
>

There are other _rcu codes else. And they were added in the same
commit e688a7f8c6cb7a18aae7e55ccdd175f0ad9e69c0.
For example, the list_add_tail_rcu in the nft_register_afinfo

I'm not sure if replace them in one patch.

Regards
Feng
--
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