2017-04-17 06:43:54 +00:00
|
|
|
From: Marcin Wojtas <mw@semihalf.com>
|
|
|
|
Date: Fri, 1 Apr 2016 15:21:18 +0200
|
|
|
|
Subject: [PATCH] net: mvneta: fix changing MTU when using per-cpu processing
|
|
|
|
|
|
|
|
After enabling per-cpu processing it appeared that under heavy load
|
|
|
|
changing MTU can result in blocking all port's interrupts and
|
|
|
|
transmitting data is not possible after the change.
|
|
|
|
|
|
|
|
This commit fixes above issue by disabling percpu interrupts for the
|
|
|
|
time, when TXQs and RXQs are reconfigured.
|
|
|
|
|
|
|
|
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
|
|
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
|
|
---
|
|
|
|
|
|
|
|
--- a/drivers/net/ethernet/marvell/mvneta.c
|
|
|
|
+++ b/drivers/net/ethernet/marvell/mvneta.c
|
2018-01-07 14:12:52 +00:00
|
|
|
@@ -3044,6 +3044,20 @@ static int mvneta_check_mtu_valid(struct
|
2017-04-17 06:43:54 +00:00
|
|
|
return mtu;
|
|
|
|
}
|
|
|
|
|
|
|
|
+static void mvneta_percpu_enable(void *arg)
|
|
|
|
+{
|
|
|
|
+ struct mvneta_port *pp = arg;
|
|
|
|
+
|
|
|
|
+ enable_percpu_irq(pp->dev->irq, IRQ_TYPE_NONE);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void mvneta_percpu_disable(void *arg)
|
|
|
|
+{
|
|
|
|
+ struct mvneta_port *pp = arg;
|
|
|
|
+
|
|
|
|
+ disable_percpu_irq(pp->dev->irq);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
/* Change the device mtu */
|
|
|
|
static int mvneta_change_mtu(struct net_device *dev, int mtu)
|
|
|
|
{
|
2018-01-07 14:12:52 +00:00
|
|
|
@@ -3068,6 +3082,7 @@ static int mvneta_change_mtu(struct net_
|
2017-04-17 06:43:54 +00:00
|
|
|
* reallocation of the queues
|
|
|
|
*/
|
|
|
|
mvneta_stop_dev(pp);
|
|
|
|
+ on_each_cpu(mvneta_percpu_disable, pp, true);
|
|
|
|
|
|
|
|
mvneta_cleanup_txqs(pp);
|
|
|
|
mvneta_cleanup_rxqs(pp);
|
2018-01-07 14:12:52 +00:00
|
|
|
@@ -3091,6 +3106,7 @@ static int mvneta_change_mtu(struct net_
|
2017-04-17 06:43:54 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ on_each_cpu(mvneta_percpu_enable, pp, true);
|
|
|
|
mvneta_start_dev(pp);
|
|
|
|
mvneta_port_up(pp);
|
|
|
|
|
2018-01-07 14:12:52 +00:00
|
|
|
@@ -3244,20 +3260,6 @@ static void mvneta_mdio_remove(struct mv
|
2017-04-17 06:43:54 +00:00
|
|
|
pp->phy_dev = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
-static void mvneta_percpu_enable(void *arg)
|
|
|
|
-{
|
|
|
|
- struct mvneta_port *pp = arg;
|
|
|
|
-
|
|
|
|
- enable_percpu_irq(pp->dev->irq, IRQ_TYPE_NONE);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void mvneta_percpu_disable(void *arg)
|
|
|
|
-{
|
|
|
|
- struct mvneta_port *pp = arg;
|
|
|
|
-
|
|
|
|
- disable_percpu_irq(pp->dev->irq);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
/* Electing a CPU must be done in an atomic way: it should be done
|
|
|
|
* after or before the removal/insertion of a CPU and this function is
|
|
|
|
* not reentrant.
|