047-net-mvneta-Fix-spinlock-usage.patch 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. From: Gregory CLEMENT <gregory.clement@free-electrons.com>
  2. Date: Sat, 12 Mar 2016 18:44:17 +0100
  3. Subject: [PATCH] net: mvneta: Fix spinlock usage
  4. In the previous patch, the spinlock was not initialized. While it didn't
  5. cause any trouble yet it could be a problem to use it uninitialized.
  6. The most annoying part was the critical section protected by the spinlock
  7. in mvneta_stop(). Some of the functions could sleep as pointed when
  8. activated CONFIG_DEBUG_ATOMIC_SLEEP. Actually, in mvneta_stop() we only
  9. need to protect the is_stopped flagged, indeed the code of the notifier
  10. for CPU online is protected by the same spinlock, so when we get the
  11. lock, the notifer work is done.
  12. Reported-by: Patrick Uiterwijk <patrick@puiterwijk.org>
  13. Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
  14. Signed-off-by: David S. Miller <davem@davemloft.net>
  15. ---
  16. --- a/drivers/net/ethernet/marvell/mvneta.c
  17. +++ b/drivers/net/ethernet/marvell/mvneta.c
  18. @@ -3488,17 +3488,17 @@ static int mvneta_stop(struct net_device
  19. struct mvneta_port *pp = netdev_priv(dev);
  20. /* Inform that we are stopping so we don't want to setup the
  21. - * driver for new CPUs in the notifiers
  22. + * driver for new CPUs in the notifiers. The code of the
  23. + * notifier for CPU online is protected by the same spinlock,
  24. + * so when we get the lock, the notifer work is done.
  25. */
  26. spin_lock(&pp->lock);
  27. pp->is_stopped = true;
  28. + spin_unlock(&pp->lock);
  29. +
  30. mvneta_stop_dev(pp);
  31. mvneta_mdio_remove(pp);
  32. unregister_cpu_notifier(&pp->cpu_notifier);
  33. - /* Now that the notifier are unregistered, we can release le
  34. - * lock
  35. - */
  36. - spin_unlock(&pp->lock);
  37. on_each_cpu(mvneta_percpu_disable, pp, true);
  38. free_percpu_irq(dev->irq, pp->ports);
  39. mvneta_cleanup_rxqs(pp);
  40. @@ -4031,6 +4031,7 @@ static int mvneta_probe(struct platform_
  41. dev->ethtool_ops = &mvneta_eth_tool_ops;
  42. pp = netdev_priv(dev);
  43. + spin_lock_init(&pp->lock);
  44. pp->phy_node = phy_node;
  45. pp->phy_interface = phy_mode;