Commit d1384133 authored by Russell King's avatar Russell King Committed by Greg Kroah-Hartman

net: phylink: avoid resolving link state too early

commit 87454b6e upstream.

During testing on Armada 388 platforms, it was found with a certain
module configuration that it was possible to trigger a kernel oops
during the module load process, caused by the phylink resolver being
triggered for a currently disabled interface.

This problem was introduced by changing the way the SFP registration
works, which now can result in the sfp link down notification being
called during phylink_create().

Fixes: b5bfc21a ("net: sfp: do not probe SFP module before we're attached")
Signed-off-by: 's avatarRussell King <>
Signed-off-by: 's avatarDavid S. Miller <>
Cc: Sasha Levin <>
Signed-off-by: 's avatarGreg Kroah-Hartman <>
parent 84b68a1b
...@@ -475,6 +475,17 @@ static void phylink_run_resolve(struct phylink *pl) ...@@ -475,6 +475,17 @@ static void phylink_run_resolve(struct phylink *pl)
queue_work(system_power_efficient_wq, &pl->resolve); queue_work(system_power_efficient_wq, &pl->resolve);
} }
static void phylink_run_resolve_and_disable(struct phylink *pl, int bit)
unsigned long state = pl->phylink_disable_state;
set_bit(bit, &pl->phylink_disable_state);
if (state == 0) {
queue_work(system_power_efficient_wq, &pl->resolve);
static void phylink_fixed_poll(struct timer_list *t) static void phylink_fixed_poll(struct timer_list *t)
{ {
struct phylink *pl = container_of(t, struct phylink, link_poll); struct phylink *pl = container_of(t, struct phylink, link_poll);
...@@ -928,9 +939,7 @@ void phylink_stop(struct phylink *pl) ...@@ -928,9 +939,7 @@ void phylink_stop(struct phylink *pl)
if (pl->link_an_mode == MLO_AN_FIXED && !IS_ERR(pl->link_gpio)) if (pl->link_an_mode == MLO_AN_FIXED && !IS_ERR(pl->link_gpio))
del_timer_sync(&pl->link_poll); del_timer_sync(&pl->link_poll);
set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); phylink_run_resolve_and_disable(pl, PHYLINK_DISABLE_STOPPED);
queue_work(system_power_efficient_wq, &pl->resolve);
} }
EXPORT_SYMBOL_GPL(phylink_stop); EXPORT_SYMBOL_GPL(phylink_stop);
...@@ -1637,9 +1646,7 @@ static void phylink_sfp_link_down(void *upstream) ...@@ -1637,9 +1646,7 @@ static void phylink_sfp_link_down(void *upstream)
set_bit(PHYLINK_DISABLE_LINK, &pl->phylink_disable_state); phylink_run_resolve_and_disable(pl, PHYLINK_DISABLE_LINK);
queue_work(system_power_efficient_wq, &pl->resolve);
} }
static void phylink_sfp_link_up(void *upstream) static void phylink_sfp_link_up(void *upstream)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment