[PATCH v2] fsl_ucc_hdlc: add a check of the return value from hdlc_open

Alexandra Diupina posted 1 patch 2 years, 3 months ago
drivers/net/wan/fsl_ucc_hdlc.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
[PATCH v2] fsl_ucc_hdlc: add a check of the return value from hdlc_open
Posted by Alexandra Diupina 2 years, 3 months ago
Process the result of hold_open() and return it from
uhdlc_open() in case of an error
It is necessary to pass the error code up the control flow,
similar to a possible error in request_irq()

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes: c19b6d246a35 ("drivers/net: support hdlc function for QE-UCC")
Signed-off-by: Alexandra Diupina <adiupina@astralinux.ru>
---
v2: Remove the 'rc' variable (stores the return value of the 
hdlc_open()) as Christophe Leroy <christophe.leroy@csgroup.eu> suggested
 drivers/net/wan/fsl_ucc_hdlc.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c
index cdd9489c712e..4164abea7725 100644
--- a/drivers/net/wan/fsl_ucc_hdlc.c
+++ b/drivers/net/wan/fsl_ucc_hdlc.c
@@ -708,7 +708,6 @@ static int uhdlc_open(struct net_device *dev)
 	hdlc_device *hdlc = dev_to_hdlc(dev);
 	struct ucc_hdlc_private *priv = hdlc->priv;
 	struct ucc_tdm *utdm = priv->utdm;
-	int rc = 0;
 
 	if (priv->hdlc_busy != 1) {
 		if (request_irq(priv->ut_info->uf_info.irq,
@@ -732,12 +731,10 @@ static int uhdlc_open(struct net_device *dev)
 		napi_enable(&priv->napi);
 		netdev_reset_queue(dev);
 		netif_start_queue(dev);
-		rc = hdlc_open(dev);
-		if (rc)
-			return rc;
+		return hdlc_open(dev);
 	}
 
-	return rc;
+	return 0;
 }
 
 static void uhdlc_memclean(struct ucc_hdlc_private *priv)
-- 
2.30.2
Re: [PATCH v2] fsl_ucc_hdlc: add a check of the return value from hdlc_open
Posted by Christophe Leroy 2 years, 3 months ago

Le 28/08/2023 à 10:27, Alexandra Diupina a écrit :
> [Vous ne recevez pas souvent de courriers de adiupina@astralinux.ru. Découvrez pourquoi ceci est important à https://aka.ms/LearnAboutSenderIdentification ]
> 
> Process the result of hold_open() and return it from
> uhdlc_open() in case of an error
> It is necessary to pass the error code up the control flow,
> similar to a possible error in request_irq()
> 
> Found by Linux Verification Center (linuxtesting.org) with SVACE.
> 
> Fixes: c19b6d246a35 ("drivers/net: support hdlc function for QE-UCC")
> Signed-off-by: Alexandra Diupina <adiupina@astralinux.ru>
> ---
> v2: Remove the 'rc' variable (stores the return value of the
> hdlc_open()) as Christophe Leroy <christophe.leroy@csgroup.eu> suggested
>   drivers/net/wan/fsl_ucc_hdlc.c | 7 ++-----
>   1 file changed, 2 insertions(+), 5 deletions(-)

I think you did a mistake. A v2 should substitute v1, not come in 
addition to it. So you have to squash this patch into previous one 
before resending.

Christophe

> 
> diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c
> index cdd9489c712e..4164abea7725 100644
> --- a/drivers/net/wan/fsl_ucc_hdlc.c
> +++ b/drivers/net/wan/fsl_ucc_hdlc.c
> @@ -708,7 +708,6 @@ static int uhdlc_open(struct net_device *dev)
>          hdlc_device *hdlc = dev_to_hdlc(dev);
>          struct ucc_hdlc_private *priv = hdlc->priv;
>          struct ucc_tdm *utdm = priv->utdm;
> -       int rc = 0;
> 
>          if (priv->hdlc_busy != 1) {
>                  if (request_irq(priv->ut_info->uf_info.irq,
> @@ -732,12 +731,10 @@ static int uhdlc_open(struct net_device *dev)
>                  napi_enable(&priv->napi);
>                  netdev_reset_queue(dev);
>                  netif_start_queue(dev);
> -               rc = hdlc_open(dev);
> -               if (rc)
> -                       return rc;
> +               return hdlc_open(dev);
>          }
> 
> -       return rc;
> +       return 0;
>   }
> 
>   static void uhdlc_memclean(struct ucc_hdlc_private *priv)
> --
> 2.30.2
> 
[PATCH v3] fsl_ucc_hdlc: process the result of hold_open()
Posted by Alexandra Diupina 2 years, 3 months ago
Process the result of hold_open() and return it from
uhdlc_open() in case of an error
It is necessary to pass the error code up the control flow,
similar to a possible error in request_irq()

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes: c19b6d246a35 ("drivers/net: support hdlc function for QE-UCC")
Signed-off-by: Alexandra Diupina <adiupina@astralinux.ru>
---
v3: Fix the commits tree
v2: Remove the 'rc' variable (stores the return value of the 
hdlc_open()) as Christophe Leroy <christophe.leroy@csgroup.eu> suggested
 drivers/net/wan/fsl_ucc_hdlc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c
index 47c2ad7a3e42..4164abea7725 100644
--- a/drivers/net/wan/fsl_ucc_hdlc.c
+++ b/drivers/net/wan/fsl_ucc_hdlc.c
@@ -731,7 +731,7 @@ static int uhdlc_open(struct net_device *dev)
 		napi_enable(&priv->napi);
 		netdev_reset_queue(dev);
 		netif_start_queue(dev);
-		hdlc_open(dev);
+		return hdlc_open(dev);
 	}
 
 	return 0;
-- 
2.30.2
Re: [PATCH v3] fsl_ucc_hdlc: process the result of hold_open()
Posted by Jakub Kicinski 2 years, 3 months ago
On Mon, 28 Aug 2023 15:12:35 +0300 Alexandra Diupina wrote:
> Process the result of hold_open() and return it from
> uhdlc_open() in case of an error
> It is necessary to pass the error code up the control flow,
> similar to a possible error in request_irq()
> 
> Found by Linux Verification Center (linuxtesting.org) with SVACE.
> 
> Fixes: c19b6d246a35 ("drivers/net: support hdlc function for QE-UCC")
> Signed-off-by: Alexandra Diupina <adiupina@astralinux.ru>
> ---
> v3: Fix the commits tree
> v2: Remove the 'rc' variable (stores the return value of the 
> hdlc_open()) as Christophe Leroy <christophe.leroy@csgroup.eu> suggested
>  drivers/net/wan/fsl_ucc_hdlc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c
> index 47c2ad7a3e42..4164abea7725 100644
> --- a/drivers/net/wan/fsl_ucc_hdlc.c
> +++ b/drivers/net/wan/fsl_ucc_hdlc.c
> @@ -731,7 +731,7 @@ static int uhdlc_open(struct net_device *dev)
>  		napi_enable(&priv->napi);
>  		netdev_reset_queue(dev);
>  		netif_start_queue(dev);
> -		hdlc_open(dev);
> +		return hdlc_open(dev);

Don't you have to undo all the things done prior to hdlc_open()?

Before you post v4 please make sure that you've read:
https://www.kernel.org/doc/html/next/process/maintainer-netdev.html#resending-after-review

Zhao, please review the next version.
-- 
pw-bot: cr
Re: [PATCH v3] fsl_ucc_hdlc: process the result of hold_open()
Posted by Александра Дюпина 2 years, 3 months ago
Thanks for the review!

28.08.2023 22:38, Jakub Kicinski пишет:
> Don't you have to undo all the things done prior to hdlc_open()?
Yes, it looks like I really need to undo everything that was done before 
hdlc_open().
But the question arose - would it be enough to call the uhdlc_close(dev) 
function?
In addition, it seems to me and my colleagues that a call to 
hdlc_close(dev) should be added to the uhdlc_close() function, similar 
to the following functions:
1. drivers/net/wan/n2.c (n2_close function)
2. drivers/net/wan/pc300too.c (pc300_close function)
3. drivers/net/wan/pci200syn.c (pci200_close function)
4. drivers/net/wan/wanxl.c (wanxl_close function)
Tell me, please, are we wrong?
Re: [PATCH v3] fsl_ucc_hdlc: process the result of hold_open()
Posted by Denis Kirjanov 2 years, 3 months ago

On 9/1/23 13:48, Александра Дюпина wrote:
> Thanks for the review!
> 
> 28.08.2023 22:38, Jakub Kicinski пишет:
>> Don't you have to undo all the things done prior to hdlc_open()?
> Yes, it looks like I really need to undo everything that was done before hdlc_open().
> But the question arose - would it be enough to call the uhdlc_close(dev) function?

looks like it is.

> In addition, it seems to me and my colleagues that a call to hdlc_close(dev) should be added to the uhdlc_close() function, similar to the 

yes, take a look at the comment for hdlc_close()

following functions:
> 1. drivers/net/wan/n2.c (n2_close function)
> 2. drivers/net/wan/pc300too.c (pc300_close function)
> 3. drivers/net/wan/pci200syn.c (pci200_close function)
> 4. drivers/net/wan/wanxl.c (wanxl_close function)
> Tell me, please, are we wrong?
> 
[PATCH v4] drivers/net: process the result of hdlc_open() and add call of hdlc_close() in uhdlc_close()
Posted by Alexandra Diupina 2 years, 3 months ago
Process the result of hdlc_open() and call uhdlc_close()
in case of an error. It is necessary to pass the error
code up the control flow, similar to a possible
error in request_irq().
Also add a hdlc_close() call to the uhdlc_close()
because the comment to hdlc_close() says it must be called
by the hardware driver when the HDLC device is being closed

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes: c19b6d246a35 ("drivers/net: support hdlc function for QE-UCC")
Signed-off-by: Alexandra Diupina <adiupina@astralinux.ru>
---
v4: undo all the things done prior to hdlc_open() as 
Jakub Kicinski <kuba@kernel.org> suggested, 
add hdlc_close() call to the uhdlc_close() to match the function comment, 
add uhdlc_close() declaration to the top of the file not to put the 
uhdlc_close() function definition before uhdlc_open()
v3: Fix the commits tree
v2: Remove the 'rc' variable (stores the return value of the 
hdlc_open()) as Christophe Leroy <christophe.leroy@csgroup.eu> suggested
 drivers/net/wan/fsl_ucc_hdlc.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c
index 47c2ad7a3e42..fd999dabdd39 100644
--- a/drivers/net/wan/fsl_ucc_hdlc.c
+++ b/drivers/net/wan/fsl_ucc_hdlc.c
@@ -34,6 +34,8 @@
 #define TDM_PPPOHT_SLIC_MAXIN
 #define RX_BD_ERRORS (R_CD_S | R_OV_S | R_CR_S | R_AB_S | R_NO_S | R_LG_S)
 
+static int uhdlc_close(struct net_device *dev);
+
 static struct ucc_tdm_info utdm_primary_info = {
 	.uf_info = {
 		.tsa = 0,
@@ -731,7 +733,9 @@ static int uhdlc_open(struct net_device *dev)
 		napi_enable(&priv->napi);
 		netdev_reset_queue(dev);
 		netif_start_queue(dev);
-		hdlc_open(dev);
+
+		int rc = hdlc_open(dev);
+		return rc == 0 ? 0 : (uhdlc_close(dev), rc);
 	}
 
 	return 0;
@@ -824,6 +828,8 @@ static int uhdlc_close(struct net_device *dev)
 	netdev_reset_queue(dev);
 	priv->hdlc_busy = 0;
 
+	hdlc_close(dev);
+
 	return 0;
 }
 
-- 
2.30.2
Re: [PATCH v4] drivers/net: process the result of hdlc_open() and add call of hdlc_close() in uhdlc_close()
Posted by Christophe Leroy 2 years, 3 months ago

Le 04/09/2023 à 14:31, Alexandra Diupina a écrit :
> Process the result of hdlc_open() and call uhdlc_close()
> in case of an error. It is necessary to pass the error
> code up the control flow, similar to a possible
> error in request_irq().
> Also add a hdlc_close() call to the uhdlc_close()
> because the comment to hdlc_close() says it must be called
> by the hardware driver when the HDLC device is being closed
> 
> Found by Linux Verification Center (linuxtesting.org) with SVACE.
> 
> Fixes: c19b6d246a35 ("drivers/net: support hdlc function for QE-UCC")
> Signed-off-by: Alexandra Diupina <adiupina@astralinux.ru>
> ---
> v4: undo all the things done prior to hdlc_open() as
> Jakub Kicinski <kuba@kernel.org> suggested,
> add hdlc_close() call to the uhdlc_close() to match the function comment,
> add uhdlc_close() declaration to the top of the file not to put the
> uhdlc_close() function definition before uhdlc_open()
> v3: Fix the commits tree
> v2: Remove the 'rc' variable (stores the return value of the
> hdlc_open()) as Christophe Leroy <christophe.leroy@csgroup.eu> suggested
>   drivers/net/wan/fsl_ucc_hdlc.c | 8 +++++++-
>   1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c
> index 47c2ad7a3e42..fd999dabdd39 100644
> --- a/drivers/net/wan/fsl_ucc_hdlc.c
> +++ b/drivers/net/wan/fsl_ucc_hdlc.c
> @@ -34,6 +34,8 @@
>   #define TDM_PPPOHT_SLIC_MAXIN
>   #define RX_BD_ERRORS (R_CD_S | R_OV_S | R_CR_S | R_AB_S | R_NO_S | R_LG_S)
>   
> +static int uhdlc_close(struct net_device *dev);
> +
>   static struct ucc_tdm_info utdm_primary_info = {
>   	.uf_info = {
>   		.tsa = 0,
> @@ -731,7 +733,9 @@ static int uhdlc_open(struct net_device *dev)
>   		napi_enable(&priv->napi);
>   		netdev_reset_queue(dev);
>   		netif_start_queue(dev);
> -		hdlc_open(dev);
> +
> +		int rc = hdlc_open(dev);

Do not mix declarations and code. Please put all declaration at the top 
of the block.

> +		return rc == 0 ? 0 : (uhdlc_close(dev), rc);
>   	}

That's not easy to read.

I know that's more changes, but I'd prefer something like:

static int uhdlc_open(struct net_device *dev)
{
	u32 cecr_subblock;
	hdlc_device *hdlc = dev_to_hdlc(dev);
	struct ucc_hdlc_private *priv = hdlc->priv;
	struct ucc_tdm *utdm = priv->utdm;
	int rc;

	if (priv->hdlc_busy != 1)
		return 0;

	if (request_irq(priv->ut_info->uf_info.irq,
			ucc_hdlc_irq_handler, 0, "hdlc", priv))
		return -ENODEV;

	cecr_subblock = ucc_fast_get_qe_cr_subblock(
				priv->ut_info->uf_info.ucc_num);

	qe_issue_cmd(QE_INIT_TX_RX, cecr_subblock,
		     QE_CR_PROTOCOL_UNSPECIFIED, 0);

	ucc_fast_enable(priv->uccf, COMM_DIR_RX | COMM_DIR_TX);

	/* Enable the TDM port */
	if (priv->tsa)
		qe_setbits_8(&utdm->si_regs->siglmr1_h, 0x1 << utdm->tdm_port);

	priv->hdlc_busy = 1;
	netif_device_attach(priv->ndev);
	napi_enable(&priv->napi);
	netdev_reset_queue(dev);
	netif_start_queue(dev);

	rc = hdlc_open(dev);
	if (rc)
		uhdlc_close(dev);

	return rc;
}



>   
>   	return 0;
> @@ -824,6 +828,8 @@ static int uhdlc_close(struct net_device *dev)
>   	netdev_reset_queue(dev);
>   	priv->hdlc_busy = 0;
>   
> +	hdlc_close(dev);
> +
>   	return 0;
>   }
>   


And while you are looking at the correctness of this code, is it sure 
that uhdlc_open() cannot be called twice in parallele ?
If it can be called in parallèle I think the "if (priv->hdlc_busy != 1)" 
should be replaced by something using cmpxchg()
Re: [PATCH v4] drivers/net: process the result of hdlc_open() and add call of hdlc_close() in uhdlc_close()
Posted by Paolo Abeni 2 years, 3 months ago
On Mon, 2023-09-04 at 17:03 +0000, Christophe Leroy wrote:
> 
> Le 04/09/2023 à 14:31, Alexandra Diupina a écrit :
> > diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c
> > index 47c2ad7a3e42..fd999dabdd39 100644
> > --- a/drivers/net/wan/fsl_ucc_hdlc.c
> > +++ b/drivers/net/wan/fsl_ucc_hdlc.c
> > @@ -34,6 +34,8 @@
> >   #define TDM_PPPOHT_SLIC_MAXIN
> >   #define RX_BD_ERRORS (R_CD_S | R_OV_S | R_CR_S | R_AB_S | R_NO_S | R_LG_S)
> >   
> > +static int uhdlc_close(struct net_device *dev);
> > +
> >   static struct ucc_tdm_info utdm_primary_info = {
> >   	.uf_info = {
> >   		.tsa = 0,
> > @@ -731,7 +733,9 @@ static int uhdlc_open(struct net_device *dev)
> >   		napi_enable(&priv->napi);
> >   		netdev_reset_queue(dev);
> >   		netif_start_queue(dev);
> > -		hdlc_open(dev);
> > +
> > +		int rc = hdlc_open(dev);
> 
> Do not mix declarations and code. Please put all declaration at the top 
> of the block.
> 
> > +		return rc == 0 ? 0 : (uhdlc_close(dev), rc);
> >   	}
> 
> That's not easy to read.
> 
> I know that's more changes, but I'd prefer something like:
> 
> static int uhdlc_open(struct net_device *dev)
> {
> 	u32 cecr_subblock;
> 	hdlc_device *hdlc = dev_to_hdlc(dev);
> 	struct ucc_hdlc_private *priv = hdlc->priv;
> 	struct ucc_tdm *utdm = priv->utdm;
> 	int rc;
> 
> 	if (priv->hdlc_busy != 1)
> 		return 0;
> 
> 	if (request_irq(priv->ut_info->uf_info.irq,
> 			ucc_hdlc_irq_handler, 0, "hdlc", priv))
> 		return -ENODEV;
> 
> 	cecr_subblock = ucc_fast_get_qe_cr_subblock(
> 				priv->ut_info->uf_info.ucc_num);
> 
> 	qe_issue_cmd(QE_INIT_TX_RX, cecr_subblock,
> 		     QE_CR_PROTOCOL_UNSPECIFIED, 0);
> 
> 	ucc_fast_enable(priv->uccf, COMM_DIR_RX | COMM_DIR_TX);
> 
> 	/* Enable the TDM port */
> 	if (priv->tsa)
> 		qe_setbits_8(&utdm->si_regs->siglmr1_h, 0x1 << utdm->tdm_port);
> 
> 	priv->hdlc_busy = 1;
> 	netif_device_attach(priv->ndev);
> 	napi_enable(&priv->napi);
> 	netdev_reset_queue(dev);
> 	netif_start_queue(dev);
> 
> 	rc = hdlc_open(dev);
> 	if (rc)
> 		uhdlc_close(dev);
> 
> 	return rc;
> }

I agree the above is more readable, but I don't think the whole
refactor is not worthy for a -net fix. I think simply rewriting the
final statements as:

		rc = hdlc_open(dev);
		if (rc)
			uhdlc_close(dev);

		return rc;	

would be good for -net.
 
> >   	return 0;
> > @@ -824,6 +828,8 @@ static int uhdlc_close(struct net_device *dev)
> >   	netdev_reset_queue(dev);
> >   	priv->hdlc_busy = 0;
> >   
> > +	hdlc_close(dev);
> > +
> >   return 0;
> >     
> 
> And while you are looking at the correctness of this code, is it sure 
> that uhdlc_open() cannot be called twice in parallele ?
> If it can be called in parallèle I think the "if (priv->hdlc_busy != 1)" 
> should be replaced by something using cmpxchg()

That part is safe, ndo_open() is invoked under the rtnl lock.

The other comments are IMHO relevant, @Alexandra: please address them.

Thanks!

Paolo
[PATCH v5] drivers/net: process the result of hdlc_open() and add call of hdlc_close() in uhdlc_close()
Posted by Alexandra Diupina 2 years, 2 months ago
Process the result of hdlc_open() and call uhdlc_close()
in case of an error. It is necessary to pass the error
code up the control flow, similar to a possible
error in request_irq().
Also add a hdlc_close() call to the uhdlc_close()
because the comment to hdlc_close() says it must be called
by the hardware driver when the HDLC device is being closed

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes: c19b6d246a35 ("drivers/net: support hdlc function for QE-UCC")
Signed-off-by: Alexandra Diupina <adiupina@astralinux.ru>
---
v5: do some refactoring as Paolo Abeni <pabeni@redhat.com> and 
Christophe Leroy <christophe.leroy@csgroup.eu> suggested
v4: undo all the things done prior to hdlc_open() as 
Jakub Kicinski <kuba@kernel.org> suggested, 
add hdlc_close() call to the uhdlc_close() to match the function comment, 
add uhdlc_close() declaration to the top of the file not to put the 
uhdlc_close() function definition before uhdlc_open()
v3: Fix the commits tree
v2: Remove the 'rc' variable (stores the return value of the 
hdlc_open()) as Christophe Leroy <christophe.leroy@csgroup.eu> suggested
 drivers/net/wan/fsl_ucc_hdlc.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c
index 47c2ad7a3e42..fd50bb313b92 100644
--- a/drivers/net/wan/fsl_ucc_hdlc.c
+++ b/drivers/net/wan/fsl_ucc_hdlc.c
@@ -34,6 +34,8 @@
 #define TDM_PPPOHT_SLIC_MAXIN
 #define RX_BD_ERRORS (R_CD_S | R_OV_S | R_CR_S | R_AB_S | R_NO_S | R_LG_S)
 
+static int uhdlc_close(struct net_device *dev);
+
 static struct ucc_tdm_info utdm_primary_info = {
 	.uf_info = {
 		.tsa = 0,
@@ -708,6 +710,7 @@ static int uhdlc_open(struct net_device *dev)
 	hdlc_device *hdlc = dev_to_hdlc(dev);
 	struct ucc_hdlc_private *priv = hdlc->priv;
 	struct ucc_tdm *utdm = priv->utdm;
+	int rc = 0;
 
 	if (priv->hdlc_busy != 1) {
 		if (request_irq(priv->ut_info->uf_info.irq,
@@ -731,10 +734,13 @@ static int uhdlc_open(struct net_device *dev)
 		napi_enable(&priv->napi);
 		netdev_reset_queue(dev);
 		netif_start_queue(dev);
-		hdlc_open(dev);
+
+		rc = hdlc_open(dev);
+		if (rc)
+			uhdlc_close(dev);
 	}
 
-	return 0;
+	return rc;
 }
 
 static void uhdlc_memclean(struct ucc_hdlc_private *priv)
@@ -824,6 +830,8 @@ static int uhdlc_close(struct net_device *dev)
 	netdev_reset_queue(dev);
 	priv->hdlc_busy = 0;
 
+	hdlc_close(dev);
+
 	return 0;
 }
 
-- 
2.30.2
Re: [PATCH v5] drivers/net: process the result of hdlc_open() and add call of hdlc_close() in uhdlc_close()
Posted by patchwork-bot+netdevbpf@kernel.org 2 years, 2 months ago
Hello:

This patch was applied to netdev/net.git (main)
by David S. Miller <davem@davemloft.net>:

On Tue, 19 Sep 2023 17:25:02 +0300 you wrote:
> Process the result of hdlc_open() and call uhdlc_close()
> in case of an error. It is necessary to pass the error
> code up the control flow, similar to a possible
> error in request_irq().
> Also add a hdlc_close() call to the uhdlc_close()
> because the comment to hdlc_close() says it must be called
> by the hardware driver when the HDLC device is being closed
> 
> [...]

Here is the summary with links:
  - [v5] drivers/net: process the result of hdlc_open() and add call of hdlc_close() in uhdlc_close()
    https://git.kernel.org/netdev/net/c/a59addacf899

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
Re: [PATCH v5] drivers/net: process the result of hdlc_open() and add call of hdlc_close() in uhdlc_close()
Posted by Christophe Leroy 2 years, 2 months ago

Le 19/09/2023 à 16:25, Alexandra Diupina a écrit :
> Process the result of hdlc_open() and call uhdlc_close()
> in case of an error. It is necessary to pass the error
> code up the control flow, similar to a possible
> error in request_irq().
> Also add a hdlc_close() call to the uhdlc_close()
> because the comment to hdlc_close() says it must be called
> by the hardware driver when the HDLC device is being closed
> 
> Found by Linux Verification Center (linuxtesting.org) with SVACE.
> 
> Fixes: c19b6d246a35 ("drivers/net: support hdlc function for QE-UCC")
> Signed-off-by: Alexandra Diupina <adiupina@astralinux.ru>

Suggested-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>

> ---
> v5: do some refactoring as Paolo Abeni <pabeni@redhat.com> and
> Christophe Leroy <christophe.leroy@csgroup.eu> suggested
> v4: undo all the things done prior to hdlc_open() as
> Jakub Kicinski <kuba@kernel.org> suggested,
> add hdlc_close() call to the uhdlc_close() to match the function comment,
> add uhdlc_close() declaration to the top of the file not to put the
> uhdlc_close() function definition before uhdlc_open()
> v3: Fix the commits tree
> v2: Remove the 'rc' variable (stores the return value of the
> hdlc_open()) as Christophe Leroy <christophe.leroy@csgroup.eu> suggested
>   drivers/net/wan/fsl_ucc_hdlc.c | 12 ++++++++++--
>   1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c
> index 47c2ad7a3e42..fd50bb313b92 100644
> --- a/drivers/net/wan/fsl_ucc_hdlc.c
> +++ b/drivers/net/wan/fsl_ucc_hdlc.c
> @@ -34,6 +34,8 @@
>   #define TDM_PPPOHT_SLIC_MAXIN
>   #define RX_BD_ERRORS (R_CD_S | R_OV_S | R_CR_S | R_AB_S | R_NO_S | R_LG_S)
>   
> +static int uhdlc_close(struct net_device *dev);
> +
>   static struct ucc_tdm_info utdm_primary_info = {
>   	.uf_info = {
>   		.tsa = 0,
> @@ -708,6 +710,7 @@ static int uhdlc_open(struct net_device *dev)
>   	hdlc_device *hdlc = dev_to_hdlc(dev);
>   	struct ucc_hdlc_private *priv = hdlc->priv;
>   	struct ucc_tdm *utdm = priv->utdm;
> +	int rc = 0;
>   
>   	if (priv->hdlc_busy != 1) {
>   		if (request_irq(priv->ut_info->uf_info.irq,
> @@ -731,10 +734,13 @@ static int uhdlc_open(struct net_device *dev)
>   		napi_enable(&priv->napi);
>   		netdev_reset_queue(dev);
>   		netif_start_queue(dev);
> -		hdlc_open(dev);
> +
> +		rc = hdlc_open(dev);
> +		if (rc)
> +			uhdlc_close(dev);
>   	}
>   
> -	return 0;
> +	return rc;
>   }
>   
>   static void uhdlc_memclean(struct ucc_hdlc_private *priv)
> @@ -824,6 +830,8 @@ static int uhdlc_close(struct net_device *dev)
>   	netdev_reset_queue(dev);
>   	priv->hdlc_busy = 0;
>   
> +	hdlc_close(dev);
> +
>   	return 0;
>   }
>   
Re: [PATCH v4] drivers/net: process the result of hdlc_open() and add call of hdlc_close() in uhdlc_close()
Posted by Christophe Leroy 2 years, 3 months ago

Le 04/09/2023 à 19:03, Christophe Leroy a écrit :
> 
> 
> Le 04/09/2023 à 14:31, Alexandra Diupina a écrit :
>> Process the result of hdlc_open() and call uhdlc_close()
>> in case of an error. It is necessary to pass the error
>> code up the control flow, similar to a possible
>> error in request_irq().
>> Also add a hdlc_close() call to the uhdlc_close()
>> because the comment to hdlc_close() says it must be called
>> by the hardware driver when the HDLC device is being closed
>>
>> Found by Linux Verification Center (linuxtesting.org) with SVACE.
>>
>> Fixes: c19b6d246a35 ("drivers/net: support hdlc function for QE-UCC")
>> Signed-off-by: Alexandra Diupina <adiupina@astralinux.ru>
>> ---
>> v4: undo all the things done prior to hdlc_open() as
>> Jakub Kicinski <kuba@kernel.org> suggested,
>> add hdlc_close() call to the uhdlc_close() to match the function comment,
>> add uhdlc_close() declaration to the top of the file not to put the
>> uhdlc_close() function definition before uhdlc_open()
>> v3: Fix the commits tree
>> v2: Remove the 'rc' variable (stores the return value of the
>> hdlc_open()) as Christophe Leroy <christophe.leroy@csgroup.eu> suggested
>>   drivers/net/wan/fsl_ucc_hdlc.c | 8 +++++++-
>>   1 file changed, 7 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/wan/fsl_ucc_hdlc.c 
>> b/drivers/net/wan/fsl_ucc_hdlc.c
>> index 47c2ad7a3e42..fd999dabdd39 100644
>> --- a/drivers/net/wan/fsl_ucc_hdlc.c
>> +++ b/drivers/net/wan/fsl_ucc_hdlc.c
>> @@ -34,6 +34,8 @@
>>   #define TDM_PPPOHT_SLIC_MAXIN
>>   #define RX_BD_ERRORS (R_CD_S | R_OV_S | R_CR_S | R_AB_S | R_NO_S | 
>> R_LG_S)
>> +static int uhdlc_close(struct net_device *dev);
>> +
>>   static struct ucc_tdm_info utdm_primary_info = {
>>       .uf_info = {
>>           .tsa = 0,
>> @@ -731,7 +733,9 @@ static int uhdlc_open(struct net_device *dev)
>>           napi_enable(&priv->napi);
>>           netdev_reset_queue(dev);
>>           netif_start_queue(dev);
>> -        hdlc_open(dev);
>> +
>> +        int rc = hdlc_open(dev);
> 
> Do not mix declarations and code. Please put all declaration at the top 
> of the block.
> 
>> +        return rc == 0 ? 0 : (uhdlc_close(dev), rc);
>>       }
> 
> That's not easy to read.
> 
> I know that's more changes, but I'd prefer something like:
> 
> static int uhdlc_open(struct net_device *dev)
> {
>      u32 cecr_subblock;
>      hdlc_device *hdlc = dev_to_hdlc(dev);
>      struct ucc_hdlc_private *priv = hdlc->priv;
>      struct ucc_tdm *utdm = priv->utdm;
>      int rc;
> 
>      if (priv->hdlc_busy != 1)

Of course should be:

	if (priv->hdlc_busy == 1)

>          return 0;
> 
>      if (request_irq(priv->ut_info->uf_info.irq,
>              ucc_hdlc_irq_handler, 0, "hdlc", priv))
>          return -ENODEV;
> 
>      cecr_subblock = ucc_fast_get_qe_cr_subblock(
>                  priv->ut_info->uf_info.ucc_num);
> 
>      qe_issue_cmd(QE_INIT_TX_RX, cecr_subblock,
>               QE_CR_PROTOCOL_UNSPECIFIED, 0);
> 
>      ucc_fast_enable(priv->uccf, COMM_DIR_RX | COMM_DIR_TX);
> 
>      /* Enable the TDM port */
>      if (priv->tsa)
>          qe_setbits_8(&utdm->si_regs->siglmr1_h, 0x1 << utdm->tdm_port);
> 
>      priv->hdlc_busy = 1;
>      netif_device_attach(priv->ndev);
>      napi_enable(&priv->napi);
>      netdev_reset_queue(dev);
>      netif_start_queue(dev);
> 
>      rc = hdlc_open(dev);
>      if (rc)
>          uhdlc_close(dev);
> 
>      return rc;
> }
> 
> 
> 
>>       return 0;
>> @@ -824,6 +828,8 @@ static int uhdlc_close(struct net_device *dev)
>>       netdev_reset_queue(dev);
>>       priv->hdlc_busy = 0;
>> +    hdlc_close(dev);
>> +
>>       return 0;
>>   }
> 
> 
> And while you are looking at the correctness of this code, is it sure 
> that uhdlc_open() cannot be called twice in parallele ?
> If it can be called in parallèle I think the "if (priv->hdlc_busy != 1)" 
> should be replaced by something using cmpxchg()
Re: [PATCH v3] fsl_ucc_hdlc: process the result of hold_open()
Posted by Christophe Leroy 2 years, 3 months ago

Le 28/08/2023 à 14:12, Alexandra Diupina a écrit :
> [Vous ne recevez pas souvent de courriers de adiupina@astralinux.ru. Découvrez pourquoi ceci est important à https://aka.ms/LearnAboutSenderIdentification ]
> 
> Process the result of hold_open() and return it from
> uhdlc_open() in case of an error
> It is necessary to pass the error code up the control flow,
> similar to a possible error in request_irq()
> 
> Found by Linux Verification Center (linuxtesting.org) with SVACE.
> 
> Fixes: c19b6d246a35 ("drivers/net: support hdlc function for QE-UCC")
> Signed-off-by: Alexandra Diupina <adiupina@astralinux.ru>

Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>

> ---
> v3: Fix the commits tree
> v2: Remove the 'rc' variable (stores the return value of the
> hdlc_open()) as Christophe Leroy <christophe.leroy@csgroup.eu> suggested
>   drivers/net/wan/fsl_ucc_hdlc.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c
> index 47c2ad7a3e42..4164abea7725 100644
> --- a/drivers/net/wan/fsl_ucc_hdlc.c
> +++ b/drivers/net/wan/fsl_ucc_hdlc.c
> @@ -731,7 +731,7 @@ static int uhdlc_open(struct net_device *dev)
>                  napi_enable(&priv->napi);
>                  netdev_reset_queue(dev);
>                  netif_start_queue(dev);
> -               hdlc_open(dev);
> +               return hdlc_open(dev);
>          }
> 
>          return 0;
> --
> 2.30.2
>