@@ -2265,6 +2265,7 @@ mlxsw_sp_neigh_entry_alloc(struct mlxsw_sp *mlxsw_sp, struct neighbour *n,
22652265 if (!neigh_entry )
22662266 return NULL ;
22672267
2268+ neigh_hold (n );
22682269 neigh_entry -> key .n = n ;
22692270 neigh_entry -> rif = rif ;
22702271 INIT_LIST_HEAD (& neigh_entry -> nexthop_list );
@@ -2274,6 +2275,7 @@ mlxsw_sp_neigh_entry_alloc(struct mlxsw_sp *mlxsw_sp, struct neighbour *n,
22742275
22752276static void mlxsw_sp_neigh_entry_free (struct mlxsw_sp_neigh_entry * neigh_entry )
22762277{
2278+ neigh_release (neigh_entry -> key .n );
22772279 kfree (neigh_entry );
22782280}
22792281
@@ -2858,6 +2860,11 @@ static int mlxsw_sp_router_schedule_work(struct net *net,
28582860 if (!net_work )
28592861 return NOTIFY_BAD ;
28602862
2863+ /* Take a reference to ensure the neighbour won't be destructed until
2864+ * we drop the reference in the work item.
2865+ */
2866+ neigh_clone (n );
2867+
28612868 INIT_WORK (& net_work -> work , cb );
28622869 net_work -> mlxsw_sp = router -> mlxsw_sp ;
28632870 net_work -> n = n ;
@@ -2881,11 +2888,6 @@ static int mlxsw_sp_router_schedule_neigh_work(struct mlxsw_sp_router *router,
28812888 struct net * net ;
28822889
28832890 net = neigh_parms_net (n -> parms );
2884-
2885- /* Take a reference to ensure the neighbour won't be destructed until we
2886- * drop the reference in delayed work.
2887- */
2888- neigh_clone (n );
28892891 return mlxsw_sp_router_schedule_work (net , router , n ,
28902892 mlxsw_sp_router_neigh_event_work );
28912893}
@@ -4320,6 +4322,8 @@ mlxsw_sp_nexthop_dead_neigh_replace(struct mlxsw_sp *mlxsw_sp,
43204322 if (err )
43214323 goto err_neigh_entry_insert ;
43224324
4325+ neigh_release (old_n );
4326+
43234327 read_lock_bh (& n -> lock );
43244328 nud_state = n -> nud_state ;
43254329 dead = n -> dead ;
@@ -4328,14 +4332,10 @@ mlxsw_sp_nexthop_dead_neigh_replace(struct mlxsw_sp *mlxsw_sp,
43284332
43294333 list_for_each_entry (nh , & neigh_entry -> nexthop_list ,
43304334 neigh_list_node ) {
4331- neigh_release (old_n );
4332- neigh_clone (n );
43334335 __mlxsw_sp_nexthop_neigh_update (nh , !entry_connected );
43344336 mlxsw_sp_nexthop_group_refresh (mlxsw_sp , nh -> nhgi -> nh_grp );
43354337 }
43364338
4337- neigh_release (n );
4338-
43394339 return 0 ;
43404340
43414341err_neigh_entry_insert :
@@ -4428,6 +4428,11 @@ static int mlxsw_sp_nexthop_neigh_init(struct mlxsw_sp *mlxsw_sp,
44284428 }
44294429 }
44304430
4431+ /* Release the reference taken by neigh_lookup() / neigh_create() since
4432+ * neigh_entry already holds one.
4433+ */
4434+ neigh_release (n );
4435+
44314436 /* If that is the first nexthop connected to that neigh, add to
44324437 * nexthop_neighs_list
44334438 */
@@ -4454,11 +4459,9 @@ static void mlxsw_sp_nexthop_neigh_fini(struct mlxsw_sp *mlxsw_sp,
44544459 struct mlxsw_sp_nexthop * nh )
44554460{
44564461 struct mlxsw_sp_neigh_entry * neigh_entry = nh -> neigh_entry ;
4457- struct neighbour * n ;
44584462
44594463 if (!neigh_entry )
44604464 return ;
4461- n = neigh_entry -> key .n ;
44624465
44634466 __mlxsw_sp_nexthop_neigh_update (nh , true);
44644467 list_del (& nh -> neigh_list_node );
@@ -4472,8 +4475,6 @@ static void mlxsw_sp_nexthop_neigh_fini(struct mlxsw_sp *mlxsw_sp,
44724475
44734476 if (!neigh_entry -> connected && list_empty (& neigh_entry -> nexthop_list ))
44744477 mlxsw_sp_neigh_entry_destroy (mlxsw_sp , neigh_entry );
4475-
4476- neigh_release (n );
44774478}
44784479
44794480static bool mlxsw_sp_ipip_netdev_ul_up (struct net_device * ol_dev )
0 commit comments