Skip to content

Commit

Permalink
net: core: introduce struct netdev_nested_priv for nested interface i…
Browse files Browse the repository at this point in the history
…nfrastructure

Functions related to nested interface infrastructure such as
netdev_walk_all_{ upper | lower }_dev() pass both private functions
and "data" pointer to handle their own things.
At this point, the data pointer type is void *.
In order to make it easier to expand common variables and functions,
this new netdev_nested_priv structure is added.

In the following patch, a new member variable will be added into this
struct to fix the lockdep issue.

Signed-off-by: Taehee Yoo <ap420073@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Taehee Yoo authored and David S. Miller committed Sep 28, 2020
1 parent fe8300f commit eff7423
Show file tree
Hide file tree
Showing 16 changed files with 183 additions and 95 deletions.
10 changes: 7 additions & 3 deletions drivers/infiniband/core/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -1320,9 +1320,10 @@ struct net_device *rdma_read_gid_attr_ndev_rcu(const struct ib_gid_attr *attr)
}
EXPORT_SYMBOL(rdma_read_gid_attr_ndev_rcu);

static int get_lower_dev_vlan(struct net_device *lower_dev, void *data)
static int get_lower_dev_vlan(struct net_device *lower_dev,
struct netdev_nested_priv *priv)
{
u16 *vlan_id = data;
u16 *vlan_id = (u16 *)priv->data;

if (is_vlan_dev(lower_dev))
*vlan_id = vlan_dev_vlan_id(lower_dev);
Expand All @@ -1348,6 +1349,9 @@ static int get_lower_dev_vlan(struct net_device *lower_dev, void *data)
int rdma_read_gid_l2_fields(const struct ib_gid_attr *attr,
u16 *vlan_id, u8 *smac)
{
struct netdev_nested_priv priv = {
.data = (void *)vlan_id,
};
struct net_device *ndev;

rcu_read_lock();
Expand All @@ -1368,7 +1372,7 @@ int rdma_read_gid_l2_fields(const struct ib_gid_attr *attr,
* the lower vlan device for this gid entry.
*/
netdev_walk_all_lower_dev_rcu(attr->ndev,
get_lower_dev_vlan, vlan_id);
get_lower_dev_vlan, &priv);
}
}
rcu_read_unlock();
Expand Down
9 changes: 6 additions & 3 deletions drivers/infiniband/core/cma.c
Original file line number Diff line number Diff line change
Expand Up @@ -2865,9 +2865,10 @@ struct iboe_prio_tc_map {
bool found;
};

static int get_lower_vlan_dev_tc(struct net_device *dev, void *data)
static int get_lower_vlan_dev_tc(struct net_device *dev,
struct netdev_nested_priv *priv)
{
struct iboe_prio_tc_map *map = data;
struct iboe_prio_tc_map *map = (struct iboe_prio_tc_map *)priv->data;

if (is_vlan_dev(dev))
map->output_tc = get_vlan_ndev_tc(dev, map->input_prio);
Expand All @@ -2886,16 +2887,18 @@ static int iboe_tos_to_sl(struct net_device *ndev, int tos)
{
struct iboe_prio_tc_map prio_tc_map = {};
int prio = rt_tos2priority(tos);
struct netdev_nested_priv priv;

/* If VLAN device, get it directly from the VLAN netdev */
if (is_vlan_dev(ndev))
return get_vlan_ndev_tc(ndev, prio);

prio_tc_map.input_prio = prio;
priv.data = (void *)&prio_tc_map;
rcu_read_lock();
netdev_walk_all_lower_dev_rcu(ndev,
get_lower_vlan_dev_tc,
&prio_tc_map);
&priv);
rcu_read_unlock();
/* If map is found from lower device, use it; Otherwise
* continue with the current netdevice to get priority to tc map.
Expand Down
9 changes: 6 additions & 3 deletions drivers/infiniband/core/roce_gid_mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -531,10 +531,11 @@ struct upper_list {
struct net_device *upper;
};

static int netdev_upper_walk(struct net_device *upper, void *data)
static int netdev_upper_walk(struct net_device *upper,
struct netdev_nested_priv *priv)
{
struct upper_list *entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
struct list_head *upper_list = data;
struct list_head *upper_list = (struct list_head *)priv->data;

if (!entry)
return 0;
Expand All @@ -553,12 +554,14 @@ static void handle_netdev_upper(struct ib_device *ib_dev, u8 port,
struct net_device *ndev))
{
struct net_device *ndev = cookie;
struct netdev_nested_priv priv;
struct upper_list *upper_iter;
struct upper_list *upper_temp;
LIST_HEAD(upper_list);

priv.data = &upper_list;
rcu_read_lock();
netdev_walk_all_upper_dev_rcu(ndev, netdev_upper_walk, &upper_list);
netdev_walk_all_upper_dev_rcu(ndev, netdev_upper_walk, &priv);
rcu_read_unlock();

handle_netdev(ib_dev, port, ndev);
Expand Down
9 changes: 6 additions & 3 deletions drivers/infiniband/ulp/ipoib/ipoib_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,9 +342,10 @@ struct ipoib_walk_data {
struct net_device *result;
};

static int ipoib_upper_walk(struct net_device *upper, void *_data)
static int ipoib_upper_walk(struct net_device *upper,
struct netdev_nested_priv *priv)
{
struct ipoib_walk_data *data = _data;
struct ipoib_walk_data *data = (struct ipoib_walk_data *)priv->data;
int ret = 0;

if (ipoib_is_dev_match_addr_rcu(data->addr, upper)) {
Expand All @@ -368,18 +369,20 @@ static int ipoib_upper_walk(struct net_device *upper, void *_data)
static struct net_device *ipoib_get_net_dev_match_addr(
const struct sockaddr *addr, struct net_device *dev)
{
struct netdev_nested_priv priv;
struct ipoib_walk_data data = {
.addr = addr,
};

priv.data = (void *)&data;
rcu_read_lock();
if (ipoib_is_dev_match_addr_rcu(addr, dev)) {
dev_hold(dev);
data.result = dev;
goto out;
}

netdev_walk_all_upper_dev_rcu(dev, ipoib_upper_walk, &data);
netdev_walk_all_upper_dev_rcu(dev, ipoib_upper_walk, &priv);
out:
rcu_read_unlock();
return data.result;
Expand Down
9 changes: 6 additions & 3 deletions drivers/net/bonding/bond_alb.c
Original file line number Diff line number Diff line change
Expand Up @@ -942,9 +942,10 @@ struct alb_walk_data {
bool strict_match;
};

static int alb_upper_dev_walk(struct net_device *upper, void *_data)
static int alb_upper_dev_walk(struct net_device *upper,
struct netdev_nested_priv *priv)
{
struct alb_walk_data *data = _data;
struct alb_walk_data *data = (struct alb_walk_data *)priv->data;
bool strict_match = data->strict_match;
struct bonding *bond = data->bond;
struct slave *slave = data->slave;
Expand Down Expand Up @@ -983,21 +984,23 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[],
bool strict_match)
{
struct bonding *bond = bond_get_bond_by_slave(slave);
struct netdev_nested_priv priv;
struct alb_walk_data data = {
.strict_match = strict_match,
.mac_addr = mac_addr,
.slave = slave,
.bond = bond,
};

priv.data = (void *)&data;
/* send untagged */
alb_send_lp_vid(slave, mac_addr, 0, 0);

/* loop through all devices and see if we need to send a packet
* for that device.
*/
rcu_read_lock();
netdev_walk_all_upper_dev_rcu(bond->dev, alb_upper_dev_walk, &data);
netdev_walk_all_upper_dev_rcu(bond->dev, alb_upper_dev_walk, &priv);
rcu_read_unlock();
}

Expand Down
10 changes: 7 additions & 3 deletions drivers/net/bonding/bond_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2511,22 +2511,26 @@ static void bond_mii_monitor(struct work_struct *work)
}
}

static int bond_upper_dev_walk(struct net_device *upper, void *data)
static int bond_upper_dev_walk(struct net_device *upper,
struct netdev_nested_priv *priv)
{
__be32 ip = *((__be32 *)data);
__be32 ip = *(__be32 *)priv->data;

return ip == bond_confirm_addr(upper, 0, ip);
}

static bool bond_has_this_ip(struct bonding *bond, __be32 ip)
{
struct netdev_nested_priv priv = {
.data = (void *)&ip,
};
bool ret = false;

if (ip == bond_confirm_addr(bond->dev, 0, ip))
return true;

rcu_read_lock();
if (netdev_walk_all_upper_dev_rcu(bond->dev, bond_upper_dev_walk, &ip))
if (netdev_walk_all_upper_dev_rcu(bond->dev, bond_upper_dev_walk, &priv))
ret = true;
rcu_read_unlock();

Expand Down
37 changes: 26 additions & 11 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -5396,9 +5396,10 @@ static int ixgbe_fwd_ring_up(struct ixgbe_adapter *adapter,
return err;
}

static int ixgbe_macvlan_up(struct net_device *vdev, void *data)
static int ixgbe_macvlan_up(struct net_device *vdev,
struct netdev_nested_priv *priv)
{
struct ixgbe_adapter *adapter = data;
struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)priv->data;
struct ixgbe_fwd_adapter *accel;

if (!netif_is_macvlan(vdev))
Expand All @@ -5415,8 +5416,12 @@ static int ixgbe_macvlan_up(struct net_device *vdev, void *data)

static void ixgbe_configure_dfwd(struct ixgbe_adapter *adapter)
{
struct netdev_nested_priv priv = {
.data = (void *)adapter,
};

netdev_walk_all_upper_dev_rcu(adapter->netdev,
ixgbe_macvlan_up, adapter);
ixgbe_macvlan_up, &priv);
}

static void ixgbe_configure(struct ixgbe_adapter *adapter)
Expand Down Expand Up @@ -9023,9 +9028,10 @@ static void ixgbe_set_prio_tc_map(struct ixgbe_adapter *adapter)
}

#endif /* CONFIG_IXGBE_DCB */
static int ixgbe_reassign_macvlan_pool(struct net_device *vdev, void *data)
static int ixgbe_reassign_macvlan_pool(struct net_device *vdev,
struct netdev_nested_priv *priv)
{
struct ixgbe_adapter *adapter = data;
struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)priv->data;
struct ixgbe_fwd_adapter *accel;
int pool;

Expand Down Expand Up @@ -9062,13 +9068,16 @@ static int ixgbe_reassign_macvlan_pool(struct net_device *vdev, void *data)
static void ixgbe_defrag_macvlan_pools(struct net_device *dev)
{
struct ixgbe_adapter *adapter = netdev_priv(dev);
struct netdev_nested_priv priv = {
.data = (void *)adapter,
};

/* flush any stale bits out of the fwd bitmask */
bitmap_clear(adapter->fwd_bitmask, 1, 63);

/* walk through upper devices reassigning pools */
netdev_walk_all_upper_dev_rcu(dev, ixgbe_reassign_macvlan_pool,
adapter);
&priv);
}

/**
Expand Down Expand Up @@ -9242,14 +9251,18 @@ struct upper_walk_data {
u8 queue;
};

static int get_macvlan_queue(struct net_device *upper, void *_data)
static int get_macvlan_queue(struct net_device *upper,
struct netdev_nested_priv *priv)
{
if (netif_is_macvlan(upper)) {
struct ixgbe_fwd_adapter *vadapter = macvlan_accel_priv(upper);
struct upper_walk_data *data = _data;
struct ixgbe_adapter *adapter = data->adapter;
int ifindex = data->ifindex;
struct ixgbe_adapter *adapter;
struct upper_walk_data *data;
int ifindex;

data = (struct upper_walk_data *)priv->data;
ifindex = data->ifindex;
adapter = data->adapter;
if (vadapter && upper->ifindex == ifindex) {
data->queue = adapter->rx_ring[vadapter->rx_base_queue]->reg_idx;
data->action = data->queue;
Expand All @@ -9265,6 +9278,7 @@ static int handle_redirect_action(struct ixgbe_adapter *adapter, int ifindex,
{
struct ixgbe_ring_feature *vmdq = &adapter->ring_feature[RING_F_VMDQ];
unsigned int num_vfs = adapter->num_vfs, vf;
struct netdev_nested_priv priv;
struct upper_walk_data data;
struct net_device *upper;

Expand All @@ -9284,8 +9298,9 @@ static int handle_redirect_action(struct ixgbe_adapter *adapter, int ifindex,
data.ifindex = ifindex;
data.action = 0;
data.queue = 0;
priv.data = (void *)&data;
if (netdev_walk_all_upper_dev_rcu(adapter->netdev,
get_macvlan_queue, &data)) {
get_macvlan_queue, &priv)) {
*action = data.action;
*queue = data.queue;

Expand Down
24 changes: 13 additions & 11 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum.c
Original file line number Diff line number Diff line change
Expand Up @@ -3690,13 +3690,13 @@ bool mlxsw_sp_port_dev_check(const struct net_device *dev)
return dev->netdev_ops == &mlxsw_sp_port_netdev_ops;
}

static int mlxsw_sp_lower_dev_walk(struct net_device *lower_dev, void *data)
static int mlxsw_sp_lower_dev_walk(struct net_device *lower_dev,
struct netdev_nested_priv *priv)
{
struct mlxsw_sp_port **p_mlxsw_sp_port = data;
int ret = 0;

if (mlxsw_sp_port_dev_check(lower_dev)) {
*p_mlxsw_sp_port = netdev_priv(lower_dev);
priv->data = (void *)netdev_priv(lower_dev);
ret = 1;
}

Expand All @@ -3705,15 +3705,16 @@ static int mlxsw_sp_lower_dev_walk(struct net_device *lower_dev, void *data)

struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find(struct net_device *dev)
{
struct mlxsw_sp_port *mlxsw_sp_port;
struct netdev_nested_priv priv = {
.data = NULL,
};

if (mlxsw_sp_port_dev_check(dev))
return netdev_priv(dev);

mlxsw_sp_port = NULL;
netdev_walk_all_lower_dev(dev, mlxsw_sp_lower_dev_walk, &mlxsw_sp_port);
netdev_walk_all_lower_dev(dev, mlxsw_sp_lower_dev_walk, &priv);

return mlxsw_sp_port;
return (struct mlxsw_sp_port *)priv.data;
}

struct mlxsw_sp *mlxsw_sp_lower_get(struct net_device *dev)
Expand All @@ -3726,16 +3727,17 @@ struct mlxsw_sp *mlxsw_sp_lower_get(struct net_device *dev)

struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find_rcu(struct net_device *dev)
{
struct mlxsw_sp_port *mlxsw_sp_port;
struct netdev_nested_priv priv = {
.data = NULL,
};

if (mlxsw_sp_port_dev_check(dev))
return netdev_priv(dev);

mlxsw_sp_port = NULL;
netdev_walk_all_lower_dev_rcu(dev, mlxsw_sp_lower_dev_walk,
&mlxsw_sp_port);
&priv);

return mlxsw_sp_port;
return (struct mlxsw_sp_port *)priv.data;
}

struct mlxsw_sp_port *mlxsw_sp_port_lower_dev_hold(struct net_device *dev)
Expand Down
11 changes: 8 additions & 3 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
Original file line number Diff line number Diff line change
Expand Up @@ -7351,9 +7351,10 @@ int mlxsw_sp_netdevice_vrf_event(struct net_device *l3_dev, unsigned long event,
return err;
}

static int __mlxsw_sp_rif_macvlan_flush(struct net_device *dev, void *data)
static int __mlxsw_sp_rif_macvlan_flush(struct net_device *dev,
struct netdev_nested_priv *priv)
{
struct mlxsw_sp_rif *rif = data;
struct mlxsw_sp_rif *rif = (struct mlxsw_sp_rif *)priv->data;

if (!netif_is_macvlan(dev))
return 0;
Expand All @@ -7364,12 +7365,16 @@ static int __mlxsw_sp_rif_macvlan_flush(struct net_device *dev, void *data)

static int mlxsw_sp_rif_macvlan_flush(struct mlxsw_sp_rif *rif)
{
struct netdev_nested_priv priv = {
.data = (void *)rif,
};

if (!netif_is_macvlan_port(rif->dev))
return 0;

netdev_warn(rif->dev, "Router interface is deleted. Upper macvlans will not work\n");
return netdev_walk_all_upper_dev_rcu(rif->dev,
__mlxsw_sp_rif_macvlan_flush, rif);
__mlxsw_sp_rif_macvlan_flush, &priv);
}

static void mlxsw_sp_rif_subport_setup(struct mlxsw_sp_rif *rif,
Expand Down
Loading

0 comments on commit eff7423

Please sign in to comment.