042-net-mvneta-Fix-race-condition-during-stopping.patch 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. From: Gregory CLEMENT <gregory.clement@free-electrons.com>
  2. Date: Thu, 4 Feb 2016 22:09:29 +0100
  3. Subject: [PATCH] net: mvneta: Fix race condition during stopping
  4. When stopping the port, the CPU notifier are still there whereas the
  5. mvneta_stop_dev function calls mvneta_percpu_disable() on each CPUs.
  6. It was possible to have a new CPU coming at this point which could be
  7. racy.
  8. This patch adds a flag preventing executing the code notifier for a new
  9. CPU when the port is stopping. It also uses the spinlock introduces
  10. previously. To avoid the deadlock, the lock has been moved outside the
  11. mvneta_percpu_elect function.
  12. Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
  13. Signed-off-by: David S. Miller <davem@davemloft.net>
  14. ---
  15. --- a/drivers/net/ethernet/marvell/mvneta.c
  16. +++ b/drivers/net/ethernet/marvell/mvneta.c
  17. @@ -374,6 +374,7 @@ struct mvneta_port {
  18. * ensuring that the configuration remains coherent.
  19. */
  20. spinlock_t lock;
  21. + bool is_stopped;
  22. /* Core clock */
  23. struct clk *clk;
  24. @@ -2853,16 +2854,14 @@ static void mvneta_percpu_disable(void *
  25. disable_percpu_irq(pp->dev->irq);
  26. }
  27. +/* Electing a CPU must be done in an atomic way: it should be done
  28. + * after or before the removal/insertion of a CPU and this function is
  29. + * not reentrant.
  30. + */
  31. static void mvneta_percpu_elect(struct mvneta_port *pp)
  32. {
  33. int elected_cpu = 0, max_cpu, cpu, i = 0;
  34. - /* Electing a CPU must be done in an atomic way: it should be
  35. - * done after or before the removal/insertion of a CPU and
  36. - * this function is not reentrant.
  37. - */
  38. - spin_lock(&pp->lock);
  39. -
  40. /* Use the cpu associated to the rxq when it is online, in all
  41. * the other cases, use the cpu 0 which can't be offline.
  42. */
  43. @@ -2906,7 +2905,6 @@ static void mvneta_percpu_elect(struct m
  44. i++;
  45. }
  46. - spin_unlock(&pp->lock);
  47. };
  48. static int mvneta_percpu_notifier(struct notifier_block *nfb,
  49. @@ -2920,6 +2918,14 @@ static int mvneta_percpu_notifier(struct
  50. switch (action) {
  51. case CPU_ONLINE:
  52. case CPU_ONLINE_FROZEN:
  53. + spin_lock(&pp->lock);
  54. + /* Configuring the driver for a new CPU while the
  55. + * driver is stopping is racy, so just avoid it.
  56. + */
  57. + if (pp->is_stopped) {
  58. + spin_unlock(&pp->lock);
  59. + break;
  60. + }
  61. netif_tx_stop_all_queues(pp->dev);
  62. /* We have to synchronise on tha napi of each CPU
  63. @@ -2957,6 +2963,7 @@ static int mvneta_percpu_notifier(struct
  64. MVNETA_CAUSE_LINK_CHANGE |
  65. MVNETA_CAUSE_PSC_SYNC_CHANGE);
  66. netif_tx_start_all_queues(pp->dev);
  67. + spin_unlock(&pp->lock);
  68. break;
  69. case CPU_DOWN_PREPARE:
  70. case CPU_DOWN_PREPARE_FROZEN:
  71. @@ -2981,7 +2988,9 @@ static int mvneta_percpu_notifier(struct
  72. case CPU_DEAD:
  73. case CPU_DEAD_FROZEN:
  74. /* Check if a new CPU must be elected now this on is down */
  75. + spin_lock(&pp->lock);
  76. mvneta_percpu_elect(pp);
  77. + spin_unlock(&pp->lock);
  78. /* Unmask all ethernet port interrupts */
  79. on_each_cpu(mvneta_percpu_unmask_interrupt, pp, true);
  80. mvreg_write(pp, MVNETA_INTR_MISC_MASK,
  81. @@ -3033,7 +3042,7 @@ static int mvneta_open(struct net_device
  82. */
  83. on_each_cpu(mvneta_percpu_enable, pp, true);
  84. -
  85. + pp->is_stopped = false;
  86. /* Register a CPU notifier to handle the case where our CPU
  87. * might be taken offline.
  88. */
  89. @@ -3066,9 +3075,18 @@ static int mvneta_stop(struct net_device
  90. {
  91. struct mvneta_port *pp = netdev_priv(dev);
  92. + /* Inform that we are stopping so we don't want to setup the
  93. + * driver for new CPUs in the notifiers
  94. + */
  95. + spin_lock(&pp->lock);
  96. + pp->is_stopped = true;
  97. mvneta_stop_dev(pp);
  98. mvneta_mdio_remove(pp);
  99. unregister_cpu_notifier(&pp->cpu_notifier);
  100. + /* Now that the notifier are unregistered, we can release le
  101. + * lock
  102. + */
  103. + spin_unlock(&pp->lock);
  104. on_each_cpu(mvneta_percpu_disable, pp, true);
  105. free_percpu_irq(dev->irq, pp->ports);
  106. mvneta_cleanup_rxqs(pp);
  107. @@ -3339,7 +3357,9 @@ static int mvneta_config_rss(struct mvn
  108. mvreg_write(pp, MVNETA_PORT_CONFIG, val);
  109. /* Update the elected CPU matching the new rxq_def */
  110. + spin_lock(&pp->lock);
  111. mvneta_percpu_elect(pp);
  112. + spin_unlock(&pp->lock);
  113. /* We have to synchronise on the napi of each CPU */
  114. for_each_online_cpu(cpu) {