aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core/uverbs_uapi.c
diff options
context:
space:
mode:
authorJason Gunthorpe <jgg@mellanox.com>2018-08-09 20:14:42 -0600
committerJason Gunthorpe <jgg@mellanox.com>2018-08-13 09:17:16 -0600
commit3a863577a7496278892360a69d90d8465733100c (patch)
treeb2db539aebd48c5d6fe2d994e8f5abe0c10cdccc /drivers/infiniband/core/uverbs_uapi.c
parentIB/uverbs: Use uverbs_alloc for allocations (diff)
downloadlinux-dev-3a863577a7496278892360a69d90d8465733100c.tar.xz
linux-dev-3a863577a7496278892360a69d90d8465733100c.zip
IB/uverbs: Use uverbs_api to unmarshal ioctl commands
Convert the ioctl method syscall path to use the uverbs_api data structures. The new uapi structure includes all the same information, just in a different and more optimal way. - Use attr_bkey instead of 2 level radix trees for everything related to attributes. This includes the attribute storage, presence, and detection of missing mandatory attributes. - Avoid iterating over all attribute storage at finish, instead use find_first_bit with the attr_bkey to locate only those attrs that need cleanup. - Organize things to always run, and always rely on, cleanup. This avoids a bunch of tricky error unwind cases. - Locate the method using the radix tree, and locate the attributes using a very efficient incremental radix tree lookup - Use the precomputed destroy_bkey to handle uobject destruction - Use the precomputed allocation sizes and precomputed 'need_stack' to avoid maths in the fast path. This is optimal if userspace does not pass (many) unsupported attributes. Overall this results in much better codegen for the attribute accessors, everything is now stored in bitmaps or linear arrays indexed by attr_bkey. The compiler can compute attr_bkey values at compile time for all method attributes, meaning things like uverbs_attr_is_valid() now compile into single instruction bit tests. Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Diffstat (limited to 'drivers/infiniband/core/uverbs_uapi.c')
-rw-r--r--drivers/infiniband/core/uverbs_uapi.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/infiniband/core/uverbs_uapi.c b/drivers/infiniband/core/uverbs_uapi.c
index 21c0de034511..73ea6f0db88f 100644
--- a/drivers/infiniband/core/uverbs_uapi.c
+++ b/drivers/infiniband/core/uverbs_uapi.c
@@ -160,6 +160,7 @@ uapi_finalize_ioctl_method(struct uverbs_api *uapi,
u32 method_key)
{
struct radix_tree_iter iter;
+ unsigned int num_attrs = 0;
unsigned int max_bkey = 0;
bool single_uobj = false;
void __rcu **slot;
@@ -204,11 +205,13 @@ uapi_finalize_ioctl_method(struct uverbs_api *uapi,
}
max_bkey = max(max_bkey, attr_bkey);
+ num_attrs++;
}
method_elm->key_bitmap_len = max_bkey + 1;
WARN_ON(method_elm->key_bitmap_len > UVERBS_API_ATTR_BKEY_LEN);
+ uapi_compute_bundle_size(method_elm, num_attrs);
return 0;
}