summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHaggai Eran <haggaie@mellanox.com>2015-02-08 13:28:51 +0200
committerRoland Dreier <roland@purestorage.com>2015-02-18 08:36:26 -0800
commitf4056bfd8ccff4475417078d6e5456dfa1962dd3 (patch)
tree55d91fc332726876bf87ca386c7a1308da13d6d7
parent02d1aa7af17ef0e0655745ce32cab369ed040a67 (diff)
downloadlinux-f4056bfd8ccff4475417078d6e5456dfa1962dd3.tar.bz2
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>
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c20
-rw-r--r--include/uapi/rdma/ib_user_verbs.h11
2 files changed, 30 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,
if (cmd.reserved)
return -EINVAL;
- resp.response_length = sizeof(resp);
+ resp.response_length = offsetof(typeof(resp), odp_caps);
if (ucore->outlen < resp.response_length)
return -ENOSPC;
@@ -3330,6 +3330,24 @@ int ib_uverbs_ex_query_device(struct ib_uverbs_file *file,
copy_query_dev_fields(file, &resp.base, &attr);
resp.comp_mask = 0;
+ if (ucore->outlen < resp.response_length + sizeof(resp.odp_caps))
+ goto end;
+
+#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
+ resp.odp_caps.general_caps = attr.odp_caps.general_caps;
+ resp.odp_caps.per_transport_caps.rc_odp_caps =
+ attr.odp_caps.per_transport_caps.rc_odp_caps;
+ resp.odp_caps.per_transport_caps.uc_odp_caps =
+ attr.odp_caps.per_transport_caps.uc_odp_caps;
+ resp.odp_caps.per_transport_caps.ud_odp_caps =
+ attr.odp_caps.per_transport_caps.ud_odp_caps;
+ resp.odp_caps.reserved = 0;
+#else
+ memset(&resp.odp_caps, 0, sizeof(resp.odp_caps));
+#endif
+ resp.response_length += sizeof(resp.odp_caps);
+
+end:
err = ib_copy_to_udata(ucore, &resp, resp.response_length);
if (err)
return err;
diff --git a/include/uapi/rdma/ib_user_verbs.h b/include/uapi/rdma/ib_user_verbs.h
index f0f799afd856..b513e662d8e4 100644
--- a/include/uapi/rdma/ib_user_verbs.h
+++ b/include/uapi/rdma/ib_user_verbs.h
@@ -207,10 +207,21 @@ struct ib_uverbs_ex_query_device {
__u32 reserved;
};
+struct ib_uverbs_odp_caps {
+ __u64 general_caps;
+ struct {
+ __u32 rc_odp_caps;
+ __u32 uc_odp_caps;
+ __u32 ud_odp_caps;
+ } per_transport_caps;
+ __u32 reserved;
+};
+
struct ib_uverbs_ex_query_device_resp {
struct ib_uverbs_query_device_resp base;
__u32 comp_mask;
__u32 response_length;
+ struct ib_uverbs_odp_caps odp_caps;
};
struct ib_uverbs_query_port {