Skip to content

Commit

Permalink
net: Explicitly initialize u64_stats_sync structures for lockdep
Browse files Browse the repository at this point in the history
In order to enable lockdep on seqcount/seqlock structures, we
must explicitly initialize any locks.

The u64_stats_sync structure, uses a seqcount, and thus we need
to introduce a u64_stats_init() function and use it to initialize
the structure.

This unfortunately adds a lot of fairly trivial initialization code
to a number of drivers. But the benefit of ensuring correctness makes
this worth while.

Because these changes are required for lockdep to be enabled, and the
changes are quite trivial, I've not yet split this patch out into 30-some
separate patches, as I figured it would be better to get the various
maintainers thoughts on how to best merge this change along with
the seqcount lockdep enablement.

Feedback would be appreciated!

Signed-off-by: John Stultz <john.stultz@linaro.org>
Acked-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Cc: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
Cc: James Morris <jmorris@namei.org>
Cc: Jesse Gross <jesse@nicira.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Mirko Lindner <mlindner@marvell.com>
Cc: Patrick McHardy <kaber@trash.net>
Cc: Roger Luethi <rl@hellgate.ch>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Simon Horman <horms@verge.net.au>
Cc: Stephen Hemminger <stephen@networkplumber.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: Wensong Zhang <wensong@linux-vs.org>
Cc: netdev@vger.kernel.org
Link: http://lkml.kernel.org/r/1381186321-4906-2-git-send-email-john.stultz@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
  • Loading branch information
johnstultz-work authored and Ingo Molnar committed Nov 6, 2013
1 parent 32cf7c3 commit 827da44
Show file tree
Hide file tree
Showing 34 changed files with 253 additions and 6 deletions.
6 changes: 6 additions & 0 deletions drivers/net/dummy.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,16 @@ static netdev_tx_t dummy_xmit(struct sk_buff *skb, struct net_device *dev)

static int dummy_dev_init(struct net_device *dev)
{
int i;
dev->dstats = alloc_percpu(struct pcpu_dstats);
if (!dev->dstats)
return -ENOMEM;

for_each_possible_cpu(i) {
struct pcpu_dstats *dstats;
dstats = per_cpu_ptr(dev->dstats, i);
u64_stats_init(&dstats->syncp);
}
return 0;
}

Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/emulex/benet/be_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2047,6 +2047,9 @@ static int be_tx_qs_create(struct be_adapter *adapter)
if (status)
return status;

u64_stats_init(&txo->stats.sync);
u64_stats_init(&txo->stats.sync_compl);

/* If num_evt_qs is less than num_tx_qs, then more than
* one txq share an eq
*/
Expand Down Expand Up @@ -2108,6 +2111,7 @@ static int be_rx_cqs_create(struct be_adapter *adapter)
if (rc)
return rc;

u64_stats_init(&rxo->stats.sync);
eq = &adapter->eq_obj[i % adapter->num_evt_qs].q;
rc = be_cmd_cq_create(adapter, cq, eq, false, 3);
if (rc)
Expand Down
5 changes: 5 additions & 0 deletions drivers/net/ethernet/intel/igb/igb_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1223,6 +1223,9 @@ static int igb_alloc_q_vector(struct igb_adapter *adapter,
ring->count = adapter->tx_ring_count;
ring->queue_index = txr_idx;

u64_stats_init(&ring->tx_syncp);
u64_stats_init(&ring->tx_syncp2);

/* assign ring to adapter */
adapter->tx_ring[txr_idx] = ring;

Expand Down Expand Up @@ -1256,6 +1259,8 @@ static int igb_alloc_q_vector(struct igb_adapter *adapter,
ring->count = adapter->rx_ring_count;
ring->queue_index = rxr_idx;

u64_stats_init(&ring->rx_syncp);

/* assign ring to adapter */
adapter->rx_ring[rxr_idx] = ring;
}
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -4867,6 +4867,8 @@ int ixgbe_setup_tx_resources(struct ixgbe_ring *tx_ring)
if (!tx_ring->tx_buffer_info)
goto err;

u64_stats_init(&tx_ring->syncp);

/* round up to nearest 4K */
tx_ring->size = tx_ring->count * sizeof(union ixgbe_adv_tx_desc);
tx_ring->size = ALIGN(tx_ring->size, 4096);
Expand Down Expand Up @@ -4949,6 +4951,8 @@ int ixgbe_setup_rx_resources(struct ixgbe_ring *rx_ring)
if (!rx_ring->rx_buffer_info)
goto err;

u64_stats_init(&rx_ring->syncp);

/* Round up to nearest 4K */
rx_ring->size = rx_ring->count * sizeof(union ixgbe_adv_rx_desc);
rx_ring->size = ALIGN(rx_ring->size, 4096);
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/marvell/mvneta.c
Original file line number Diff line number Diff line change
Expand Up @@ -2792,6 +2792,9 @@ static int mvneta_probe(struct platform_device *pdev)

pp = netdev_priv(dev);

u64_stats_init(&pp->tx_stats.syncp);
u64_stats_init(&pp->rx_stats.syncp);

pp->weight = MVNETA_RX_POLL_WEIGHT;
pp->phy_node = phy_node;
pp->phy_interface = phy_mode;
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/marvell/sky2.c
Original file line number Diff line number Diff line change
Expand Up @@ -4763,6 +4763,9 @@ static struct net_device *sky2_init_netdev(struct sky2_hw *hw, unsigned port,
sky2->hw = hw;
sky2->msg_enable = netif_msg_init(debug, default_msg);

u64_stats_init(&sky2->tx_stats.syncp);
u64_stats_init(&sky2->rx_stats.syncp);

/* Auto speed and flow control */
sky2->flags = SKY2_FLAG_AUTO_SPEED | SKY2_FLAG_AUTO_PAUSE;
if (hw->chip_id != CHIP_ID_YUKON_XL)
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/neterion/vxge/vxge-main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2072,6 +2072,10 @@ static int vxge_open_vpaths(struct vxgedev *vdev)
vdev->config.tx_steering_type;
vpath->fifo.ndev = vdev->ndev;
vpath->fifo.pdev = vdev->pdev;

u64_stats_init(&vpath->fifo.stats.syncp);
u64_stats_init(&vpath->ring.stats.syncp);

if (vdev->config.tx_steering_type)
vpath->fifo.txq =
netdev_get_tx_queue(vdev->ndev, i);
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/nvidia/forcedeth.c
Original file line number Diff line number Diff line change
Expand Up @@ -5619,6 +5619,8 @@ static int nv_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
spin_lock_init(&np->lock);
spin_lock_init(&np->hwstats_lock);
SET_NETDEV_DEV(dev, &pci_dev->dev);
u64_stats_init(&np->swstats_rx_syncp);
u64_stats_init(&np->swstats_tx_syncp);

init_timer(&np->oom_kick);
np->oom_kick.data = (unsigned long) dev;
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/realtek/8139too.c
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,9 @@ static struct net_device *rtl8139_init_board(struct pci_dev *pdev)

pci_set_master (pdev);

u64_stats_init(&tp->rx_stats.syncp);
u64_stats_init(&tp->tx_stats.syncp);

retry:
/* PIO bar register comes first. */
bar = !use_io;
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/tile/tilepro.c
Original file line number Diff line number Diff line change
Expand Up @@ -1008,6 +1008,8 @@ static void tile_net_register(void *dev_ptr)
info->egress_timer.data = (long)info;
info->egress_timer.function = tile_net_handle_egress_timer;

u64_stats_init(&info->stats.syncp);

priv->cpu[my_cpu] = info;

/*
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/via/via-rhine.c
Original file line number Diff line number Diff line change
Expand Up @@ -987,6 +987,9 @@ static int rhine_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)

rp->base = ioaddr;

u64_stats_init(&rp->tx_stats.syncp);
u64_stats_init(&rp->rx_stats.syncp);

/* Get chip registers into a sane state */
rhine_power_init(dev);
rhine_hw_init(dev, pioaddr);
Expand Down
5 changes: 5 additions & 0 deletions drivers/net/ifb.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ MODULE_PARM_DESC(numifbs, "Number of ifb devices");
static int __init ifb_init_one(int index)
{
struct net_device *dev_ifb;
struct ifb_private *dp;
int err;

dev_ifb = alloc_netdev(sizeof(struct ifb_private),
Expand All @@ -273,6 +274,10 @@ static int __init ifb_init_one(int index)
if (!dev_ifb)
return -ENOMEM;

dp = netdev_priv(dev_ifb);
u64_stats_init(&dp->rsync);
u64_stats_init(&dp->tsync);

dev_ifb->rtnl_link_ops = &ifb_link_ops;
err = register_netdevice(dev_ifb);
if (err < 0)
Expand Down
6 changes: 6 additions & 0 deletions drivers/net/loopback.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,16 @@ static const struct ethtool_ops loopback_ethtool_ops = {

static int loopback_dev_init(struct net_device *dev)
{
int i;
dev->lstats = alloc_percpu(struct pcpu_lstats);
if (!dev->lstats)
return -ENOMEM;

for_each_possible_cpu(i) {
struct pcpu_lstats *lb_stats;
lb_stats = per_cpu_ptr(dev->lstats, i);
u64_stats_init(&lb_stats->syncp);
}
return 0;
}

Expand Down
7 changes: 7 additions & 0 deletions drivers/net/macvlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,7 @@ static int macvlan_init(struct net_device *dev)
{
struct macvlan_dev *vlan = netdev_priv(dev);
const struct net_device *lowerdev = vlan->lowerdev;
int i;

dev->state = (dev->state & ~MACVLAN_STATE_MASK) |
(lowerdev->state & MACVLAN_STATE_MASK);
Expand All @@ -516,6 +517,12 @@ static int macvlan_init(struct net_device *dev)
if (!vlan->pcpu_stats)
return -ENOMEM;

for_each_possible_cpu(i) {
struct macvlan_pcpu_stats *mvlstats;
mvlstats = per_cpu_ptr(vlan->pcpu_stats, i);
u64_stats_init(&mvlstats->syncp);
}

return 0;
}

Expand Down
8 changes: 8 additions & 0 deletions drivers/net/nlmon.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,16 @@ static int nlmon_change_mtu(struct net_device *dev, int new_mtu)

static int nlmon_dev_init(struct net_device *dev)
{
int i;

dev->lstats = alloc_percpu(struct pcpu_lstats);

for_each_possible_cpu(i) {
struct pcpu_lstats *nlmstats;
nlmstats = per_cpu_ptr(dev->lstats, i);
u64_stats_init(&nlmstats->syncp);
}

return dev->lstats == NULL ? -ENOMEM : 0;
}

Expand Down
6 changes: 6 additions & 0 deletions drivers/net/team/team.c
Original file line number Diff line number Diff line change
Expand Up @@ -1540,6 +1540,12 @@ static int team_init(struct net_device *dev)
if (!team->pcpu_stats)
return -ENOMEM;

for_each_possible_cpu(i) {
struct team_pcpu_stats *team_stats;
team_stats = per_cpu_ptr(team->pcpu_stats, i);
u64_stats_init(&team_stats->syncp);
}

for (i = 0; i < TEAM_PORT_HASHENTRIES; i++)
INIT_HLIST_HEAD(&team->en_port_hlist[i]);
INIT_LIST_HEAD(&team->port_list);
Expand Down
9 changes: 8 additions & 1 deletion drivers/net/team/team_mode_loadbalance.c
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ static int lb_init(struct team *team)
{
struct lb_priv *lb_priv = get_lb_priv(team);
lb_select_tx_port_func_t *func;
int err;
int i, err;

/* set default tx port selector */
func = lb_select_tx_port_get_func("hash");
Expand All @@ -588,6 +588,13 @@ static int lb_init(struct team *team)
goto err_alloc_pcpu_stats;
}

for_each_possible_cpu(i) {
struct lb_pcpu_stats *team_lb_stats;
team_lb_stats = per_cpu_ptr(lb_priv->pcpu_stats, i);
u64_stats_init(&team_lb_stats->syncp);
}


INIT_DELAYED_WORK(&lb_priv->ex->stats.refresh_dw, lb_stats_refresh);

err = team_options_register(team, lb_options, ARRAY_SIZE(lb_options));
Expand Down
8 changes: 8 additions & 0 deletions drivers/net/veth.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,18 @@ static int veth_change_mtu(struct net_device *dev, int new_mtu)

static int veth_dev_init(struct net_device *dev)
{
int i;

dev->vstats = alloc_percpu(struct pcpu_vstats);
if (!dev->vstats)
return -ENOMEM;

for_each_possible_cpu(i) {
struct pcpu_vstats *veth_stats;
veth_stats = per_cpu_ptr(dev->vstats, i);
u64_stats_init(&veth_stats->syncp);
}

return 0;
}

Expand Down
8 changes: 8 additions & 0 deletions drivers/net/virtio_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -1569,6 +1569,14 @@ static int virtnet_probe(struct virtio_device *vdev)
if (vi->stats == NULL)
goto free;

for_each_possible_cpu(i) {
struct virtnet_stats *virtnet_stats;
virtnet_stats = per_cpu_ptr(vi->stats, i);
u64_stats_init(&virtnet_stats->tx_syncp);
u64_stats_init(&virtnet_stats->rx_syncp);
}


vi->vq_index = alloc_percpu(int);
if (vi->vq_index == NULL)
goto free_stats;
Expand Down
8 changes: 8 additions & 0 deletions drivers/net/vxlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -1884,11 +1884,19 @@ static int vxlan_init(struct net_device *dev)
struct vxlan_dev *vxlan = netdev_priv(dev);
struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id);
struct vxlan_sock *vs;
int i;

dev->tstats = alloc_percpu(struct pcpu_tstats);
if (!dev->tstats)
return -ENOMEM;

for_each_possible_cpu(i) {
struct pcpu_tstats *vxlan_stats;
vxlan_stats = per_cpu_ptr(dev->tstats, i);
u64_stats_init(&vxlan_stats->syncp);
}


spin_lock(&vn->sock_lock);
vs = vxlan_find_sock(dev_net(dev), vxlan->dst_port);
if (vs) {
Expand Down
6 changes: 6 additions & 0 deletions drivers/net/xen-netfront.c
Original file line number Diff line number Diff line change
Expand Up @@ -1338,6 +1338,12 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev)
if (np->stats == NULL)
goto exit;

for_each_possible_cpu(i) {
struct netfront_stats *xen_nf_stats;
xen_nf_stats = per_cpu_ptr(np->stats, i);
u64_stats_init(&xen_nf_stats->syncp);
}

/* Initialise tx_skbs as a free chain containing every entry. */
np->tx_skb_freelist = 0;
for (i = 0; i < NET_TX_RING_SIZE; i++) {
Expand Down
7 changes: 7 additions & 0 deletions include/linux/u64_stats_sync.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ struct u64_stats_sync {
#endif
};


#if BITS_PER_LONG == 32 && defined(CONFIG_SMP)
# define u64_stats_init(syncp) seqcount_init(syncp.seq)
#else
# define u64_stats_init(syncp) do { } while (0)
#endif

static inline void u64_stats_update_begin(struct u64_stats_sync *syncp)
{
#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
Expand Down
9 changes: 8 additions & 1 deletion net/8021q/vlan_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,7 @@ static const struct net_device_ops vlan_netdev_ops;
static int vlan_dev_init(struct net_device *dev)
{
struct net_device *real_dev = vlan_dev_priv(dev)->real_dev;
int subclass = 0;
int subclass = 0, i;

netif_carrier_off(dev);

Expand Down Expand Up @@ -612,6 +612,13 @@ static int vlan_dev_init(struct net_device *dev)
if (!vlan_dev_priv(dev)->vlan_pcpu_stats)
return -ENOMEM;

for_each_possible_cpu(i) {
struct vlan_pcpu_stats *vlan_stat;
vlan_stat = per_cpu_ptr(vlan_dev_priv(dev)->vlan_pcpu_stats, i);
u64_stats_init(&vlan_stat->syncp);
}


return 0;
}

Expand Down
7 changes: 7 additions & 0 deletions net/bridge/br_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,18 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
static int br_dev_init(struct net_device *dev)
{
struct net_bridge *br = netdev_priv(dev);
int i;

br->stats = alloc_percpu(struct br_cpu_netstats);
if (!br->stats)
return -ENOMEM;

for_each_possible_cpu(i) {
struct br_cpu_netstats *br_dev_stats;
br_dev_stats = per_cpu_ptr(br->stats, i);
u64_stats_init(&br_dev_stats->syncp);
}

return 0;
}

Expand Down
Loading

0 comments on commit 827da44

Please sign in to comment.