diff mbox series

[net,v3] net: lan743x: Don't sleep in atomic context

Message ID 20230627035000.1295254-1-moritzf@google.com (mailing list archive)
State Accepted
Commit 7a8227b2e76be506b2ac64d2beac950ca04892a5
Delegated to: Netdev Maintainers
Headers show
Series [net,v3] net: lan743x: Don't sleep in atomic context | expand

Checks

Context Check Description
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for net
netdev/fixes_present success Fixes tag present in non-next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 8 this patch: 8
netdev/cc_maintainers fail 1 blamed authors not CCed: andrew@lunn.ch; 1 maintainers not CCed: andrew@lunn.ch
netdev/build_clang success Errors and warnings before: 8 this patch: 8
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 8 this patch: 8
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 39 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Moritz Fischer June 27, 2023, 3:50 a.m. UTC
dev_set_rx_mode() grabs a spin_lock, and the lan743x implementation
proceeds subsequently to go to sleep using readx_poll_timeout().

Introduce a helper wrapping the readx_poll_timeout_atomic() function
and use it to replace the calls to readx_polL_timeout().

Fixes: 23f0703c125b ("lan743x: Add main source files for new lan743x driver")
Cc: stable@vger.kernel.org
Cc: Bryan Whitehead <bryan.whitehead@microchip.com>
Cc: UNGLinuxDriver@microchip.com
Signed-off-by: Moritz Fischer <moritzf@google.com>
---

Changes from v2:
- Incorporate suggestion from Jakub

Changes from v1:
- Added line-breaks
- Changed subject to target net-next
- Removed Tested-by: tag

---
 drivers/net/ethernet/microchip/lan743x_main.c | 21 +++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

Comments

Maciej Fijalkowski June 27, 2023, 12:58 p.m. UTC | #1
On Tue, Jun 27, 2023 at 03:50:00AM +0000, Moritz Fischer wrote:

Hi Moritz,

> dev_set_rx_mode() grabs a spin_lock, and the lan743x implementation
> proceeds subsequently to go to sleep using readx_poll_timeout().
> 
> Introduce a helper wrapping the readx_poll_timeout_atomic() function
> and use it to replace the calls to readx_polL_timeout().

nit: weird typo with capital L

> 
> Fixes: 23f0703c125b ("lan743x: Add main source files for new lan743x driver")
> Cc: stable@vger.kernel.org
> Cc: Bryan Whitehead <bryan.whitehead@microchip.com>
> Cc: UNGLinuxDriver@microchip.com
> Signed-off-by: Moritz Fischer <moritzf@google.com>
> ---
> 
> Changes from v2:
> - Incorporate suggestion from Jakub

suggestions were to skip the ternary operator i believe - would be good to
spell this out here

> 
> Changes from v1:
> - Added line-breaks
> - Changed subject to target net-next
> - Removed Tested-by: tag
> 
> ---
>  drivers/net/ethernet/microchip/lan743x_main.c | 21 +++++++++++++++----
>  1 file changed, 17 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c
> index f1bded993edc..61eadc0bca8b 100644
> --- a/drivers/net/ethernet/microchip/lan743x_main.c
> +++ b/drivers/net/ethernet/microchip/lan743x_main.c
> @@ -144,6 +144,18 @@ static int lan743x_csr_light_reset(struct lan743x_adapter *adapter)
>  				  !(data & HW_CFG_LRST_), 100000, 10000000);
>  }
>  
> +static int lan743x_csr_wait_for_bit_atomic(struct lan743x_adapter *adapter,

adapter is not used in readx_poll_timeout_atomic() call, right?
can be removed.

> +					   int offset, u32 bit_mask,
> +					   int target_value, int udelay_min,
> +					   int udelay_max, int count)
> +{
> +	u32 data;
> +
> +	return readx_poll_timeout_atomic(LAN743X_CSR_READ_OP, offset, data,
> +					 target_value == !!(data & bit_mask),
> +					 udelay_max, udelay_min * count);
> +}
> +
>  static int lan743x_csr_wait_for_bit(struct lan743x_adapter *adapter,
>  				    int offset, u32 bit_mask,
>  				    int target_value, int usleep_min,
> @@ -736,8 +748,8 @@ static int lan743x_dp_write(struct lan743x_adapter *adapter,
>  	u32 dp_sel;
>  	int i;
>  
> -	if (lan743x_csr_wait_for_bit(adapter, DP_SEL, DP_SEL_DPRDY_,
> -				     1, 40, 100, 100))
> +	if (lan743x_csr_wait_for_bit_atomic(adapter, DP_SEL, DP_SEL_DPRDY_,
> +					    1, 40, 100, 100))
>  		return -EIO;
>  	dp_sel = lan743x_csr_read(adapter, DP_SEL);
>  	dp_sel &= ~DP_SEL_MASK_;
> @@ -748,8 +760,9 @@ static int lan743x_dp_write(struct lan743x_adapter *adapter,
>  		lan743x_csr_write(adapter, DP_ADDR, addr + i);
>  		lan743x_csr_write(adapter, DP_DATA_0, buf[i]);
>  		lan743x_csr_write(adapter, DP_CMD, DP_CMD_WRITE_);
> -		if (lan743x_csr_wait_for_bit(adapter, DP_SEL, DP_SEL_DPRDY_,
> -					     1, 40, 100, 100))
> +		if (lan743x_csr_wait_for_bit_atomic(adapter, DP_SEL,
> +						    DP_SEL_DPRDY_,
> +						    1, 40, 100, 100))
>  			return -EIO;
>  	}
>  
> -- 
> 2.41.0.178.g377b9f9a00-goog
> 
>
Andrew Lunn June 27, 2023, 1:07 p.m. UTC | #2
> > +static int lan743x_csr_wait_for_bit_atomic(struct lan743x_adapter *adapter,
> 
> adapter is not used in readx_poll_timeout_atomic() call, right?
> can be removed.

I thought that when i first looked at an earlier version of this
patch. But LAN743X_CSR_READ_OP is not what you think :-(

       Andrew
Moritz Fischer June 27, 2023, 1:40 p.m. UTC | #3
Hi Andrew,

On Tue, Jun 27, 2023 at 3:07 PM Andrew Lunn <andrew@lunn.ch> wrote:
>
> > > +static int lan743x_csr_wait_for_bit_atomic(struct lan743x_adapter *adapter,
> >
> > adapter is not used in readx_poll_timeout_atomic() call, right?
> > can be removed.
>
> I thought that when i first looked at an earlier version of this
> patch. But LAN743X_CSR_READ_OP is not what you think :-(

Yeah, it's not great / confusing. I tried to keep it the same as the
rest of the file when fixing the bug.

I can see if I can clean it up across the file in a follow up.
>
>        Andrew

Do you want me to send a v4 with an updated commit message?

Thanks,
Moritz
Maciej Fijalkowski June 27, 2023, 2:41 p.m. UTC | #4
On Tue, Jun 27, 2023 at 03:40:04PM +0200, Moritz Fischer wrote:
> Hi Andrew,
> 
> On Tue, Jun 27, 2023 at 3:07 PM Andrew Lunn <andrew@lunn.ch> wrote:
> >
> > > > +static int lan743x_csr_wait_for_bit_atomic(struct lan743x_adapter *adapter,
> > >
> > > adapter is not used in readx_poll_timeout_atomic() call, right?
> > > can be removed.
> >
> > I thought that when i first looked at an earlier version of this
> > patch. But LAN743X_CSR_READ_OP is not what you think :-(
> 
> Yeah, it's not great / confusing. I tried to keep it the same as the
> rest of the file when fixing the bug.

Ahh bummer. Additionally from the first sight @data looked like being used
uninited, I thought I haven't got fooled here :)

Side note would be that I don't see much value in iopoll.h's macros
returning

	(cond) ? 0 : -ETIMEDOUT; \

this could be just !!cond but given the count of the callsites...probably
better to leave it as is.

> 
> I can see if I can clean it up across the file in a follow up.
> >
> >        Andrew
> 
> Do you want me to send a v4 with an updated commit message?

From my POV I don't think it's worth it...

> 
> Thanks,
> Moritz
Andrew Lunn June 27, 2023, 2:50 p.m. UTC | #5
> Side note would be that I don't see much value in iopoll.h's macros
> returning
> 
> 	(cond) ? 0 : -ETIMEDOUT; \
> 
> this could be just !!cond but given the count of the callsites...probably
> better to leave it as is.

The general pattern everywhere in linux is:

    err = foo(bar);
    if (err)
        return err;

We want functions to return meaningful error codes, otherwise the
caller needs to figure out an error code and return it. Having iopoll
return an error code means we have consistency. Otherwise i would
expect some developers to decide on EIO, ETIMEDOUT, EINVAL, maybe
ENXIO?

	Andrew
Moritz Fischer June 28, 2023, 8:12 a.m. UTC | #6
Hi Andrew,

On Tue, Jun 27, 2023 at 4:51 PM Andrew Lunn <andrew@lunn.ch> wrote:
>
> > Side note would be that I don't see much value in iopoll.h's macros
> > returning
> >
> >       (cond) ? 0 : -ETIMEDOUT; \
> >
> > this could be just !!cond but given the count of the callsites...probably
> > better to leave it as is.
>
> The general pattern everywhere in linux is:
>
>     err = foo(bar);
>     if (err)
>         return err;
>
> We want functions to return meaningful error codes, otherwise the
> caller needs to figure out an error code and return it. Having iopoll
> return an error code means we have consistency. Otherwise i would
> expect some developers to decide on EIO, ETIMEDOUT, EINVAL, maybe
> ENXIO?

Can you clarify if you suggest to leave this alone as-is in patch, or
replace with something returning one of the errors above?

If the former, anything else missing in the patch?

Thanks,
Moritz
patchwork-bot+netdevbpf@kernel.org June 29, 2023, 9:20 a.m. UTC | #7
Hello:

This patch was applied to netdev/net.git (main)
by Paolo Abeni <pabeni@redhat.com>:

On Tue, 27 Jun 2023 03:50:00 +0000 you wrote:
> dev_set_rx_mode() grabs a spin_lock, and the lan743x implementation
> proceeds subsequently to go to sleep using readx_poll_timeout().
> 
> Introduce a helper wrapping the readx_poll_timeout_atomic() function
> and use it to replace the calls to readx_polL_timeout().
> 
> Fixes: 23f0703c125b ("lan743x: Add main source files for new lan743x driver")
> Cc: stable@vger.kernel.org
> Cc: Bryan Whitehead <bryan.whitehead@microchip.com>
> Cc: UNGLinuxDriver@microchip.com
> Signed-off-by: Moritz Fischer <moritzf@google.com>
> 
> [...]

Here is the summary with links:
  - [net,v3] net: lan743x: Don't sleep in atomic context
    https://git.kernel.org/netdev/net/c/7a8227b2e76b

You are awesome, thank you!
diff mbox series

Patch

diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c
index f1bded993edc..61eadc0bca8b 100644
--- a/drivers/net/ethernet/microchip/lan743x_main.c
+++ b/drivers/net/ethernet/microchip/lan743x_main.c
@@ -144,6 +144,18 @@  static int lan743x_csr_light_reset(struct lan743x_adapter *adapter)
 				  !(data & HW_CFG_LRST_), 100000, 10000000);
 }
 
+static int lan743x_csr_wait_for_bit_atomic(struct lan743x_adapter *adapter,
+					   int offset, u32 bit_mask,
+					   int target_value, int udelay_min,
+					   int udelay_max, int count)
+{
+	u32 data;
+
+	return readx_poll_timeout_atomic(LAN743X_CSR_READ_OP, offset, data,
+					 target_value == !!(data & bit_mask),
+					 udelay_max, udelay_min * count);
+}
+
 static int lan743x_csr_wait_for_bit(struct lan743x_adapter *adapter,
 				    int offset, u32 bit_mask,
 				    int target_value, int usleep_min,
@@ -736,8 +748,8 @@  static int lan743x_dp_write(struct lan743x_adapter *adapter,
 	u32 dp_sel;
 	int i;
 
-	if (lan743x_csr_wait_for_bit(adapter, DP_SEL, DP_SEL_DPRDY_,
-				     1, 40, 100, 100))
+	if (lan743x_csr_wait_for_bit_atomic(adapter, DP_SEL, DP_SEL_DPRDY_,
+					    1, 40, 100, 100))
 		return -EIO;
 	dp_sel = lan743x_csr_read(adapter, DP_SEL);
 	dp_sel &= ~DP_SEL_MASK_;
@@ -748,8 +760,9 @@  static int lan743x_dp_write(struct lan743x_adapter *adapter,
 		lan743x_csr_write(adapter, DP_ADDR, addr + i);
 		lan743x_csr_write(adapter, DP_DATA_0, buf[i]);
 		lan743x_csr_write(adapter, DP_CMD, DP_CMD_WRITE_);
-		if (lan743x_csr_wait_for_bit(adapter, DP_SEL, DP_SEL_DPRDY_,
-					     1, 40, 100, 100))
+		if (lan743x_csr_wait_for_bit_atomic(adapter, DP_SEL,
+						    DP_SEL_DPRDY_,
+						    1, 40, 100, 100))
 			return -EIO;
 	}