forked from mirrors/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>
This commit is contained in:
		
							parent
							
								
									4fa2813d26
								
							
						
					
					
						commit
						641d1207d2
					
				
					 5 changed files with 118 additions and 53 deletions
				
			
		| 
						 | 
					@ -293,4 +293,29 @@ extern const struct uverbs_object_def UVERBS_OBJECT(UVERBS_OBJECT_FLOW_ACTION);
 | 
				
			||||||
extern const struct uverbs_object_def UVERBS_OBJECT(UVERBS_OBJECT_DM);
 | 
					extern const struct uverbs_object_def UVERBS_OBJECT(UVERBS_OBJECT_DM);
 | 
				
			||||||
extern const struct uverbs_object_def UVERBS_OBJECT(UVERBS_OBJECT_COUNTERS);
 | 
					extern const struct uverbs_object_def UVERBS_OBJECT(UVERBS_OBJECT_COUNTERS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * ib_uverbs_query_port_resp.port_cap_flags started out as just a copy of the
 | 
				
			||||||
 | 
					 * PortInfo CapabilityMask, but was extended with unique bits.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline u32 make_port_cap_flags(const struct ib_port_attr *attr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u32 res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* All IBA CapabilityMask bits are passed through here, except bit 26,
 | 
				
			||||||
 | 
						 * which is overridden with IP_BASED_GIDS. This is due to a historical
 | 
				
			||||||
 | 
						 * mistake in the implementation of IP_BASED_GIDS. Otherwise all other
 | 
				
			||||||
 | 
						 * bits match the IBA definition across all kernel versions.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						res = attr->port_cap_flags & ~(u32)IB_UVERBS_PCF_IP_BASED_GIDS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (attr->ip_gids)
 | 
				
			||||||
 | 
							res |= IB_UVERBS_PCF_IP_BASED_GIDS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void copy_port_attr_to_resp(struct ib_port_attr *attr,
 | 
				
			||||||
 | 
								    struct ib_uverbs_query_port_resp *resp,
 | 
				
			||||||
 | 
								    struct ib_device *ib_dev, u8 port_num);
 | 
				
			||||||
#endif /* UVERBS_H */
 | 
					#endif /* UVERBS_H */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -361,27 +361,6 @@ static int ib_uverbs_query_device(struct uverbs_attr_bundle *attrs)
 | 
				
			||||||
	return uverbs_response(attrs, &resp, sizeof(resp));
 | 
						return uverbs_response(attrs, &resp, sizeof(resp));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * ib_uverbs_query_port_resp.port_cap_flags started out as just a copy of the
 | 
					 | 
				
			||||||
 * PortInfo CapabilityMask, but was extended with unique bits.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static u32 make_port_cap_flags(const struct ib_port_attr *attr)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	u32 res;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* All IBA CapabilityMask bits are passed through here, except bit 26,
 | 
					 | 
				
			||||||
	 * which is overridden with IP_BASED_GIDS. This is due to a historical
 | 
					 | 
				
			||||||
	 * mistake in the implementation of IP_BASED_GIDS. Otherwise all other
 | 
					 | 
				
			||||||
	 * bits match the IBA definition across all kernel versions.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	res = attr->port_cap_flags & ~(u32)IB_UVERBS_PCF_IP_BASED_GIDS;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (attr->ip_gids)
 | 
					 | 
				
			||||||
		res |= IB_UVERBS_PCF_IP_BASED_GIDS;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return res;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int ib_uverbs_query_port(struct uverbs_attr_bundle *attrs)
 | 
					static int ib_uverbs_query_port(struct uverbs_attr_bundle *attrs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct ib_uverbs_query_port      cmd;
 | 
						struct ib_uverbs_query_port      cmd;
 | 
				
			||||||
| 
						 | 
					@ -405,37 +384,7 @@ static int ib_uverbs_query_port(struct uverbs_attr_bundle *attrs)
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset(&resp, 0, sizeof resp);
 | 
						memset(&resp, 0, sizeof resp);
 | 
				
			||||||
 | 
						copy_port_attr_to_resp(&attr, &resp, ib_dev, cmd.port_num);
 | 
				
			||||||
	resp.state 	     = attr.state;
 | 
					 | 
				
			||||||
	resp.max_mtu 	     = attr.max_mtu;
 | 
					 | 
				
			||||||
	resp.active_mtu      = attr.active_mtu;
 | 
					 | 
				
			||||||
	resp.gid_tbl_len     = attr.gid_tbl_len;
 | 
					 | 
				
			||||||
	resp.port_cap_flags  = make_port_cap_flags(&attr);
 | 
					 | 
				
			||||||
	resp.max_msg_sz      = attr.max_msg_sz;
 | 
					 | 
				
			||||||
	resp.bad_pkey_cntr   = attr.bad_pkey_cntr;
 | 
					 | 
				
			||||||
	resp.qkey_viol_cntr  = attr.qkey_viol_cntr;
 | 
					 | 
				
			||||||
	resp.pkey_tbl_len    = attr.pkey_tbl_len;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (rdma_is_grh_required(ib_dev, cmd.port_num))
 | 
					 | 
				
			||||||
		resp.flags |= IB_UVERBS_QPF_GRH_REQUIRED;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (rdma_cap_opa_ah(ib_dev, cmd.port_num)) {
 | 
					 | 
				
			||||||
		resp.lid     = OPA_TO_IB_UCAST_LID(attr.lid);
 | 
					 | 
				
			||||||
		resp.sm_lid  = OPA_TO_IB_UCAST_LID(attr.sm_lid);
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		resp.lid     = ib_lid_cpu16(attr.lid);
 | 
					 | 
				
			||||||
		resp.sm_lid  = ib_lid_cpu16(attr.sm_lid);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	resp.lmc 	     = attr.lmc;
 | 
					 | 
				
			||||||
	resp.max_vl_num      = attr.max_vl_num;
 | 
					 | 
				
			||||||
	resp.sm_sl 	     = attr.sm_sl;
 | 
					 | 
				
			||||||
	resp.subnet_timeout  = attr.subnet_timeout;
 | 
					 | 
				
			||||||
	resp.init_type_reply = attr.init_type_reply;
 | 
					 | 
				
			||||||
	resp.active_width    = attr.active_width;
 | 
					 | 
				
			||||||
	resp.active_speed    = attr.active_speed;
 | 
					 | 
				
			||||||
	resp.phys_state      = attr.phys_state;
 | 
					 | 
				
			||||||
	resp.link_layer      = rdma_port_get_link_layer(ib_dev,
 | 
					 | 
				
			||||||
							cmd.port_num);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return uverbs_response(attrs, &resp, sizeof(resp));
 | 
						return uverbs_response(attrs, &resp, sizeof(resp));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,8 @@
 | 
				
			||||||
#include <rdma/uverbs_std_types.h>
 | 
					#include <rdma/uverbs_std_types.h>
 | 
				
			||||||
#include "rdma_core.h"
 | 
					#include "rdma_core.h"
 | 
				
			||||||
#include "uverbs.h"
 | 
					#include "uverbs.h"
 | 
				
			||||||
 | 
					#include <rdma/uverbs_ioctl.h>
 | 
				
			||||||
 | 
					#include <rdma/opa_addr.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * This ioctl method allows calling any defined write or write_ex
 | 
					 * This ioctl method allows calling any defined write or write_ex
 | 
				
			||||||
| 
						 | 
					@ -127,6 +129,71 @@ static int UVERBS_HANDLER(UVERBS_METHOD_INFO_HANDLES)(
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void copy_port_attr_to_resp(struct ib_port_attr *attr,
 | 
				
			||||||
 | 
								    struct ib_uverbs_query_port_resp *resp,
 | 
				
			||||||
 | 
								    struct ib_device *ib_dev, u8 port_num)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						resp->state = attr->state;
 | 
				
			||||||
 | 
						resp->max_mtu = attr->max_mtu;
 | 
				
			||||||
 | 
						resp->active_mtu = attr->active_mtu;
 | 
				
			||||||
 | 
						resp->gid_tbl_len = attr->gid_tbl_len;
 | 
				
			||||||
 | 
						resp->port_cap_flags = make_port_cap_flags(attr);
 | 
				
			||||||
 | 
						resp->max_msg_sz = attr->max_msg_sz;
 | 
				
			||||||
 | 
						resp->bad_pkey_cntr = attr->bad_pkey_cntr;
 | 
				
			||||||
 | 
						resp->qkey_viol_cntr = attr->qkey_viol_cntr;
 | 
				
			||||||
 | 
						resp->pkey_tbl_len = attr->pkey_tbl_len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (rdma_is_grh_required(ib_dev, port_num))
 | 
				
			||||||
 | 
							resp->flags |= IB_UVERBS_QPF_GRH_REQUIRED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (rdma_cap_opa_ah(ib_dev, port_num)) {
 | 
				
			||||||
 | 
							resp->lid = OPA_TO_IB_UCAST_LID(attr->lid);
 | 
				
			||||||
 | 
							resp->sm_lid = OPA_TO_IB_UCAST_LID(attr->sm_lid);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							resp->lid = ib_lid_cpu16(attr->lid);
 | 
				
			||||||
 | 
							resp->sm_lid = ib_lid_cpu16(attr->sm_lid);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						resp->lmc = attr->lmc;
 | 
				
			||||||
 | 
						resp->max_vl_num = attr->max_vl_num;
 | 
				
			||||||
 | 
						resp->sm_sl = attr->sm_sl;
 | 
				
			||||||
 | 
						resp->subnet_timeout = attr->subnet_timeout;
 | 
				
			||||||
 | 
						resp->init_type_reply = attr->init_type_reply;
 | 
				
			||||||
 | 
						resp->active_width = attr->active_width;
 | 
				
			||||||
 | 
						resp->active_speed = attr->active_speed;
 | 
				
			||||||
 | 
						resp->phys_state = attr->phys_state;
 | 
				
			||||||
 | 
						resp->link_layer = rdma_port_get_link_layer(ib_dev, port_num);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int UVERBS_HANDLER(UVERBS_METHOD_QUERY_PORT)(
 | 
				
			||||||
 | 
						struct uverbs_attr_bundle *attrs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ib_device *ib_dev = attrs->ufile->device->ib_dev;
 | 
				
			||||||
 | 
						struct ib_port_attr attr = {};
 | 
				
			||||||
 | 
						struct ib_uverbs_query_port_resp_ex resp = {};
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
						u8 port_num;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* FIXME: Extend the UAPI_DEF_OBJ_NEEDS_FN stuff.. */
 | 
				
			||||||
 | 
						if (!ib_dev->ops.query_port)
 | 
				
			||||||
 | 
							return -EOPNOTSUPP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = uverbs_get_const(&port_num, attrs,
 | 
				
			||||||
 | 
								       UVERBS_ATTR_QUERY_PORT_PORT_NUM);
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = ib_query_port(ib_dev, port_num, &attr);
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						copy_port_attr_to_resp(&attr, &resp.legacy_resp, ib_dev, port_num);
 | 
				
			||||||
 | 
						resp.port_cap_flags2 = attr.port_cap_flags2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return uverbs_copy_to_struct_or_zero(attrs, UVERBS_ATTR_QUERY_PORT_RESP,
 | 
				
			||||||
 | 
										     &resp, sizeof(resp));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DECLARE_UVERBS_NAMED_METHOD(
 | 
					DECLARE_UVERBS_NAMED_METHOD(
 | 
				
			||||||
	UVERBS_METHOD_INFO_HANDLES,
 | 
						UVERBS_METHOD_INFO_HANDLES,
 | 
				
			||||||
	/* Also includes any device specific object ids */
 | 
						/* Also includes any device specific object ids */
 | 
				
			||||||
| 
						 | 
					@ -137,9 +204,19 @@ DECLARE_UVERBS_NAMED_METHOD(
 | 
				
			||||||
	UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_INFO_HANDLES_LIST,
 | 
						UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_INFO_HANDLES_LIST,
 | 
				
			||||||
			    UVERBS_ATTR_MIN_SIZE(sizeof(u32)), UA_OPTIONAL));
 | 
								    UVERBS_ATTR_MIN_SIZE(sizeof(u32)), UA_OPTIONAL));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DECLARE_UVERBS_NAMED_METHOD(
 | 
				
			||||||
 | 
						UVERBS_METHOD_QUERY_PORT,
 | 
				
			||||||
 | 
						UVERBS_ATTR_CONST_IN(UVERBS_ATTR_QUERY_PORT_PORT_NUM, u8, UA_MANDATORY),
 | 
				
			||||||
 | 
						UVERBS_ATTR_PTR_OUT(
 | 
				
			||||||
 | 
							UVERBS_ATTR_QUERY_PORT_RESP,
 | 
				
			||||||
 | 
							UVERBS_ATTR_STRUCT(struct ib_uverbs_query_port_resp_ex,
 | 
				
			||||||
 | 
									   reserved),
 | 
				
			||||||
 | 
							UA_MANDATORY));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DECLARE_UVERBS_GLOBAL_METHODS(UVERBS_OBJECT_DEVICE,
 | 
					DECLARE_UVERBS_GLOBAL_METHODS(UVERBS_OBJECT_DEVICE,
 | 
				
			||||||
			      &UVERBS_METHOD(UVERBS_METHOD_INVOKE_WRITE),
 | 
								      &UVERBS_METHOD(UVERBS_METHOD_INVOKE_WRITE),
 | 
				
			||||||
			      &UVERBS_METHOD(UVERBS_METHOD_INFO_HANDLES));
 | 
								      &UVERBS_METHOD(UVERBS_METHOD_INFO_HANDLES),
 | 
				
			||||||
 | 
								      &UVERBS_METHOD(UVERBS_METHOD_QUERY_PORT));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct uapi_definition uverbs_def_obj_device[] = {
 | 
					const struct uapi_definition uverbs_def_obj_device[] = {
 | 
				
			||||||
	UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_DEVICE),
 | 
						UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_DEVICE),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -66,6 +66,7 @@ enum {
 | 
				
			||||||
enum uverbs_methods_device {
 | 
					enum uverbs_methods_device {
 | 
				
			||||||
	UVERBS_METHOD_INVOKE_WRITE,
 | 
						UVERBS_METHOD_INVOKE_WRITE,
 | 
				
			||||||
	UVERBS_METHOD_INFO_HANDLES,
 | 
						UVERBS_METHOD_INFO_HANDLES,
 | 
				
			||||||
 | 
						UVERBS_METHOD_QUERY_PORT,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum uverbs_attrs_invoke_write_cmd_attr_ids {
 | 
					enum uverbs_attrs_invoke_write_cmd_attr_ids {
 | 
				
			||||||
| 
						 | 
					@ -74,6 +75,11 @@ enum uverbs_attrs_invoke_write_cmd_attr_ids {
 | 
				
			||||||
	UVERBS_ATTR_WRITE_CMD,
 | 
						UVERBS_ATTR_WRITE_CMD,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum uverbs_attrs_query_port_cmd_attr_ids {
 | 
				
			||||||
 | 
						UVERBS_ATTR_QUERY_PORT_PORT_NUM,
 | 
				
			||||||
 | 
						UVERBS_ATTR_QUERY_PORT_RESP,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum uverbs_attrs_create_cq_cmd_attr_ids {
 | 
					enum uverbs_attrs_create_cq_cmd_attr_ids {
 | 
				
			||||||
	UVERBS_ATTR_CREATE_CQ_HANDLE,
 | 
						UVERBS_ATTR_CREATE_CQ_HANDLE,
 | 
				
			||||||
	UVERBS_ATTR_CREATE_CQ_CQE,
 | 
						UVERBS_ATTR_CREATE_CQ_CQE,
 | 
				
			||||||
| 
						 | 
					@ -234,4 +240,5 @@ enum uverbs_methods_flow {
 | 
				
			||||||
enum uverbs_attrs_flow_destroy_ids {
 | 
					enum uverbs_attrs_flow_destroy_ids {
 | 
				
			||||||
	UVERBS_ATTR_DESTROY_FLOW_HANDLE,
 | 
						UVERBS_ATTR_DESTROY_FLOW_HANDLE,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,6 +35,7 @@
 | 
				
			||||||
#define IB_USER_IOCTL_VERBS_H
 | 
					#define IB_USER_IOCTL_VERBS_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <linux/types.h>
 | 
					#include <linux/types.h>
 | 
				
			||||||
 | 
					#include <rdma/ib_user_verbs.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef RDMA_UAPI_PTR
 | 
					#ifndef RDMA_UAPI_PTR
 | 
				
			||||||
#define RDMA_UAPI_PTR(_type, _name)	__aligned_u64 _name
 | 
					#define RDMA_UAPI_PTR(_type, _name)	__aligned_u64 _name
 | 
				
			||||||
| 
						 | 
					@ -166,4 +167,10 @@ enum ib_uverbs_advise_mr_flag {
 | 
				
			||||||
	IB_UVERBS_ADVISE_MR_FLAG_FLUSH = 1 << 0,
 | 
						IB_UVERBS_ADVISE_MR_FLAG_FLUSH = 1 << 0,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ib_uverbs_query_port_resp_ex {
 | 
				
			||||||
 | 
						struct ib_uverbs_query_port_resp legacy_resp;
 | 
				
			||||||
 | 
						__u16 port_cap_flags2;
 | 
				
			||||||
 | 
						__u8  reserved[6];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue