aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorHaggai Eran <haggaie@mellanox.com>2015-02-08 06:28:51 -0500
committerRoland Dreier <roland@purestorage.com>2015-02-18 11:36:26 -0500
commitf4056bfd8ccff4475417078d6e5456dfa1962dd3 (patch)
tree55d91fc332726876bf87ca386c7a1308da13d6d7 /drivers/infiniband
parent02d1aa7af17ef0e0655745ce32cab369ed040a67 (diff)
IB/core: Add on demand paging caps to ib_uverbs_ex_query_device
Add on-demand paging capabilities reporting to the extended query device verb. Yann Droneaud writes: Note: as offsetof() is used to retrieve the size of the lower chunk of the response, beware that it only works if the upper chunk is right after, without any implicit padding. And, as the size of the latter chunk is added to the base size, implicit padding at the end of the structure is not taken in account. Both point must be taken in account when extending the uverbs functionalities. Signed-off-by: Haggai Eran <haggaie@mellanox.com> Reviewed-by: Yann Droneaud <ydroneaud@opteya.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index 8f507538c42b..04ca04559ce5 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -3318,7 +3318,7 @@ int ib_uverbs_ex_query_device(struct ib_uverbs_file *file,
3318 if (cmd.reserved) 3318 if (cmd.reserved)
3319 return -EINVAL; 3319 return -EINVAL;
3320 3320
3321 resp.response_length = sizeof(resp); 3321 resp.response_length = offsetof(typeof(resp), odp_caps);
3322 3322
3323 if (ucore->outlen < resp.response_length) 3323 if (ucore->outlen < resp.response_length)
3324 return -ENOSPC; 3324 return -ENOSPC;
@@ -3330,6 +3330,24 @@ int ib_uverbs_ex_query_device(struct ib_uverbs_file *file,
3330 copy_query_dev_fields(file, &resp.base, &attr); 3330 copy_query_dev_fields(file, &resp.base, &attr);
3331 resp.comp_mask = 0; 3331 resp.comp_mask = 0;
3332 3332
3333 if (ucore->outlen < resp.response_length + sizeof(resp.odp_caps))
3334 goto end;
3335
3336#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
3337 resp.odp_caps.general_caps = attr.odp_caps.general_caps;
3338 resp.odp_caps.per_transport_caps.rc_odp_caps =
3339 attr.odp_caps.per_transport_caps.rc_odp_caps;
3340 resp.odp_caps.per_transport_caps.uc_odp_caps =
3341 attr.odp_caps.per_transport_caps.uc_odp_caps;
3342 resp.odp_caps.per_transport_caps.ud_odp_caps =
3343 attr.odp_caps.per_transport_caps.ud_odp_caps;
3344 resp.odp_caps.reserved = 0;
3345#else
3346 memset(&resp.odp_caps, 0, sizeof(resp.odp_caps));
3347#endif
3348 resp.response_length += sizeof(resp.odp_caps);
3349
3350end:
3333 err = ib_copy_to_udata(ucore, &resp, resp.response_length); 3351 err = ib_copy_to_udata(ucore, &resp, resp.response_length);
3334 if (err) 3352 if (err)
3335 return err; 3353 return err;