linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] drivers: net: cpsw: fix driver loading/unloading
@ 2016-07-22 13:58 Grygorii Strashko
  2016-07-22 13:58 ` [PATCH 1/3] net: ethernet: ti: cpdma: fix lockup in cpdma_ctlr_destroy() Grygorii Strashko
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Grygorii Strashko @ 2016-07-22 13:58 UTC (permalink / raw)
  To: David S. Miller, netdev, Mugunthan V N
  Cc: Sekhar Nori, linux-kernel, linux-omap, Grygorii Strashko

This series fixes set of isssues observed when CPSW driver module is unloaded/loaded:
1) rmmod: deadlock in cpdma_ctlr_destroy
2) rmmod: L3 back-trace and crash if all net interfaces are down, because CPSW
can be powerred down by PM runtime in this case.
3) insmod: mdio device is not recreated on next insmod
 - need to use of_platform_depopulate() in cpsw_remove().

Grygorii Strashko (3):
  net: ethernet: ti: cpdma: fix lockup in cpdma_ctlr_destroy()
  drivers: net: cpsw: fix wrong regs access in cpsw_remove
  drivers: net: cpsw: use of_platform_depopulate()

 drivers/net/ethernet/ti/cpsw.c          | 19 +++++++++----------
 drivers/net/ethernet/ti/davinci_cpdma.c |  2 --
 2 files changed, 9 insertions(+), 12 deletions(-)

-- 
2.9.2

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/3] net: ethernet: ti: cpdma: fix lockup in cpdma_ctlr_destroy()
  2016-07-22 13:58 [PATCH 0/3] drivers: net: cpsw: fix driver loading/unloading Grygorii Strashko
@ 2016-07-22 13:58 ` Grygorii Strashko
  2016-07-22 16:03   ` kbuild test robot
  2016-07-23  6:24   ` Ivan Khoronzhuk
  2016-07-22 13:58 ` [PATCH 2/3] drivers: net: cpsw: fix wrong regs access in cpsw_remove Grygorii Strashko
  2016-07-22 13:58 ` [PATCH 3/3] drivers: net: cpsw: use of_platform_depopulate() Grygorii Strashko
  2 siblings, 2 replies; 9+ messages in thread
From: Grygorii Strashko @ 2016-07-22 13:58 UTC (permalink / raw)
  To: David S. Miller, netdev, Mugunthan V N
  Cc: Sekhar Nori, linux-kernel, linux-omap, Grygorii Strashko

Fix deadlock in cpdma_ctlr_destroy() which is triggered now on
cpsw module removal:
 cpsw_remove()
 - cpdma_ctlr_destroy()
   - spin_lock_irqsave(&ctlr->lock, flags)
   - cpdma_ctlr_stop()
     - spin_lock_irqsave(&ctlr->lock, flags); <- deadlock
   - cpdma_chan_destroy()
     - spin_lock_irqsave(&ctlr->lock, flags); <- deadlock

The issue has not been observed before because CPDMA channels have
been destroyed manually by CPSW until commit d941ebe88a41 ("net:
ethernet: ti: cpsw: use destroy ctlr to destroy channels") was merged.

Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
 drivers/net/ethernet/ti/davinci_cpdma.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c b/drivers/net/ethernet/ti/davinci_cpdma.c
index a68652a..89242e9 100644
--- a/drivers/net/ethernet/ti/davinci_cpdma.c
+++ b/drivers/net/ethernet/ti/davinci_cpdma.c
@@ -436,7 +436,6 @@ int cpdma_ctlr_destroy(struct cpdma_ctlr *ctlr)
 	if (!ctlr)
 		return -EINVAL;
 
-	spin_lock_irqsave(&ctlr->lock, flags);
 	if (ctlr->state != CPDMA_STATE_IDLE)
 		cpdma_ctlr_stop(ctlr);
 
@@ -444,7 +443,6 @@ int cpdma_ctlr_destroy(struct cpdma_ctlr *ctlr)
 		cpdma_chan_destroy(ctlr->channels[i]);
 
 	cpdma_desc_pool_destroy(ctlr->pool);
-	spin_unlock_irqrestore(&ctlr->lock, flags);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(cpdma_ctlr_destroy);
-- 
2.9.2

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/3] drivers: net: cpsw: fix wrong regs access in cpsw_remove
  2016-07-22 13:58 [PATCH 0/3] drivers: net: cpsw: fix driver loading/unloading Grygorii Strashko
  2016-07-22 13:58 ` [PATCH 1/3] net: ethernet: ti: cpdma: fix lockup in cpdma_ctlr_destroy() Grygorii Strashko
@ 2016-07-22 13:58 ` Grygorii Strashko
  2016-07-22 13:58 ` [PATCH 3/3] drivers: net: cpsw: use of_platform_depopulate() Grygorii Strashko
  2 siblings, 0 replies; 9+ messages in thread
From: Grygorii Strashko @ 2016-07-22 13:58 UTC (permalink / raw)
  To: David S. Miller, netdev, Mugunthan V N
  Cc: Sekhar Nori, linux-kernel, linux-omap, Grygorii Strashko

The L3 error will be generated and system will crash during unloading
of CPSW driver if CPSW is used as module and ethX devices are down.
This happens because CPSW can be power off by PM runtime now when ethX
devices are down.

Hence, ensure that CPSW powered up by PM runtime before performing any
deinitialization actions which require CPSW registers access. In case
of PM runtime error just leave cpsw_remove() as we can't do anything
anymore.

Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
 drivers/net/ethernet/ti/cpsw.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 46423dd..a4d6eb5 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -2589,6 +2589,13 @@ static int cpsw_remove(struct platform_device *pdev)
 {
 	struct net_device *ndev = platform_get_drvdata(pdev);
 	struct cpsw_priv *priv = netdev_priv(ndev);
+	int ret;
+
+	ret = pm_runtime_get_sync(&pdev->dev);
+	if (ret < 0) {
+		pm_runtime_put_noidle(&pdev->dev);
+		return ret;
+	}
 
 	if (priv->data.dual_emac)
 		unregister_netdev(cpsw_get_slave_ndev(priv, 1));
@@ -2596,8 +2603,9 @@ static int cpsw_remove(struct platform_device *pdev)
 
 	cpsw_ale_destroy(priv->ale);
 	cpdma_ctlr_destroy(priv->dma);
-	pm_runtime_disable(&pdev->dev);
 	device_for_each_child(&pdev->dev, NULL, cpsw_remove_child_device);
+	pm_runtime_put_sync(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
 	if (priv->data.dual_emac)
 		free_netdev(cpsw_get_slave_ndev(priv, 1));
 	free_netdev(ndev);
-- 
2.9.2

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/3] drivers: net: cpsw: use of_platform_depopulate()
  2016-07-22 13:58 [PATCH 0/3] drivers: net: cpsw: fix driver loading/unloading Grygorii Strashko
  2016-07-22 13:58 ` [PATCH 1/3] net: ethernet: ti: cpdma: fix lockup in cpdma_ctlr_destroy() Grygorii Strashko
  2016-07-22 13:58 ` [PATCH 2/3] drivers: net: cpsw: fix wrong regs access in cpsw_remove Grygorii Strashko
@ 2016-07-22 13:58 ` Grygorii Strashko
  2 siblings, 0 replies; 9+ messages in thread
From: Grygorii Strashko @ 2016-07-22 13:58 UTC (permalink / raw)
  To: David S. Miller, netdev, Mugunthan V N
  Cc: Sekhar Nori, linux-kernel, linux-omap, Grygorii Strashko

Use of_platform_depopulate() in cpsw_remove() instead of
of_device_unregister(), because CSPW child devices will not be
recreated otherwise on next insmod. of_platform_depopulate() is
correct way now as it will ensure that all steps done in
of_platform_populate() are reverted, including cleaning up of
OF_POPULATED flag.

Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
 drivers/net/ethernet/ti/cpsw.c | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index a4d6eb5..ca5890f 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -2576,15 +2576,6 @@ clean_ndev_ret:
 	return ret;
 }
 
-static int cpsw_remove_child_device(struct device *dev, void *c)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-
-	of_device_unregister(pdev);
-
-	return 0;
-}
-
 static int cpsw_remove(struct platform_device *pdev)
 {
 	struct net_device *ndev = platform_get_drvdata(pdev);
@@ -2603,7 +2594,7 @@ static int cpsw_remove(struct platform_device *pdev)
 
 	cpsw_ale_destroy(priv->ale);
 	cpdma_ctlr_destroy(priv->dma);
-	device_for_each_child(&pdev->dev, NULL, cpsw_remove_child_device);
+	of_platform_depopulate(&pdev->dev);
 	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 	if (priv->data.dual_emac)
-- 
2.9.2

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/3] net: ethernet: ti: cpdma: fix lockup in cpdma_ctlr_destroy()
  2016-07-22 13:58 ` [PATCH 1/3] net: ethernet: ti: cpdma: fix lockup in cpdma_ctlr_destroy() Grygorii Strashko
@ 2016-07-22 16:03   ` kbuild test robot
  2016-07-23  6:24   ` Ivan Khoronzhuk
  1 sibling, 0 replies; 9+ messages in thread
From: kbuild test robot @ 2016-07-22 16:03 UTC (permalink / raw)
  To: Grygorii Strashko
  Cc: kbuild-all, David S. Miller, netdev, Mugunthan V N, Sekhar Nori,
	linux-kernel, linux-omap, Grygorii Strashko

[-- Attachment #1: Type: text/plain, Size: 4060 bytes --]

Hi,

[auto build test WARNING on net-next/master]
[also build test WARNING on v4.7-rc7 next-20160722]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Grygorii-Strashko/drivers-net-cpsw-fix-driver-loading-unloading/20160722-221708
config: arm-multi_v7_defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 5.4.0-6) 5.4.0 20160609
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=arm 

All warnings (new ones prefixed by >>):

   drivers/net/ethernet/ti/davinci_cpdma.c: In function 'cpdma_ctlr_destroy':
>> drivers/net/ethernet/ti/davinci_cpdma.c:433:16: warning: unused variable 'flags' [-Wunused-variable]
     unsigned long flags;
                   ^

vim +/flags +433 drivers/net/ethernet/ti/davinci_cpdma.c

ef8c2dab drivers/net/davinci_cpdma.c             Cyril Chemparathy 2010-09-15  417  			 dma_reg_read(ctlr, CPDMA_DMASTATUS));
ef8c2dab drivers/net/davinci_cpdma.c             Cyril Chemparathy 2010-09-15  418  		dev_info(dev, "CPDMA: rxbuffofs: %x",
ef8c2dab drivers/net/davinci_cpdma.c             Cyril Chemparathy 2010-09-15  419  			 dma_reg_read(ctlr, CPDMA_RXBUFFOFS));
ef8c2dab drivers/net/davinci_cpdma.c             Cyril Chemparathy 2010-09-15  420  	}
ef8c2dab drivers/net/davinci_cpdma.c             Cyril Chemparathy 2010-09-15  421  
ef8c2dab drivers/net/davinci_cpdma.c             Cyril Chemparathy 2010-09-15  422  	for (i = 0; i < ARRAY_SIZE(ctlr->channels); i++)
ef8c2dab drivers/net/davinci_cpdma.c             Cyril Chemparathy 2010-09-15  423  		if (ctlr->channels[i])
ef8c2dab drivers/net/davinci_cpdma.c             Cyril Chemparathy 2010-09-15  424  			cpdma_chan_dump(ctlr->channels[i]);
ef8c2dab drivers/net/davinci_cpdma.c             Cyril Chemparathy 2010-09-15  425  
ef8c2dab drivers/net/davinci_cpdma.c             Cyril Chemparathy 2010-09-15  426  	spin_unlock_irqrestore(&ctlr->lock, flags);
ef8c2dab drivers/net/davinci_cpdma.c             Cyril Chemparathy 2010-09-15  427  	return 0;
ef8c2dab drivers/net/davinci_cpdma.c             Cyril Chemparathy 2010-09-15  428  }
32a6d90b drivers/net/ethernet/ti/davinci_cpdma.c Arnd Bergmann     2012-04-20  429  EXPORT_SYMBOL_GPL(cpdma_ctlr_dump);
ef8c2dab drivers/net/davinci_cpdma.c             Cyril Chemparathy 2010-09-15  430  
ef8c2dab drivers/net/davinci_cpdma.c             Cyril Chemparathy 2010-09-15  431  int cpdma_ctlr_destroy(struct cpdma_ctlr *ctlr)
ef8c2dab drivers/net/davinci_cpdma.c             Cyril Chemparathy 2010-09-15  432  {
ef8c2dab drivers/net/davinci_cpdma.c             Cyril Chemparathy 2010-09-15 @433  	unsigned long flags;
ef8c2dab drivers/net/davinci_cpdma.c             Cyril Chemparathy 2010-09-15  434  	int ret = 0, i;
ef8c2dab drivers/net/davinci_cpdma.c             Cyril Chemparathy 2010-09-15  435  
ef8c2dab drivers/net/davinci_cpdma.c             Cyril Chemparathy 2010-09-15  436  	if (!ctlr)
ef8c2dab drivers/net/davinci_cpdma.c             Cyril Chemparathy 2010-09-15  437  		return -EINVAL;
ef8c2dab drivers/net/davinci_cpdma.c             Cyril Chemparathy 2010-09-15  438  
ef8c2dab drivers/net/davinci_cpdma.c             Cyril Chemparathy 2010-09-15  439  	if (ctlr->state != CPDMA_STATE_IDLE)
ef8c2dab drivers/net/davinci_cpdma.c             Cyril Chemparathy 2010-09-15  440  		cpdma_ctlr_stop(ctlr);
ef8c2dab drivers/net/davinci_cpdma.c             Cyril Chemparathy 2010-09-15  441  

:::::: The code at line 433 was first introduced by commit
:::::: ef8c2dab01b6e30c4b2ca3ea3b8db33430493589 net: davinci_emac: separate out cpdma code

:::::: TO: Cyril Chemparathy <cyril@ti.com>
:::::: CC: Kevin Hilman <khilman@deeprootsystems.com>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 37759 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/3] net: ethernet: ti: cpdma: fix lockup in cpdma_ctlr_destroy()
  2016-07-22 13:58 ` [PATCH 1/3] net: ethernet: ti: cpdma: fix lockup in cpdma_ctlr_destroy() Grygorii Strashko
  2016-07-22 16:03   ` kbuild test robot
@ 2016-07-23  6:24   ` Ivan Khoronzhuk
  2016-07-26 16:02     ` Grygorii Strashko
  1 sibling, 1 reply; 9+ messages in thread
From: Ivan Khoronzhuk @ 2016-07-23  6:24 UTC (permalink / raw)
  To: Grygorii Strashko, David S. Miller, netdev, Mugunthan V N
  Cc: Sekhar Nori, linux-kernel, linux-omap



On 22.07.16 16:58, Grygorii Strashko wrote:
> Fix deadlock in cpdma_ctlr_destroy() which is triggered now on
> cpsw module removal:
>  cpsw_remove()
>  - cpdma_ctlr_destroy()
>    - spin_lock_irqsave(&ctlr->lock, flags)
>    - cpdma_ctlr_stop()
>      - spin_lock_irqsave(&ctlr->lock, flags); <- deadlock
>    - cpdma_chan_destroy()
>      - spin_lock_irqsave(&ctlr->lock, flags); <- deadlock
>
> The issue has not been observed before because CPDMA channels have
> been destroyed manually by CPSW until commit d941ebe88a41 ("net:
> ethernet: ti: cpsw: use destroy ctlr to destroy channels") was merged.
>
> Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
> ---
>  drivers/net/ethernet/ti/davinci_cpdma.c | 2 --
>  1 file changed, 2 deletions(-)
>
> diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c b/drivers/net/ethernet/ti/davinci_cpdma.c
> index a68652a..89242e9 100644
> --- a/drivers/net/ethernet/ti/davinci_cpdma.c
> +++ b/drivers/net/ethernet/ti/davinci_cpdma.c
> @@ -436,7 +436,6 @@ int cpdma_ctlr_destroy(struct cpdma_ctlr *ctlr)
>  	if (!ctlr)
>  		return -EINVAL;
>
> -	spin_lock_irqsave(&ctlr->lock, flags);
Should ctlr->state be checked under lock?
Seems like here should be used unlocked static versions of
cpdma_ctlr_stop() and cpdma_chan_destroy() instead.

>  	if (ctlr->state != CPDMA_STATE_IDLE)
>  		cpdma_ctlr_stop(ctlr);
>
> @@ -444,7 +443,6 @@ int cpdma_ctlr_destroy(struct cpdma_ctlr *ctlr)
>  		cpdma_chan_destroy(ctlr->channels[i]);
>
>  	cpdma_desc_pool_destroy(ctlr->pool);
> -	spin_unlock_irqrestore(&ctlr->lock, flags);
>  	return ret;
>  }
>  EXPORT_SYMBOL_GPL(cpdma_ctlr_destroy);
>

-- 
Regards,
Ivan Khoronzhuk

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/3] net: ethernet: ti: cpdma: fix lockup in cpdma_ctlr_destroy()
  2016-07-23  6:24   ` Ivan Khoronzhuk
@ 2016-07-26 16:02     ` Grygorii Strashko
  2016-07-26 20:54       ` ivan.khoronzhuk
  0 siblings, 1 reply; 9+ messages in thread
From: Grygorii Strashko @ 2016-07-26 16:02 UTC (permalink / raw)
  To: Ivan Khoronzhuk, David S. Miller, netdev, Mugunthan V N
  Cc: Sekhar Nori, linux-kernel, linux-omap

On 07/23/2016 09:24 AM, Ivan Khoronzhuk wrote:
> 
> 
> On 22.07.16 16:58, Grygorii Strashko wrote:
>> Fix deadlock in cpdma_ctlr_destroy() which is triggered now on
>> cpsw module removal:
>>  cpsw_remove()
>>  - cpdma_ctlr_destroy()
>>    - spin_lock_irqsave(&ctlr->lock, flags)
>>    - cpdma_ctlr_stop()
>>      - spin_lock_irqsave(&ctlr->lock, flags); <- deadlock
>>    - cpdma_chan_destroy()
>>      - spin_lock_irqsave(&ctlr->lock, flags); <- deadlock
>>
>> The issue has not been observed before because CPDMA channels have
>> been destroyed manually by CPSW until commit d941ebe88a41 ("net:
>> ethernet: ti: cpsw: use destroy ctlr to destroy channels") was merged.
>>
>> Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
>> ---
>>  drivers/net/ethernet/ti/davinci_cpdma.c | 2 --
>>  1 file changed, 2 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c
>> b/drivers/net/ethernet/ti/davinci_cpdma.c
>> index a68652a..89242e9 100644
>> --- a/drivers/net/ethernet/ti/davinci_cpdma.c
>> +++ b/drivers/net/ethernet/ti/davinci_cpdma.c
>> @@ -436,7 +436,6 @@ int cpdma_ctlr_destroy(struct cpdma_ctlr *ctlr)
>>      if (!ctlr)
>>          return -EINVAL;
>>
>> -    spin_lock_irqsave(&ctlr->lock, flags);
> Should ctlr->state be checked under lock?
> Seems like here should be used unlocked static versions of
> cpdma_ctlr_stop() and cpdma_chan_destroy() instead.

As per my understanding it's not expected the ctlr->state will be changed at this 
moment as all net devices has been unregistered already.

> 
>>      if (ctlr->state != CPDMA_STATE_IDLE)

May be I can move above check in cpdma_ctlr_stop() instead.
What do you think?

>>          cpdma_ctlr_stop(ctlr);
>>
>> @@ -444,7 +443,6 @@ int cpdma_ctlr_destroy(struct cpdma_ctlr *ctlr)
>>          cpdma_chan_destroy(ctlr->channels[i]);
>>
>>      cpdma_desc_pool_destroy(ctlr->pool);
>> -    spin_unlock_irqrestore(&ctlr->lock, flags);
>>      return ret;
>>  }
>>  EXPORT_SYMBOL_GPL(cpdma_ctlr_destroy);
>>
> 


-- 
regards,
-grygorii

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/3] net: ethernet: ti: cpdma: fix lockup in cpdma_ctlr_destroy()
  2016-07-26 16:02     ` Grygorii Strashko
@ 2016-07-26 20:54       ` ivan.khoronzhuk
  2016-07-28  9:44         ` Grygorii Strashko
  0 siblings, 1 reply; 9+ messages in thread
From: ivan.khoronzhuk @ 2016-07-26 20:54 UTC (permalink / raw)
  To: Grygorii Strashko, Ivan Khoronzhuk, David S. Miller, netdev,
	Mugunthan V N
  Cc: Sekhar Nori, linux-kernel, linux-omap



On 26.07.16 19:02, Grygorii Strashko wrote:
> On 07/23/2016 09:24 AM, Ivan Khoronzhuk wrote:
>>
>>
>> On 22.07.16 16:58, Grygorii Strashko wrote:
>>> Fix deadlock in cpdma_ctlr_destroy() which is triggered now on
>>> cpsw module removal:
>>>  cpsw_remove()
>>>  - cpdma_ctlr_destroy()
>>>    - spin_lock_irqsave(&ctlr->lock, flags)
>>>    - cpdma_ctlr_stop()
>>>      - spin_lock_irqsave(&ctlr->lock, flags); <- deadlock
>>>    - cpdma_chan_destroy()
>>>      - spin_lock_irqsave(&ctlr->lock, flags); <- deadlock
>>>
>>> The issue has not been observed before because CPDMA channels have
>>> been destroyed manually by CPSW until commit d941ebe88a41 ("net:
>>> ethernet: ti: cpsw: use destroy ctlr to destroy channels") was merged.
>>>
>>> Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
>>> ---
>>>  drivers/net/ethernet/ti/davinci_cpdma.c | 2 --
>>>  1 file changed, 2 deletions(-)
>>>
>>> diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c
>>> b/drivers/net/ethernet/ti/davinci_cpdma.c
>>> index a68652a..89242e9 100644
>>> --- a/drivers/net/ethernet/ti/davinci_cpdma.c
>>> +++ b/drivers/net/ethernet/ti/davinci_cpdma.c
>>> @@ -436,7 +436,6 @@ int cpdma_ctlr_destroy(struct cpdma_ctlr *ctlr)
>>>      if (!ctlr)
>>>          return -EINVAL;
>>>
>>> -    spin_lock_irqsave(&ctlr->lock, flags);
>> Should ctlr->state be checked under lock?
>> Seems like here should be used unlocked static versions of
>> cpdma_ctlr_stop() and cpdma_chan_destroy() instead.
>
> As per my understanding it's not expected the ctlr->state will be changed at this
> moment as all net devices has been unregistered already.
Seems yes, the race can be only in case of incorrect usage, stop while destroy,
destroy while start...etc..all they are mostly unreal use-cases, you are right,
but such check w/o lock always under eyes control, that always makes you think
that smth wrong.

>
>>
>>>      if (ctlr->state != CPDMA_STATE_IDLE)
>
> May be I can move above check in cpdma_ctlr_stop() instead.
> What do you think?
Yes, it be more clear.
I was thinking about lock deletion also, as under this destroy function the
ctlr destroys it's resources one by one, ok, the channels are destroyed under lock,
but pool ....(it's good that it's destroyed after channels). I see that it should never
happen, but ctrl is external structure, who knows as it can be used while destroying.
That was my paranoiac point, so don't pay a lot attention to it. In case of normal usage,
as it's currently is and should be, the lock can be removed.

>
>>>          cpdma_ctlr_stop(ctlr);
>>>
>>> @@ -444,7 +443,6 @@ int cpdma_ctlr_destroy(struct cpdma_ctlr *ctlr)
>>>          cpdma_chan_destroy(ctlr->channels[i]);
>>>
>>>      cpdma_desc_pool_destroy(ctlr->pool);
>>> -    spin_unlock_irqrestore(&ctlr->lock, flags);
>>>      return ret;
>>>  }
>>>  EXPORT_SYMBOL_GPL(cpdma_ctlr_destroy);
>>>
>>
>
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/3] net: ethernet: ti: cpdma: fix lockup in cpdma_ctlr_destroy()
  2016-07-26 20:54       ` ivan.khoronzhuk
@ 2016-07-28  9:44         ` Grygorii Strashko
  0 siblings, 0 replies; 9+ messages in thread
From: Grygorii Strashko @ 2016-07-28  9:44 UTC (permalink / raw)
  To: ivan.khoronzhuk, David S. Miller, netdev, Mugunthan V N
  Cc: Sekhar Nori, linux-kernel, linux-omap

On 07/26/2016 11:54 PM, ivan.khoronzhuk wrote:
> 
> 
> On 26.07.16 19:02, Grygorii Strashko wrote:
>> On 07/23/2016 09:24 AM, Ivan Khoronzhuk wrote:
>>>
>>>
>>> On 22.07.16 16:58, Grygorii Strashko wrote:
>>>> Fix deadlock in cpdma_ctlr_destroy() which is triggered now on
>>>> cpsw module removal:
>>>>  cpsw_remove()
>>>>  - cpdma_ctlr_destroy()
>>>>    - spin_lock_irqsave(&ctlr->lock, flags)
>>>>    - cpdma_ctlr_stop()
>>>>      - spin_lock_irqsave(&ctlr->lock, flags); <- deadlock
>>>>    - cpdma_chan_destroy()
>>>>      - spin_lock_irqsave(&ctlr->lock, flags); <- deadlock
>>>>
>>>> The issue has not been observed before because CPDMA channels have
>>>> been destroyed manually by CPSW until commit d941ebe88a41 ("net:
>>>> ethernet: ti: cpsw: use destroy ctlr to destroy channels") was merged.
>>>>
>>>> Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
>>>> ---
>>>>  drivers/net/ethernet/ti/davinci_cpdma.c | 2 --
>>>>  1 file changed, 2 deletions(-)
>>>>
>>>> diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c
>>>> b/drivers/net/ethernet/ti/davinci_cpdma.c
>>>> index a68652a..89242e9 100644
>>>> --- a/drivers/net/ethernet/ti/davinci_cpdma.c
>>>> +++ b/drivers/net/ethernet/ti/davinci_cpdma.c
>>>> @@ -436,7 +436,6 @@ int cpdma_ctlr_destroy(struct cpdma_ctlr *ctlr)
>>>>      if (!ctlr)
>>>>          return -EINVAL;
>>>>
>>>> -    spin_lock_irqsave(&ctlr->lock, flags);
>>> Should ctlr->state be checked under lock?
>>> Seems like here should be used unlocked static versions of
>>> cpdma_ctlr_stop() and cpdma_chan_destroy() instead.
>>
>> As per my understanding it's not expected the ctlr->state will be
>> changed at this
>> moment as all net devices has been unregistered already.
> Seems yes, the race can be only in case of incorrect usage, stop while
> destroy,
> destroy while start...etc..all they are mostly unreal use-cases, you are
> right,
> but such check w/o lock always under eyes control, that always makes you
> think
> that smth wrong.
> 
>>
>>>
>>>>      if (ctlr->state != CPDMA_STATE_IDLE)
>>
>> May be I can move above check in cpdma_ctlr_stop() instead.
>> What do you think?
> Yes, it be more clear.
> I was thinking about lock deletion also, as under this destroy function the
> ctlr destroys it's resources one by one, ok, the channels are destroyed
> under lock,
> but pool ....(it's good that it's destroyed after channels). I see that
> it should never
> happen, but ctrl is external structure, who knows as it can be used
> while destroying.
> That was my paranoiac point, so don't pay a lot attention to it. In case
> of normal usage,
> as it's currently is and should be, the lock can be removed.


I'm going to keep it as is after some thinking and code checking -
I don't see any reasons for races here and I can't simply move this check in cpdma_ctlr_stop() 
as it might break ndo_open failure handling (and this is not smth. I'd like to fix within this series).

I'll resend v2 with build issue fixed and with fix for new issue I've found.
> 
>>
>>>>          cpdma_ctlr_stop(ctlr);
>>>>
>>>> @@ -444,7 +443,6 @@ int cpdma_ctlr_destroy(struct cpdma_ctlr *ctlr)
>>>>          cpdma_chan_destroy(ctlr->channels[i]);
>>>>
>>>>      cpdma_desc_pool_destroy(ctlr->pool);
>>>> -    spin_unlock_irqrestore(&ctlr->lock, flags);
>>>>      return ret;
>>>>  }
>>>>  EXPORT_SYMBOL_GPL(cpdma_ctlr_destroy);
>>>>
>>>
>>
>>


-- 
regards,
-grygorii

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2016-07-28  9:45 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-22 13:58 [PATCH 0/3] drivers: net: cpsw: fix driver loading/unloading Grygorii Strashko
2016-07-22 13:58 ` [PATCH 1/3] net: ethernet: ti: cpdma: fix lockup in cpdma_ctlr_destroy() Grygorii Strashko
2016-07-22 16:03   ` kbuild test robot
2016-07-23  6:24   ` Ivan Khoronzhuk
2016-07-26 16:02     ` Grygorii Strashko
2016-07-26 20:54       ` ivan.khoronzhuk
2016-07-28  9:44         ` Grygorii Strashko
2016-07-22 13:58 ` [PATCH 2/3] drivers: net: cpsw: fix wrong regs access in cpsw_remove Grygorii Strashko
2016-07-22 13:58 ` [PATCH 3/3] drivers: net: cpsw: use of_platform_depopulate() Grygorii Strashko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).