From 9c160941403ba833c8e67981806ccae73ff7aca7 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 28 Nov 2017 09:48:43 -0500 Subject: idr: Delete idr_remove_ext function Simply changing idr_remove's 'id' argument to 'unsigned long' suffices for all callers. Signed-off-by: Matthew Wilcox --- net/sched/cls_u32.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'net/sched/cls_u32.c') diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index e3c5e390ec23..bd55ed783cb1 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -596,7 +596,7 @@ static void u32_clear_hnode(struct tcf_proto *tp, struct tc_u_hnode *ht, rtnl_dereference(n->next)); tcf_unbind_filter(tp, &n->res); u32_remove_hw_knode(tp, n, extack); - idr_remove_ext(&ht->handle_idr, n->handle); + idr_remove(&ht->handle_idr, n->handle); if (tcf_exts_get_net(&n->exts)) call_rcu(&n->rcu, u32_delete_key_freepf_rcu); else @@ -623,7 +623,7 @@ static int u32_destroy_hnode(struct tcf_proto *tp, struct tc_u_hnode *ht, if (phn == ht) { u32_clear_hw_hnode(tp, ht, extack); idr_destroy(&ht->handle_idr); - idr_remove_ext(&tp_c->handle_idr, ht->handle); + idr_remove(&tp_c->handle_idr, ht->handle); RCU_INIT_POINTER(*hn, ht->next); kfree_rcu(ht, rcu); return 0; @@ -1026,7 +1026,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb, err = u32_replace_hw_hnode(tp, ht, flags, extack); if (err) { - idr_remove_ext(&tp_c->handle_idr, handle); + idr_remove(&tp_c->handle_idr, handle); kfree(ht); return err; } @@ -1162,7 +1162,7 @@ errfree: #endif kfree(n); erridr: - idr_remove_ext(&ht->handle_idr, handle); + idr_remove(&ht->handle_idr, handle); return err; } -- cgit v1.2.3 From 234a4624efe5629a777b4c00dbdf41dd8b7332db Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 28 Nov 2017 09:56:36 -0500 Subject: idr: Delete idr_replace_ext function Changing idr_replace's 'id' argument to 'unsigned long' works for all callers. Callers which passed a negative ID now get -ENOENT instead of -EINVAL. No callers relied on this error value. Signed-off-by: Matthew Wilcox --- include/linux/idr.h | 3 +-- lib/idr.c | 15 +++------------ net/sched/act_api.c | 2 +- net/sched/cls_basic.c | 2 +- net/sched/cls_bpf.c | 2 +- net/sched/cls_flower.c | 2 +- net/sched/cls_u32.c | 2 +- 7 files changed, 9 insertions(+), 19 deletions(-) (limited to 'net/sched/cls_u32.c') diff --git a/include/linux/idr.h b/include/linux/idr.h index 118987a17ada..f1299c4dc45f 100644 --- a/include/linux/idr.h +++ b/include/linux/idr.h @@ -136,8 +136,7 @@ int idr_for_each(const struct idr *, int (*fn)(int id, void *p, void *data), void *data); void *idr_get_next(struct idr *, int *nextid); void *idr_get_next_ext(struct idr *idr, unsigned long *nextid); -void *idr_replace(struct idr *, void *, int id); -void *idr_replace_ext(struct idr *idr, void *ptr, unsigned long id); +void *idr_replace(struct idr *, void *, unsigned long id); void idr_destroy(struct idr *); static inline void *idr_remove(struct idr *idr, unsigned long id) diff --git a/lib/idr.c b/lib/idr.c index 2593ce513a18..577bfd4fe5c2 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -147,18 +147,9 @@ EXPORT_SYMBOL(idr_get_next_ext); * the one being replaced!). * * Returns: the old value on success. %-ENOENT indicates that @id was not - * found. %-EINVAL indicates that @id or @ptr were not valid. + * found. %-EINVAL indicates that @ptr was not valid. */ -void *idr_replace(struct idr *idr, void *ptr, int id) -{ - if (id < 0) - return ERR_PTR(-EINVAL); - - return idr_replace_ext(idr, ptr, id); -} -EXPORT_SYMBOL(idr_replace); - -void *idr_replace_ext(struct idr *idr, void *ptr, unsigned long id) +void *idr_replace(struct idr *idr, void *ptr, unsigned long id) { struct radix_tree_node *node; void __rcu **slot = NULL; @@ -175,7 +166,7 @@ void *idr_replace_ext(struct idr *idr, void *ptr, unsigned long id) return entry; } -EXPORT_SYMBOL(idr_replace_ext); +EXPORT_SYMBOL(idr_replace); /** * DOC: IDA description diff --git a/net/sched/act_api.c b/net/sched/act_api.c index be5b2b455371..1572466be031 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -348,7 +348,7 @@ void tcf_idr_insert(struct tc_action_net *tn, struct tc_action *a) struct tcf_idrinfo *idrinfo = tn->idrinfo; spin_lock_bh(&idrinfo->lock); - idr_replace_ext(&idrinfo->action_idr, a, a->tcfa_index); + idr_replace(&idrinfo->action_idr, a, a->tcfa_index); spin_unlock_bh(&idrinfo->lock); } EXPORT_SYMBOL(tcf_idr_insert); diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c index 121dff0a1763..588c635f195e 100644 --- a/net/sched/cls_basic.c +++ b/net/sched/cls_basic.c @@ -235,7 +235,7 @@ static int basic_change(struct net *net, struct sk_buff *in_skb, *arg = fnew; if (fold) { - idr_replace_ext(&head->handle_idr, fnew, fnew->handle); + idr_replace(&head->handle_idr, fnew, fnew->handle); list_replace_rcu(&fold->link, &fnew->link); tcf_unbind_filter(tp, &fold->res); tcf_exts_get_net(&fold->exts); diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c index e45137e3f567..8cb3a33b1afd 100644 --- a/net/sched/cls_bpf.c +++ b/net/sched/cls_bpf.c @@ -526,7 +526,7 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb, prog->gen_flags |= TCA_CLS_FLAGS_NOT_IN_HW; if (oldprog) { - idr_replace_ext(&head->handle_idr, prog, handle); + idr_replace(&head->handle_idr, prog, handle); list_replace_rcu(&oldprog->link, &prog->link); tcf_unbind_filter(tp, &oldprog->res); tcf_exts_get_net(&oldprog->exts); diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c index e098e8ab76c9..0d1b0c11de34 100644 --- a/net/sched/cls_flower.c +++ b/net/sched/cls_flower.c @@ -967,7 +967,7 @@ static int fl_change(struct net *net, struct sk_buff *in_skb, if (fold) { fnew->handle = handle; - idr_replace_ext(&head->handle_idr, fnew, fnew->handle); + idr_replace(&head->handle_idr, fnew, fnew->handle); list_replace_rcu(&fold->list, &fnew->list); tcf_unbind_filter(tp, &fold->res); tcf_exts_get_net(&fold->exts); diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index bd55ed783cb1..5b256da985b1 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -848,7 +848,7 @@ static void u32_replace_knode(struct tcf_proto *tp, struct tc_u_common *tp_c, if (pins->handle == n->handle) break; - idr_replace_ext(&ht->handle_idr, n, n->handle); + idr_replace(&ht->handle_idr, n, n->handle); RCU_INIT_POINTER(n->next, pins->next); rcu_assign_pointer(*ins, n); } -- cgit v1.2.3 From ffdc2d9e1afd20e9f9d205115661481e984542d6 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 28 Nov 2017 12:05:54 -0500 Subject: cls_u32: Reinstate cyclic allocation Commit e7614370d6f0 ("net_sched: use idr to allocate u32 filter handles) converted htid allocation to use the IDR. The ID allocated by this scheme changes; it used to be cyclic, but now always allocates the lowest available. The IDR supports cyclic allocation, so just use the right function. Signed-off-by: Matthew Wilcox --- net/sched/cls_u32.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'net/sched/cls_u32.c') diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 5b256da985b1..d2805f24ddd3 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -316,19 +316,13 @@ static void *u32_get(struct tcf_proto *tp, u32 handle) return u32_lookup_key(ht, handle); } +/* Protected by rtnl lock */ static u32 gen_new_htid(struct tc_u_common *tp_c, struct tc_u_hnode *ptr) { - unsigned long idr_index; - int err; - - /* This is only used inside rtnl lock it is safe to increment - * without read _copy_ update semantics - */ - err = idr_alloc_ext(&tp_c->handle_idr, ptr, &idr_index, - 1, 0x7FF, GFP_KERNEL); - if (err) + int id = idr_alloc_cyclic(&tp_c->handle_idr, ptr, 1, 0x7FF, GFP_KERNEL); + if (id < 0) return 0; - return (u32)(idr_index | 0x800) << 20; + return (id | 0x800U) << 20; } static struct hlist_head *tc_u_common_hash; -- cgit v1.2.3 From f730cb93db8e640f95ba4acb339d5732e1721730 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 28 Nov 2017 13:45:02 -0500 Subject: cls_u32: Convert to idr_alloc_u32 No real benefit to this classifier, but since we're allocating a u32 anyway, we should use this function. Signed-off-by: Matthew Wilcox --- net/sched/cls_u32.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) (limited to 'net/sched/cls_u32.c') diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index d2805f24ddd3..82f85d6a245a 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -740,19 +740,17 @@ ret: static u32 gen_new_kid(struct tc_u_hnode *ht, u32 htid) { - unsigned long idr_index; - u32 start = htid | 0x800; + u32 index = htid | 0x800; u32 max = htid | 0xFFF; - u32 min = htid; - if (idr_alloc_ext(&ht->handle_idr, NULL, &idr_index, - start, max + 1, GFP_KERNEL)) { - if (idr_alloc_ext(&ht->handle_idr, NULL, &idr_index, - min + 1, max + 1, GFP_KERNEL)) - return max; + if (idr_alloc_u32(&ht->handle_idr, NULL, &index, max, GFP_KERNEL)) { + index = htid + 1; + if (idr_alloc_u32(&ht->handle_idr, NULL, &index, max, + GFP_KERNEL)) + index = max; } - return (u32)idr_index; + return index; } static const struct nla_policy u32_policy[TCA_U32_MAX + 1] = { @@ -1003,8 +1001,8 @@ static int u32_change(struct net *net, struct sk_buff *in_skb, return -ENOMEM; } } else { - err = idr_alloc_ext(&tp_c->handle_idr, ht, NULL, - handle, handle + 1, GFP_KERNEL); + err = idr_alloc_u32(&tp_c->handle_idr, ht, &handle, + handle, GFP_KERNEL); if (err) { kfree(ht); return err; @@ -1060,8 +1058,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb, return -EINVAL; } handle = htid | TC_U32_NODE(handle); - err = idr_alloc_ext(&ht->handle_idr, NULL, NULL, - handle, handle + 1, + err = idr_alloc_u32(&ht->handle_idr, NULL, &handle, handle, GFP_KERNEL); if (err) return err; -- cgit v1.2.3