lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Fri,  3 Nov 2017 19:05:22 -0400
From:   Vivien Didelot <vivien.didelot@...oirfairelinux.com>
To:     netdev@...r.kernel.org
Cc:     linux-kernel@...r.kernel.org, kernel@...oirfairelinux.com,
        "David S. Miller" <davem@...emloft.net>,
        Florian Fainelli <f.fainelli@...il.com>,
        Andrew Lunn <andrew@...n.ch>,
        Vivien Didelot <vivien.didelot@...oirfairelinux.com>
Subject: [PATCH net-next 03/11] 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@...oirfairelinux.com>
---
 net/dsa/dsa2.c | 30 ++++++++++--------------------
 1 file changed, 10 insertions(+), 20 deletions(-)

diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
index 8b68dc2f5707..d3f1a7607463 100644
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
@@ -32,10 +32,9 @@ static struct dsa_switch_tree *dsa_get_dst(unsigned int index)
 	struct dsa_switch_tree *dst;
 
 	list_for_each_entry(dst, &dsa_switch_trees, list)
-		if (dst->index == index) {
-			kref_get(&dst->refcount);
+		if (dst->index == index)
 			return dst;
-		}
+
 	return NULL;
 }
 
@@ -48,11 +47,6 @@ static void dsa_free_dst(struct kref *ref)
 	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)
 {
 	struct dsa_switch_tree *dst;
@@ -63,7 +57,10 @@ static struct dsa_switch_tree *dsa_add_dst(unsigned int index)
 	dst->index = index;
 	INIT_LIST_HEAD(&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);
+	refcount_set(&dst->refcount.refcount, 0);
 
 	return dst;
 }
@@ -739,10 +736,8 @@ static int _dsa_register_switch(struct dsa_switch *ds)
 			return -ENOMEM;
 	}
 
-	if (dst->ds[index]) {
-		err = -EBUSY;
-		goto out;
-	}
+	if (dst->ds[index])
+		return -EBUSY;
 
 	ds->dst = dst;
 	ds->index = index;
@@ -758,11 +753,9 @@ static int _dsa_register_switch(struct dsa_switch *ds)
 	if (err < 0)
 		goto out_del_dst;
 
-	if (err == 1) {
-		/* Not all switches registered yet */
-		err = 0;
-		goto out;
-	}
+	/* Not all switches registered yet */
+	if (err == 1)
+		return 0;
 
 	if (dst->applied) {
 		pr_info("DSA: Disjoint trees?\n");
@@ -779,13 +772,10 @@ static int _dsa_register_switch(struct dsa_switch *ds)
 		goto out_del_dst;
 	}
 
-	dsa_put_dst(dst);
 	return 0;
 
 out_del_dst:
 	dsa_dst_del_ds(dst, ds, ds->index);
-out:
-	dsa_put_dst(dst);
 
 	return err;
 }
-- 
2.14.3

Powered by blists - more mailing lists