Skip to content

Commit

Permalink
IB/core: Move query port to ioctl
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Leon Romanovsky <[email protected]>
Signed-off-by: Jason Gunthorpe <[email protected]>
  • Loading branch information
mikijoy authored and jgunthorpe committed Dec 20, 2018
1 parent 4fa2813 commit 641d120
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 53 deletions.
25 changes: 25 additions & 0 deletions drivers/infiniband/core/uverbs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_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 */
53 changes: 1 addition & 52 deletions drivers/infiniband/core/uverbs_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,27 +361,6 @@ static int ib_uverbs_query_device(struct uverbs_attr_bundle *attrs)
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)
{
struct ib_uverbs_query_port cmd;
Expand All @@ -405,37 +384,7 @@ static int ib_uverbs_query_port(struct uverbs_attr_bundle *attrs)
return ret;

memset(&resp, 0, sizeof resp);

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);
copy_port_attr_to_resp(&attr, &resp, ib_dev, cmd.port_num);

return uverbs_response(attrs, &resp, sizeof(resp));
}
Expand Down
79 changes: 78 additions & 1 deletion drivers/infiniband/core/uverbs_std_types_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include <rdma/uverbs_std_types.h>
#include "rdma_core.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
Expand Down Expand Up @@ -127,6 +129,71 @@ static int UVERBS_HANDLER(UVERBS_METHOD_INFO_HANDLES)(
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(
UVERBS_METHOD_INFO_HANDLES,
/* Also includes any device specific object ids */
Expand All @@ -137,9 +204,19 @@ DECLARE_UVERBS_NAMED_METHOD(
UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_INFO_HANDLES_LIST,
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,
&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[] = {
UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_DEVICE),
Expand Down
7 changes: 7 additions & 0 deletions include/uapi/rdma/ib_user_ioctl_cmds.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ enum {
enum uverbs_methods_device {
UVERBS_METHOD_INVOKE_WRITE,
UVERBS_METHOD_INFO_HANDLES,
UVERBS_METHOD_QUERY_PORT,
};

enum uverbs_attrs_invoke_write_cmd_attr_ids {
Expand All @@ -74,6 +75,11 @@ enum uverbs_attrs_invoke_write_cmd_attr_ids {
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 {
UVERBS_ATTR_CREATE_CQ_HANDLE,
UVERBS_ATTR_CREATE_CQ_CQE,
Expand Down Expand Up @@ -234,4 +240,5 @@ enum uverbs_methods_flow {
enum uverbs_attrs_flow_destroy_ids {
UVERBS_ATTR_DESTROY_FLOW_HANDLE,
};

#endif
7 changes: 7 additions & 0 deletions include/uapi/rdma/ib_user_ioctl_verbs.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#define IB_USER_IOCTL_VERBS_H

#include <linux/types.h>
#include <rdma/ib_user_verbs.h>

#ifndef RDMA_UAPI_PTR
#define RDMA_UAPI_PTR(_type, _name) __aligned_u64 _name
Expand Down Expand Up @@ -166,4 +167,10 @@ enum ib_uverbs_advise_mr_flag {
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

0 comments on commit 641d120

Please sign in to comment.