Skip to content

Commit 1119972

Browse files
Kuen-Han Tsaigregkh
authored andcommitted
Revert "usb: gadget: f_ncm: Fix atomic context locking issue"
This reverts commit 0d6c814. This commit is being reverted as part of a series-wide revert. By deferring the net_device allocation to the bind() phase, a single function instance will spawn multiple network devices if it is symlinked to multiple USB configurations. This causes regressions for userspace tools (like the postmarketOS DHCP daemon) that rely on reading the interface name (e.g., "usb0") from configfs. Currently, configfs returns the template "usb%d", causing the userspace network setup to fail. Crucially, because this patch breaks the 1:1 mapping between the function instance and the network device, this naming issue cannot simply be patched. Configfs only exposes a single 'ifname' attribute per instance, making it impossible to accurately report the actual interface name when multiple underlying network devices can exist for that single instance. All configurations tied to the same function instance are meant to share a single network device. Revert this change to restore the 1:1 mapping by allocating the network device at the instance level (alloc_inst). Reported-by: David Heidelberg <david@ixit.cz> Closes: https://lore.kernel.org/linux-usb/70b558ea-a12e-4170-9b8e-c951131249af@ixit.cz/ Fixes: 56a512a ("usb: gadget: f_ncm: align net_device lifecycle with bind/unbind") Cc: stable <stable@kernel.org> Signed-off-by: Kuen-Han Tsai <khtsai@google.com> Link: https://patch.msgid.link/20260309-f-ncm-revert-v2-1-ea2afbc7d9b2@google.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent e8557ac commit 1119972

3 files changed

Lines changed: 28 additions & 13 deletions

File tree

drivers/usb/gadget/function/f_ncm.c

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ struct f_ncm {
5858
u8 notify_state;
5959
atomic_t notify_count;
6060
bool is_open;
61-
bool is_connected;
6261

6362
const struct ndp_parser_opts *parser_opts;
6463
bool is_crc;
@@ -865,6 +864,7 @@ static int ncm_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
865864
static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
866865
{
867866
struct f_ncm *ncm = func_to_ncm(f);
867+
struct f_ncm_opts *opts = func_to_ncm_opts(f);
868868
struct usb_composite_dev *cdev = f->config->cdev;
869869

870870
/* Control interface has only altsetting 0 */
@@ -887,12 +887,13 @@ static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
887887
if (alt > 1)
888888
goto fail;
889889

890-
if (ncm->is_connected) {
891-
DBG(cdev, "reset ncm\n");
892-
ncm->is_connected = false;
893-
gether_disconnect(&ncm->port);
894-
ncm_reset_values(ncm);
895-
}
890+
scoped_guard(mutex, &opts->lock)
891+
if (opts->net) {
892+
DBG(cdev, "reset ncm\n");
893+
opts->net = NULL;
894+
gether_disconnect(&ncm->port);
895+
ncm_reset_values(ncm);
896+
}
896897

897898
/*
898899
* CDC Network only sends data in non-default altsettings.
@@ -925,7 +926,8 @@ static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
925926
net = gether_connect(&ncm->port);
926927
if (IS_ERR(net))
927928
return PTR_ERR(net);
928-
ncm->is_connected = true;
929+
scoped_guard(mutex, &opts->lock)
930+
opts->net = net;
929931
}
930932

931933
spin_lock(&ncm->lock);
@@ -1372,14 +1374,16 @@ static int ncm_unwrap_ntb(struct gether *port,
13721374
static void ncm_disable(struct usb_function *f)
13731375
{
13741376
struct f_ncm *ncm = func_to_ncm(f);
1377+
struct f_ncm_opts *opts = func_to_ncm_opts(f);
13751378
struct usb_composite_dev *cdev = f->config->cdev;
13761379

13771380
DBG(cdev, "ncm deactivated\n");
13781381

1379-
if (ncm->is_connected) {
1380-
ncm->is_connected = false;
1381-
gether_disconnect(&ncm->port);
1382-
}
1382+
scoped_guard(mutex, &opts->lock)
1383+
if (opts->net) {
1384+
opts->net = NULL;
1385+
gether_disconnect(&ncm->port);
1386+
}
13831387

13841388
if (ncm->notify->enabled) {
13851389
usb_ep_disable(ncm->notify);
@@ -1683,6 +1687,7 @@ static struct usb_function_instance *ncm_alloc_inst(void)
16831687
if (!opts)
16841688
return ERR_PTR(-ENOMEM);
16851689

1690+
opts->net = NULL;
16861691
opts->ncm_os_desc.ext_compat_id = opts->ncm_ext_compat_id;
16871692
gether_setup_opts_default(&opts->net_opts, "usb");
16881693

drivers/usb/gadget/function/u_ether_configfs.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,9 +327,18 @@ out: \
327327
char *page) \
328328
{ \
329329
struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \
330+
const char *name; \
330331
\
331332
guard(mutex)(&opts->lock); \
332-
return sysfs_emit(page, "%s\n", opts->net_opts.name); \
333+
rtnl_lock(); \
334+
if (opts->net_opts.ifname_set) \
335+
name = opts->net_opts.name; \
336+
else if (opts->net) \
337+
name = netdev_name(opts->net); \
338+
else \
339+
name = "(inactive net_device)"; \
340+
rtnl_unlock(); \
341+
return sysfs_emit(page, "%s\n", name); \
333342
} \
334343
\
335344
static ssize_t _f_##_opts_ifname_store(struct config_item *item, \

drivers/usb/gadget/function/u_ncm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
struct f_ncm_opts {
2121
struct usb_function_instance func_inst;
22+
struct net_device *net;
2223

2324
struct gether_opts net_opts;
2425
struct config_group *ncm_interf_group;

0 commit comments

Comments
 (0)