On 9/14/19 12:45 AM, Jiri Pirko wrote:
>  #define FIB_DUMP_MAX_RETRIES 5
> -int register_fib_notifier(struct notifier_block *nb,
> +int register_fib_notifier(struct net *net, struct notifier_block *nb,
>                         void (*cb)(struct notifier_block *nb))
>  {
>       int retries = 0;
>       int err;
>  
>       do {
> -             unsigned int fib_seq = fib_seq_sum();
> -             struct net *net;
> -
> -             rcu_read_lock();
> -             for_each_net_rcu(net) {
> -                     err = fib_net_dump(net, nb);
> -                     if (err)
> -                             goto err_fib_net_dump;
> -             }
> -             rcu_read_unlock();
> -
> -             if (fib_dump_is_consistent(nb, cb, fib_seq))
> +             unsigned int fib_seq = fib_seq_sum(net);
> +
> +             err = fib_net_dump(net, nb);
> +             if (err)
> +                     return err;
> +
> +             if (fib_dump_is_consistent(net, nb, cb, fib_seq))
>                       return 0;
>       } while (++retries < FIB_DUMP_MAX_RETRIES);

This is still more complicated than it needs to be. Why lump all
fib_notifier_ops into 1 dump when they are separate databases with
separate seq numbers? Just dump them 1 at a time and retry that 1
database as needed.

ie., This:
    list_for_each_entry_rcu(ops, &net->fib_notifier_ops, list) {
should be in register_fib_notifier and not fib_net_dump.

as it stands you are potentially replaying way more than is needed when
a dump is inconsistent.


>  
>       return -EBUSY;
> -
> -err_fib_net_dump:
> -     rcu_read_unlock();
> -     return err;
>  }
>  EXPORT_SYMBOL(register_fib_notifier);
>  
> -int unregister_fib_notifier(struct notifier_block *nb)
> +int unregister_fib_notifier(struct net *net, struct notifier_block *nb)
>  {
> -     return atomic_notifier_chain_unregister(&fib_chain, nb);
> +     struct fib_notifier_net *fn_net = net_generic(net, fib_notifier_net_id);
> +
> +     return atomic_notifier_chain_unregister(&fn_net->fib_chain, nb);
>  }
>  EXPORT_SYMBOL(unregister_fib_notifier);
>  





Reply via email to