RDMA: Fix storage of PortInfo CapabilityMask in the kernel
authorJason Gunthorpe <jgg@mellanox.com>
Wed, 4 Jul 2018 12:57:48 +0000 (15:57 +0300)
committerJason Gunthorpe <jgg@mellanox.com>
Tue, 10 Jul 2018 17:06:45 +0000 (11:06 -0600)
The internal flag IP_BASED_GIDS was added to a field that was being used
to hold the port Info CapabilityMask without considering the effects this
will have. Since most drivers just use the value from the HW MAD it means
IP_BASED_GIDS will also become set on any HW that sets the IBA flag
IsOtherLocalChangesNoticeSupported - which is not intended.

Fix this by keeping port_cap_flags only for the IBA CapabilityMask value
and store unrelated flags externally. Move the bit definitions for this to
ib_mad.h to make it clear what is happening.

To keep the uAPI unchanged define a new set of flags in the uapi header
that are only used by ib_uverbs_query_port_resp.port_cap_flags which match
the current flags supported in rdma-core, and the values exposed by the
current kernel.

Fixes: b4a26a27287a ("IB: Report using RoCE IP based gids in port caps")
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Signed-off-by: Artemy Kovalyov <artemyko@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
12 files changed:
drivers/infiniband/core/uverbs_cmd.c
drivers/infiniband/hw/bnxt_re/ib_verbs.c
drivers/infiniband/hw/mlx4/main.c
drivers/infiniband/hw/mlx5/main.c
drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
drivers/infiniband/hw/qedr/verbs.c
drivers/infiniband/hw/qib/qib_verbs.h
drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
include/rdma/ib_mad.h
include/rdma/ib_verbs.h
include/uapi/rdma/ib_user_ioctl_verbs.h
include/uapi/rdma/ib_user_verbs.h

index d048cabc424690c82d271c3403b1217a902cabbf..1bc9ceb16b701dad51aeee299bf3312733984132 100644 (file)
@@ -241,6 +241,27 @@ ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file,
        return in_len;
 }
 
+/*
+ * 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;
+}
+
 ssize_t ib_uverbs_query_port(struct ib_uverbs_file *file,
                             struct ib_device *ib_dev,
                             const char __user *buf,
@@ -267,7 +288,7 @@ ssize_t ib_uverbs_query_port(struct ib_uverbs_file *file,
        resp.max_mtu         = attr.max_mtu;
        resp.active_mtu      = attr.active_mtu;
        resp.gid_tbl_len     = attr.gid_tbl_len;
-       resp.port_cap_flags  = attr.port_cap_flags;
+       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;
index 6c0c6d3426e077c473d482693f06a2d2fb9ab8de..492c750f7ed63c740a36666ef3486e342075239d 100644 (file)
@@ -244,8 +244,8 @@ int bnxt_re_query_port(struct ib_device *ibdev, u8 port_num,
        port_attr->gid_tbl_len = dev_attr->max_sgid;
        port_attr->port_cap_flags = IB_PORT_CM_SUP | IB_PORT_REINIT_SUP |
                                    IB_PORT_DEVICE_MGMT_SUP |
-                                   IB_PORT_VENDOR_CLASS_SUP |
-                                   IB_PORT_IP_BASED_GIDS;
+                                   IB_PORT_VENDOR_CLASS_SUP;
+       port_attr->ip_gids = true;
 
        port_attr->max_msg_sz = (u32)BNXT_RE_MAX_MR_SIZE_LOW;
        port_attr->bad_pkey_cntr = 0;
index 5bc522ca9431ce84cb5213518cf83806d51d2141..ca0f1ee26091b38200b2447ccfe92324a3c0bd32 100644 (file)
@@ -762,7 +762,8 @@ static int eth_link_query_port(struct ib_device *ibdev, u8 port,
                                           IB_WIDTH_4X : IB_WIDTH_1X;
        props->active_speed     =  (((u8 *)mailbox->buf)[5] == 0x20 /*56Gb*/) ?
                                           IB_SPEED_FDR : IB_SPEED_QDR;
-       props->port_cap_flags   = IB_PORT_CM_SUP | IB_PORT_IP_BASED_GIDS;
+       props->port_cap_flags   = IB_PORT_CM_SUP;
+       props->ip_gids = true;
        props->gid_tbl_len      = mdev->dev->caps.gid_table_len[port];
        props->max_msg_sz       = mdev->dev->caps.max_msg_sz;
        props->pkey_tbl_len     = 1;
index 0f482d2a760fedbc5ed0ed2bb7d9830cd06b07ff..d1f1beefe599e057a3049942ac60980fe89c615a 100644 (file)
@@ -419,8 +419,8 @@ static int mlx5_query_port_roce(struct ib_device *device, u8 port_num,
        translate_eth_proto_oper(eth_prot_oper, &props->active_speed,
                                 &props->active_width);
 
-       props->port_cap_flags  |= IB_PORT_CM_SUP;
-       props->port_cap_flags  |= IB_PORT_IP_BASED_GIDS;
+       props->port_cap_flags |= IB_PORT_CM_SUP;
+       props->ip_gids = true;
 
        props->gid_tbl_len      = MLX5_CAP_ROCE(dev->mdev,
                                                roce_address_table_size);
index 1f057fdb3a8c35a393ab1872a61883edd77b5756..9d0431e01dce537b55b86b24e152d038624a09ac 100644 (file)
@@ -197,11 +197,10 @@ int ocrdma_query_port(struct ib_device *ibdev,
        props->sm_lid = 0;
        props->sm_sl = 0;
        props->state = port_state;
-       props->port_cap_flags =
-           IB_PORT_CM_SUP |
-           IB_PORT_REINIT_SUP |
-           IB_PORT_DEVICE_MGMT_SUP | IB_PORT_VENDOR_CLASS_SUP |
-           IB_PORT_IP_BASED_GIDS;
+       props->port_cap_flags = IB_PORT_CM_SUP | IB_PORT_REINIT_SUP |
+                               IB_PORT_DEVICE_MGMT_SUP |
+                               IB_PORT_VENDOR_CLASS_SUP;
+       props->ip_gids = true;
        props->gid_tbl_len = OCRDMA_MAX_SGID;
        props->pkey_tbl_len = 1;
        props->bad_pkey_cntr = 0;
index 0c41d54f586b4fc5dcc5596c8eeff1ff1cfce530..b82c5d5fb0e37870cb1806b613e813336e36c1bc 100644 (file)
@@ -225,7 +225,7 @@ int qedr_query_port(struct ib_device *ibdev, u8 port, struct ib_port_attr *attr)
        attr->lmc = 0;
        attr->sm_lid = 0;
        attr->sm_sl = 0;
-       attr->port_cap_flags = IB_PORT_IP_BASED_GIDS;
+       attr->ip_gids = true;
        if (rdma_protocol_iwarp(&dev->ibdev, 1)) {
                attr->gid_tbl_len = 1;
                attr->pkey_tbl_len = 1;
index f9a46768a19a4a8279429fe5c5b6645f00aeee8d..e72562a8959aedc36142a17d363c90eb1d548575 100644 (file)
@@ -78,9 +78,6 @@ struct qib_verbs_txreq;
 
 #define QIB_VENDOR_IPG         cpu_to_be16(0xFFA0)
 
-/* XXX Should be defined in ib_verbs.h enum ib_port_cap_flags */
-#define IB_PORT_OTHER_LOCAL_CHANGES_SUP (1 << 26)
-
 #define IB_DEFAULT_GID_PREFIX  cpu_to_be64(0xfe80000000000000ULL)
 
 /* Values for set/get portinfo VLCap OperationalVLs */
index 816cc285daf60be7950d2160997e259850882967..b65d10b0a87591e8d1049d95806b2208cc2120fd 100644 (file)
@@ -155,7 +155,8 @@ int pvrdma_query_port(struct ib_device *ibdev, u8 port,
        props->gid_tbl_len = resp->attrs.gid_tbl_len;
        props->port_cap_flags =
                pvrdma_port_cap_flags_to_ib(resp->attrs.port_cap_flags);
-       props->port_cap_flags |= IB_PORT_CM_SUP | IB_PORT_IP_BASED_GIDS;
+       props->port_cap_flags |= IB_PORT_CM_SUP;
+       props->ip_gids = true;
        props->max_msg_sz = resp->attrs.max_msg_sz;
        props->bad_pkey_cntr = resp->attrs.bad_pkey_cntr;
        props->qkey_viol_cntr = resp->attrs.qkey_viol_cntr;
index 2f4f1768ded4f7978a61e21ea43e7ef21fd4641e..f6ba366051c734607d5c09d0f63cf759fdc46a43 100644 (file)
@@ -262,6 +262,39 @@ struct ib_class_port_info {
        __be32                  trap_qkey;
 };
 
+/* PortInfo CapabilityMask */
+enum ib_port_capability_mask_bits {
+       IB_PORT_SM = 1 << 1,
+       IB_PORT_NOTICE_SUP = 1 << 2,
+       IB_PORT_TRAP_SUP = 1 << 3,
+       IB_PORT_OPT_IPD_SUP = 1 << 4,
+       IB_PORT_AUTO_MIGR_SUP = 1 << 5,
+       IB_PORT_SL_MAP_SUP = 1 << 6,
+       IB_PORT_MKEY_NVRAM = 1 << 7,
+       IB_PORT_PKEY_NVRAM = 1 << 8,
+       IB_PORT_LED_INFO_SUP = 1 << 9,
+       IB_PORT_SM_DISABLED = 1 << 10,
+       IB_PORT_SYS_IMAGE_GUID_SUP = 1 << 11,
+       IB_PORT_PKEY_SW_EXT_PORT_TRAP_SUP = 1 << 12,
+       IB_PORT_EXTENDED_SPEEDS_SUP = 1 << 14,
+       IB_PORT_CM_SUP = 1 << 16,
+       IB_PORT_SNMP_TUNNEL_SUP = 1 << 17,
+       IB_PORT_REINIT_SUP = 1 << 18,
+       IB_PORT_DEVICE_MGMT_SUP = 1 << 19,
+       IB_PORT_VENDOR_CLASS_SUP = 1 << 20,
+       IB_PORT_DR_NOTICE_SUP = 1 << 21,
+       IB_PORT_CAP_MASK_NOTICE_SUP = 1 << 22,
+       IB_PORT_BOOT_MGMT_SUP = 1 << 23,
+       IB_PORT_LINK_LATENCY_SUP = 1 << 24,
+       IB_PORT_CLIENT_REG_SUP = 1 << 25,
+       IB_PORT_OTHER_LOCAL_CHANGES_SUP = 1 << 26,
+       IB_PORT_LINK_SPEED_WIDTH_TABLE_SUP = 1 << 27,
+       IB_PORT_VENDOR_SPECIFIC_MADS_TABLE_SUP = 1 << 28,
+       IB_PORT_MCAST_PKEY_TRAP_SUPPRESSION_SUP = 1 << 29,
+       IB_PORT_MCAST_FDB_TOP_SUP = 1 << 30,
+       IB_PORT_HIERARCHY_INFO_SUP = 1ULL << 31,
+};
+
 #define OPA_CLASS_PORT_INFO_PR_SUPPORT BIT(26)
 
 struct opa_class_port_info {
index 031d121190fd9f686eb4cbbce41296ffc39e9f8d..98e0257597910217b8ea3565194634194d2f6bba 100644 (file)
@@ -432,33 +432,6 @@ enum ib_port_state {
        IB_PORT_ACTIVE_DEFER    = 5
 };
 
-enum ib_port_cap_flags {
-       IB_PORT_SM                              = 1 <<  1,
-       IB_PORT_NOTICE_SUP                      = 1 <<  2,
-       IB_PORT_TRAP_SUP                        = 1 <<  3,
-       IB_PORT_OPT_IPD_SUP                     = 1 <<  4,
-       IB_PORT_AUTO_MIGR_SUP                   = 1 <<  5,
-       IB_PORT_SL_MAP_SUP                      = 1 <<  6,
-       IB_PORT_MKEY_NVRAM                      = 1 <<  7,
-       IB_PORT_PKEY_NVRAM                      = 1 <<  8,
-       IB_PORT_LED_INFO_SUP                    = 1 <<  9,
-       IB_PORT_SM_DISABLED                     = 1 << 10,
-       IB_PORT_SYS_IMAGE_GUID_SUP              = 1 << 11,
-       IB_PORT_PKEY_SW_EXT_PORT_TRAP_SUP       = 1 << 12,
-       IB_PORT_EXTENDED_SPEEDS_SUP             = 1 << 14,
-       IB_PORT_CM_SUP                          = 1 << 16,
-       IB_PORT_SNMP_TUNNEL_SUP                 = 1 << 17,
-       IB_PORT_REINIT_SUP                      = 1 << 18,
-       IB_PORT_DEVICE_MGMT_SUP                 = 1 << 19,
-       IB_PORT_VENDOR_CLASS_SUP                = 1 << 20,
-       IB_PORT_DR_NOTICE_SUP                   = 1 << 21,
-       IB_PORT_CAP_MASK_NOTICE_SUP             = 1 << 22,
-       IB_PORT_BOOT_MGMT_SUP                   = 1 << 23,
-       IB_PORT_LINK_LATENCY_SUP                = 1 << 24,
-       IB_PORT_CLIENT_REG_SUP                  = 1 << 25,
-       IB_PORT_IP_BASED_GIDS                   = 1 << 26,
-};
-
 enum ib_port_width {
        IB_WIDTH_1X     = 1,
        IB_WIDTH_4X     = 2,
@@ -597,6 +570,9 @@ struct ib_port_attr {
        enum ib_mtu             max_mtu;
        enum ib_mtu             active_mtu;
        int                     gid_tbl_len;
+       unsigned int            grh_required:1;
+       unsigned int            ip_gids:1;
+       /* This is the value from PortInfo CapabilityMask, defined by IBA */
        u32                     port_cap_flags;
        u32                     max_msg_sz;
        u32                     bad_pkey_cntr;
@@ -612,7 +588,6 @@ struct ib_port_attr {
        u8                      active_width;
        u8                      active_speed;
        u8                      phys_state;
-       bool                    grh_required;
 };
 
 enum ib_device_modify_flags {
index 625545d862d7e479bb80b59d60dfdf86a19beada..1220f1df3deddf4488538c11067e8ddbd02cce9d 100644 (file)
 #define RDMA_UAPI_PTR(_type, _name)    __aligned_u64 _name
 #endif
 
+enum ib_uverbs_query_port_cap_flags {
+       IB_UVERBS_PCF_SM = 1 << 1,
+       IB_UVERBS_PCF_NOTICE_SUP = 1 << 2,
+       IB_UVERBS_PCF_TRAP_SUP = 1 << 3,
+       IB_UVERBS_PCF_OPT_IPD_SUP = 1 << 4,
+       IB_UVERBS_PCF_AUTO_MIGR_SUP = 1 << 5,
+       IB_UVERBS_PCF_SL_MAP_SUP = 1 << 6,
+       IB_UVERBS_PCF_MKEY_NVRAM = 1 << 7,
+       IB_UVERBS_PCF_PKEY_NVRAM = 1 << 8,
+       IB_UVERBS_PCF_LED_INFO_SUP = 1 << 9,
+       IB_UVERBS_PCF_SM_DISABLED = 1 << 10,
+       IB_UVERBS_PCF_SYS_IMAGE_GUID_SUP = 1 << 11,
+       IB_UVERBS_PCF_PKEY_SW_EXT_PORT_TRAP_SUP = 1 << 12,
+       IB_UVERBS_PCF_EXTENDED_SPEEDS_SUP = 1 << 14,
+       IB_UVERBS_PCF_CM_SUP = 1 << 16,
+       IB_UVERBS_PCF_SNMP_TUNNEL_SUP = 1 << 17,
+       IB_UVERBS_PCF_REINIT_SUP = 1 << 18,
+       IB_UVERBS_PCF_DEVICE_MGMT_SUP = 1 << 19,
+       IB_UVERBS_PCF_VENDOR_CLASS_SUP = 1 << 20,
+       IB_UVERBS_PCF_DR_NOTICE_SUP = 1 << 21,
+       IB_UVERBS_PCF_CAP_MASK_NOTICE_SUP = 1 << 22,
+       IB_UVERBS_PCF_BOOT_MGMT_SUP = 1 << 23,
+       IB_UVERBS_PCF_LINK_LATENCY_SUP = 1 << 24,
+       IB_UVERBS_PCF_CLIENT_REG_SUP = 1 << 25,
+       /*
+        * IsOtherLocalChangesNoticeSupported is aliased by IP_BASED_GIDS and
+        * is inaccessible
+        */
+       IB_UVERBS_PCF_LINK_SPEED_WIDTH_TABLE_SUP = 1 << 27,
+       IB_UVERBS_PCF_VENDOR_SPECIFIC_MADS_TABLE_SUP = 1 << 28,
+       IB_UVERBS_PCF_MCAST_PKEY_TRAP_SUPPRESSION_SUP = 1 << 29,
+       IB_UVERBS_PCF_MCAST_FDB_TOP_SUP = 1 << 30,
+       IB_UVERBS_PCF_HIERARCHY_INFO_SUP = 1ULL << 31,
+
+       /* NOTE this is an internal flag, not an IBA flag */
+       IB_UVERBS_PCF_IP_BASED_GIDS = 1 << 26,
+};
+
 enum ib_uverbs_flow_action_esp_keymat {
        IB_UVERBS_FLOW_ACTION_ESP_KEYMAT_AES_GCM,
 };
index 4f9991de8e3adccc8fcea97acf2cec2704a673fe..0a9070abb3f865bd1871092e70e8f9b01a002c70 100644 (file)
@@ -279,7 +279,7 @@ struct ib_uverbs_query_port {
 };
 
 struct ib_uverbs_query_port_resp {
-       __u32 port_cap_flags;
+       __u32 port_cap_flags;           /* see ib_uverbs_query_port_cap_flags */
        __u32 max_msg_sz;
        __u32 bad_pkey_cntr;
        __u32 qkey_viol_cntr;