net: dsa: simplify tree reference counting
DSA trees have a refcount used to automatically free the dsa_switch_tree structure once there is no switch devices inside of it. The refcount is incremented when a switch is added to the tree, and decremented when it is removed from it. But because of kref_init, the refcount is also incremented at initialization, and when looking up the tree from the list for symmetry. Thus the current code stores the number of switches plus one, and makes the switch registration more complex. To simplify the switch registration function, we reset the refcount to zero after initialization and don't increment it when looking up a tree. Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
49463b7f2d
Коммит
8e5bf9759a
|
@ -32,10 +32,9 @@ static struct dsa_switch_tree *dsa_get_dst(unsigned int index)
|
||||||
struct dsa_switch_tree *dst;
|
struct dsa_switch_tree *dst;
|
||||||
|
|
||||||
list_for_each_entry(dst, &dsa_switch_trees, list)
|
list_for_each_entry(dst, &dsa_switch_trees, list)
|
||||||
if (dst->index == index) {
|
if (dst->index == index)
|
||||||
kref_get(&dst->refcount);
|
|
||||||
return dst;
|
return dst;
|
||||||
}
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,11 +47,6 @@ static void dsa_free_dst(struct kref *ref)
|
||||||
kfree(dst);
|
kfree(dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dsa_put_dst(struct dsa_switch_tree *dst)
|
|
||||||
{
|
|
||||||
kref_put(&dst->refcount, dsa_free_dst);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct dsa_switch_tree *dsa_add_dst(unsigned int index)
|
static struct dsa_switch_tree *dsa_add_dst(unsigned int index)
|
||||||
{
|
{
|
||||||
struct dsa_switch_tree *dst;
|
struct dsa_switch_tree *dst;
|
||||||
|
@ -63,7 +57,10 @@ static struct dsa_switch_tree *dsa_add_dst(unsigned int index)
|
||||||
dst->index = index;
|
dst->index = index;
|
||||||
INIT_LIST_HEAD(&dst->list);
|
INIT_LIST_HEAD(&dst->list);
|
||||||
list_add_tail(&dsa_switch_trees, &dst->list);
|
list_add_tail(&dsa_switch_trees, &dst->list);
|
||||||
|
|
||||||
|
/* Initialize the reference counter to the number of switches, not 1 */
|
||||||
kref_init(&dst->refcount);
|
kref_init(&dst->refcount);
|
||||||
|
refcount_set(&dst->refcount.refcount, 0);
|
||||||
|
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
@ -739,10 +736,8 @@ static int _dsa_register_switch(struct dsa_switch *ds)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dst->ds[index]) {
|
if (dst->ds[index])
|
||||||
err = -EBUSY;
|
return -EBUSY;
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
ds->dst = dst;
|
ds->dst = dst;
|
||||||
ds->index = index;
|
ds->index = index;
|
||||||
|
@ -758,11 +753,9 @@ static int _dsa_register_switch(struct dsa_switch *ds)
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto out_del_dst;
|
goto out_del_dst;
|
||||||
|
|
||||||
if (err == 1) {
|
/* Not all switches registered yet */
|
||||||
/* Not all switches registered yet */
|
if (err == 1)
|
||||||
err = 0;
|
return 0;
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dst->applied) {
|
if (dst->applied) {
|
||||||
pr_info("DSA: Disjoint trees?\n");
|
pr_info("DSA: Disjoint trees?\n");
|
||||||
|
@ -779,13 +772,10 @@ static int _dsa_register_switch(struct dsa_switch *ds)
|
||||||
goto out_del_dst;
|
goto out_del_dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
dsa_put_dst(dst);
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_del_dst:
|
out_del_dst:
|
||||||
dsa_dst_del_ds(dst, ds, ds->index);
|
dsa_dst_del_ds(dst, ds, ds->index);
|
||||||
out:
|
|
||||||
dsa_put_dst(dst);
|
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче