Skip to content

Commit 1799cdd

Browse files
Jisheng Zhangdavem330
authored andcommitted
net: mvneta: improve suspend/resume
Current suspend/resume implementation reuses the mvneta_open() and mvneta_close(), but it could be optimized to take only necessary actions during suspend/resume. One obvious problem of current implementation is: after hundreds of system suspend/resume cycles, the resume of mvneta could fail due to fragmented dma coherent memory. After this patch, the non-necessary memory alloc/free is optimized out. Signed-off-by: Jisheng Zhang <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 4a188a6 commit 1799cdd

File tree

1 file changed

+62
-7
lines changed

1 file changed

+62
-7
lines changed

drivers/net/ethernet/marvell/mvneta.c

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4571,16 +4571,45 @@ static int mvneta_remove(struct platform_device *pdev)
45714571
#ifdef CONFIG_PM_SLEEP
45724572
static int mvneta_suspend(struct device *device)
45734573
{
4574+
int queue;
45744575
struct net_device *dev = dev_get_drvdata(device);
45754576
struct mvneta_port *pp = netdev_priv(dev);
45764577

4578+
if (!netif_running(dev))
4579+
goto clean_exit;
4580+
4581+
if (!pp->neta_armada3700) {
4582+
spin_lock(&pp->lock);
4583+
pp->is_stopped = true;
4584+
spin_unlock(&pp->lock);
4585+
4586+
cpuhp_state_remove_instance_nocalls(online_hpstate,
4587+
&pp->node_online);
4588+
cpuhp_state_remove_instance_nocalls(CPUHP_NET_MVNETA_DEAD,
4589+
&pp->node_dead);
4590+
}
4591+
45774592
rtnl_lock();
4578-
if (netif_running(dev))
4579-
mvneta_stop(dev);
4593+
mvneta_stop_dev(pp);
45804594
rtnl_unlock();
4595+
4596+
for (queue = 0; queue < rxq_number; queue++) {
4597+
struct mvneta_rx_queue *rxq = &pp->rxqs[queue];
4598+
4599+
mvneta_rxq_drop_pkts(pp, rxq);
4600+
}
4601+
4602+
for (queue = 0; queue < txq_number; queue++) {
4603+
struct mvneta_tx_queue *txq = &pp->txqs[queue];
4604+
4605+
mvneta_txq_hw_deinit(pp, txq);
4606+
}
4607+
4608+
clean_exit:
45814609
netif_device_detach(dev);
45824610
clk_disable_unprepare(pp->clk_bus);
45834611
clk_disable_unprepare(pp->clk);
4612+
45844613
return 0;
45854614
}
45864615

@@ -4589,7 +4618,7 @@ static int mvneta_resume(struct device *device)
45894618
struct platform_device *pdev = to_platform_device(device);
45904619
struct net_device *dev = dev_get_drvdata(device);
45914620
struct mvneta_port *pp = netdev_priv(dev);
4592-
int err;
4621+
int err, queue;
45934622

45944623
clk_prepare_enable(pp->clk);
45954624
if (!IS_ERR(pp->clk_bus))
@@ -4611,12 +4640,38 @@ static int mvneta_resume(struct device *device)
46114640
}
46124641

46134642
netif_device_attach(dev);
4614-
rtnl_lock();
4615-
if (netif_running(dev)) {
4616-
mvneta_open(dev);
4617-
mvneta_set_rx_mode(dev);
4643+
4644+
if (!netif_running(dev))
4645+
return 0;
4646+
4647+
for (queue = 0; queue < rxq_number; queue++) {
4648+
struct mvneta_rx_queue *rxq = &pp->rxqs[queue];
4649+
4650+
rxq->next_desc_to_proc = 0;
4651+
mvneta_rxq_hw_init(pp, rxq);
4652+
}
4653+
4654+
for (queue = 0; queue < txq_number; queue++) {
4655+
struct mvneta_tx_queue *txq = &pp->txqs[queue];
4656+
4657+
txq->next_desc_to_proc = 0;
4658+
mvneta_txq_hw_init(pp, txq);
46184659
}
4660+
4661+
if (!pp->neta_armada3700) {
4662+
spin_lock(&pp->lock);
4663+
pp->is_stopped = false;
4664+
spin_unlock(&pp->lock);
4665+
cpuhp_state_add_instance_nocalls(online_hpstate,
4666+
&pp->node_online);
4667+
cpuhp_state_add_instance_nocalls(CPUHP_NET_MVNETA_DEAD,
4668+
&pp->node_dead);
4669+
}
4670+
4671+
rtnl_lock();
4672+
mvneta_start_dev(pp);
46194673
rtnl_unlock();
4674+
mvneta_set_rx_mode(dev);
46204675

46214676
return 0;
46224677
}

0 commit comments

Comments
 (0)