diff mbox series

[net,1/4] net-sysfs: check device is present when showing carrier

Message ID 066463d84fa14d5f61247b95340fca12d4d3bf34.1721784184.git.jamie.bainbridge@gmail.com (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series net-sysfs: check device is present when showing paths | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
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: 273 this patch: 273
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers success CCed 6 of 6 maintainers
netdev/build_clang success Errors and warnings before: 281 this patch: 281
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 fail Problems with Fixes tag: 1
netdev/build_allmodconfig_warn success Errors and warnings before: 281 this patch: 281
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 8 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
netdev/contest success net-next-2024-07-25--00-00 (tests: 703)

Commit Message

Jamie Bainbridge July 24, 2024, 1:46 a.m. UTC
A sysfs reader can race with a device reset or removal.

This was fixed for speed_show with commit 4224cfd7fb65 ("net-sysfs: add
check for netdevice being present to speed_show") so add the same check
to carrier_show.

Fixes: facd15dfd691 ("net: core: synchronize link-watch when carrier is queried")

Signed-off-by: Jamie Bainbridge <jamie.bainbridge@gmail.com>
---
 net/core/net-sysfs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Johannes Berg July 24, 2024, 9:35 a.m. UTC | #1
On Wed, 2024-07-24 at 01:46 +0000, Jamie Bainbridge wrote:
> A sysfs reader can race with a device reset or removal.

Kind of, yes, but please check what the race actually is.

> This was fixed for speed_show with commit 4224cfd7fb65 ("net-sysfs: add
> check for netdevice being present to speed_show") so add the same check
> to carrier_show.

You didn't say why it's needed here, so ... why is it?

FWIW, I don't think it actually _is_ needed, since the netdev struct
itself is still around, linkwatch_sync_dev() will not do anything that's
not still needed anyway (the removal from list must clearly either still
happen or nothing happens in the function). This will not call into the
driver (which would be the problematic part).

So while I don't think this is _wrong_ per se, I also don't think it's
necessary, nor are you demonstrating that it is.

And for userspace it should be pretty much immaterial whether it gets a
real value or -EINVAL in the race, or -ENOENT because the file
disappeared anyway?

johannes
Johannes Berg July 24, 2024, 9:41 a.m. UTC | #2
On Wed, 2024-07-24 at 11:35 +0200, Johannes Berg wrote:
> On Wed, 2024-07-24 at 01:46 +0000, Jamie Bainbridge wrote:
> > A sysfs reader can race with a device reset or removal.
> 
> Kind of, yes, but please check what the race actually is.
> 
> > This was fixed for speed_show with commit 4224cfd7fb65 ("net-sysfs: add
> > check for netdevice being present to speed_show") so add the same check
> > to carrier_show.
> 
> You didn't say why it's needed here, so ... why is it?
> 
> FWIW, I don't think it actually _is_ needed, since the netdev struct
> itself is still around, linkwatch_sync_dev() will not do anything that's
> not still needed anyway (the removal from list must clearly either still
> happen or nothing happens in the function). This will not call into the
> driver (which would be the problematic part).
> 
> So while I don't think this is _wrong_ per se, I also don't think it's
> necessary, nor are you demonstrating that it is.
> 
> And for userspace it should be pretty much immaterial whether it gets a
> real value or -EINVAL in the race, or -ENOENT because the file
> disappeared anyway?
> 

All of which, btw, is also true for patches 3 and 4 in this set.

For patch 2 it seems applicable.

I do wonder if ethtool itself, at least ethtool netlink, doesn't have a
similar problem though, since it just uses netdev_get_by_name() /
netdev_get_by_index()?

johannes
Jamie Bainbridge July 24, 2024, 10:54 p.m. UTC | #3
On Wed, 24 Jul 2024 at 19:42, Johannes Berg <johannes@sipsolutions.net> wrote:
>
> On Wed, 2024-07-24 at 11:35 +0200, Johannes Berg wrote:
> > On Wed, 2024-07-24 at 01:46 +0000, Jamie Bainbridge wrote:
> > > A sysfs reader can race with a device reset or removal.
> >
> > Kind of, yes, but please check what the race actually is.
> >
> > > This was fixed for speed_show with commit 4224cfd7fb65 ("net-sysfs: add
> > > check for netdevice being present to speed_show") so add the same check
> > > to carrier_show.
> >
> > You didn't say why it's needed here, so ... why is it?
> >
> > FWIW, I don't think it actually _is_ needed, since the netdev struct
> > itself is still around, linkwatch_sync_dev() will not do anything that's
> > not still needed anyway (the removal from list must clearly either still
> > happen or nothing happens in the function). This will not call into the
> > driver (which would be the problematic part).
> >
> > So while I don't think this is _wrong_ per se, I also don't think it's
> > necessary, nor are you demonstrating that it is.
> >
> > And for userspace it should be pretty much immaterial whether it gets a
> > real value or -EINVAL in the race, or -ENOENT because the file
> > disappeared anyway?
> >
>
> All of which, btw, is also true for patches 3 and 4 in this set.
>
> For patch 2 it seems applicable.
>
> I do wonder if ethtool itself, at least ethtool netlink, doesn't have a
> similar problem though, since it just uses netdev_get_by_name() /
> netdev_get_by_index()?
>
> johannes

You are correct, patch 2 (duplex) is the one where we panicked during
device reset. I thought to fix the other "show" functions in advance
while I was there.

I will revise this and re-submit with only the necessary patch.

Thanks for the review, it is appreciated.

Jamie
Shigeru Yoshida July 25, 2024, 2:22 a.m. UTC | #4
Hi Jamie,

On Wed, 24 Jul 2024 11:46:50 +1000, Jamie Bainbridge wrote:
> A sysfs reader can race with a device reset or removal.
> 
> This was fixed for speed_show with commit 4224cfd7fb65 ("net-sysfs: add
> check for netdevice being present to speed_show") so add the same check
> to carrier_show.
> 
> Fixes: facd15dfd691 ("net: core: synchronize link-watch when carrier is queried")
> 
> Signed-off-by: Jamie Bainbridge <jamie.bainbridge@gmail.com>

nit: When resubmitting your fix, there is no need for a blank line
     between the Fixes and SOB tags.

Thanks,
Shigeru

> ---
>  net/core/net-sysfs.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
> index 0e2084ce7b7572bff458ed7e02358d9258c74628..7fabe5afa3012ecad6551e12f478b755952933b8 100644
> --- a/net/core/net-sysfs.c
> +++ b/net/core/net-sysfs.c
> @@ -206,7 +206,7 @@ static ssize_t carrier_show(struct device *dev,
>  	if (!rtnl_trylock())
>  		return restart_syscall();
>  
> -	if (netif_running(netdev)) {
> +	if (netif_running(netdev) && netif_device_present(netdev)) {
>  		/* Synchronize carrier state with link watch,
>  		 * see also rtnl_getlink().
>  		 */
> -- 
> 2.39.2
> 
>
diff mbox series

Patch

diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 0e2084ce7b7572bff458ed7e02358d9258c74628..7fabe5afa3012ecad6551e12f478b755952933b8 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -206,7 +206,7 @@  static ssize_t carrier_show(struct device *dev,
 	if (!rtnl_trylock())
 		return restart_syscall();
 
-	if (netif_running(netdev)) {
+	if (netif_running(netdev) && netif_device_present(netdev)) {
 		/* Synchronize carrier state with link watch,
 		 * see also rtnl_getlink().
 		 */