Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

IB/core: Move query port to ioctl

Add a method for query port under the uverbs global methods. Current
ib_port_attr struct is passed as a single attribute and port_cap_flags2 is
added as a new attribute to the function.

Signed-off-by: Michael Guralnik <michaelgur@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>

authored by

Michael Guralnik and committed by
Jason Gunthorpe
641d1207 4fa2813d

+118 -53
+25
drivers/infiniband/core/uverbs.h
··· 293 293 extern const struct uverbs_object_def UVERBS_OBJECT(UVERBS_OBJECT_DM); 294 294 extern const struct uverbs_object_def UVERBS_OBJECT(UVERBS_OBJECT_COUNTERS); 295 295 296 + /* 297 + * ib_uverbs_query_port_resp.port_cap_flags started out as just a copy of the 298 + * PortInfo CapabilityMask, but was extended with unique bits. 299 + */ 300 + static inline u32 make_port_cap_flags(const struct ib_port_attr *attr) 301 + { 302 + u32 res; 303 + 304 + /* All IBA CapabilityMask bits are passed through here, except bit 26, 305 + * which is overridden with IP_BASED_GIDS. This is due to a historical 306 + * mistake in the implementation of IP_BASED_GIDS. Otherwise all other 307 + * bits match the IBA definition across all kernel versions. 308 + */ 309 + res = attr->port_cap_flags & ~(u32)IB_UVERBS_PCF_IP_BASED_GIDS; 310 + 311 + if (attr->ip_gids) 312 + res |= IB_UVERBS_PCF_IP_BASED_GIDS; 313 + 314 + return res; 315 + } 316 + 317 + 318 + void copy_port_attr_to_resp(struct ib_port_attr *attr, 319 + struct ib_uverbs_query_port_resp *resp, 320 + struct ib_device *ib_dev, u8 port_num); 296 321 #endif /* UVERBS_H */
+1 -52
drivers/infiniband/core/uverbs_cmd.c
··· 361 361 return uverbs_response(attrs, &resp, sizeof(resp)); 362 362 } 363 363 364 - /* 365 - * ib_uverbs_query_port_resp.port_cap_flags started out as just a copy of the 366 - * PortInfo CapabilityMask, but was extended with unique bits. 367 - */ 368 - static u32 make_port_cap_flags(const struct ib_port_attr *attr) 369 - { 370 - u32 res; 371 - 372 - /* All IBA CapabilityMask bits are passed through here, except bit 26, 373 - * which is overridden with IP_BASED_GIDS. This is due to a historical 374 - * mistake in the implementation of IP_BASED_GIDS. Otherwise all other 375 - * bits match the IBA definition across all kernel versions. 376 - */ 377 - res = attr->port_cap_flags & ~(u32)IB_UVERBS_PCF_IP_BASED_GIDS; 378 - 379 - if (attr->ip_gids) 380 - res |= IB_UVERBS_PCF_IP_BASED_GIDS; 381 - 382 - return res; 383 - } 384 - 385 364 static int ib_uverbs_query_port(struct uverbs_attr_bundle *attrs) 386 365 { 387 366 struct ib_uverbs_query_port cmd; ··· 384 405 return ret; 385 406 386 407 memset(&resp, 0, sizeof resp); 387 - 388 - resp.state = attr.state; 389 - resp.max_mtu = attr.max_mtu; 390 - resp.active_mtu = attr.active_mtu; 391 - resp.gid_tbl_len = attr.gid_tbl_len; 392 - resp.port_cap_flags = make_port_cap_flags(&attr); 393 - resp.max_msg_sz = attr.max_msg_sz; 394 - resp.bad_pkey_cntr = attr.bad_pkey_cntr; 395 - resp.qkey_viol_cntr = attr.qkey_viol_cntr; 396 - resp.pkey_tbl_len = attr.pkey_tbl_len; 397 - 398 - if (rdma_is_grh_required(ib_dev, cmd.port_num)) 399 - resp.flags |= IB_UVERBS_QPF_GRH_REQUIRED; 400 - 401 - if (rdma_cap_opa_ah(ib_dev, cmd.port_num)) { 402 - resp.lid = OPA_TO_IB_UCAST_LID(attr.lid); 403 - resp.sm_lid = OPA_TO_IB_UCAST_LID(attr.sm_lid); 404 - } else { 405 - resp.lid = ib_lid_cpu16(attr.lid); 406 - resp.sm_lid = ib_lid_cpu16(attr.sm_lid); 407 - } 408 - resp.lmc = attr.lmc; 409 - resp.max_vl_num = attr.max_vl_num; 410 - resp.sm_sl = attr.sm_sl; 411 - resp.subnet_timeout = attr.subnet_timeout; 412 - resp.init_type_reply = attr.init_type_reply; 413 - resp.active_width = attr.active_width; 414 - resp.active_speed = attr.active_speed; 415 - resp.phys_state = attr.phys_state; 416 - resp.link_layer = rdma_port_get_link_layer(ib_dev, 417 - cmd.port_num); 408 + copy_port_attr_to_resp(&attr, &resp, ib_dev, cmd.port_num); 418 409 419 410 return uverbs_response(attrs, &resp, sizeof(resp)); 420 411 }
+78 -1
drivers/infiniband/core/uverbs_std_types_device.c
··· 6 6 #include <rdma/uverbs_std_types.h> 7 7 #include "rdma_core.h" 8 8 #include "uverbs.h" 9 + #include <rdma/uverbs_ioctl.h> 10 + #include <rdma/opa_addr.h> 9 11 10 12 /* 11 13 * This ioctl method allows calling any defined write or write_ex ··· 129 127 return ret; 130 128 } 131 129 130 + void copy_port_attr_to_resp(struct ib_port_attr *attr, 131 + struct ib_uverbs_query_port_resp *resp, 132 + struct ib_device *ib_dev, u8 port_num) 133 + { 134 + resp->state = attr->state; 135 + resp->max_mtu = attr->max_mtu; 136 + resp->active_mtu = attr->active_mtu; 137 + resp->gid_tbl_len = attr->gid_tbl_len; 138 + resp->port_cap_flags = make_port_cap_flags(attr); 139 + resp->max_msg_sz = attr->max_msg_sz; 140 + resp->bad_pkey_cntr = attr->bad_pkey_cntr; 141 + resp->qkey_viol_cntr = attr->qkey_viol_cntr; 142 + resp->pkey_tbl_len = attr->pkey_tbl_len; 143 + 144 + if (rdma_is_grh_required(ib_dev, port_num)) 145 + resp->flags |= IB_UVERBS_QPF_GRH_REQUIRED; 146 + 147 + if (rdma_cap_opa_ah(ib_dev, port_num)) { 148 + resp->lid = OPA_TO_IB_UCAST_LID(attr->lid); 149 + resp->sm_lid = OPA_TO_IB_UCAST_LID(attr->sm_lid); 150 + } else { 151 + resp->lid = ib_lid_cpu16(attr->lid); 152 + resp->sm_lid = ib_lid_cpu16(attr->sm_lid); 153 + } 154 + 155 + resp->lmc = attr->lmc; 156 + resp->max_vl_num = attr->max_vl_num; 157 + resp->sm_sl = attr->sm_sl; 158 + resp->subnet_timeout = attr->subnet_timeout; 159 + resp->init_type_reply = attr->init_type_reply; 160 + resp->active_width = attr->active_width; 161 + resp->active_speed = attr->active_speed; 162 + resp->phys_state = attr->phys_state; 163 + resp->link_layer = rdma_port_get_link_layer(ib_dev, port_num); 164 + } 165 + 166 + static int UVERBS_HANDLER(UVERBS_METHOD_QUERY_PORT)( 167 + struct uverbs_attr_bundle *attrs) 168 + { 169 + struct ib_device *ib_dev = attrs->ufile->device->ib_dev; 170 + struct ib_port_attr attr = {}; 171 + struct ib_uverbs_query_port_resp_ex resp = {}; 172 + int ret; 173 + u8 port_num; 174 + 175 + /* FIXME: Extend the UAPI_DEF_OBJ_NEEDS_FN stuff.. */ 176 + if (!ib_dev->ops.query_port) 177 + return -EOPNOTSUPP; 178 + 179 + ret = uverbs_get_const(&port_num, attrs, 180 + UVERBS_ATTR_QUERY_PORT_PORT_NUM); 181 + if (ret) 182 + return ret; 183 + 184 + ret = ib_query_port(ib_dev, port_num, &attr); 185 + if (ret) 186 + return ret; 187 + 188 + copy_port_attr_to_resp(&attr, &resp.legacy_resp, ib_dev, port_num); 189 + resp.port_cap_flags2 = attr.port_cap_flags2; 190 + 191 + return uverbs_copy_to_struct_or_zero(attrs, UVERBS_ATTR_QUERY_PORT_RESP, 192 + &resp, sizeof(resp)); 193 + } 194 + 132 195 DECLARE_UVERBS_NAMED_METHOD( 133 196 UVERBS_METHOD_INFO_HANDLES, 134 197 /* Also includes any device specific object ids */ ··· 204 137 UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_INFO_HANDLES_LIST, 205 138 UVERBS_ATTR_MIN_SIZE(sizeof(u32)), UA_OPTIONAL)); 206 139 140 + DECLARE_UVERBS_NAMED_METHOD( 141 + UVERBS_METHOD_QUERY_PORT, 142 + UVERBS_ATTR_CONST_IN(UVERBS_ATTR_QUERY_PORT_PORT_NUM, u8, UA_MANDATORY), 143 + UVERBS_ATTR_PTR_OUT( 144 + UVERBS_ATTR_QUERY_PORT_RESP, 145 + UVERBS_ATTR_STRUCT(struct ib_uverbs_query_port_resp_ex, 146 + reserved), 147 + UA_MANDATORY)); 148 + 207 149 DECLARE_UVERBS_GLOBAL_METHODS(UVERBS_OBJECT_DEVICE, 208 150 &UVERBS_METHOD(UVERBS_METHOD_INVOKE_WRITE), 209 - &UVERBS_METHOD(UVERBS_METHOD_INFO_HANDLES)); 151 + &UVERBS_METHOD(UVERBS_METHOD_INFO_HANDLES), 152 + &UVERBS_METHOD(UVERBS_METHOD_QUERY_PORT)); 210 153 211 154 const struct uapi_definition uverbs_def_obj_device[] = { 212 155 UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_DEVICE),
+7
include/uapi/rdma/ib_user_ioctl_cmds.h
··· 66 66 enum uverbs_methods_device { 67 67 UVERBS_METHOD_INVOKE_WRITE, 68 68 UVERBS_METHOD_INFO_HANDLES, 69 + UVERBS_METHOD_QUERY_PORT, 69 70 }; 70 71 71 72 enum uverbs_attrs_invoke_write_cmd_attr_ids { 72 73 UVERBS_ATTR_CORE_IN, 73 74 UVERBS_ATTR_CORE_OUT, 74 75 UVERBS_ATTR_WRITE_CMD, 76 + }; 77 + 78 + enum uverbs_attrs_query_port_cmd_attr_ids { 79 + UVERBS_ATTR_QUERY_PORT_PORT_NUM, 80 + UVERBS_ATTR_QUERY_PORT_RESP, 75 81 }; 76 82 77 83 enum uverbs_attrs_create_cq_cmd_attr_ids { ··· 240 234 enum uverbs_attrs_flow_destroy_ids { 241 235 UVERBS_ATTR_DESTROY_FLOW_HANDLE, 242 236 }; 237 + 243 238 #endif
+7
include/uapi/rdma/ib_user_ioctl_verbs.h
··· 35 35 #define IB_USER_IOCTL_VERBS_H 36 36 37 37 #include <linux/types.h> 38 + #include <rdma/ib_user_verbs.h> 38 39 39 40 #ifndef RDMA_UAPI_PTR 40 41 #define RDMA_UAPI_PTR(_type, _name) __aligned_u64 _name ··· 165 164 166 165 enum ib_uverbs_advise_mr_flag { 167 166 IB_UVERBS_ADVISE_MR_FLAG_FLUSH = 1 << 0, 167 + }; 168 + 169 + struct ib_uverbs_query_port_resp_ex { 170 + struct ib_uverbs_query_port_resp legacy_resp; 171 + __u16 port_cap_flags2; 172 + __u8 reserved[6]; 168 173 }; 169 174 170 175 #endif