lkml.org 
[lkml]   [2019]   [Oct]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH net-next 15/16] net: dsa: allocate ports on touch
    Date
    Allocate the struct dsa_port the first time it is accessed with
    dsa_port_touch, and remove the static dsa_port array from the
    dsa_switch structure.

    Signed-off-by: Vivien Didelot <vivien.didelot@gmail.com>
    ---
    include/net/dsa.h | 2 --
    net/dsa/dsa2.c | 16 ++++++++++++++--
    2 files changed, 14 insertions(+), 4 deletions(-)

    diff --git a/include/net/dsa.h b/include/net/dsa.h
    index 020f5db8666b..d28ac54cb8c4 100644
    --- a/include/net/dsa.h
    +++ b/include/net/dsa.h
    @@ -277,9 +277,7 @@ struct dsa_switch {
    */
    bool vlan_filtering;

    - /* Dynamically allocated ports, keep last */
    size_t num_ports;
    - struct dsa_port ports[];
    };

    static inline struct dsa_port *dsa_to_port(struct dsa_switch *ds, int p)
    diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
    index 772deacc33d3..7669a6278c40 100644
    --- a/net/dsa/dsa2.c
    +++ b/net/dsa/dsa2.c
    @@ -596,7 +596,13 @@ static struct dsa_port *dsa_port_touch(struct dsa_switch *ds, int index)
    struct dsa_switch_tree *dst = ds->dst;
    struct dsa_port *dp;

    - dp = &ds->ports[index];
    + list_for_each_entry(dp, &dst->ports, list)
    + if (dp->ds == ds && dp->index == index)
    + return dp;
    +
    + dp = kzalloc(sizeof(*dp), GFP_KERNEL);
    + if (!dp)
    + return NULL;

    dp->ds = ds;
    dp->index = index;
    @@ -865,7 +871,7 @@ struct dsa_switch *dsa_switch_alloc(struct device *dev, size_t n)
    {
    struct dsa_switch *ds;

    - ds = devm_kzalloc(dev, struct_size(ds, ports, n), GFP_KERNEL);
    + ds = devm_kzalloc(dev, sizeof(*ds), GFP_KERNEL);
    if (!ds)
    return NULL;

    @@ -893,6 +899,12 @@ static void dsa_switch_remove(struct dsa_switch *ds)
    {
    struct dsa_switch_tree *dst = ds->dst;
    unsigned int index = ds->index;
    + struct dsa_port *dp, *next;
    +
    + list_for_each_entry_safe(dp, next, &dst->ports, list) {
    + list_del(&dp->list);
    + kfree(dp);
    + }

    dsa_tree_remove_switch(dst, index);
    }
    --
    2.23.0
    \
     
     \ /
      Last update: 2019-10-20 05:21    [W:6.289 / U:0.324 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site