get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/806402/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 806402,
    "url": "http://patchwork.ozlabs.org/api/patches/806402/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/netdev/patch/1503902477-39829-4-git-send-email-chrism@mellanox.com/",
    "project": {
        "id": 7,
        "url": "http://patchwork.ozlabs.org/api/projects/7/?format=api",
        "name": "Linux network development",
        "link_name": "netdev",
        "list_id": "netdev.vger.kernel.org",
        "list_email": "netdev@vger.kernel.org",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<1503902477-39829-4-git-send-email-chrism@mellanox.com>",
    "list_archive_url": null,
    "date": "2017-08-28T06:41:17",
    "name": "[net-next,3/3] net/sched: Change act_api and act_xxx modules to use IDR",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "73a5396529a239e79af5fd9aede1720f6497cbb2",
    "submitter": {
        "id": 72170,
        "url": "http://patchwork.ozlabs.org/api/people/72170/?format=api",
        "name": "Chris Mi",
        "email": "chrism@mellanox.com"
    },
    "delegate": {
        "id": 34,
        "url": "http://patchwork.ozlabs.org/api/users/34/?format=api",
        "username": "davem",
        "first_name": "David",
        "last_name": "Miller",
        "email": "davem@davemloft.net"
    },
    "mbox": "http://patchwork.ozlabs.org/project/netdev/patch/1503902477-39829-4-git-send-email-chrism@mellanox.com/mbox/",
    "series": [
        {
            "id": 87,
            "url": "http://patchwork.ozlabs.org/api/series/87/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/netdev/list/?series=87",
            "date": "2017-08-28T06:41:15",
            "name": "net/sched: Improve getting objects by indexes",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/87/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/806402/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/806402/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<netdev-owner@vger.kernel.org>",
        "X-Original-To": "patchwork-incoming@ozlabs.org",
        "Delivered-To": "patchwork-incoming@ozlabs.org",
        "Authentication-Results": "ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=netdev-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)",
        "Received": [
            "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xghyH1N0Vz9sNq\n\tfor <patchwork-incoming@ozlabs.org>;\n\tMon, 28 Aug 2017 16:41:59 +1000 (AEST)",
            "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751249AbdH1Glw (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tMon, 28 Aug 2017 02:41:52 -0400",
            "from mail-il-dmz.mellanox.com ([193.47.165.129]:48406 \"EHLO\n\tmellanox.co.il\" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org\n\twith ESMTP id S1750767AbdH1Glu (ORCPT\n\t<rfc822;netdev@vger.kernel.org>); Mon, 28 Aug 2017 02:41:50 -0400",
            "from Internal Mail-Server by MTLPINE1 (envelope-from\n\tchrism@mellanox.com)\n\twith ESMTPS (AES256-SHA encrypted); 28 Aug 2017 09:41:44 +0300",
            "from bjglab-18.mtbc.labs.mlnx (bjglab-18.mtbc.labs.mlnx\n\t[10.200.0.168])\n\tby labmailer.mlnx (8.13.8/8.13.8) with ESMTP id v7S6fPZp022940;\n\tMon, 28 Aug 2017 09:41:42 +0300"
        ],
        "From": "Chris Mi <chrism@mellanox.com>",
        "To": "netdev@vger.kernel.org",
        "Cc": "jhs@mojatatu.com, xiyou.wangcong@gmail.com, jiri@resnulli.us,\n\tdavem@davemloft.net, mawilcox@microsoft.com",
        "Subject": "[patch net-next 3/3] net/sched: Change act_api and act_xxx modules\n\tto use IDR",
        "Date": "Mon, 28 Aug 2017 02:41:17 -0400",
        "Message-Id": "<1503902477-39829-4-git-send-email-chrism@mellanox.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1503902477-39829-1-git-send-email-chrism@mellanox.com>",
        "References": "<1503902477-39829-1-git-send-email-chrism@mellanox.com>",
        "Sender": "netdev-owner@vger.kernel.org",
        "Precedence": "bulk",
        "List-ID": "<netdev.vger.kernel.org>",
        "X-Mailing-List": "netdev@vger.kernel.org"
    },
    "content": "Typically, each TC filter has its own action. All the actions of the\nsame type are saved in its hash table. But the hash buckets are too\nsmall that it degrades to a list. And the performance is greatly\naffected. For example, it takes about 0m11.914s to insert 64K rules.\nIf we convert the hash table to IDR, it only takes about 0m1.500s.\nThe improvement is huge.\n\nBut please note that the test result is based on previous patch that\ncls_flower uses IDR.\n\nSigned-off-by: Chris Mi <chrism@mellanox.com>\nSigned-off-by: Jiri Pirko <jiri@mellanox.com>\n---\n include/net/act_api.h      |  76 +++++---------\n net/sched/act_api.c        | 251 ++++++++++++++++++++++-----------------------\n net/sched/act_bpf.c        |  17 ++-\n net/sched/act_connmark.c   |  16 ++-\n net/sched/act_csum.c       |  16 ++-\n net/sched/act_gact.c       |  16 ++-\n net/sched/act_ife.c        |  20 ++--\n net/sched/act_ipt.c        |  26 +++--\n net/sched/act_mirred.c     |  19 ++--\n net/sched/act_nat.c        |  16 ++-\n net/sched/act_pedit.c      |  18 ++--\n net/sched/act_police.c     |  18 ++--\n net/sched/act_sample.c     |  17 ++-\n net/sched/act_simple.c     |  20 ++--\n net/sched/act_skbedit.c    |  18 ++--\n net/sched/act_skbmod.c     |  18 ++--\n net/sched/act_tunnel_key.c |  20 ++--\n net/sched/act_vlan.c       |  22 ++--\n 18 files changed, 279 insertions(+), 345 deletions(-)",
    "diff": "diff --git a/include/net/act_api.h b/include/net/act_api.h\nindex 26ffd83..8f3d5d8 100644\n--- a/include/net/act_api.h\n+++ b/include/net/act_api.h\n@@ -10,12 +10,9 @@\n #include <net/net_namespace.h>\n #include <net/netns/generic.h>\n \n-\n-struct tcf_hashinfo {\n-\tstruct hlist_head\t*htab;\n-\tunsigned int\t\thmask;\n-\tspinlock_t\t\tlock;\n-\tu32\t\t\tindex;\n+struct tcf_idrinfo {\n+\tspinlock_t\tlock;\n+\tstruct idr\taction_idr;\n };\n \n struct tc_action_ops;\n@@ -25,9 +22,8 @@ struct tc_action {\n \t__u32\t\t\t\ttype; /* for backward compat(TCA_OLD_COMPAT) */\n \t__u32\t\t\t\torder;\n \tstruct list_head\t\tlist;\n-\tstruct tcf_hashinfo\t\t*hinfo;\n+\tstruct tcf_idrinfo\t\t*idrinfo;\n \n-\tstruct hlist_node\t\ttcfa_head;\n \tu32\t\t\t\ttcfa_index;\n \tint\t\t\t\ttcfa_refcnt;\n \tint\t\t\t\ttcfa_bindcnt;\n@@ -44,7 +40,6 @@ struct tc_action {\n \tstruct tc_cookie\t*act_cookie;\n \tstruct tcf_chain\t*goto_chain;\n };\n-#define tcf_head\tcommon.tcfa_head\n #define tcf_index\tcommon.tcfa_index\n #define tcf_refcnt\tcommon.tcfa_refcnt\n #define tcf_bindcnt\tcommon.tcfa_bindcnt\n@@ -57,27 +52,6 @@ struct tc_action {\n #define tcf_lock\tcommon.tcfa_lock\n #define tcf_rcu\t\tcommon.tcfa_rcu\n \n-static inline unsigned int tcf_hash(u32 index, unsigned int hmask)\n-{\n-\treturn index & hmask;\n-}\n-\n-static inline int tcf_hashinfo_init(struct tcf_hashinfo *hf, unsigned int mask)\n-{\n-\tint i;\n-\n-\tspin_lock_init(&hf->lock);\n-\thf->index = 0;\n-\thf->hmask = mask;\n-\thf->htab = kzalloc((mask + 1) * sizeof(struct hlist_head),\n-\t\t\t   GFP_KERNEL);\n-\tif (!hf->htab)\n-\t\treturn -ENOMEM;\n-\tfor (i = 0; i < mask + 1; i++)\n-\t\tINIT_HLIST_HEAD(&hf->htab[i]);\n-\treturn 0;\n-}\n-\n /* Update lastuse only if needed, to avoid dirtying a cache line.\n  * We use a temp variable to avoid fetching jiffies twice.\n  */\n@@ -126,53 +100,51 @@ struct tc_action_ops {\n };\n \n struct tc_action_net {\n-\tstruct tcf_hashinfo *hinfo;\n+\tstruct tcf_idrinfo *idrinfo;\n \tconst struct tc_action_ops *ops;\n };\n \n static inline\n int tc_action_net_init(struct tc_action_net *tn,\n-\t\t       const struct tc_action_ops *ops, unsigned int mask)\n+\t\t       const struct tc_action_ops *ops)\n {\n \tint err = 0;\n \n-\ttn->hinfo = kmalloc(sizeof(*tn->hinfo), GFP_KERNEL);\n-\tif (!tn->hinfo)\n+\ttn->idrinfo = kmalloc(sizeof(*tn->idrinfo), GFP_KERNEL);\n+\tif (!tn->idrinfo)\n \t\treturn -ENOMEM;\n \ttn->ops = ops;\n-\terr = tcf_hashinfo_init(tn->hinfo, mask);\n-\tif (err)\n-\t\tkfree(tn->hinfo);\n+\tspin_lock_init(&tn->idrinfo->lock);\n+\tidr_init(&tn->idrinfo->action_idr);\n \treturn err;\n }\n \n-void tcf_hashinfo_destroy(const struct tc_action_ops *ops,\n-\t\t\t  struct tcf_hashinfo *hinfo);\n+void tcf_idrinfo_destroy(const struct tc_action_ops *ops,\n+\t\t\t struct tcf_idrinfo *idrinfo);\n \n static inline void tc_action_net_exit(struct tc_action_net *tn)\n {\n-\ttcf_hashinfo_destroy(tn->ops, tn->hinfo);\n-\tkfree(tn->hinfo);\n+\ttcf_idrinfo_destroy(tn->ops, tn->idrinfo);\n+\tkfree(tn->idrinfo);\n }\n \n int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb,\n \t\t       struct netlink_callback *cb, int type,\n \t\t       const struct tc_action_ops *ops);\n-int tcf_hash_search(struct tc_action_net *tn, struct tc_action **a, u32 index);\n-u32 tcf_hash_new_index(struct tc_action_net *tn);\n-bool tcf_hash_check(struct tc_action_net *tn, u32 index, struct tc_action **a,\n+int tcf_idr_search(struct tc_action_net *tn, struct tc_action **a, u32 index);\n+bool tcf_idr_check(struct tc_action_net *tn, u32 index, struct tc_action **a,\n \t\t    int bind);\n-int tcf_hash_create(struct tc_action_net *tn, u32 index, struct nlattr *est,\n-\t\t    struct tc_action **a, const struct tc_action_ops *ops, int bind,\n-\t\t    bool cpustats);\n-void tcf_hash_cleanup(struct tc_action *a, struct nlattr *est);\n-void tcf_hash_insert(struct tc_action_net *tn, struct tc_action *a);\n+int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est,\n+\t\t   struct tc_action **a, const struct tc_action_ops *ops,\n+\t\t   int bind, bool cpustats);\n+void tcf_idr_cleanup(struct tc_action *a, struct nlattr *est);\n+void tcf_idr_insert(struct tc_action_net *tn, struct tc_action *a);\n \n-int __tcf_hash_release(struct tc_action *a, bool bind, bool strict);\n+int __tcf_idr_release(struct tc_action *a, bool bind, bool strict);\n \n-static inline int tcf_hash_release(struct tc_action *a, bool bind)\n+static inline int tcf_idr_release(struct tc_action *a, bool bind)\n {\n-\treturn __tcf_hash_release(a, bind, false);\n+\treturn __tcf_idr_release(a, bind, false);\n }\n \n int tcf_register_action(struct tc_action_ops *a, struct pernet_operations *ops);\ndiff --git a/net/sched/act_api.c b/net/sched/act_api.c\nindex 02fcb0c..0eb545b 100644\n--- a/net/sched/act_api.c\n+++ b/net/sched/act_api.c\n@@ -70,11 +70,11 @@ static void free_tcf(struct rcu_head *head)\n \tkfree(p);\n }\n \n-static void tcf_hash_destroy(struct tcf_hashinfo *hinfo, struct tc_action *p)\n+static void tcf_idr_remove(struct tcf_idrinfo *idrinfo, struct tc_action *p)\n {\n-\tspin_lock_bh(&hinfo->lock);\n-\thlist_del(&p->tcfa_head);\n-\tspin_unlock_bh(&hinfo->lock);\n+\tspin_lock_bh(&idrinfo->lock);\n+\tidr_remove_ext(&idrinfo->action_idr, p->tcfa_index);\n+\tspin_unlock_bh(&idrinfo->lock);\n \tgen_kill_estimator(&p->tcfa_rate_est);\n \t/*\n \t * gen_estimator est_timer() might access p->tcfa_lock\n@@ -83,7 +83,7 @@ static void tcf_hash_destroy(struct tcf_hashinfo *hinfo, struct tc_action *p)\n \tcall_rcu(&p->tcfa_rcu, free_tcf);\n }\n \n-int __tcf_hash_release(struct tc_action *p, bool bind, bool strict)\n+int __tcf_idr_release(struct tc_action *p, bool bind, bool strict)\n {\n \tint ret = 0;\n \n@@ -97,64 +97,60 @@ int __tcf_hash_release(struct tc_action *p, bool bind, bool strict)\n \t\tif (p->tcfa_bindcnt <= 0 && p->tcfa_refcnt <= 0) {\n \t\t\tif (p->ops->cleanup)\n \t\t\t\tp->ops->cleanup(p, bind);\n-\t\t\ttcf_hash_destroy(p->hinfo, p);\n+\t\t\ttcf_idr_remove(p->idrinfo, p);\n \t\t\tret = ACT_P_DELETED;\n \t\t}\n \t}\n \n \treturn ret;\n }\n-EXPORT_SYMBOL(__tcf_hash_release);\n+EXPORT_SYMBOL(__tcf_idr_release);\n \n-static int tcf_dump_walker(struct tcf_hashinfo *hinfo, struct sk_buff *skb,\n+static int tcf_dump_walker(struct tcf_idrinfo *idrinfo, struct sk_buff *skb,\n \t\t\t   struct netlink_callback *cb)\n {\n-\tint err = 0, index = -1, i = 0, s_i = 0, n_i = 0;\n+\tint err = 0, index = -1, s_i = 0, n_i = 0;\n \tu32 act_flags = cb->args[2];\n \tunsigned long jiffy_since = cb->args[3];\n \tstruct nlattr *nest;\n+\tstruct idr *idr = &idrinfo->action_idr;\n+\tstruct tc_action *p;\n+\tunsigned long id = 1;\n \n-\tspin_lock_bh(&hinfo->lock);\n+\tspin_lock_bh(&idrinfo->lock);\n \n \ts_i = cb->args[0];\n \n-\tfor (i = 0; i < (hinfo->hmask + 1); i++) {\n-\t\tstruct hlist_head *head;\n-\t\tstruct tc_action *p;\n-\n-\t\thead = &hinfo->htab[tcf_hash(i, hinfo->hmask)];\n-\n-\t\thlist_for_each_entry_rcu(p, head, tcfa_head) {\n-\t\t\tindex++;\n-\t\t\tif (index < s_i)\n-\t\t\t\tcontinue;\n-\n-\t\t\tif (jiffy_since &&\n-\t\t\t    time_after(jiffy_since,\n-\t\t\t\t       (unsigned long)p->tcfa_tm.lastuse))\n-\t\t\t\tcontinue;\n-\n-\t\t\tnest = nla_nest_start(skb, n_i);\n-\t\t\tif (nest == NULL)\n-\t\t\t\tgoto nla_put_failure;\n-\t\t\terr = tcf_action_dump_1(skb, p, 0, 0);\n-\t\t\tif (err < 0) {\n-\t\t\t\tindex--;\n-\t\t\t\tnlmsg_trim(skb, nest);\n-\t\t\t\tgoto done;\n-\t\t\t}\n-\t\t\tnla_nest_end(skb, nest);\n-\t\t\tn_i++;\n-\t\t\tif (!(act_flags & TCA_FLAG_LARGE_DUMP_ON) &&\n-\t\t\t    n_i >= TCA_ACT_MAX_PRIO)\n-\t\t\t\tgoto done;\n+\tidr_for_each_entry_ext(idr, p, id) {\n+\t\tindex++;\n+\t\tif (index < s_i)\n+\t\t\tcontinue;\n+\n+\t\tif (jiffy_since &&\n+\t\t    time_after(jiffy_since,\n+\t\t\t       (unsigned long)p->tcfa_tm.lastuse))\n+\t\t\tcontinue;\n+\n+\t\tnest = nla_nest_start(skb, n_i);\n+\t\tif (!nest)\n+\t\t\tgoto nla_put_failure;\n+\t\terr = tcf_action_dump_1(skb, p, 0, 0);\n+\t\tif (err < 0) {\n+\t\t\tindex--;\n+\t\t\tnlmsg_trim(skb, nest);\n+\t\t\tgoto done;\n \t\t}\n+\t\tnla_nest_end(skb, nest);\n+\t\tn_i++;\n+\t\tif (!(act_flags & TCA_FLAG_LARGE_DUMP_ON) &&\n+\t\t    n_i >= TCA_ACT_MAX_PRIO)\n+\t\t\tgoto done;\n \t}\n done:\n \tif (index >= 0)\n \t\tcb->args[0] = index + 1;\n \n-\tspin_unlock_bh(&hinfo->lock);\n+\tspin_unlock_bh(&idrinfo->lock);\n \tif (n_i) {\n \t\tif (act_flags & TCA_FLAG_LARGE_DUMP_ON)\n \t\t\tcb->args[1] = n_i;\n@@ -166,31 +162,29 @@ static int tcf_dump_walker(struct tcf_hashinfo *hinfo, struct sk_buff *skb,\n \tgoto done;\n }\n \n-static int tcf_del_walker(struct tcf_hashinfo *hinfo, struct sk_buff *skb,\n+static int tcf_del_walker(struct tcf_idrinfo *idrinfo, struct sk_buff *skb,\n \t\t\t  const struct tc_action_ops *ops)\n {\n \tstruct nlattr *nest;\n-\tint i = 0, n_i = 0;\n+\tint n_i = 0;\n \tint ret = -EINVAL;\n+\tstruct idr *idr = &idrinfo->action_idr;\n+\tstruct tc_action *p;\n+\tunsigned long id = 1;\n \n \tnest = nla_nest_start(skb, 0);\n \tif (nest == NULL)\n \t\tgoto nla_put_failure;\n \tif (nla_put_string(skb, TCA_KIND, ops->kind))\n \t\tgoto nla_put_failure;\n-\tfor (i = 0; i < (hinfo->hmask + 1); i++) {\n-\t\tstruct hlist_head *head;\n-\t\tstruct hlist_node *n;\n-\t\tstruct tc_action *p;\n-\n-\t\thead = &hinfo->htab[tcf_hash(i, hinfo->hmask)];\n-\t\thlist_for_each_entry_safe(p, n, head, tcfa_head) {\n-\t\t\tret = __tcf_hash_release(p, false, true);\n-\t\t\tif (ret == ACT_P_DELETED) {\n-\t\t\t\tmodule_put(p->ops->owner);\n-\t\t\t\tn_i++;\n-\t\t\t} else if (ret < 0)\n-\t\t\t\tgoto nla_put_failure;\n+\n+\tidr_for_each_entry_ext(idr, p, id) {\n+\t\tret = __tcf_idr_release(p, false, true);\n+\t\tif (ret == ACT_P_DELETED) {\n+\t\t\tmodule_put(p->ops->owner);\n+\t\t\tn_i++;\n+\t\t} else if (ret < 0) {\n+\t\t\tgoto nla_put_failure;\n \t\t}\n \t}\n \tif (nla_put_u32(skb, TCA_FCNT, n_i))\n@@ -207,12 +201,12 @@ int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb,\n \t\t       struct netlink_callback *cb, int type,\n \t\t       const struct tc_action_ops *ops)\n {\n-\tstruct tcf_hashinfo *hinfo = tn->hinfo;\n+\tstruct tcf_idrinfo *idrinfo = tn->idrinfo;\n \n \tif (type == RTM_DELACTION) {\n-\t\treturn tcf_del_walker(hinfo, skb, ops);\n+\t\treturn tcf_del_walker(idrinfo, skb, ops);\n \t} else if (type == RTM_GETACTION) {\n-\t\treturn tcf_dump_walker(hinfo, skb, cb);\n+\t\treturn tcf_dump_walker(idrinfo, skb, cb);\n \t} else {\n \t\tWARN(1, \"tcf_generic_walker: unknown action %d\\n\", type);\n \t\treturn -EINVAL;\n@@ -220,40 +214,21 @@ int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb,\n }\n EXPORT_SYMBOL(tcf_generic_walker);\n \n-static struct tc_action *tcf_hash_lookup(u32 index, struct tcf_hashinfo *hinfo)\n+static struct tc_action *tcf_idr_lookup(u32 index, struct tcf_idrinfo *idrinfo)\n {\n \tstruct tc_action *p = NULL;\n-\tstruct hlist_head *head;\n \n-\tspin_lock_bh(&hinfo->lock);\n-\thead = &hinfo->htab[tcf_hash(index, hinfo->hmask)];\n-\thlist_for_each_entry_rcu(p, head, tcfa_head)\n-\t\tif (p->tcfa_index == index)\n-\t\t\tbreak;\n-\tspin_unlock_bh(&hinfo->lock);\n+\tspin_lock_bh(&idrinfo->lock);\n+\tp = idr_find_ext(&idrinfo->action_idr, index);\n+\tspin_unlock_bh(&idrinfo->lock);\n \n \treturn p;\n }\n \n-u32 tcf_hash_new_index(struct tc_action_net *tn)\n-{\n-\tstruct tcf_hashinfo *hinfo = tn->hinfo;\n-\tu32 val = hinfo->index;\n-\n-\tdo {\n-\t\tif (++val == 0)\n-\t\t\tval = 1;\n-\t} while (tcf_hash_lookup(val, hinfo));\n-\n-\thinfo->index = val;\n-\treturn val;\n-}\n-EXPORT_SYMBOL(tcf_hash_new_index);\n-\n-int tcf_hash_search(struct tc_action_net *tn, struct tc_action **a, u32 index)\n+int tcf_idr_search(struct tc_action_net *tn, struct tc_action **a, u32 index)\n {\n-\tstruct tcf_hashinfo *hinfo = tn->hinfo;\n-\tstruct tc_action *p = tcf_hash_lookup(index, hinfo);\n+\tstruct tcf_idrinfo *idrinfo = tn->idrinfo;\n+\tstruct tc_action *p = tcf_idr_lookup(index, idrinfo);\n \n \tif (p) {\n \t\t*a = p;\n@@ -261,15 +236,15 @@ int tcf_hash_search(struct tc_action_net *tn, struct tc_action **a, u32 index)\n \t}\n \treturn 0;\n }\n-EXPORT_SYMBOL(tcf_hash_search);\n+EXPORT_SYMBOL(tcf_idr_search);\n \n-bool tcf_hash_check(struct tc_action_net *tn, u32 index, struct tc_action **a,\n-\t\t    int bind)\n+bool tcf_idr_check(struct tc_action_net *tn, u32 index, struct tc_action **a,\n+\t\t   int bind)\n {\n-\tstruct tcf_hashinfo *hinfo = tn->hinfo;\n-\tstruct tc_action *p = NULL;\n+\tstruct tcf_idrinfo *idrinfo = tn->idrinfo;\n+\tstruct tc_action *p = tcf_idr_lookup(index, idrinfo);\n \n-\tif (index && (p = tcf_hash_lookup(index, hinfo)) != NULL) {\n+\tif (index && p) {\n \t\tif (bind)\n \t\t\tp->tcfa_bindcnt++;\n \t\tp->tcfa_refcnt++;\n@@ -278,23 +253,25 @@ bool tcf_hash_check(struct tc_action_net *tn, u32 index, struct tc_action **a,\n \t}\n \treturn false;\n }\n-EXPORT_SYMBOL(tcf_hash_check);\n+EXPORT_SYMBOL(tcf_idr_check);\n \n-void tcf_hash_cleanup(struct tc_action *a, struct nlattr *est)\n+void tcf_idr_cleanup(struct tc_action *a, struct nlattr *est)\n {\n \tif (est)\n \t\tgen_kill_estimator(&a->tcfa_rate_est);\n \tcall_rcu(&a->tcfa_rcu, free_tcf);\n }\n-EXPORT_SYMBOL(tcf_hash_cleanup);\n+EXPORT_SYMBOL(tcf_idr_cleanup);\n \n-int tcf_hash_create(struct tc_action_net *tn, u32 index, struct nlattr *est,\n-\t\t    struct tc_action **a, const struct tc_action_ops *ops,\n-\t\t    int bind, bool cpustats)\n+int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est,\n+\t\t   struct tc_action **a, const struct tc_action_ops *ops,\n+\t\t   int bind, bool cpustats)\n {\n \tstruct tc_action *p = kzalloc(ops->size, GFP_KERNEL);\n-\tstruct tcf_hashinfo *hinfo = tn->hinfo;\n+\tstruct tcf_idrinfo *idrinfo = tn->idrinfo;\n+\tstruct idr *idr = &idrinfo->action_idr;\n \tint err = -ENOMEM;\n+\tunsigned long idr_index;\n \n \tif (unlikely(!p))\n \t\treturn -ENOMEM;\n@@ -317,8 +294,28 @@ int tcf_hash_create(struct tc_action_net *tn, u32 index, struct nlattr *est,\n \t\t}\n \t}\n \tspin_lock_init(&p->tcfa_lock);\n-\tINIT_HLIST_NODE(&p->tcfa_head);\n-\tp->tcfa_index = index ? index : tcf_hash_new_index(tn);\n+\t/* user doesn't specify an index */\n+\tif (!index) {\n+\t\tspin_lock_bh(&idrinfo->lock);\n+\t\terr = idr_alloc_ext(idr, NULL, &idr_index, 1, 0,\n+\t\t\t\t    GFP_KERNEL);\n+\t\tspin_unlock_bh(&idrinfo->lock);\n+\t\tif (err) {\n+err3:\n+\t\t\tfree_percpu(p->cpu_qstats);\n+\t\t\tgoto err2;\n+\t\t}\n+\t\tp->tcfa_index = idr_index;\n+\t} else {\n+\t\tspin_lock_bh(&idrinfo->lock);\n+\t\terr = idr_alloc_ext(idr, NULL, NULL, index, index + 1,\n+\t\t\t\t    GFP_KERNEL);\n+\t\tspin_unlock_bh(&idrinfo->lock);\n+\t\tif (err)\n+\t\t\tgoto err3;\n+\t\tp->tcfa_index = index;\n+\t}\n+\n \tp->tcfa_tm.install = jiffies;\n \tp->tcfa_tm.lastuse = jiffies;\n \tp->tcfa_tm.firstuse = 0;\n@@ -327,52 +324,46 @@ int tcf_hash_create(struct tc_action_net *tn, u32 index, struct nlattr *est,\n \t\t\t\t\t&p->tcfa_rate_est,\n \t\t\t\t\t&p->tcfa_lock, NULL, est);\n \t\tif (err) {\n-\t\t\tfree_percpu(p->cpu_qstats);\n-\t\t\tgoto err2;\n+\t\t\tgoto err3;\n \t\t}\n \t}\n \n-\tp->hinfo = hinfo;\n+\tp->idrinfo = idrinfo;\n \tp->ops = ops;\n \tINIT_LIST_HEAD(&p->list);\n \t*a = p;\n \treturn 0;\n }\n-EXPORT_SYMBOL(tcf_hash_create);\n+EXPORT_SYMBOL(tcf_idr_create);\n \n-void tcf_hash_insert(struct tc_action_net *tn, struct tc_action *a)\n+void tcf_idr_insert(struct tc_action_net *tn, struct tc_action *a)\n {\n-\tstruct tcf_hashinfo *hinfo = tn->hinfo;\n-\tunsigned int h = tcf_hash(a->tcfa_index, hinfo->hmask);\n+\tstruct tcf_idrinfo *idrinfo = tn->idrinfo;\n \n-\tspin_lock_bh(&hinfo->lock);\n-\thlist_add_head(&a->tcfa_head, &hinfo->htab[h]);\n-\tspin_unlock_bh(&hinfo->lock);\n+\tspin_lock_bh(&idrinfo->lock);\n+\tidr_replace_ext(&idrinfo->action_idr, a, a->tcfa_index);\n+\tspin_unlock_bh(&idrinfo->lock);\n }\n-EXPORT_SYMBOL(tcf_hash_insert);\n+EXPORT_SYMBOL(tcf_idr_insert);\n \n-void tcf_hashinfo_destroy(const struct tc_action_ops *ops,\n-\t\t\t  struct tcf_hashinfo *hinfo)\n+void tcf_idrinfo_destroy(const struct tc_action_ops *ops,\n+\t\t\t struct tcf_idrinfo *idrinfo)\n {\n-\tint i;\n-\n-\tfor (i = 0; i < hinfo->hmask + 1; i++) {\n-\t\tstruct tc_action *p;\n-\t\tstruct hlist_node *n;\n-\n-\t\thlist_for_each_entry_safe(p, n, &hinfo->htab[i], tcfa_head) {\n-\t\t\tint ret;\n+\tstruct idr *idr = &idrinfo->action_idr;\n+\tstruct tc_action *p;\n+\tint ret;\n+\tunsigned long id = 1;\n \n-\t\t\tret = __tcf_hash_release(p, false, true);\n-\t\t\tif (ret == ACT_P_DELETED)\n-\t\t\t\tmodule_put(ops->owner);\n-\t\t\telse if (ret < 0)\n-\t\t\t\treturn;\n-\t\t}\n+\tidr_for_each_entry_ext(idr, p, id) {\n+\t\tret = __tcf_idr_release(p, false, true);\n+\t\tif (ret == ACT_P_DELETED)\n+\t\t\tmodule_put(ops->owner);\n+\t\telse if (ret < 0)\n+\t\t\treturn;\n \t}\n-\tkfree(hinfo->htab);\n+\tidr_destroy(&idrinfo->action_idr);\n }\n-EXPORT_SYMBOL(tcf_hashinfo_destroy);\n+EXPORT_SYMBOL(tcf_idrinfo_destroy);\n \n static LIST_HEAD(act_base);\n static DEFINE_RWLOCK(act_mod_lock);\n@@ -524,7 +515,7 @@ int tcf_action_destroy(struct list_head *actions, int bind)\n \tint ret = 0;\n \n \tlist_for_each_entry_safe(a, tmp, actions, list) {\n-\t\tret = __tcf_hash_release(a, bind, true);\n+\t\tret = __tcf_idr_release(a, bind, true);\n \t\tif (ret == ACT_P_DELETED)\n \t\t\tmodule_put(a->ops->owner);\n \t\telse if (ret < 0)\ndiff --git a/net/sched/act_bpf.c b/net/sched/act_bpf.c\nindex 9afe133..c0c707e 100644\n--- a/net/sched/act_bpf.c\n+++ b/net/sched/act_bpf.c\n@@ -21,7 +21,6 @@\n #include <linux/tc_act/tc_bpf.h>\n #include <net/tc_act/tc_bpf.h>\n \n-#define BPF_TAB_MASK\t\t15\n #define ACT_BPF_NAME_LEN\t256\n \n struct tcf_bpf_cfg {\n@@ -295,9 +294,9 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla,\n \n \tparm = nla_data(tb[TCA_ACT_BPF_PARMS]);\n \n-\tif (!tcf_hash_check(tn, parm->index, act, bind)) {\n-\t\tret = tcf_hash_create(tn, parm->index, est, act,\n-\t\t\t\t      &act_bpf_ops, bind, true);\n+\tif (!tcf_idr_check(tn, parm->index, act, bind)) {\n+\t\tret = tcf_idr_create(tn, parm->index, est, act,\n+\t\t\t\t     &act_bpf_ops, bind, true);\n \t\tif (ret < 0)\n \t\t\treturn ret;\n \n@@ -307,7 +306,7 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla,\n \t\tif (bind)\n \t\t\treturn 0;\n \n-\t\ttcf_hash_release(*act, bind);\n+\t\ttcf_idr_release(*act, bind);\n \t\tif (!replace)\n \t\t\treturn -EEXIST;\n \t}\n@@ -343,7 +342,7 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla,\n \trcu_assign_pointer(prog->filter, cfg.filter);\n \n \tif (res == ACT_P_CREATED) {\n-\t\ttcf_hash_insert(tn, *act);\n+\t\ttcf_idr_insert(tn, *act);\n \t} else {\n \t\t/* make sure the program being replaced is no longer executing */\n \t\tsynchronize_rcu();\n@@ -353,7 +352,7 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla,\n \treturn res;\n out:\n \tif (res == ACT_P_CREATED)\n-\t\ttcf_hash_cleanup(*act, est);\n+\t\ttcf_idr_cleanup(*act, est);\n \n \treturn ret;\n }\n@@ -379,7 +378,7 @@ static int tcf_bpf_search(struct net *net, struct tc_action **a, u32 index)\n {\n \tstruct tc_action_net *tn = net_generic(net, bpf_net_id);\n \n-\treturn tcf_hash_search(tn, a, index);\n+\treturn tcf_idr_search(tn, a, index);\n }\n \n static struct tc_action_ops act_bpf_ops __read_mostly = {\n@@ -399,7 +398,7 @@ static __net_init int bpf_init_net(struct net *net)\n {\n \tstruct tc_action_net *tn = net_generic(net, bpf_net_id);\n \n-\treturn tc_action_net_init(tn, &act_bpf_ops, BPF_TAB_MASK);\n+\treturn tc_action_net_init(tn, &act_bpf_ops);\n }\n \n static void __net_exit bpf_exit_net(struct net *net)\ndiff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c\nindex 2155bc6..10b7a88 100644\n--- a/net/sched/act_connmark.c\n+++ b/net/sched/act_connmark.c\n@@ -28,8 +28,6 @@\n #include <net/netfilter/nf_conntrack_core.h>\n #include <net/netfilter/nf_conntrack_zones.h>\n \n-#define CONNMARK_TAB_MASK     3\n-\n static unsigned int connmark_net_id;\n static struct tc_action_ops act_connmark_ops;\n \n@@ -119,9 +117,9 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla,\n \n \tparm = nla_data(tb[TCA_CONNMARK_PARMS]);\n \n-\tif (!tcf_hash_check(tn, parm->index, a, bind)) {\n-\t\tret = tcf_hash_create(tn, parm->index, est, a,\n-\t\t\t\t      &act_connmark_ops, bind, false);\n+\tif (!tcf_idr_check(tn, parm->index, a, bind)) {\n+\t\tret = tcf_idr_create(tn, parm->index, est, a,\n+\t\t\t\t     &act_connmark_ops, bind, false);\n \t\tif (ret)\n \t\t\treturn ret;\n \n@@ -130,13 +128,13 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla,\n \t\tci->net = net;\n \t\tci->zone = parm->zone;\n \n-\t\ttcf_hash_insert(tn, *a);\n+\t\ttcf_idr_insert(tn, *a);\n \t\tret = ACT_P_CREATED;\n \t} else {\n \t\tci = to_connmark(*a);\n \t\tif (bind)\n \t\t\treturn 0;\n-\t\ttcf_hash_release(*a, bind);\n+\t\ttcf_idr_release(*a, bind);\n \t\tif (!ovr)\n \t\t\treturn -EEXIST;\n \t\t/* replacing action and zone */\n@@ -189,7 +187,7 @@ static int tcf_connmark_search(struct net *net, struct tc_action **a, u32 index)\n {\n \tstruct tc_action_net *tn = net_generic(net, connmark_net_id);\n \n-\treturn tcf_hash_search(tn, a, index);\n+\treturn tcf_idr_search(tn, a, index);\n }\n \n static struct tc_action_ops act_connmark_ops = {\n@@ -208,7 +206,7 @@ static __net_init int connmark_init_net(struct net *net)\n {\n \tstruct tc_action_net *tn = net_generic(net, connmark_net_id);\n \n-\treturn tc_action_net_init(tn, &act_connmark_ops, CONNMARK_TAB_MASK);\n+\treturn tc_action_net_init(tn, &act_connmark_ops);\n }\n \n static void __net_exit connmark_exit_net(struct net *net)\ndiff --git a/net/sched/act_csum.c b/net/sched/act_csum.c\nindex 67afc12..1c40caa 100644\n--- a/net/sched/act_csum.c\n+++ b/net/sched/act_csum.c\n@@ -37,8 +37,6 @@\n #include <linux/tc_act/tc_csum.h>\n #include <net/tc_act/tc_csum.h>\n \n-#define CSUM_TAB_MASK 15\n-\n static const struct nla_policy csum_policy[TCA_CSUM_MAX + 1] = {\n \t[TCA_CSUM_PARMS] = { .len = sizeof(struct tc_csum), },\n };\n@@ -67,16 +65,16 @@ static int tcf_csum_init(struct net *net, struct nlattr *nla,\n \t\treturn -EINVAL;\n \tparm = nla_data(tb[TCA_CSUM_PARMS]);\n \n-\tif (!tcf_hash_check(tn, parm->index, a, bind)) {\n-\t\tret = tcf_hash_create(tn, parm->index, est, a,\n-\t\t\t\t      &act_csum_ops, bind, false);\n+\tif (!tcf_idr_check(tn, parm->index, a, bind)) {\n+\t\tret = tcf_idr_create(tn, parm->index, est, a,\n+\t\t\t\t     &act_csum_ops, bind, false);\n \t\tif (ret)\n \t\t\treturn ret;\n \t\tret = ACT_P_CREATED;\n \t} else {\n \t\tif (bind)/* dont override defaults */\n \t\t\treturn 0;\n-\t\ttcf_hash_release(*a, bind);\n+\t\ttcf_idr_release(*a, bind);\n \t\tif (!ovr)\n \t\t\treturn -EEXIST;\n \t}\n@@ -88,7 +86,7 @@ static int tcf_csum_init(struct net *net, struct nlattr *nla,\n \tspin_unlock_bh(&p->tcf_lock);\n \n \tif (ret == ACT_P_CREATED)\n-\t\ttcf_hash_insert(tn, *a);\n+\t\ttcf_idr_insert(tn, *a);\n \n \treturn ret;\n }\n@@ -609,7 +607,7 @@ static int tcf_csum_search(struct net *net, struct tc_action **a, u32 index)\n {\n \tstruct tc_action_net *tn = net_generic(net, csum_net_id);\n \n-\treturn tcf_hash_search(tn, a, index);\n+\treturn tcf_idr_search(tn, a, index);\n }\n \n static struct tc_action_ops act_csum_ops = {\n@@ -628,7 +626,7 @@ static __net_init int csum_init_net(struct net *net)\n {\n \tstruct tc_action_net *tn = net_generic(net, csum_net_id);\n \n-\treturn tc_action_net_init(tn, &act_csum_ops, CSUM_TAB_MASK);\n+\treturn tc_action_net_init(tn, &act_csum_ops);\n }\n \n static void __net_exit csum_exit_net(struct net *net)\ndiff --git a/net/sched/act_gact.c b/net/sched/act_gact.c\nindex 99afe8b..e29a48e 100644\n--- a/net/sched/act_gact.c\n+++ b/net/sched/act_gact.c\n@@ -23,8 +23,6 @@\n #include <linux/tc_act/tc_gact.h>\n #include <net/tc_act/tc_gact.h>\n \n-#define GACT_TAB_MASK\t15\n-\n static unsigned int gact_net_id;\n static struct tc_action_ops act_gact_ops;\n \n@@ -92,16 +90,16 @@ static int tcf_gact_init(struct net *net, struct nlattr *nla,\n \t}\n #endif\n \n-\tif (!tcf_hash_check(tn, parm->index, a, bind)) {\n-\t\tret = tcf_hash_create(tn, parm->index, est, a,\n-\t\t\t\t      &act_gact_ops, bind, true);\n+\tif (!tcf_idr_check(tn, parm->index, a, bind)) {\n+\t\tret = tcf_idr_create(tn, parm->index, est, a,\n+\t\t\t\t     &act_gact_ops, bind, true);\n \t\tif (ret)\n \t\t\treturn ret;\n \t\tret = ACT_P_CREATED;\n \t} else {\n \t\tif (bind)/* dont override defaults */\n \t\t\treturn 0;\n-\t\ttcf_hash_release(*a, bind);\n+\t\ttcf_idr_release(*a, bind);\n \t\tif (!ovr)\n \t\t\treturn -EEXIST;\n \t}\n@@ -122,7 +120,7 @@ static int tcf_gact_init(struct net *net, struct nlattr *nla,\n \t}\n #endif\n \tif (ret == ACT_P_CREATED)\n-\t\ttcf_hash_insert(tn, *a);\n+\t\ttcf_idr_insert(tn, *a);\n \treturn ret;\n }\n \n@@ -214,7 +212,7 @@ static int tcf_gact_search(struct net *net, struct tc_action **a, u32 index)\n {\n \tstruct tc_action_net *tn = net_generic(net, gact_net_id);\n \n-\treturn tcf_hash_search(tn, a, index);\n+\treturn tcf_idr_search(tn, a, index);\n }\n \n static struct tc_action_ops act_gact_ops = {\n@@ -234,7 +232,7 @@ static __net_init int gact_init_net(struct net *net)\n {\n \tstruct tc_action_net *tn = net_generic(net, gact_net_id);\n \n-\treturn tc_action_net_init(tn, &act_gact_ops, GACT_TAB_MASK);\n+\treturn tc_action_net_init(tn, &act_gact_ops);\n }\n \n static void __net_exit gact_exit_net(struct net *net)\ndiff --git a/net/sched/act_ife.c b/net/sched/act_ife.c\nindex c5dec30..770c5d9 100644\n--- a/net/sched/act_ife.c\n+++ b/net/sched/act_ife.c\n@@ -34,8 +34,6 @@\n #include <linux/etherdevice.h>\n #include <net/ife.h>\n \n-#define IFE_TAB_MASK 15\n-\n static unsigned int ife_net_id;\n static int max_metacnt = IFE_META_MAX + 1;\n static struct tc_action_ops act_ife_ops;\n@@ -452,7 +450,7 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla,\n \n \tparm = nla_data(tb[TCA_IFE_PARMS]);\n \n-\texists = tcf_hash_check(tn, parm->index, a, bind);\n+\texists = tcf_idr_check(tn, parm->index, a, bind);\n \tif (exists && bind)\n \t\treturn 0;\n \n@@ -462,20 +460,20 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla,\n \t\t**/\n \t\tif (!tb[TCA_IFE_TYPE]) {\n \t\t\tif (exists)\n-\t\t\t\ttcf_hash_release(*a, bind);\n+\t\t\t\ttcf_idr_release(*a, bind);\n \t\t\tpr_info(\"You MUST pass etherype for encoding\\n\");\n \t\t\treturn -EINVAL;\n \t\t}\n \t}\n \n \tif (!exists) {\n-\t\tret = tcf_hash_create(tn, parm->index, est, a, &act_ife_ops,\n-\t\t\t\t      bind, false);\n+\t\tret = tcf_idr_create(tn, parm->index, est, a, &act_ife_ops,\n+\t\t\t\t     bind, false);\n \t\tif (ret)\n \t\t\treturn ret;\n \t\tret = ACT_P_CREATED;\n \t} else {\n-\t\ttcf_hash_release(*a, bind);\n+\t\ttcf_idr_release(*a, bind);\n \t\tif (!ovr)\n \t\t\treturn -EEXIST;\n \t}\n@@ -518,7 +516,7 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla,\n \t\tif (err) {\n metadata_parse_err:\n \t\t\tif (exists)\n-\t\t\t\ttcf_hash_release(*a, bind);\n+\t\t\t\ttcf_idr_release(*a, bind);\n \t\t\tif (ret == ACT_P_CREATED)\n \t\t\t\t_tcf_ife_cleanup(*a, bind);\n \n@@ -552,7 +550,7 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla,\n \t\tspin_unlock_bh(&ife->tcf_lock);\n \n \tif (ret == ACT_P_CREATED)\n-\t\ttcf_hash_insert(tn, *a);\n+\t\ttcf_idr_insert(tn, *a);\n \n \treturn ret;\n }\n@@ -811,7 +809,7 @@ static int tcf_ife_search(struct net *net, struct tc_action **a, u32 index)\n {\n \tstruct tc_action_net *tn = net_generic(net, ife_net_id);\n \n-\treturn tcf_hash_search(tn, a, index);\n+\treturn tcf_idr_search(tn, a, index);\n }\n \n static struct tc_action_ops act_ife_ops = {\n@@ -831,7 +829,7 @@ static __net_init int ife_init_net(struct net *net)\n {\n \tstruct tc_action_net *tn = net_generic(net, ife_net_id);\n \n-\treturn tc_action_net_init(tn, &act_ife_ops, IFE_TAB_MASK);\n+\treturn tc_action_net_init(tn, &act_ife_ops);\n }\n \n static void __net_exit ife_exit_net(struct net *net)\ndiff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c\nindex 5417078..d9e399a 100644\n--- a/net/sched/act_ipt.c\n+++ b/net/sched/act_ipt.c\n@@ -28,8 +28,6 @@\n #include <linux/netfilter_ipv4/ip_tables.h>\n \n \n-#define IPT_TAB_MASK     15\n-\n static unsigned int ipt_net_id;\n static struct tc_action_ops act_ipt_ops;\n \n@@ -118,33 +116,33 @@ static int __tcf_ipt_init(struct net *net, unsigned int id, struct nlattr *nla,\n \tif (tb[TCA_IPT_INDEX] != NULL)\n \t\tindex = nla_get_u32(tb[TCA_IPT_INDEX]);\n \n-\texists = tcf_hash_check(tn, index, a, bind);\n+\texists = tcf_idr_check(tn, index, a, bind);\n \tif (exists && bind)\n \t\treturn 0;\n \n \tif (tb[TCA_IPT_HOOK] == NULL || tb[TCA_IPT_TARG] == NULL) {\n \t\tif (exists)\n-\t\t\ttcf_hash_release(*a, bind);\n+\t\t\ttcf_idr_release(*a, bind);\n \t\treturn -EINVAL;\n \t}\n \n \ttd = (struct xt_entry_target *)nla_data(tb[TCA_IPT_TARG]);\n \tif (nla_len(tb[TCA_IPT_TARG]) < td->u.target_size) {\n \t\tif (exists)\n-\t\t\ttcf_hash_release(*a, bind);\n+\t\t\ttcf_idr_release(*a, bind);\n \t\treturn -EINVAL;\n \t}\n \n \tif (!exists) {\n-\t\tret = tcf_hash_create(tn, index, est, a, ops, bind,\n-\t\t\t\t      false);\n+\t\tret = tcf_idr_create(tn, index, est, a, ops, bind,\n+\t\t\t\t     false);\n \t\tif (ret)\n \t\t\treturn ret;\n \t\tret = ACT_P_CREATED;\n \t} else {\n \t\tif (bind)/* dont override defaults */\n \t\t\treturn 0;\n-\t\ttcf_hash_release(*a, bind);\n+\t\ttcf_idr_release(*a, bind);\n \n \t\tif (!ovr)\n \t\t\treturn -EEXIST;\n@@ -180,7 +178,7 @@ static int __tcf_ipt_init(struct net *net, unsigned int id, struct nlattr *nla,\n \tipt->tcfi_hook  = hook;\n \tspin_unlock_bh(&ipt->tcf_lock);\n \tif (ret == ACT_P_CREATED)\n-\t\ttcf_hash_insert(tn, *a);\n+\t\ttcf_idr_insert(tn, *a);\n \treturn ret;\n \n err3:\n@@ -189,7 +187,7 @@ static int __tcf_ipt_init(struct net *net, unsigned int id, struct nlattr *nla,\n \tkfree(tname);\n err1:\n \tif (ret == ACT_P_CREATED)\n-\t\ttcf_hash_cleanup(*a, est);\n+\t\ttcf_idr_cleanup(*a, est);\n \treturn err;\n }\n \n@@ -316,7 +314,7 @@ static int tcf_ipt_search(struct net *net, struct tc_action **a, u32 index)\n {\n \tstruct tc_action_net *tn = net_generic(net, ipt_net_id);\n \n-\treturn tcf_hash_search(tn, a, index);\n+\treturn tcf_idr_search(tn, a, index);\n }\n \n static struct tc_action_ops act_ipt_ops = {\n@@ -336,7 +334,7 @@ static __net_init int ipt_init_net(struct net *net)\n {\n \tstruct tc_action_net *tn = net_generic(net, ipt_net_id);\n \n-\treturn tc_action_net_init(tn, &act_ipt_ops, IPT_TAB_MASK);\n+\treturn tc_action_net_init(tn, &act_ipt_ops);\n }\n \n static void __net_exit ipt_exit_net(struct net *net)\n@@ -366,7 +364,7 @@ static int tcf_xt_search(struct net *net, struct tc_action **a, u32 index)\n {\n \tstruct tc_action_net *tn = net_generic(net, xt_net_id);\n \n-\treturn tcf_hash_search(tn, a, index);\n+\treturn tcf_idr_search(tn, a, index);\n }\n \n static struct tc_action_ops act_xt_ops = {\n@@ -386,7 +384,7 @@ static __net_init int xt_init_net(struct net *net)\n {\n \tstruct tc_action_net *tn = net_generic(net, xt_net_id);\n \n-\treturn tc_action_net_init(tn, &act_xt_ops, IPT_TAB_MASK);\n+\treturn tc_action_net_init(tn, &act_xt_ops);\n }\n \n static void __net_exit xt_exit_net(struct net *net)\ndiff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c\nindex 1b5549a..416627c 100644\n--- a/net/sched/act_mirred.c\n+++ b/net/sched/act_mirred.c\n@@ -28,7 +28,6 @@\n #include <linux/tc_act/tc_mirred.h>\n #include <net/tc_act/tc_mirred.h>\n \n-#define MIRRED_TAB_MASK     7\n static LIST_HEAD(mirred_list);\n static DEFINE_SPINLOCK(mirred_list_lock);\n \n@@ -94,7 +93,7 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,\n \t\treturn -EINVAL;\n \tparm = nla_data(tb[TCA_MIRRED_PARMS]);\n \n-\texists = tcf_hash_check(tn, parm->index, a, bind);\n+\texists = tcf_idr_check(tn, parm->index, a, bind);\n \tif (exists && bind)\n \t\treturn 0;\n \n@@ -106,14 +105,14 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,\n \t\tbreak;\n \tdefault:\n \t\tif (exists)\n-\t\t\ttcf_hash_release(*a, bind);\n+\t\t\ttcf_idr_release(*a, bind);\n \t\treturn -EINVAL;\n \t}\n \tif (parm->ifindex) {\n \t\tdev = __dev_get_by_index(net, parm->ifindex);\n \t\tif (dev == NULL) {\n \t\t\tif (exists)\n-\t\t\t\ttcf_hash_release(*a, bind);\n+\t\t\t\ttcf_idr_release(*a, bind);\n \t\t\treturn -ENODEV;\n \t\t}\n \t\tmac_header_xmit = dev_is_mac_header_xmit(dev);\n@@ -124,13 +123,13 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,\n \tif (!exists) {\n \t\tif (dev == NULL)\n \t\t\treturn -EINVAL;\n-\t\tret = tcf_hash_create(tn, parm->index, est, a,\n-\t\t\t\t      &act_mirred_ops, bind, true);\n+\t\tret = tcf_idr_create(tn, parm->index, est, a,\n+\t\t\t\t     &act_mirred_ops, bind, true);\n \t\tif (ret)\n \t\t\treturn ret;\n \t\tret = ACT_P_CREATED;\n \t} else {\n-\t\ttcf_hash_release(*a, bind);\n+\t\ttcf_idr_release(*a, bind);\n \t\tif (!ovr)\n \t\t\treturn -EEXIST;\n \t}\n@@ -152,7 +151,7 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,\n \t\tspin_lock_bh(&mirred_list_lock);\n \t\tlist_add(&m->tcfm_list, &mirred_list);\n \t\tspin_unlock_bh(&mirred_list_lock);\n-\t\ttcf_hash_insert(tn, *a);\n+\t\ttcf_idr_insert(tn, *a);\n \t}\n \n \treturn ret;\n@@ -283,7 +282,7 @@ static int tcf_mirred_search(struct net *net, struct tc_action **a, u32 index)\n {\n \tstruct tc_action_net *tn = net_generic(net, mirred_net_id);\n \n-\treturn tcf_hash_search(tn, a, index);\n+\treturn tcf_idr_search(tn, a, index);\n }\n \n static int mirred_device_event(struct notifier_block *unused,\n@@ -344,7 +343,7 @@ static __net_init int mirred_init_net(struct net *net)\n {\n \tstruct tc_action_net *tn = net_generic(net, mirred_net_id);\n \n-\treturn tc_action_net_init(tn, &act_mirred_ops, MIRRED_TAB_MASK);\n+\treturn tc_action_net_init(tn, &act_mirred_ops);\n }\n \n static void __net_exit mirred_exit_net(struct net *net)\ndiff --git a/net/sched/act_nat.c b/net/sched/act_nat.c\nindex 9016ab8..c365d01 100644\n--- a/net/sched/act_nat.c\n+++ b/net/sched/act_nat.c\n@@ -29,8 +29,6 @@\n #include <net/udp.h>\n \n \n-#define NAT_TAB_MASK\t15\n-\n static unsigned int nat_net_id;\n static struct tc_action_ops act_nat_ops;\n \n@@ -58,16 +56,16 @@ static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est,\n \t\treturn -EINVAL;\n \tparm = nla_data(tb[TCA_NAT_PARMS]);\n \n-\tif (!tcf_hash_check(tn, parm->index, a, bind)) {\n-\t\tret = tcf_hash_create(tn, parm->index, est, a,\n-\t\t\t\t      &act_nat_ops, bind, false);\n+\tif (!tcf_idr_check(tn, parm->index, a, bind)) {\n+\t\tret = tcf_idr_create(tn, parm->index, est, a,\n+\t\t\t\t     &act_nat_ops, bind, false);\n \t\tif (ret)\n \t\t\treturn ret;\n \t\tret = ACT_P_CREATED;\n \t} else {\n \t\tif (bind)\n \t\t\treturn 0;\n-\t\ttcf_hash_release(*a, bind);\n+\t\ttcf_idr_release(*a, bind);\n \t\tif (!ovr)\n \t\t\treturn -EEXIST;\n \t}\n@@ -83,7 +81,7 @@ static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est,\n \tspin_unlock_bh(&p->tcf_lock);\n \n \tif (ret == ACT_P_CREATED)\n-\t\ttcf_hash_insert(tn, *a);\n+\t\ttcf_idr_insert(tn, *a);\n \n \treturn ret;\n }\n@@ -290,7 +288,7 @@ static int tcf_nat_search(struct net *net, struct tc_action **a, u32 index)\n {\n \tstruct tc_action_net *tn = net_generic(net, nat_net_id);\n \n-\treturn tcf_hash_search(tn, a, index);\n+\treturn tcf_idr_search(tn, a, index);\n }\n \n static struct tc_action_ops act_nat_ops = {\n@@ -309,7 +307,7 @@ static __net_init int nat_init_net(struct net *net)\n {\n \tstruct tc_action_net *tn = net_generic(net, nat_net_id);\n \n-\treturn tc_action_net_init(tn, &act_nat_ops, NAT_TAB_MASK);\n+\treturn tc_action_net_init(tn, &act_nat_ops);\n }\n \n static void __net_exit nat_exit_net(struct net *net)\ndiff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c\nindex 7dc5892..491fe5de 100644\n--- a/net/sched/act_pedit.c\n+++ b/net/sched/act_pedit.c\n@@ -24,8 +24,6 @@\n #include <net/tc_act/tc_pedit.h>\n #include <uapi/linux/tc_act/tc_pedit.h>\n \n-#define PEDIT_TAB_MASK\t15\n-\n static unsigned int pedit_net_id;\n static struct tc_action_ops act_pedit_ops;\n \n@@ -168,17 +166,17 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,\n \tif (IS_ERR(keys_ex))\n \t\treturn PTR_ERR(keys_ex);\n \n-\tif (!tcf_hash_check(tn, parm->index, a, bind)) {\n+\tif (!tcf_idr_check(tn, parm->index, a, bind)) {\n \t\tif (!parm->nkeys)\n \t\t\treturn -EINVAL;\n-\t\tret = tcf_hash_create(tn, parm->index, est, a,\n-\t\t\t\t      &act_pedit_ops, bind, false);\n+\t\tret = tcf_idr_create(tn, parm->index, est, a,\n+\t\t\t\t     &act_pedit_ops, bind, false);\n \t\tif (ret)\n \t\t\treturn ret;\n \t\tp = to_pedit(*a);\n \t\tkeys = kmalloc(ksize, GFP_KERNEL);\n \t\tif (keys == NULL) {\n-\t\t\ttcf_hash_cleanup(*a, est);\n+\t\t\ttcf_idr_cleanup(*a, est);\n \t\t\tkfree(keys_ex);\n \t\t\treturn -ENOMEM;\n \t\t}\n@@ -186,7 +184,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,\n \t} else {\n \t\tif (bind)\n \t\t\treturn 0;\n-\t\ttcf_hash_release(*a, bind);\n+\t\ttcf_idr_release(*a, bind);\n \t\tif (!ovr)\n \t\t\treturn -EEXIST;\n \t\tp = to_pedit(*a);\n@@ -214,7 +212,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,\n \n \tspin_unlock_bh(&p->tcf_lock);\n \tif (ret == ACT_P_CREATED)\n-\t\ttcf_hash_insert(tn, *a);\n+\t\ttcf_idr_insert(tn, *a);\n \treturn ret;\n }\n \n@@ -432,7 +430,7 @@ static int tcf_pedit_search(struct net *net, struct tc_action **a, u32 index)\n {\n \tstruct tc_action_net *tn = net_generic(net, pedit_net_id);\n \n-\treturn tcf_hash_search(tn, a, index);\n+\treturn tcf_idr_search(tn, a, index);\n }\n \n static struct tc_action_ops act_pedit_ops = {\n@@ -452,7 +450,7 @@ static __net_init int pedit_init_net(struct net *net)\n {\n \tstruct tc_action_net *tn = net_generic(net, pedit_net_id);\n \n-\treturn tc_action_net_init(tn, &act_pedit_ops, PEDIT_TAB_MASK);\n+\treturn tc_action_net_init(tn, &act_pedit_ops);\n }\n \n static void __net_exit pedit_exit_net(struct net *net)\ndiff --git a/net/sched/act_police.c b/net/sched/act_police.c\nindex b062bc8..3bb2ebf 100644\n--- a/net/sched/act_police.c\n+++ b/net/sched/act_police.c\n@@ -40,8 +40,6 @@ struct tcf_police {\n \n #define to_police(pc) ((struct tcf_police *)pc)\n \n-#define POL_TAB_MASK     15\n-\n /* old policer structure from before tc actions */\n struct tc_police_compat {\n \tu32\t\t\tindex;\n@@ -101,18 +99,18 @@ static int tcf_act_police_init(struct net *net, struct nlattr *nla,\n \t\treturn -EINVAL;\n \n \tparm = nla_data(tb[TCA_POLICE_TBF]);\n-\texists = tcf_hash_check(tn, parm->index, a, bind);\n+\texists = tcf_idr_check(tn, parm->index, a, bind);\n \tif (exists && bind)\n \t\treturn 0;\n \n \tif (!exists) {\n-\t\tret = tcf_hash_create(tn, parm->index, NULL, a,\n-\t\t\t\t      &act_police_ops, bind, false);\n+\t\tret = tcf_idr_create(tn, parm->index, NULL, a,\n+\t\t\t\t     &act_police_ops, bind, false);\n \t\tif (ret)\n \t\t\treturn ret;\n \t\tret = ACT_P_CREATED;\n \t} else {\n-\t\ttcf_hash_release(*a, bind);\n+\t\ttcf_idr_release(*a, bind);\n \t\tif (!ovr)\n \t\t\treturn -EEXIST;\n \t}\n@@ -188,7 +186,7 @@ static int tcf_act_police_init(struct net *net, struct nlattr *nla,\n \t\treturn ret;\n \n \tpolice->tcfp_t_c = ktime_get_ns();\n-\ttcf_hash_insert(tn, *a);\n+\ttcf_idr_insert(tn, *a);\n \n \treturn ret;\n \n@@ -196,7 +194,7 @@ static int tcf_act_police_init(struct net *net, struct nlattr *nla,\n \tqdisc_put_rtab(P_tab);\n \tqdisc_put_rtab(R_tab);\n \tif (ret == ACT_P_CREATED)\n-\t\ttcf_hash_cleanup(*a, est);\n+\t\ttcf_idr_cleanup(*a, est);\n \treturn err;\n }\n \n@@ -310,7 +308,7 @@ static int tcf_police_search(struct net *net, struct tc_action **a, u32 index)\n {\n \tstruct tc_action_net *tn = net_generic(net, police_net_id);\n \n-\treturn tcf_hash_search(tn, a, index);\n+\treturn tcf_idr_search(tn, a, index);\n }\n \n MODULE_AUTHOR(\"Alexey Kuznetsov\");\n@@ -333,7 +331,7 @@ static __net_init int police_init_net(struct net *net)\n {\n \tstruct tc_action_net *tn = net_generic(net, police_net_id);\n \n-\treturn tc_action_net_init(tn, &act_police_ops, POL_TAB_MASK);\n+\treturn tc_action_net_init(tn, &act_police_ops);\n }\n \n static void __net_exit police_exit_net(struct net *net)\ndiff --git a/net/sched/act_sample.c b/net/sched/act_sample.c\nindex 59d6645..ec986ae 100644\n--- a/net/sched/act_sample.c\n+++ b/net/sched/act_sample.c\n@@ -25,7 +25,6 @@\n \n #include <linux/if_arp.h>\n \n-#define SAMPLE_TAB_MASK     7\n static unsigned int sample_net_id;\n static struct tc_action_ops act_sample_ops;\n \n@@ -59,18 +58,18 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla,\n \n \tparm = nla_data(tb[TCA_SAMPLE_PARMS]);\n \n-\texists = tcf_hash_check(tn, parm->index, a, bind);\n+\texists = tcf_idr_check(tn, parm->index, a, bind);\n \tif (exists && bind)\n \t\treturn 0;\n \n \tif (!exists) {\n-\t\tret = tcf_hash_create(tn, parm->index, est, a,\n-\t\t\t\t      &act_sample_ops, bind, false);\n+\t\tret = tcf_idr_create(tn, parm->index, est, a,\n+\t\t\t\t     &act_sample_ops, bind, false);\n \t\tif (ret)\n \t\t\treturn ret;\n \t\tret = ACT_P_CREATED;\n \t} else {\n-\t\ttcf_hash_release(*a, bind);\n+\t\ttcf_idr_release(*a, bind);\n \t\tif (!ovr)\n \t\t\treturn -EEXIST;\n \t}\n@@ -82,7 +81,7 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla,\n \tpsample_group = psample_group_get(net, s->psample_group_num);\n \tif (!psample_group) {\n \t\tif (ret == ACT_P_CREATED)\n-\t\t\ttcf_hash_release(*a, bind);\n+\t\t\ttcf_idr_release(*a, bind);\n \t\treturn -ENOMEM;\n \t}\n \tRCU_INIT_POINTER(s->psample_group, psample_group);\n@@ -93,7 +92,7 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla,\n \t}\n \n \tif (ret == ACT_P_CREATED)\n-\t\ttcf_hash_insert(tn, *a);\n+\t\ttcf_idr_insert(tn, *a);\n \treturn ret;\n }\n \n@@ -221,7 +220,7 @@ static int tcf_sample_search(struct net *net, struct tc_action **a, u32 index)\n {\n \tstruct tc_action_net *tn = net_generic(net, sample_net_id);\n \n-\treturn tcf_hash_search(tn, a, index);\n+\treturn tcf_idr_search(tn, a, index);\n }\n \n static struct tc_action_ops act_sample_ops = {\n@@ -241,7 +240,7 @@ static __net_init int sample_init_net(struct net *net)\n {\n \tstruct tc_action_net *tn = net_generic(net, sample_net_id);\n \n-\treturn tc_action_net_init(tn, &act_sample_ops, SAMPLE_TAB_MASK);\n+\treturn tc_action_net_init(tn, &act_sample_ops);\n }\n \n static void __net_exit sample_exit_net(struct net *net)\ndiff --git a/net/sched/act_simple.c b/net/sched/act_simple.c\nindex 43605e7..e7b57e5 100644\n--- a/net/sched/act_simple.c\n+++ b/net/sched/act_simple.c\n@@ -24,8 +24,6 @@\n #include <linux/tc_act/tc_defact.h>\n #include <net/tc_act/tc_defact.h>\n \n-#define SIMP_TAB_MASK     7\n-\n static unsigned int simp_net_id;\n static struct tc_action_ops act_simp_ops;\n \n@@ -102,28 +100,28 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla,\n \t\treturn -EINVAL;\n \n \tparm = nla_data(tb[TCA_DEF_PARMS]);\n-\texists = tcf_hash_check(tn, parm->index, a, bind);\n+\texists = tcf_idr_check(tn, parm->index, a, bind);\n \tif (exists && bind)\n \t\treturn 0;\n \n \tif (tb[TCA_DEF_DATA] == NULL) {\n \t\tif (exists)\n-\t\t\ttcf_hash_release(*a, bind);\n+\t\t\ttcf_idr_release(*a, bind);\n \t\treturn -EINVAL;\n \t}\n \n \tdefdata = nla_data(tb[TCA_DEF_DATA]);\n \n \tif (!exists) {\n-\t\tret = tcf_hash_create(tn, parm->index, est, a,\n-\t\t\t\t      &act_simp_ops, bind, false);\n+\t\tret = tcf_idr_create(tn, parm->index, est, a,\n+\t\t\t\t     &act_simp_ops, bind, false);\n \t\tif (ret)\n \t\t\treturn ret;\n \n \t\td = to_defact(*a);\n \t\tret = alloc_defdata(d, defdata);\n \t\tif (ret < 0) {\n-\t\t\ttcf_hash_cleanup(*a, est);\n+\t\t\ttcf_idr_cleanup(*a, est);\n \t\t\treturn ret;\n \t\t}\n \t\td->tcf_action = parm->action;\n@@ -131,7 +129,7 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla,\n \t} else {\n \t\td = to_defact(*a);\n \n-\t\ttcf_hash_release(*a, bind);\n+\t\ttcf_idr_release(*a, bind);\n \t\tif (!ovr)\n \t\t\treturn -EEXIST;\n \n@@ -139,7 +137,7 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla,\n \t}\n \n \tif (ret == ACT_P_CREATED)\n-\t\ttcf_hash_insert(tn, *a);\n+\t\ttcf_idr_insert(tn, *a);\n \treturn ret;\n }\n \n@@ -183,7 +181,7 @@ static int tcf_simp_search(struct net *net, struct tc_action **a, u32 index)\n {\n \tstruct tc_action_net *tn = net_generic(net, simp_net_id);\n \n-\treturn tcf_hash_search(tn, a, index);\n+\treturn tcf_idr_search(tn, a, index);\n }\n \n static struct tc_action_ops act_simp_ops = {\n@@ -203,7 +201,7 @@ static __net_init int simp_init_net(struct net *net)\n {\n \tstruct tc_action_net *tn = net_generic(net, simp_net_id);\n \n-\treturn tc_action_net_init(tn, &act_simp_ops, SIMP_TAB_MASK);\n+\treturn tc_action_net_init(tn, &act_simp_ops);\n }\n \n static void __net_exit simp_exit_net(struct net *net)\ndiff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c\nindex 6b3e65d..59949d6 100644\n--- a/net/sched/act_skbedit.c\n+++ b/net/sched/act_skbedit.c\n@@ -27,8 +27,6 @@\n #include <linux/tc_act/tc_skbedit.h>\n #include <net/tc_act/tc_skbedit.h>\n \n-#define SKBEDIT_TAB_MASK     15\n-\n static unsigned int skbedit_net_id;\n static struct tc_action_ops act_skbedit_ops;\n \n@@ -118,18 +116,18 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla,\n \n \tparm = nla_data(tb[TCA_SKBEDIT_PARMS]);\n \n-\texists = tcf_hash_check(tn, parm->index, a, bind);\n+\texists = tcf_idr_check(tn, parm->index, a, bind);\n \tif (exists && bind)\n \t\treturn 0;\n \n \tif (!flags) {\n-\t\ttcf_hash_release(*a, bind);\n+\t\ttcf_idr_release(*a, bind);\n \t\treturn -EINVAL;\n \t}\n \n \tif (!exists) {\n-\t\tret = tcf_hash_create(tn, parm->index, est, a,\n-\t\t\t\t      &act_skbedit_ops, bind, false);\n+\t\tret = tcf_idr_create(tn, parm->index, est, a,\n+\t\t\t\t     &act_skbedit_ops, bind, false);\n \t\tif (ret)\n \t\t\treturn ret;\n \n@@ -137,7 +135,7 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla,\n \t\tret = ACT_P_CREATED;\n \t} else {\n \t\td = to_skbedit(*a);\n-\t\ttcf_hash_release(*a, bind);\n+\t\ttcf_idr_release(*a, bind);\n \t\tif (!ovr)\n \t\t\treturn -EEXIST;\n \t}\n@@ -163,7 +161,7 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla,\n \tspin_unlock_bh(&d->tcf_lock);\n \n \tif (ret == ACT_P_CREATED)\n-\t\ttcf_hash_insert(tn, *a);\n+\t\ttcf_idr_insert(tn, *a);\n \treturn ret;\n }\n \n@@ -221,7 +219,7 @@ static int tcf_skbedit_search(struct net *net, struct tc_action **a, u32 index)\n {\n \tstruct tc_action_net *tn = net_generic(net, skbedit_net_id);\n \n-\treturn tcf_hash_search(tn, a, index);\n+\treturn tcf_idr_search(tn, a, index);\n }\n \n static struct tc_action_ops act_skbedit_ops = {\n@@ -240,7 +238,7 @@ static __net_init int skbedit_init_net(struct net *net)\n {\n \tstruct tc_action_net *tn = net_generic(net, skbedit_net_id);\n \n-\treturn tc_action_net_init(tn, &act_skbedit_ops, SKBEDIT_TAB_MASK);\n+\treturn tc_action_net_init(tn, &act_skbedit_ops);\n }\n \n static void __net_exit skbedit_exit_net(struct net *net)\ndiff --git a/net/sched/act_skbmod.c b/net/sched/act_skbmod.c\nindex a73c4bb..b642ad3 100644\n--- a/net/sched/act_skbmod.c\n+++ b/net/sched/act_skbmod.c\n@@ -20,8 +20,6 @@\n #include <linux/tc_act/tc_skbmod.h>\n #include <net/tc_act/tc_skbmod.h>\n \n-#define SKBMOD_TAB_MASK     15\n-\n static unsigned int skbmod_net_id;\n static struct tc_action_ops act_skbmod_ops;\n \n@@ -129,7 +127,7 @@ static int tcf_skbmod_init(struct net *net, struct nlattr *nla,\n \tif (parm->flags & SKBMOD_F_SWAPMAC)\n \t\tlflags = SKBMOD_F_SWAPMAC;\n \n-\texists = tcf_hash_check(tn, parm->index, a, bind);\n+\texists = tcf_idr_check(tn, parm->index, a, bind);\n \tif (exists && bind)\n \t\treturn 0;\n \n@@ -137,14 +135,14 @@ static int tcf_skbmod_init(struct net *net, struct nlattr *nla,\n \t\treturn -EINVAL;\n \n \tif (!exists) {\n-\t\tret = tcf_hash_create(tn, parm->index, est, a,\n-\t\t\t\t      &act_skbmod_ops, bind, true);\n+\t\tret = tcf_idr_create(tn, parm->index, est, a,\n+\t\t\t\t     &act_skbmod_ops, bind, true);\n \t\tif (ret)\n \t\t\treturn ret;\n \n \t\tret = ACT_P_CREATED;\n \t} else {\n-\t\ttcf_hash_release(*a, bind);\n+\t\ttcf_idr_release(*a, bind);\n \t\tif (!ovr)\n \t\t\treturn -EEXIST;\n \t}\n@@ -155,7 +153,7 @@ static int tcf_skbmod_init(struct net *net, struct nlattr *nla,\n \tp = kzalloc(sizeof(struct tcf_skbmod_params), GFP_KERNEL);\n \tif (unlikely(!p)) {\n \t\tif (ovr)\n-\t\t\ttcf_hash_release(*a, bind);\n+\t\t\ttcf_idr_release(*a, bind);\n \t\treturn -ENOMEM;\n \t}\n \n@@ -182,7 +180,7 @@ static int tcf_skbmod_init(struct net *net, struct nlattr *nla,\n \t\tkfree_rcu(p_old, rcu);\n \n \tif (ret == ACT_P_CREATED)\n-\t\ttcf_hash_insert(tn, *a);\n+\t\ttcf_idr_insert(tn, *a);\n \treturn ret;\n }\n \n@@ -245,7 +243,7 @@ static int tcf_skbmod_search(struct net *net, struct tc_action **a, u32 index)\n {\n \tstruct tc_action_net *tn = net_generic(net, skbmod_net_id);\n \n-\treturn tcf_hash_search(tn, a, index);\n+\treturn tcf_idr_search(tn, a, index);\n }\n \n static struct tc_action_ops act_skbmod_ops = {\n@@ -265,7 +263,7 @@ static __net_init int skbmod_init_net(struct net *net)\n {\n \tstruct tc_action_net *tn = net_generic(net, skbmod_net_id);\n \n-\treturn tc_action_net_init(tn, &act_skbmod_ops, SKBMOD_TAB_MASK);\n+\treturn tc_action_net_init(tn, &act_skbmod_ops);\n }\n \n static void __net_exit skbmod_exit_net(struct net *net)\ndiff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c\nindex fd7e756..30c9627 100644\n--- a/net/sched/act_tunnel_key.c\n+++ b/net/sched/act_tunnel_key.c\n@@ -20,8 +20,6 @@\n #include <linux/tc_act/tc_tunnel_key.h>\n #include <net/tc_act/tc_tunnel_key.h>\n \n-#define TUNNEL_KEY_TAB_MASK     15\n-\n static unsigned int tunnel_key_net_id;\n static struct tc_action_ops act_tunnel_key_ops;\n \n@@ -100,7 +98,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,\n \t\treturn -EINVAL;\n \n \tparm = nla_data(tb[TCA_TUNNEL_KEY_PARMS]);\n-\texists = tcf_hash_check(tn, parm->index, a, bind);\n+\texists = tcf_idr_check(tn, parm->index, a, bind);\n \tif (exists && bind)\n \t\treturn 0;\n \n@@ -159,14 +157,14 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,\n \t}\n \n \tif (!exists) {\n-\t\tret = tcf_hash_create(tn, parm->index, est, a,\n-\t\t\t\t      &act_tunnel_key_ops, bind, true);\n+\t\tret = tcf_idr_create(tn, parm->index, est, a,\n+\t\t\t\t     &act_tunnel_key_ops, bind, true);\n \t\tif (ret)\n \t\t\treturn ret;\n \n \t\tret = ACT_P_CREATED;\n \t} else {\n-\t\ttcf_hash_release(*a, bind);\n+\t\ttcf_idr_release(*a, bind);\n \t\tif (!ovr)\n \t\t\treturn -EEXIST;\n \t}\n@@ -177,7 +175,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,\n \tparams_new = kzalloc(sizeof(*params_new), GFP_KERNEL);\n \tif (unlikely(!params_new)) {\n \t\tif (ret == ACT_P_CREATED)\n-\t\t\ttcf_hash_release(*a, bind);\n+\t\t\ttcf_idr_release(*a, bind);\n \t\treturn -ENOMEM;\n \t}\n \n@@ -193,13 +191,13 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,\n \t\tkfree_rcu(params_old, rcu);\n \n \tif (ret == ACT_P_CREATED)\n-\t\ttcf_hash_insert(tn, *a);\n+\t\ttcf_idr_insert(tn, *a);\n \n \treturn ret;\n \n err_out:\n \tif (exists)\n-\t\ttcf_hash_release(*a, bind);\n+\t\ttcf_idr_release(*a, bind);\n \treturn ret;\n }\n \n@@ -304,7 +302,7 @@ static int tunnel_key_search(struct net *net, struct tc_action **a, u32 index)\n {\n \tstruct tc_action_net *tn = net_generic(net, tunnel_key_net_id);\n \n-\treturn tcf_hash_search(tn, a, index);\n+\treturn tcf_idr_search(tn, a, index);\n }\n \n static struct tc_action_ops act_tunnel_key_ops = {\n@@ -324,7 +322,7 @@ static __net_init int tunnel_key_init_net(struct net *net)\n {\n \tstruct tc_action_net *tn = net_generic(net, tunnel_key_net_id);\n \n-\treturn tc_action_net_init(tn, &act_tunnel_key_ops, TUNNEL_KEY_TAB_MASK);\n+\treturn tc_action_net_init(tn, &act_tunnel_key_ops);\n }\n \n static void __net_exit tunnel_key_exit_net(struct net *net)\ndiff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c\nindex 13ba3a8..16eb067 100644\n--- a/net/sched/act_vlan.c\n+++ b/net/sched/act_vlan.c\n@@ -19,8 +19,6 @@\n #include <linux/tc_act/tc_vlan.h>\n #include <net/tc_act/tc_vlan.h>\n \n-#define VLAN_TAB_MASK     15\n-\n static unsigned int vlan_net_id;\n static struct tc_action_ops act_vlan_ops;\n \n@@ -128,7 +126,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla,\n \tif (!tb[TCA_VLAN_PARMS])\n \t\treturn -EINVAL;\n \tparm = nla_data(tb[TCA_VLAN_PARMS]);\n-\texists = tcf_hash_check(tn, parm->index, a, bind);\n+\texists = tcf_idr_check(tn, parm->index, a, bind);\n \tif (exists && bind)\n \t\treturn 0;\n \n@@ -139,13 +137,13 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla,\n \tcase TCA_VLAN_ACT_MODIFY:\n \t\tif (!tb[TCA_VLAN_PUSH_VLAN_ID]) {\n \t\t\tif (exists)\n-\t\t\t\ttcf_hash_release(*a, bind);\n+\t\t\t\ttcf_idr_release(*a, bind);\n \t\t\treturn -EINVAL;\n \t\t}\n \t\tpush_vid = nla_get_u16(tb[TCA_VLAN_PUSH_VLAN_ID]);\n \t\tif (push_vid >= VLAN_VID_MASK) {\n \t\t\tif (exists)\n-\t\t\t\ttcf_hash_release(*a, bind);\n+\t\t\t\ttcf_idr_release(*a, bind);\n \t\t\treturn -ERANGE;\n \t\t}\n \n@@ -167,20 +165,20 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla,\n \t\tbreak;\n \tdefault:\n \t\tif (exists)\n-\t\t\ttcf_hash_release(*a, bind);\n+\t\t\ttcf_idr_release(*a, bind);\n \t\treturn -EINVAL;\n \t}\n \taction = parm->v_action;\n \n \tif (!exists) {\n-\t\tret = tcf_hash_create(tn, parm->index, est, a,\n-\t\t\t\t      &act_vlan_ops, bind, false);\n+\t\tret = tcf_idr_create(tn, parm->index, est, a,\n+\t\t\t\t     &act_vlan_ops, bind, false);\n \t\tif (ret)\n \t\t\treturn ret;\n \n \t\tret = ACT_P_CREATED;\n \t} else {\n-\t\ttcf_hash_release(*a, bind);\n+\t\ttcf_idr_release(*a, bind);\n \t\tif (!ovr)\n \t\t\treturn -EEXIST;\n \t}\n@@ -199,7 +197,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla,\n \tspin_unlock_bh(&v->tcf_lock);\n \n \tif (ret == ACT_P_CREATED)\n-\t\ttcf_hash_insert(tn, *a);\n+\t\ttcf_idr_insert(tn, *a);\n \treturn ret;\n }\n \n@@ -252,7 +250,7 @@ static int tcf_vlan_search(struct net *net, struct tc_action **a, u32 index)\n {\n \tstruct tc_action_net *tn = net_generic(net, vlan_net_id);\n \n-\treturn tcf_hash_search(tn, a, index);\n+\treturn tcf_idr_search(tn, a, index);\n }\n \n static struct tc_action_ops act_vlan_ops = {\n@@ -271,7 +269,7 @@ static __net_init int vlan_init_net(struct net *net)\n {\n \tstruct tc_action_net *tn = net_generic(net, vlan_net_id);\n \n-\treturn tc_action_net_init(tn, &act_vlan_ops, VLAN_TAB_MASK);\n+\treturn tc_action_net_init(tn, &act_vlan_ops);\n }\n \n static void __net_exit vlan_exit_net(struct net *net)\n",
    "prefixes": [
        "net-next",
        "3/3"
    ]
}