76 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			76 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
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
 | 
						|
@@ -3040,6 +3040,20 @@ static int mvneta_check_mtu_valid(struct
 | 
						|
 	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)
 | 
						|
 {
 | 
						|
@@ -3064,6 +3078,7 @@ static int mvneta_change_mtu(struct net_
 | 
						|
 	 * reallocation of the queues
 | 
						|
 	 */
 | 
						|
 	mvneta_stop_dev(pp);
 | 
						|
+	on_each_cpu(mvneta_percpu_disable, pp, true);
 | 
						|
 
 | 
						|
 	mvneta_cleanup_txqs(pp);
 | 
						|
 	mvneta_cleanup_rxqs(pp);
 | 
						|
@@ -3087,6 +3102,7 @@ static int mvneta_change_mtu(struct net_
 | 
						|
 		return ret;
 | 
						|
 	}
 | 
						|
 
 | 
						|
+	on_each_cpu(mvneta_percpu_enable, pp, true);
 | 
						|
 	mvneta_start_dev(pp);
 | 
						|
 	mvneta_port_up(pp);
 | 
						|
 
 | 
						|
@@ -3240,20 +3256,6 @@ static void mvneta_mdio_remove(struct mv
 | 
						|
 	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.
 |