From ff63ffc002bf9b6d1307558186421b9cd3c7ad05 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Fri, 11 Jan 2019 15:41:39 -0500 Subject: [PATCH] bpf: Convert btf_idr to XArray Signed-off-by: Matthew Wilcox --- kernel/bpf/btf.c | 40 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index 5fcc7a17eb5a..e62b35f209fa 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -12,8 +12,8 @@ #include #include #include -#include #include +#include #include #include @@ -195,8 +195,8 @@ i < btf_type_vlen(struct_type); \ i++, member++) -static DEFINE_IDR(btf_idr); -static DEFINE_SPINLOCK(btf_idr_lock); +static DEFINE_XARRAY_FLAGS(btf_xa, XA_FLAGS_ALLOC1 | XA_FLAGS_LOCK_BH); +static u32 btf_next_id; struct btf { void *data; @@ -860,20 +860,8 @@ static int btf_add_type(struct btf_verifier_env *env, struct btf_type *t) static int btf_alloc_id(struct btf *btf) { - int id; - - idr_preload(GFP_KERNEL); - spin_lock_bh(&btf_idr_lock); - id = idr_alloc_cyclic(&btf_idr, btf, 1, INT_MAX, GFP_ATOMIC); - if (id > 0) - btf->id = id; - spin_unlock_bh(&btf_idr_lock); - idr_preload_end(); - - if (WARN_ON_ONCE(!id)) - return -ENOSPC; - - return id > 0 ? 0 : id; + return xa_alloc_cyclic_bh(&btf_xa, &btf->id, btf, xa_limit_31b, + &btf_next_id, GFP_KERNEL); } static void btf_free_id(struct btf *btf) @@ -889,9 +877,9 @@ static void btf_free_id(struct btf *btf) * we need to use the _irqsave() version instead * of the _bh() version. */ - spin_lock_irqsave(&btf_idr_lock, flags); - idr_remove(&btf_idr, btf->id); - spin_unlock_irqrestore(&btf_idr_lock, flags); + xa_lock_irqsave(&btf_xa, flags); + __xa_erase(&btf_xa, btf->id); + xa_unlock_irqrestore(&btf_xa, flags); } static void btf_free(struct btf *btf) @@ -3404,7 +3392,7 @@ int btf_new_fd(const union bpf_attr *attr) return PTR_ERR(btf); ret = btf_alloc_id(btf); - if (ret) { + if (ret < 0) { btf_free(btf); return ret; } @@ -3481,13 +3469,13 @@ int btf_get_fd_by_id(u32 id) int fd; rcu_read_lock(); - btf = idr_find(&btf_idr, id); - if (!btf || !refcount_inc_not_zero(&btf->refcnt)) - btf = ERR_PTR(-ENOENT); + btf = xa_load(&btf_xa, id); + if (btf && !refcount_inc_not_zero(&btf->refcnt)) + btf = NULL; rcu_read_unlock(); - if (IS_ERR(btf)) - return PTR_ERR(btf); + if (!btf) + return -ENOENT; fd = __btf_new_fd(btf); if (fd < 0) -- 2.50.1