Skip to content

Commit

Permalink
net: mvneta: fix changing MTU when using per-cpu processing
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Marcin Wojtas authored and David S. Miller committed Apr 1, 2016
1 parent ce2a04c commit db5dd0d
Showing 1 changed file with 16 additions and 14 deletions.
30 changes: 16 additions & 14 deletions drivers/net/ethernet/marvell/mvneta.c
Original file line number Diff line number Diff line change
Expand Up @@ -3042,6 +3042,20 @@ static int mvneta_check_mtu_valid(struct net_device *dev, int mtu)
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)
{
Expand All @@ -3066,6 +3080,7 @@ static int mvneta_change_mtu(struct net_device *dev, int mtu)
* reallocation of the queues
*/
mvneta_stop_dev(pp);
on_each_cpu(mvneta_percpu_disable, pp, true);

mvneta_cleanup_txqs(pp);
mvneta_cleanup_rxqs(pp);
Expand All @@ -3089,6 +3104,7 @@ static int mvneta_change_mtu(struct net_device *dev, int mtu)
return ret;
}

on_each_cpu(mvneta_percpu_enable, pp, true);
mvneta_start_dev(pp);
mvneta_port_up(pp);

Expand Down Expand Up @@ -3242,20 +3258,6 @@ static void mvneta_mdio_remove(struct mvneta_port *pp)
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.
Expand Down

0 comments on commit db5dd0d

Please sign in to comment.