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 |
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 > >
> > +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
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
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
> 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
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
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 --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; }
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(-)