Skip to content

Commit 87e190f

Browse files
committed
net: eth-mux: try decoupling work-queue suggested by chatgpt
but still rcu lock $ ip link set eth1 up [ 31.594416] Aeonsemi AS21xxx mdio-bus:1c: Firmware Version: 1.8.5 [ 31.600622] mtk_soc_eth 15100000.ethernet eth1: PHY [mdio-bus:1c] driver [Aeonsemi AS21xxx] (irq=POLL) [ 31.617827] mtk_soc_eth 15100000.ethernet eth1: configuring for phy/usxgmii link mode [ 31.638421] mtk_soc_eth 15100000.ethernet eth1: DBG phylink_start:2654 [ 91.635970] rcu: INFO: rcu_sched self-detected stall on CPU [ 91.641548] rcu: 1-....: (5999 ticks this GP) idle=feb4/1/0x4000000000000000 softirq=1332/1332 fqs=3000 [ 91.651018] rcu: (t=6000 jiffies g=489 q=16 ncpus=4) [ 91.656062] CPU: 1 UID: 0 PID: 3408 Comm: ip Not tainted 6.18.0-rc1-bpi-r4 #2 NONE [ 91.656069] Hardware name: Bananapi BPI-R4 (DT) [ 91.656071] pstate: 20400005 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 91.656076] pc : phylink_start+0xd4/0x57c [ 91.656088] lr : phylink_start+0x2cc/0x57c [ 91.656092] sp : ffffffc08826b4a0 [ 91.656094] x29: ffffffc08826b4a0 x28: ffffff80c2bde080 x27: ffffffc080fbac48 [ 91.656101] x26: ffffff80c0f56000 x25: ffffffc080fb9c98 x24: 0000000000000001 [ 91.656106] x23: 0000000000001002 x22: ffffff80c0f56a00 x21: ffffff80c0f56000 [ 91.656111] x20: 0000000000000000 x19: ffffff80c1370c00 x18: 00000000ffffffff [ 91.656116] x17: 0000000000003040 x16: 0000000000005078 x15: 0000000000000006 [ 91.656121] x14: 00000000ffffffea x13: ffffffc08826b148 x12: ffffffc081869cf0 [ 91.656126] x11: 0000000000000001 x10: 0000000000000001 x9 : 0000000000017fe8 [ 91.656131] x8 : c0000000ffffefff x7 : ffffffc081811c70 x6 : 0000000000000001 [ 91.656136] x5 : ffffff80ff761688 x4 : 0000000000000000 x3 : 0000000000000000 [ 91.656140] x2 : ffffff80c1370ca0 x1 : ffffff80c0a7eca0 x0 : ffffff80c0a7ec80 [ 91.656146] Call trace: [ 91.656148] phylink_start+0xd4/0x57c (P) [ 91.656154] mtk_open+0x45c/0xb24 [ 91.656159] __dev_open+0x110/0x228 [ 91.656167] __dev_change_flags+0x1e8/0x240 [ 91.656172] netif_change_flags+0x24/0x6c [ 91.656176] do_setlink.isra.0+0xb50/0xe4c [ 91.656181] rtnl_newlink+0x684/0x968
1 parent 90d3028 commit 87e190f

1 file changed

Lines changed: 29 additions & 17 deletions

File tree

drivers/net/ethernet/mediatek/mtk_eth_soc.c

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4919,26 +4919,17 @@ static const struct net_device_ops mtk_netdev_ops = {
49194919
.ndo_select_queue = mtk_select_queue,
49204920
};
49214921

4922-
static void mux_poll(struct work_struct *work)
4922+
static void mtk_mux_reconfig_work(struct work_struct *work)
49234923
{
4924-
struct mtk_mux *mux = container_of(work, struct mtk_mux, poll.work);
4924+
struct mtk_mux *mux = container_of(work, struct mtk_mux, reconfig_work);
49254925
struct mtk_mac *mac = mux->mac;
49264926
struct mtk_eth *eth = mac->hw;
49274927
struct net_device *dev = eth->netdev[mac->id];
4928-
unsigned int new_channel;
4929-
int sfp_present;
4928+
unsigned int new_channel = mux->pending_channel;
49304929

4931-
//dev_info(eth->dev, "ethernet mux: %s:%d\n",__func__,__LINE__);
4932-
if (IS_ERR(mux->mod_def0_gpio) || IS_ERR(mux->chan_sel_gpio))
4933-
goto reschedule;
4934-
4935-
sfp_present = gpiod_get_value_cansleep(mux->mod_def0_gpio);
4936-
new_channel = sfp_present ? mux->sfp_present_channel : !mux->sfp_present_channel;
4937-
4938-
if (mux->channel == new_channel || !netif_running(dev))
4939-
goto reschedule;
4930+
if (!netif_running(dev))
4931+
return;
49404932

4941-
dev_info(eth->dev, "ethernet mux: line:%d new channel:%d,sfp:%d\n",__LINE__, new_channel,sfp_present);
49424933
rtnl_lock();
49434934

49444935
mtk_stop(dev);
@@ -4950,13 +4941,32 @@ static void mux_poll(struct work_struct *work)
49504941

49514942
gpiod_set_value_cansleep(mux->chan_sel_gpio, new_channel);
49524943

4953-
usleep_range(100000,200000);
4954-
49554944
mtk_open(dev);
49564945

4946+
mux->channel = new_channel;
4947+
49574948
rtnl_unlock();
4949+
}
49584950

4959-
mux->channel = new_channel;
4951+
static void mux_poll(struct work_struct *work)
4952+
{
4953+
struct mtk_mux *mux = container_of(work, struct mtk_mux, poll.work);
4954+
struct mtk_mac *mac = mux->mac;
4955+
struct mtk_eth *eth = mac->hw;
4956+
struct net_device *dev = eth->netdev[mac->id];
4957+
unsigned int new_channel;
4958+
int sfp_present;
4959+
4960+
if (IS_ERR(mux->mod_def0_gpio) || IS_ERR(mux->chan_sel_gpio))
4961+
goto reschedule;
4962+
4963+
sfp_present = gpiod_get_value_cansleep(mux->mod_def0_gpio);
4964+
new_channel = sfp_present ? mux->sfp_present_channel : !mux->sfp_present_channel;
4965+
4966+
if (mux->channel != new_channel && netif_running(dev)) {
4967+
mux->pending_channel = new_channel;
4968+
schedule_work(&mux->reconfig_work);
4969+
}
49604970

49614971
reschedule:
49624972
mod_delayed_work(system_wq, &mux->poll, msecs_to_jiffies(100));
@@ -5025,6 +5035,7 @@ static void mtk_release_mux(struct mtk_eth *eth, int id)
50255035
return;
50265036

50275037
cancel_delayed_work_sync(&mux->poll);
5038+
cancel_work_sync(&mux->reconfig_work);
50285039

50295040
if (!IS_ERR_OR_NULL(mux->mod_def0_gpio))
50305041
gpiod_put(mux->mod_def0_gpio);
@@ -5116,6 +5127,7 @@ static int mtk_add_mux(struct mtk_eth *eth, struct device_node *np)
51165127
dev_info(eth->dev, "ethernet mux: line:%d added new mux\n",__LINE__);
51175128
INIT_DELAYED_WORK(&mux->poll, mux_poll);
51185129
mod_delayed_work(system_wq, &mux->poll, msecs_to_jiffies(3000));
5130+
INIT_WORK(&mux->reconfig_work, mtk_mux_reconfig_work);
51195131

51205132
return 0;
51215133

0 commit comments

Comments
 (0)