From: Wei Fang <[email protected]>

Replace the struct ipft_entry_data pointer in struct netc_port with a
plain u32 entry ID (ipft_hf_eid), using NTMP_NULL_ENTRY_ID as the
sentinel value. The ipft_entry_data allocation is now freed immediately
inside netc_port_add_host_flood_rule() after the hardware entry is
committed, so no heap memory survives beyond that function. As a result,
netc_free_host_flood_rules() is no longer needed and can be removed.

Signed-off-by: Wei Fang <[email protected]>
---
 drivers/net/dsa/netc/netc_main.c   | 63 ++++++++++++------------------
 drivers/net/dsa/netc/netc_switch.h |  2 +-
 2 files changed, 25 insertions(+), 40 deletions(-)

diff --git a/drivers/net/dsa/netc/netc_main.c b/drivers/net/dsa/netc/netc_main.c
index 77077352c1a5..d326a00104e1 100644
--- a/drivers/net/dsa/netc/netc_main.c
+++ b/drivers/net/dsa/netc/netc_main.c
@@ -286,6 +286,12 @@ static int netc_init_all_ports(struct netc_switch *priv)
                                dev_err(dev, "Failed to create MDIO bus\n");
                                return err;
                        }
+
+                       /* The ipft_hf_eid is initialized to an invalid entry
+                        * ID because the host flood rule (IPFT entry) has not
+                        * been created.
+                        */
+                       np->ipft_hf_eid = NTMP_NULL_ENTRY_ID;
                }
        }
 
@@ -938,30 +944,12 @@ static void netc_destroy_all_lists(struct netc_switch 
*priv)
        mutex_destroy(&priv->vft_lock);
 }
 
-static void netc_free_host_flood_rules(struct netc_switch *priv)
-{
-       struct dsa_port *dp;
-
-       dsa_switch_for_each_user_port(dp, priv->ds) {
-               struct netc_port *np = priv->ports[dp->index];
-
-               /* No need to clear the hardware IPFT entry. Because PCIe
-                * FLR will be performed when the switch is re-registered,
-                * it will reset hardware state. So only need to free the
-                * memory to avoid memory leak.
-                */
-               kfree(np->host_flood);
-               np->host_flood = NULL;
-       }
-}
-
 static void netc_teardown(struct dsa_switch *ds)
 {
        struct netc_switch *priv = ds->priv;
 
        disable_delayed_work_sync(&priv->fdbt_ageing_work);
        netc_destroy_all_lists(priv);
-       netc_free_host_flood_rules(priv);
        netc_free_ntmp_user(priv);
 }
 
@@ -1759,37 +1747,36 @@ static int netc_port_add_host_flood_rule(struct 
netc_port *np,
        cfge->cfg = cpu_to_le32(cfg);
 
        err = ntmp_ipft_add_entry(&priv->ntmp, host_flood);
-       if (err) {
-               kfree(host_flood);
-               return err;
-       }
+       if (err)
+               goto free_host_flood;
 
        np->uc = uc;
        np->mc = mc;
-       np->host_flood = host_flood;
+       np->ipft_hf_eid = host_flood->entry_id;
        /* Enable ingress port filter table lookup */
        netc_port_wr(np, NETC_PIPFCR, PIPFCR_EN);
 
-       return 0;
+free_host_flood:
+       kfree(host_flood);
+
+       return err;
 }
 
-static void netc_port_remove_host_flood(struct netc_port *np,
-                                       struct ipft_entry_data *host_flood)
+static void netc_port_remove_host_flood(struct netc_port *np, u32 entry_id)
 {
        struct netc_switch *priv = np->switch_priv;
        bool disable_host_flood = false;
 
-       if (!host_flood)
+       if (entry_id == NTMP_NULL_ENTRY_ID)
                return;
 
-       if (np->host_flood == host_flood)
+       if (np->ipft_hf_eid == entry_id)
                disable_host_flood = true;
 
-       ntmp_ipft_delete_entry(&priv->ntmp, host_flood->entry_id);
-       kfree(host_flood);
+       ntmp_ipft_delete_entry(&priv->ntmp, entry_id);
 
        if (disable_host_flood) {
-               np->host_flood = NULL;
+               np->ipft_hf_eid = NTMP_NULL_ENTRY_ID;
                np->uc = false;
                np->mc = false;
                netc_port_wr(np, NETC_PIPFCR, 0);
@@ -1800,7 +1787,7 @@ static void netc_port_set_host_flood(struct dsa_switch 
*ds, int port,
                                     bool uc, bool mc)
 {
        struct netc_port *np = NETC_PORT(ds, port);
-       struct ipft_entry_data *old_host_flood;
+       u32 old_entry_id;
 
        /* Do not add host flood rule to ingress port filter table when
         * the port has joined a bridge. Otherwise, the ingress frames
@@ -1808,7 +1795,7 @@ static void netc_port_set_host_flood(struct dsa_switch 
*ds, int port,
         * will be redirected directly to the CPU port.
         */
        if (dsa_port_bridge_dev_get(np->dp)) {
-               netc_port_remove_host_flood(np, np->host_flood);
+               netc_port_remove_host_flood(np, np->ipft_hf_eid);
 
                return;
        }
@@ -1818,20 +1805,18 @@ static void netc_port_set_host_flood(struct dsa_switch 
*ds, int port,
 
        /* IPFT does not support in-place updates to the KEYE element,
         * we need to add a new entry and then delete the old one. So
-        * save the old entry first.
+        * save the old entry ID first.
         */
-       old_host_flood = np->host_flood;
-       np->host_flood = NULL;
+       old_entry_id = np->ipft_hf_eid;
 
        if (netc_port_add_host_flood_rule(np, uc, mc)) {
-               np->host_flood = old_host_flood;
                dev_err(ds->dev, "Failed to add host flood rule on port %d\n",
                        port);
                return;
        }
 
        /* Remove the old host flood entry */
-       netc_port_remove_host_flood(np, old_host_flood);
+       netc_port_remove_host_flood(np, old_entry_id);
 }
 
 static int netc_single_vlan_aware_bridge(struct dsa_switch *ds,
@@ -2020,7 +2005,7 @@ static int netc_port_bridge_join(struct dsa_switch *ds, 
int port,
        netc_port_set_pvid(np, vlan_unaware_pvid);
 
 out:
-       netc_port_remove_host_flood(np, np->host_flood);
+       netc_port_remove_host_flood(np, np->ipft_hf_eid);
 
        if (atomic_inc_return(&priv->br_cnt) == 1)
                schedule_delayed_work(&priv->fdbt_ageing_work,
diff --git a/drivers/net/dsa/netc/netc_switch.h 
b/drivers/net/dsa/netc/netc_switch.h
index 305f2a92e2f9..fd36ec2d0e90 100644
--- a/drivers/net/dsa/netc/netc_switch.h
+++ b/drivers/net/dsa/netc/netc_switch.h
@@ -84,7 +84,7 @@ struct netc_port {
        u16 uc:1;
        u16 mc:1;
        u16 pvid;
-       struct ipft_entry_data *host_flood;
+       u32 ipft_hf_eid;
 };
 
 struct netc_switch_regs {
-- 
2.34.1


Reply via email to