diff options
author | Petr Machata <petrm@nvidia.com> | 2021-03-11 19:03:13 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2021-03-12 01:12:59 +0100 |
commit | 96a856256a43b88202f2ac8933092940146102ed (patch) | |
tree | 1e4c7645e78566f08d8b3e4605d9b5be001eb480 /net/ipv4/nexthop.c | |
parent | nexthop: Pass nh_config to replace_nexthop() (diff) | |
download | linux-96a856256a43b88202f2ac8933092940146102ed.tar.xz linux-96a856256a43b88202f2ac8933092940146102ed.zip |
nexthop: __nh_notifier_single_info_init(): Make nh_info an argument
The cited function currently uses rtnl_dereference() to get nh_info from a
handed-in nexthop. However, under the resilient hashing scheme, this
function will not always be called under RTNL, sometimes the mutual
exclusion will be achieved differently. Therefore move the nh_info
extraction from the function to its callers to make it possible to use a
different synchronization guarantee.
Signed-off-by: Petr Machata <petrm@nvidia.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/nexthop.c')
-rw-r--r-- | net/ipv4/nexthop.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c index f723dc97dcd3..69c8b50a936e 100644 --- a/net/ipv4/nexthop.c +++ b/net/ipv4/nexthop.c @@ -52,10 +52,8 @@ static bool nexthop_notifiers_is_empty(struct net *net) static void __nh_notifier_single_info_init(struct nh_notifier_single_info *nh_info, - const struct nexthop *nh) + const struct nh_info *nhi) { - struct nh_info *nhi = rtnl_dereference(nh->nh_info); - nh_info->dev = nhi->fib_nhc.nhc_dev; nh_info->gw_family = nhi->fib_nhc.nhc_gw_family; if (nh_info->gw_family == AF_INET) @@ -71,12 +69,14 @@ __nh_notifier_single_info_init(struct nh_notifier_single_info *nh_info, static int nh_notifier_single_info_init(struct nh_notifier_info *info, const struct nexthop *nh) { + struct nh_info *nhi = rtnl_dereference(nh->nh_info); + info->type = NH_NOTIFIER_INFO_TYPE_SINGLE; info->nh = kzalloc(sizeof(*info->nh), GFP_KERNEL); if (!info->nh) return -ENOMEM; - __nh_notifier_single_info_init(info->nh, nh); + __nh_notifier_single_info_init(info->nh, nhi); return 0; } @@ -103,11 +103,13 @@ static int nh_notifier_mp_info_init(struct nh_notifier_info *info, for (i = 0; i < num_nh; i++) { struct nh_grp_entry *nhge = &nhg->nh_entries[i]; + struct nh_info *nhi; + nhi = rtnl_dereference(nhge->nh->nh_info); info->nh_grp->nh_entries[i].id = nhge->nh->id; info->nh_grp->nh_entries[i].weight = nhge->weight; __nh_notifier_single_info_init(&info->nh_grp->nh_entries[i].nh, - nhge->nh); + nhi); } return 0; |