From: Quanyang Wang <[email protected]>

The phy->id is an unique id under &phy_ida after calling phy_create,
but the s32g serdes driver uses it to save lane_id (0 or 1), this results
that phy->id is not unique anymore and will trigger calltrace as below
for being freed multiple times.

[  129.135513] ida_free called for id=0 which is not allocated.
[  129.135668] WARNING: CPU: 3 PID: 46 at lib/idr.c:524 ida_free+0x13c/0x150
[  129.135704] Modules linked in:
[  129.135718] CPU: 1 PID: 27 Comm: kworker/1:1 Not tainted 
5.15.32-rt34-yocto-preempt-rt #1
[  129.135729] Hardware name: Freescale S32G274A (DT)
[  129.135737] Workqueue: events kobject_delayed_cleanup
[  129.135751] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[  129.135761] pc : ida_free+0x13c/0x150
[  129.135769] lr : ida_free+0x13c/0x150
[  129.135778] sp : ffffffc00bdfbc60
[  129.135781] x29: ffffffc00bdfbc60 x28: ffffff885bffc205 x27: ffffffc009bfa0b8
[  129.135793] x26: ffffffc00a49ed80 x25: 0000000000000000 x24: 0000000000000000
[  129.135803] x23: ffffff880642e100 x22: 0000000000000000 x21: ffffff8801445a40
[  129.135815] x20: 000000000000000c x19: 0000000000000000 x18: 0000000000000001
[  129.135825] x17: 0000000000000000 x16: 0000000000000000 x15: ffffff8801445fb8
[  129.135836] x14: ffffffffffffffff x13: 0a2e64657461636f x12: 6c6c6120746f6e20
[  129.135847] x11: 656820747563205b x10: ffffffc009c4ac20 x9 : ffffffc0080d5850
[  129.135858] x8 : ffffffc00bdfbc60 x7 : 0000000000000000 x6 : 0000000000000001
[  129.135868] x5 : ffffffc009bfa000 x4 : ffffffc009bfaa18 x3 : 0000000000000000
[  129.135878] x2 : ffffff8801445a40 x1 : 0000000000000000 x0 : 0000000000000000
[  129.135889] Call trace:
[  129.135893]  ida_free+0x13c/0x150
[  129.135903]  phy_release+0x38/0x50
[  129.135913]  device_release+0x3c/0x98
[  129.135923]  kobject_delayed_cleanup+0x68/0x1b0
[  129.135932]  process_one_work+0x294/0x760
[  129.135944]  worker_thread+0x54/0x408
[  129.135951]  kthread+0x178/0x190
[  129.135963]  ret_from_fork+0x10/0x20

Let's introduce a new function get_lane_id to retrieve lane_id instead
of saving it in phy->id.

Signed-off-by: Quanyang Wang <[email protected]>
Signed-off-by: Bruce Ashfield <[email protected]>
[Fix: change the file name from phy-fsl-s32gen1-serdes.c to
phy-nxp-s32cc-serdes.c]
Signed-off-by: Zhantao Tang <[email protected]>
---
 drivers/phy/freescale/phy-nxp-s32cc-serdes.c | 21 ++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/freescale/phy-nxp-s32cc-serdes.c 
b/drivers/phy/freescale/phy-nxp-s32cc-serdes.c
index e10665c6020d..4d06f19494d5 100644
--- a/drivers/phy/freescale/phy-nxp-s32cc-serdes.c
+++ b/drivers/phy/freescale/phy-nxp-s32cc-serdes.c
@@ -157,6 +157,19 @@ static int serdes_phy_reset(struct phy *p)
        return 0;
 }
 
+static int get_lane_id(struct phy *phy)
+{
+       struct serdes *serdes = phy_get_drvdata(phy);
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(serdes->phys); i++)
+               if (serdes->phys[i] == phy)
+                       return i;
+
+       WARN_ON(i == ARRAY_SIZE(serdes->phys));
+       return 0;
+}
+
 static bool pcie_phy_is_locked(struct serdes *serdes)
 {
        u32 mplla = readl(serdes->ctrl.ss_base + PCIE_PHY_MPLLA_CTRL);
@@ -603,8 +616,9 @@ struct s32cc_xpcs *s32cc_phy2xpcs(struct phy *phy)
 {
        struct serdes *serdes = phy_get_drvdata(phy);
        struct xpcs_ctrl *xpcs = &serdes->xpcs;
+       int lane_id = get_lane_id(phy);
 
-       return xpcs->phys[phy->id];
+       return xpcs->phys[lane_id];
 }
 EXPORT_SYMBOL_GPL(s32cc_phy2xpcs);
 
@@ -613,9 +627,10 @@ static int xpcs_phy_configure(struct phy *phy, struct 
phylink_link_state *state)
        struct serdes *serdes = phy_get_drvdata(phy);
        struct xpcs_ctrl *xpcs = &serdes->xpcs;
        struct device *dev = serdes->dev;
+       int lane_id = get_lane_id(phy);
        int ret;
 
-       ret = xpcs->ops->config(xpcs->phys[phy->id], NULL);
+       ret = xpcs->ops->config(xpcs->phys[lane_id], NULL);
        if (ret) {
                dev_err(dev, "Failed to configure XPCS\n");
                return ret;
@@ -785,7 +800,6 @@ static struct phy *serdes_xlate(struct device *dev,
                return ERR_PTR(ret);
 
        phy = serdes->phys[lane_id];
-       phy->id = lane_id;
        phy->attrs.mode = mode;
 
        return phy;
@@ -1012,7 +1026,6 @@ static int serdes_probe(struct platform_device *pdev)
                if (IS_ERR(serdes->phys[i]))
                        return PTR_ERR(serdes->phys[i]);
                phy_set_drvdata(serdes->phys[i], serdes);
-               serdes->phys[i]->id = i;
        }
 
        ret = ss_dt_init(pdev, serdes);
-- 
2.25.1

-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#12320): 
https://lists.yoctoproject.org/g/linux-yocto/message/12320
Mute This Topic: https://lists.yoctoproject.org/mt/97898132/21656
Group Owner: [email protected]
Unsubscribe: https://lists.yoctoproject.org/g/linux-yocto/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to