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  linux-cve-announce  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]
Message-Id: <20190820223259.22348-37-willy@infradead.org>
Date:   Tue, 20 Aug 2019 15:32:57 -0700
From:   Matthew Wilcox <willy@...radead.org>
To:     netdev@...r.kernel.org
Cc:     "Matthew Wilcox (Oracle)" <willy@...radead.org>
Subject: [PATCH 36/38] netlink: Convert genl_fam_idr to XArray

From: "Matthew Wilcox (Oracle)" <willy@...radead.org>

Straightforward conversion without touching the locking.

Signed-off-by: Matthew Wilcox (Oracle) <willy@...radead.org>
---
 net/netlink/genetlink.c | 46 +++++++++++++++++------------------------
 1 file changed, 19 insertions(+), 27 deletions(-)

diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index efccd1ac9a66..02f5c7453f84 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -18,7 +18,7 @@
 #include <linux/mutex.h>
 #include <linux/bitmap.h>
 #include <linux/rwsem.h>
-#include <linux/idr.h>
+#include <linux/xarray.h>
 #include <net/sock.h>
 #include <net/genetlink.h>
 
@@ -60,7 +60,8 @@ static void genl_unlock_all(void)
 	up_write(&cb_lock);
 }
 
-static DEFINE_IDR(genl_fam_idr);
+static unsigned int genl_families_next;
+static DEFINE_XARRAY_ALLOC(genl_families);
 
 /*
  * Bitmap of multicast groups that are currently in use.
@@ -92,15 +93,15 @@ static int genl_ctrl_event(int event, const struct genl_family *family,
 
 static const struct genl_family *genl_family_find_byid(unsigned int id)
 {
-	return idr_find(&genl_fam_idr, id);
+	return xa_load(&genl_families, id);
 }
 
 static const struct genl_family *genl_family_find_byname(char *name)
 {
 	const struct genl_family *family;
-	unsigned int id;
+	unsigned long id;
 
-	idr_for_each_entry(&genl_fam_idr, family, id)
+	xa_for_each(&genl_families, id, family)
 		if (strcmp(family->name, name) == 0)
 			return family;
 
@@ -362,12 +363,10 @@ int genl_register_family(struct genl_family *family)
 	} else
 		family->attrbuf = NULL;
 
-	family->id = idr_alloc_cyclic(&genl_fam_idr, family,
-				      start, end + 1, GFP_KERNEL);
-	if (family->id < 0) {
-		err = family->id;
+	err = xa_alloc_cyclic(&genl_families, &family->id, family,
+			XA_LIMIT(start, end), &genl_families_next, GFP_KERNEL);
+	if (err < 0)
 		goto errout_free;
-	}
 
 	err = genl_validate_assign_mc_groups(family);
 	if (err)
@@ -384,7 +383,7 @@ int genl_register_family(struct genl_family *family)
 	return 0;
 
 errout_remove:
-	idr_remove(&genl_fam_idr, family->id);
+	xa_erase(&genl_families, family->id);
 errout_free:
 	kfree(family->attrbuf);
 errout_locked:
@@ -412,7 +411,7 @@ int genl_unregister_family(const struct genl_family *family)
 
 	genl_unregister_mc_groups(family);
 
-	idr_remove(&genl_fam_idr, family->id);
+	xa_erase(&genl_families, family->id);
 
 	up_write(&cb_lock);
 	wait_event(genl_sk_destructing_waitq,
@@ -802,28 +801,21 @@ static int ctrl_fill_mcgrp_info(const struct genl_family *family,
 
 static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb)
 {
-	int n = 0;
 	struct genl_family *rt;
 	struct net *net = sock_net(skb->sk);
-	int fams_to_skip = cb->args[0];
-	unsigned int id;
+	unsigned long id;
 
-	idr_for_each_entry(&genl_fam_idr, rt, id) {
+	xa_for_each_start(&genl_families, id, rt, cb->args[0]) {
 		if (!rt->netnsok && !net_eq(net, &init_net))
 			continue;
 
-		if (n++ < fams_to_skip)
-			continue;
-
 		if (ctrl_fill_info(rt, NETLINK_CB(cb->skb).portid,
 				   cb->nlh->nlmsg_seq, NLM_F_MULTI,
-				   skb, CTRL_CMD_NEWFAMILY) < 0) {
-			n--;
+				   skb, CTRL_CMD_NEWFAMILY) < 0)
 			break;
-		}
 	}
 
-	cb->args[0] = n;
+	cb->args[0] = id;
 	return skb->len;
 }
 
@@ -993,11 +985,11 @@ static int genl_bind(struct net *net, int group)
 {
 	struct genl_family *f;
 	int err = -ENOENT;
-	unsigned int id;
+	unsigned long id;
 
 	down_read(&cb_lock);
 
-	idr_for_each_entry(&genl_fam_idr, f, id) {
+	xa_for_each(&genl_families, id, f) {
 		if (group >= f->mcgrp_offset &&
 		    group < f->mcgrp_offset + f->n_mcgrps) {
 			int fam_grp = group - f->mcgrp_offset;
@@ -1019,11 +1011,11 @@ static int genl_bind(struct net *net, int group)
 static void genl_unbind(struct net *net, int group)
 {
 	struct genl_family *f;
-	unsigned int id;
+	unsigned long id;
 
 	down_read(&cb_lock);
 
-	idr_for_each_entry(&genl_fam_idr, f, id) {
+	xa_for_each(&genl_families, id, f) {
 		if (group >= f->mcgrp_offset &&
 		    group < f->mcgrp_offset + f->n_mcgrps) {
 			int fam_grp = group - f->mcgrp_offset;
-- 
2.23.0.rc1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ