From: "Matthew Wilcox (Oracle)" <wi...@infradead.org>

Straightforward conversion without touching the locking.

Signed-off-by: Matthew Wilcox (Oracle) <wi...@infradead.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

Reply via email to