net: mana: Fix probe/remove error path bugs
v4 cover net: mana: Fix probe/remove error path bugs
Fix five bugs in mana_probe()/mana_remove() error handling that can cause warnings on uninitialized work structs, NULL pointer dereferences, masked errors, and resource leaks when early probe steps fail.
Patches 1-2 move work struct initialization (link_change_work and gf_stats_work) to before any error path that could trigger mana_remove(), preventing WARN_ON in __flush_work() or debug object warnings when sync cancellation runs on uninitialized work structs.
Patch 3 guards mana_remove() against double invocation. If PM resume fails, mana_probe() calls mana_remove() which sets gdma_context and driver_data to NULL. A failed resume does not unbind the driver, so when the device is eventually unbound, mana_remove() is called again and dereferences NULL, causing a kernel panic. An early return on NULL gdma_context or driver_data makes the second call harmless.
Patch 4 prevents add_adev() from overwriting a port probe error, which could leave the driver in a broken state with NULL ports while reporting success.
Patch 5 changes 'goto out' to 'break' in mana_remove()'s port loop so that mana_destroy_eq() is always reached, preventing EQ leaks when a NULL port is encountered.
---
Changes in v4:
* Correct Fixes tag from ca9c54d2d6a5 to 635096a86edb
* Correct Fixes tag from ced82fce77e9 to a69839d4327d Changes in v3:
* Add patch 3: net: mana: Guard mana_remove against double invocation.
* Fix inaccurate comments.
* Correct Fixes tag from ca9c54d2d6a5 to 1e2d0824a9c3. Changes in v2:
* Apply the patchset in net instead of net-next.
---
Erni Sri Satya Vennela (5):
net: mana: Init link_change_work before potential error paths in probe
net: mana: Init gf_stats_work before potential error paths in probe
net: mana: Guard mana_remove against double invocation
net: mana: Don't overwrite port probe error with add_adev result
net: mana: Fix EQ leak in mana_remove on NULL port
drivers/net/ethernet/microsoft/mana/mana_en.c | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-)
Signature · 1 line
2.34.1
PATCH v4 1/5 net: mana: Init link_change_work before potential error paths in probe
Move INIT_WORK(link_change_work) to right after the mana_context allocation, before any error path that could reach mana_remove().
Previously, if mana_create_eq() or mana_query_device_cfg() failed, mana_probe() would jump to the error path which calls mana_remove(). mana_remove() unconditionally calls disable_work_sync(link_change_work), but the work struct had not been initialized yet. This can trigger CONFIG_DEBUG_OBJECTS_WORK enabled.
---
Changes in v3,v4:
* No change.
Changes in v2:
* Apply the patch in net instead of net-next.
--- drivers/net/ethernet/microsoft/mana/mana_en.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/microsoft/mana/mana_en.c +2 -2
@@ -3631,6 +3631,8 @@ int mana_probe(struct gdma_dev *gd, bool resuming) ac->gdma_dev = gd; gd->driver_data = ac; + +INIT_WORK (&ac->link_change_work, mana_link_state_handle); } err =mana_create_eq (ac);
@@ -3648,8 +3650,6 @@ int mana_probe(struct gdma_dev *gd, bool resuming)if (!resuming) { ac->num_ports = num_ports; - -INIT_WORK (&ac->link_change_work, mana_link_state_handle); }else {if (ac->num_ports != num_ports) { dev_err(dev, "The number of vPorts changed: %d->%d\n",
Signature · 1 line
2.34.1
PATCH v4 2/5 net: mana: Init gf_stats_work before potential error paths in probe
In reply to Erni Sri Satya VennelaMove INIT_DELAYED_WORK(gf_stats_work) to before mana_create_eq(), while keeping schedule_delayed_work() at its original location.
Previously, if any function between mana_create_eq() and the INIT_DELAYED_WORK call failed, mana_probe() would call mana_remove() which unconditionally calls cancel_delayed_work_sync(gf_stats_work) in __flush_work() or debug object warnings with CONFIG_DEBUG_OBJECTS_WORK enabled.
---
Changes in v3,v4:
* No change.
Changes in v2:
* Apply the patch in net instead of net-next.
--- drivers/net/ethernet/microsoft/mana/mana_en.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/ethernet/microsoft/mana/mana_en.c +2 -1
@@ -3635,6 +3635,8 @@ int mana_probe(struct gdma_dev *gd, bool resuming)INIT_WORK (&ac->link_change_work, mana_link_state_handle); } +INIT_DELAYED_WORK (&ac->gf_stats_work, mana_gf_stats_work_handler); + err =mana_create_eq (ac);if (err) {dev_err (dev,"Failed to create EQs: %d\n" , err);
@@ -3709,7 +3711,6 @@ int mana_probe(struct gdma_dev *gd, bool resuming) err =add_adev (gd,"eth" ); -INIT_DELAYED_WORK (&ac->gf_stats_work, mana_gf_stats_work_handler);schedule_delayed_work (&ac->gf_stats_work,MANA_GF_STATS_PERIOD ); out:
Signature · 1 line
2.34.1
PATCH v4 3/5 net: mana: Guard mana_remove against double invocation
In reply to Erni Sri Satya VennelaIf PM resume fails (e.g., mana_attach() returns an error), mana_probe() calls mana_remove(), which tears down the device and sets gd->gdma_context = NULL and gd->driver_data = NULL.
However, a failed resume callback does not automatically unbind the driver. When the device is eventually unbound, mana_remove() is invoked a second time. Without a NULL check, it dereferences gc->dev with gc == NULL, causing a kernel panic.
Add an early return if gdma_context or driver_data is NULL so the second invocation is harmless. Move the dev = gc->dev assignment after the guard so it cannot dereference NULL.
---
Changes in v4:
* Update Fixes tag to 635096a86edb
Changes in v3:
* Add this patch to the patchset
--- drivers/net/ethernet/microsoft/mana/mana_en.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/net/ethernet/microsoft/mana/mana_en.c +6 -1
@@ -3731,11 +3731,16 @@ void mana_remove(struct gdma_dev *gd, bool suspending)struct gdma_context *gc = gd->gdma_context;struct mana_context *ac = gd->driver_data;struct mana_port_context *apc; -struct device *dev = gc->dev; +struct device *dev;struct net_device *ndev;int err;int i; +if (!gc || !ac) +return ; + + dev = gc->dev; +disable_work_sync (&ac->link_change_work);cancel_delayed_work_sync (&ac->gf_stats_work);
Signature · 1 line
2.34.1
Paolo Abeni
maintainerRe: [PATCH net v4 3/5] net: mana: Guard mana_remove against double invocation
Quoted 29 lines · Erni Sri Satya Vennela
If PM resume fails (e.g.,
mana_attach()returns an error),mana_probe()callsmana_remove(), which tears down the device and setsgd->gdma_context= NULL andgd->driver_data= NULL.However, a failed resume callback does not automatically unbind the driver. When the device is eventually unbound,
mana_remove()is invoked a second time. Without a NULL check, it dereferencesgc->devwith gc == NULL, causing a kernel panic.Add an early return if
gdma_contextordriver_datais NULL so the second invocation is harmless. Move the dev =gc->devassignment after the guard so it cannot dereference NULL.Fixes 635096a86edb ("net: mana: Support hibernation and kexec")Signed-off-by Erni Sri Satya Vennela <[email protected]>---
Changes in v4:
* Update Fixes tag to635096a86edb
Changes in v3:
* Add this patch to the patchset--- drivers/net/ethernet/microsoft/mana/mana_en.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)drivers/net/ethernet/microsoft/mana/mana_en.c +0
-0
drivers/net/ethernet/microsoft/mana/mana_en.c void mana_remove(struct gdma_dev *gd, bool suspending) · line 3737
Quoted 8 lines
drivers/net/ethernet/microsoft/mana/mana_en.c +1
-1@@ -3731,11 +3731,16 @@ void mana_remove(struct gdma_dev *gd, bool suspending)struct gdma_context *gc = gd->gdma_context;struct mana_context *ac = gd->driver_data;struct mana_port_context *apc; -struct device *dev = gc->dev; +struct device *dev;struct net_device *ndev;int err;int i;
The above breaks the reverse christmas tree order. I'll apply the patch as-is to avoid additional traffic for very little to no gain, but should you touch again this code in the future for other reasons, please restore the above.
/P
PATCH v4 4/5 net: mana: Don't overwrite port probe error with add_adev result
In reply to Erni Sri Satya VennelaIn mana_probe(), if mana_probe_port() fails for any port, the error is stored in 'err' and the loop breaks. However, the subsequent unconditional 'err = add_adev(gd, "eth")' overwrites this error. If add_adev() succeeds, mana_probe() returns success despite ports being left in a partially initialized state (ac->ports[i] == NULL).
Only call add_adev() when there is no prior error, so the probe correctly fails and triggers mana_remove() cleanup.
---
Changes in v4:
* Update Fixes tag to a69839d4327d.
Changes in v3:
* Fix inaccurate comments.
Changes in v2:
* Apply the patch in net instead of net-next.
--- drivers/net/ethernet/microsoft/mana/mana_en.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-)
drivers/net/ethernet/microsoft/mana/mana_en.c +8 -9
@@ -3680,10 +3680,9 @@ int mana_probe(struct gdma_dev *gd, bool resuming)if (!resuming) {for (i =0 ; i < ac->num_ports; i++) { err =mana_probe_port (ac, i, &ac->ports[i]); -/* we log the port for which the probe failed and stop -* probes for subsequent ports. -* Note that we keep running ports, for which the probes -* were successful, unless add_adev fails too +/* Log the port for which the probe failed, stop probing +* subsequent ports, and skip add_adev. +* mana_remove() will clean up already-probed ports. */ if (err) {dev_err (dev,"Probe Failed for port %d\n" , i);
@@ -3697,10 +3696,9 @@ int mana_probe(struct gdma_dev *gd, bool resuming)enable_work (&apc->queue_reset_work); err =mana_attach (ac->ports[i]);rtnl_unlock (); -/* we log the port for which the attach failed and stop -* attach for subsequent ports -* Note that we keep running ports, for which the attach -* were successful, unless add_adev fails too +/* Log the port for which the attach failed, stop +* attaching subsequent ports, and skip add_adev. +* mana_remove() will clean up already-attached ports. */ if (err) {dev_err (dev,"Attach Failed for port %d\n" , i);
@@ -3709,7 +3707,8 @@ int mana_probe(struct gdma_dev *gd, bool resuming) } } - err =add_adev (gd,"eth" ); +if (!err) + err =add_adev (gd,"eth" );schedule_delayed_work (&ac->gf_stats_work,MANA_GF_STATS_PERIOD );
Signature · 1 line
2.34.1
PATCH v4 5/5 net: mana: Fix EQ leak in mana_remove on NULL port
In reply to Erni Sri Satya VennelaIn mana_remove(), when a NULL port is encountered in the port iteration loop, 'goto out' skips the mana_destroy_eq(ac) call, leaking the event queues allocated earlier by mana_create_eq().
This can happen when mana_probe_port() fails for port 0, leaving ac->ports[0] as NULL. On driver unload or error cleanup, mana_remove() hits the NULL entry and jumps past mana_destroy_eq().
Change 'goto out' to 'break' so the for-loop exits normally and mana_destroy_eq() is always reached. Remove the now-unreferenced out:
label.
---
Changes in v4:
* No change
Changes in v3;
* Update Fixes tag to appropriate commit id.
Changes in v2:
* Apply the patch in net instead of net-next.
--- drivers/net/ethernet/microsoft/mana/mana_en.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/microsoft/mana/mana_en.c +2 -2
@@ -3752,7 +3752,7 @@ void mana_remove(struct gdma_dev *gd, bool suspending)if (!ndev) {if (i ==0 )dev_err (dev,"No net device to remove\n" ); - goto out; +break ; } apc =netdev_priv (ndev);
@@ -3783,7 +3783,7 @@ void mana_remove(struct gdma_dev *gd, bool suspending) }mana_destroy_eq (ac); -out: +if (ac->per_port_queue_reset_wq) {destroy_workqueue (ac->per_port_queue_reset_wq); ac->per_port_queue_reset_wq =NULL ;
Signature · 1 line
2.34.1
Quoted 20 lines · Erni Sri Satya Vennela
Fix five bugs in mana_probe()/mana_remove() error handling that can cause warnings on uninitialized work structs, NULL pointer dereferences, masked errors, and resource leaks when early probe steps fail.
Patches 1-2 move work struct initialization (
link_change_workandgf_stats_work) to before any error path that could triggermana_remove(), preventingWARN_ONin__flush_work()or debug object warnings when sync cancellation runs on uninitialized work structs.Patch 3 guards
mana_remove()against double invocation. If PM resume fails,mana_probe()callsmana_remove()which setsgdma_contextanddriver_datato NULL. A failed resume does not unbind the driver, so when the device is eventually unbound,mana_remove()is called again and dereferences NULL, causing a kernel panic. An early return on NULLgdma_contextordriver_datamakes the second call harmless.Patch 4 prevents
add_adev()from overwriting a port probe error, which could leave the driver in a broken state with NULL ports while reporting success.
Quoted 7 lines
Patch 5 changes 'goto out' to 'break' in mana_remove()'s port loop so that
mana_destroy_eq()is always reached, preventing EQ leaks when a NULL port is encountered.
---
Changes in v4:
* Correct Fixes tag fromca9c54d2d6a5to635096a86edb
* Correct Fixes tag fromced82fce77e9toa69839d4327d
Thanks for the updates.
For the series:
I see that Sashiko provided feedback on patch 4/5. However, as it notes, the issue it flags is addressed in patch 5/5. No further action required AFAICS.
This series was applied to netdev/net.git (main) by Paolo Abeni <[email protected]>:
Hello:
This series was applied to netdev/net.git (main)
by Paolo Abeni <[email protected]>:
Quoted 10 lines · On Mon, 20 Apr 2026 05:47:34 -0700 you wrote:
Fix five bugs in mana_probe()/mana_remove() error handling that can cause warnings on uninitialized work structs, NULL pointer dereferences, masked errors, and resource leaks when early probe steps fail.
Patches 1-2 move work struct initialization (
link_change_workandgf_stats_work) to before any error path that could triggermana_remove(), preventingWARN_ONin__flush_work()or debug object warnings when sync cancellation runs on uninitialized work structs.[...]
Here is the summary with links:
- [net,v4,1/5] net: mana: Init link_change_work before potential error paths in probe
https://git.kernel.org/netdev/net/c/cb4a90744bcd - [net,v4,2/5] net: mana: Init gf_stats_work before potential error paths in probe https://git.kernel.org/netdev/net/c/6e8bc03349fe - [net,v4,3/5] net: mana: Guard mana_remove against double invocation https://git.kernel.org/netdev/net/c/50271d7ec951 - [net,v4,4/5] net: mana: Don't overwrite port probe error with add_adev result https://git.kernel.org/netdev/net/c/a7fdaf069bd0 - [net,v4,5/5] net: mana: Fix EQ leak in mana_remove on NULL port https://git.kernel.org/netdev/net/c/65267c9c4f28
You are awesome, thank you!
Signature · 2 lines
Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html