IB/mad: Add support for additional MAD info to/from drivers
authorIra Weiny <ira.weiny@intel.com>
Sat, 6 Jun 2015 18:38:31 +0000 (14:38 -0400)
committerDoug Ledford <dledford@redhat.com>
Fri, 12 Jun 2015 18:49:17 +0000 (14:49 -0400)
In order to support alternate sized MADs (and variable sized MADs on OPA
devices) add in/out MAD size parameters to the process_mad core call.

In addition, add an out_mad_pkey_index to communicate the pkey index the driver
wishes the MAD stack to use when sending OPA MAD responses.

The out MAD size and the out MAD PKey index are required by the MAD
stack to generate responses on OPA devices.

Furthermore, the in and out MAD parameters are made generic by specifying them
as ib_mad_hdr rather than ib_mad.

Drivers are modified as needed and are protected by BUG_ON flags if the MAD
sizes passed to them is incorrect.

Signed-off-by: Ira Weiny <ira.weiny@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
21 files changed:
drivers/infiniband/core/mad.c
drivers/infiniband/core/sysfs.c
drivers/infiniband/hw/amso1100/c2_provider.c
drivers/infiniband/hw/cxgb3/iwch_provider.c
drivers/infiniband/hw/cxgb4/provider.c
drivers/infiniband/hw/ehca/ehca_iverbs.h
drivers/infiniband/hw/ehca/ehca_sqp.c
drivers/infiniband/hw/ipath/ipath_mad.c
drivers/infiniband/hw/ipath/ipath_verbs.h
drivers/infiniband/hw/mlx4/mad.c
drivers/infiniband/hw/mlx4/mlx4_ib.h
drivers/infiniband/hw/mlx5/mad.c
drivers/infiniband/hw/mlx5/mlx5_ib.h
drivers/infiniband/hw/mthca/mthca_dev.h
drivers/infiniband/hw/mthca/mthca_mad.c
drivers/infiniband/hw/nes/nes_verbs.c
drivers/infiniband/hw/ocrdma/ocrdma_ah.c
drivers/infiniband/hw/ocrdma/ocrdma_ah.h
drivers/infiniband/hw/qib/qib_mad.c
drivers/infiniband/hw/qib/qib_verbs.h
include/rdma/ib_verbs.h

index 0dde135c6428dbda2430fd7111e09f0941722fa3..aa4f8d4a4eba33873265e82907340a59c63a816d 100644 (file)
@@ -761,6 +761,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
        struct ib_wc mad_wc;
        struct ib_send_wr *send_wr = &mad_send_wr->send_wr;
        size_t mad_size = port_mad_size(mad_agent_priv->qp_info->port_priv);
+       u16 out_mad_pkey_index = 0;
 
        if (device->node_type == RDMA_NODE_IB_SWITCH &&
            smp->mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)
@@ -811,8 +812,9 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
 
        /* No GRH for DR SMP */
        ret = device->process_mad(device, 0, port_num, &mad_wc, NULL,
-                                 (const struct ib_mad *)smp,
-                                 (struct ib_mad *)mad_priv->mad);
+                                 (const struct ib_mad_hdr *)smp, mad_size,
+                                 (struct ib_mad_hdr *)mad_priv->mad,
+                                 &mad_size, &out_mad_pkey_index);
        switch (ret)
        {
        case IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY:
@@ -2030,6 +2032,8 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv,
        struct ib_mad_agent_private *mad_agent;
        int port_num;
        int ret = IB_MAD_RESULT_SUCCESS;
+       size_t mad_size;
+       u16 resp_mad_pkey_index = 0;
 
        mad_list = (struct ib_mad_list_head *)(unsigned long)wc->wr_id;
        qp_info = mad_list->mad_queue->qp_info;
@@ -2057,7 +2061,8 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv,
        if (!validate_mad((const struct ib_mad_hdr *)recv->mad, qp_info->qp->qp_num))
                goto out;
 
-       response = alloc_mad_private(recv->mad_size, GFP_ATOMIC);
+       mad_size = recv->mad_size;
+       response = alloc_mad_private(mad_size, GFP_KERNEL);
        if (!response) {
                dev_err(&port_priv->device->dev,
                        "ib_mad_recv_done_handler no memory for response buffer\n");
@@ -2082,8 +2087,10 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv,
                ret = port_priv->device->process_mad(port_priv->device, 0,
                                                     port_priv->port_num,
                                                     wc, &recv->grh,
-                                                    (const struct ib_mad *)recv->mad,
-                                                    (struct ib_mad *)response->mad);
+                                                    (const struct ib_mad_hdr *)recv->mad,
+                                                    recv->mad_size,
+                                                    (struct ib_mad_hdr *)response->mad,
+                                                    &mad_size, &resp_mad_pkey_index);
                if (ret & IB_MAD_RESULT_SUCCESS) {
                        if (ret & IB_MAD_RESULT_CONSUMED)
                                goto out;
index d0334c101ecb0d2ef06f62e0bcd29483c0d021af..ed6b6c85c334b124e3fa4a47225c3f8a6b5c62df 100644 (file)
@@ -326,6 +326,8 @@ static ssize_t show_pma_counter(struct ib_port *p, struct port_attribute *attr,
        int width  = (tab_attr->index >> 16) & 0xff;
        struct ib_mad *in_mad  = NULL;
        struct ib_mad *out_mad = NULL;
+       size_t mad_size = sizeof(*out_mad);
+       u16 out_mad_pkey_index = 0;
        ssize_t ret;
 
        if (!p->ibdev->process_mad)
@@ -347,7 +349,10 @@ static ssize_t show_pma_counter(struct ib_port *p, struct port_attribute *attr,
        in_mad->data[41] = p->port_num; /* PortSelect field */
 
        if ((p->ibdev->process_mad(p->ibdev, IB_MAD_IGNORE_MKEY,
-                p->port_num, NULL, NULL, in_mad, out_mad) &
+                p->port_num, NULL, NULL,
+                (const struct ib_mad_hdr *)in_mad, mad_size,
+                (struct ib_mad_hdr *)out_mad, &mad_size,
+                &out_mad_pkey_index) &
             (IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY)) !=
            (IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY)) {
                ret = -EINVAL;
index adfcef0946f73fed3180eb42a056c8a11db2f689..25c3f008556380eb87678a3129fe2051158cdf82 100644 (file)
@@ -592,7 +592,11 @@ static int c2_process_mad(struct ib_device *ibdev,
                          u8 port_num,
                          const struct ib_wc *in_wc,
                          const struct ib_grh *in_grh,
-                         const struct ib_mad *in_mad, struct ib_mad *out_mad)
+                         const struct ib_mad_hdr *in_mad,
+                         size_t in_mad_size,
+                         struct ib_mad_hdr *out_mad,
+                         size_t *out_mad_size,
+                         u16 *out_mad_pkey_index)
 {
        pr_debug("%s:%u\n", __func__, __LINE__);
        return -ENOSYS;
index 208b68b9bba1af4fe2777b3c13acad802771f933..b1b73232f21702161d7dc068f08e23e6759e04e8 100644 (file)
@@ -87,7 +87,11 @@ static int iwch_process_mad(struct ib_device *ibdev,
                            u8 port_num,
                            const struct ib_wc *in_wc,
                            const struct ib_grh *in_grh,
-                           const struct ib_mad *in_mad, struct ib_mad *out_mad)
+                           const struct ib_mad_hdr *in_mad,
+                           size_t in_mad_size,
+                           struct ib_mad_hdr *out_mad,
+                           size_t *out_mad_size,
+                           u16 *out_mad_pkey_index)
 {
        return -ENOSYS;
 }
index 2e909ddd065fb67a71ef174bf48ed7af5a611de2..62c816af46e480a433e31bdeae22fbcd81f710e9 100644 (file)
@@ -82,8 +82,11 @@ static int c4iw_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
 static int c4iw_process_mad(struct ib_device *ibdev, int mad_flags,
                            u8 port_num, const struct ib_wc *in_wc,
                            const struct ib_grh *in_grh,
-                           const struct ib_mad *in_mad,
-                           struct ib_mad *out_mad)
+                           const struct ib_mad_hdr *in_mad,
+                           size_t in_mad_size,
+                           struct ib_mad_hdr *out_mad,
+                           size_t *out_mad_size,
+                           u16 *out_mad_pkey_index)
 {
        return -ENOSYS;
 }
index 568e52bcfb605fbc6a1b51c9a988e87f8e344bbc..80e6a3d5df3e035ea1afdc3ec6bc013050ec9e3e 100644 (file)
@@ -194,8 +194,9 @@ int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma);
 
 int ehca_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
                     const struct ib_wc *in_wc, const struct ib_grh *in_grh,
-                    const struct ib_mad *in_mad,
-                    struct ib_mad *out_mad);
+                    const struct ib_mad_hdr *in, size_t in_mad_size,
+                    struct ib_mad_hdr *out, size_t *out_mad_size,
+                    u16 *out_mad_pkey_index);
 
 void ehca_poll_eqs(unsigned long data);
 
index 889ccfda640104acee6736a4db87149c9eeed712..12b5bc23832b13804c1f07b61ee4d83b8650dcd1 100644 (file)
@@ -218,9 +218,16 @@ perf_reply:
 
 int ehca_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
                     const struct ib_wc *in_wc, const struct ib_grh *in_grh,
-                    const struct ib_mad *in_mad, struct ib_mad *out_mad)
+                    const struct ib_mad_hdr *in, size_t in_mad_size,
+                    struct ib_mad_hdr *out, size_t *out_mad_size,
+                    u16 *out_mad_pkey_index)
 {
        int ret;
+       const struct ib_mad *in_mad = (const struct ib_mad *)in;
+       struct ib_mad *out_mad = (struct ib_mad *)out;
+
+       BUG_ON(in_mad_size != sizeof(*in_mad) ||
+              *out_mad_size != sizeof(*out_mad));
 
        if (!port_num || port_num > ibdev->phys_port_cnt || !in_wc)
                return IB_MAD_RESULT_FAILURE;
index 9e8929e23740a6b2fca967eaf49a378ce8ea65e1..948188e37f95ab3fc2dfb2dd4ab7a1698c0ae84f 100644 (file)
@@ -1491,9 +1491,16 @@ bail:
  */
 int ipath_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
                      const struct ib_wc *in_wc, const struct ib_grh *in_grh,
-                     const struct ib_mad *in_mad, struct ib_mad *out_mad)
+                     const struct ib_mad_hdr *in, size_t in_mad_size,
+                     struct ib_mad_hdr *out, size_t *out_mad_size,
+                     u16 *out_mad_pkey_index)
 {
        int ret;
+       const struct ib_mad *in_mad = (const struct ib_mad *)in;
+       struct ib_mad *out_mad = (struct ib_mad *)out;
+
+       BUG_ON(in_mad_size != sizeof(*in_mad) ||
+              *out_mad_size != sizeof(*out_mad));
 
        switch (in_mad->mad_hdr.mgmt_class) {
        case IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE:
index 8a9b0787c187e4812d4379c46cc3cd37ceac4033..ec167e545e15c3df3d9d61dbad49d7152bbe3846 100644 (file)
@@ -703,7 +703,9 @@ int ipath_process_mad(struct ib_device *ibdev,
                      u8 port_num,
                      const struct ib_wc *in_wc,
                      const struct ib_grh *in_grh,
-                     const struct ib_mad *in_mad, struct ib_mad *out_mad);
+                     const struct ib_mad_hdr *in, size_t in_mad_size,
+                     struct ib_mad_hdr *out, size_t *out_mad_size,
+                     u16 *out_mad_pkey_index);
 
 /*
  * Compare the lower 24 bits of the two values.
index 532818785a7f9cd5a699c393ee120d201b963926..3e2dee46caa27163644338ab214c59e966d4cf27 100644 (file)
@@ -869,8 +869,16 @@ static int iboe_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
 
 int mlx4_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
                        const struct ib_wc *in_wc, const struct ib_grh *in_grh,
-                       const struct ib_mad *in_mad, struct ib_mad *out_mad)
+                       const struct ib_mad_hdr *in, size_t in_mad_size,
+                       struct ib_mad_hdr *out, size_t *out_mad_size,
+                       u16 *out_mad_pkey_index)
 {
+       const struct ib_mad *in_mad = (const struct ib_mad *)in;
+       struct ib_mad *out_mad = (struct ib_mad *)out;
+
+       BUG_ON(in_mad_size != sizeof(*in_mad) ||
+              *out_mad_size != sizeof(*out_mad));
+
        switch (rdma_port_get_link_layer(ibdev, port_num)) {
        case IB_LINK_LAYER_INFINIBAND:
                return ib_process_mad(ibdev, mad_flags, port_num, in_wc,
index ac8cfece3e910c11ddfc059e25a3bdc20d3eb0d9..7933adfff662c7f7c8f3a970bf6760b58445781c 100644 (file)
@@ -727,7 +727,9 @@ int mlx4_MAD_IFC(struct mlx4_ib_dev *dev, int mad_ifc_flags,
                 const void *in_mad, void *response_mad);
 int mlx4_ib_process_mad(struct ib_device *ibdev, int mad_flags,        u8 port_num,
                        const struct ib_wc *in_wc, const struct ib_grh *in_grh,
-                       const struct ib_mad *in_mad, struct ib_mad *out_mad);
+                       const struct ib_mad_hdr *in, size_t in_mad_size,
+                       struct ib_mad_hdr *out, size_t *out_mad_size,
+                       u16 *out_mad_pkey_index);
 int mlx4_ib_mad_init(struct mlx4_ib_dev *dev);
 void mlx4_ib_mad_cleanup(struct mlx4_ib_dev *dev);
 
index 34e519cd4c6419e34246ee9d3c0117949b1d0062..8e45714fa369832ae9a42d81b76f19d18b2fd846 100644 (file)
@@ -59,10 +59,17 @@ int mlx5_MAD_IFC(struct mlx5_ib_dev *dev, int ignore_mkey, int ignore_bkey,
 
 int mlx5_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
                        const struct ib_wc *in_wc, const struct ib_grh *in_grh,
-                       const struct ib_mad *in_mad, struct ib_mad *out_mad)
+                       const struct ib_mad_hdr *in, size_t in_mad_size,
+                       struct ib_mad_hdr *out, size_t *out_mad_size,
+                       u16 *out_mad_pkey_index)
 {
        u16 slid;
        int err;
+       const struct ib_mad *in_mad = (const struct ib_mad *)in;
+       struct ib_mad *out_mad = (struct ib_mad *)out;
+
+       BUG_ON(in_mad_size != sizeof(*in_mad) ||
+              *out_mad_size != sizeof(*out_mad));
 
        slid = in_wc ? in_wc->slid : be16_to_cpu(IB_LID_PERMISSIVE);
 
index 2f72f326d5c2db179a53d2b36819933834558465..178314e764dab8ac6a6a3200b2a79fc6dbc63075 100644 (file)
@@ -588,7 +588,9 @@ int mlx5_ib_unmap_fmr(struct list_head *fmr_list);
 int mlx5_ib_fmr_dealloc(struct ib_fmr *ibfmr);
 int mlx5_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
                        const struct ib_wc *in_wc, const struct ib_grh *in_grh,
-                       const struct ib_mad *in_mad, struct ib_mad *out_mad);
+                       const struct ib_mad_hdr *in, size_t in_mad_size,
+                       struct ib_mad_hdr *out, size_t *out_mad_size,
+                       u16 *out_mad_pkey_index);
 struct ib_xrcd *mlx5_ib_alloc_xrcd(struct ib_device *ibdev,
                                          struct ib_ucontext *context,
                                          struct ib_udata *udata);
index b70f9ff23171f2c2c04b5f61f575ed66bc9b8db9..4393a022867badb9b5631f8e0110c4de629badbb 100644 (file)
@@ -578,8 +578,9 @@ int mthca_process_mad(struct ib_device *ibdev,
                      u8 port_num,
                      const struct ib_wc *in_wc,
                      const struct ib_grh *in_grh,
-                     const struct ib_mad *in_mad,
-                     struct ib_mad *out_mad);
+                     const struct ib_mad_hdr *in, size_t in_mad_size,
+                     struct ib_mad_hdr *out, size_t *out_mad_size,
+                     u16 *out_mad_pkey_index);
 int mthca_create_agents(struct mthca_dev *dev);
 void mthca_free_agents(struct mthca_dev *dev);
 
index e121e646591d2e63a764df523b9ae989945d61da..6b2418b74c99ab84345403afe9d310f04aa465e5 100644 (file)
@@ -198,13 +198,19 @@ int mthca_process_mad(struct ib_device *ibdev,
                      u8 port_num,
                      const struct ib_wc *in_wc,
                      const struct ib_grh *in_grh,
-                     const struct ib_mad *in_mad,
-                     struct ib_mad *out_mad)
+                     const struct ib_mad_hdr *in, size_t in_mad_size,
+                     struct ib_mad_hdr *out, size_t *out_mad_size,
+                     u16 *out_mad_pkey_index)
 {
        int err;
        u16 slid = in_wc ? in_wc->slid : be16_to_cpu(IB_LID_PERMISSIVE);
        u16 prev_lid = 0;
        struct ib_port_attr pattr;
+       const struct ib_mad *in_mad = (const struct ib_mad *)in;
+       struct ib_mad *out_mad = (struct ib_mad *)out;
+
+       BUG_ON(in_mad_size != sizeof(*in_mad) ||
+              *out_mad_size != sizeof(*out_mad));
 
        /* Forward locally generated traps to the SM */
        if (in_mad->mad_hdr.method == IB_MGMT_METHOD_TRAP &&
index c94390b57de1a937f521a33209659f5ac55eb4b7..fbc43e5f717b024b4c50832e7aab8a229554fc82 100644 (file)
@@ -3231,7 +3231,9 @@ static int nes_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
  */
 static int nes_process_mad(struct ib_device *ibdev, int mad_flags,
                u8 port_num, const struct ib_wc *in_wc, const struct ib_grh *in_grh,
-               const struct ib_mad *in_mad, struct ib_mad *out_mad)
+               const struct ib_mad_hdr *in, size_t in_mad_size,
+               struct ib_mad_hdr *out, size_t *out_mad_size,
+               u16 *out_mad_pkey_index)
 {
        nes_debug(NES_DBG_INIT, "\n");
        return -ENOSYS;
index 3216bce08a106411f2939a681bc08fd696da60a1..5f8a8dd423fc6eac921cb02d400e249629a917bf 100644 (file)
@@ -198,10 +198,17 @@ int ocrdma_process_mad(struct ib_device *ibdev,
                       u8 port_num,
                       const struct ib_wc *in_wc,
                       const struct ib_grh *in_grh,
-                      const struct ib_mad *in_mad, struct ib_mad *out_mad)
+                      const struct ib_mad_hdr *in, size_t in_mad_size,
+                      struct ib_mad_hdr *out, size_t *out_mad_size,
+                      u16 *out_mad_pkey_index)
 {
        int status;
        struct ocrdma_dev *dev;
+       const struct ib_mad *in_mad = (const struct ib_mad *)in;
+       struct ib_mad *out_mad = (struct ib_mad *)out;
+
+       BUG_ON(in_mad_size != sizeof(*in_mad) ||
+              *out_mad_size != sizeof(*out_mad));
 
        switch (in_mad->mad_hdr.mgmt_class) {
        case IB_MGMT_CLASS_PERF_MGMT:
index 5c4ae3eba47c4339cd9e3667f44e8c29c381de2c..cf366fe03cb822580fe96b69e5873ad255a34632 100644 (file)
@@ -44,5 +44,7 @@ int ocrdma_process_mad(struct ib_device *,
                       u8 port_num,
                       const struct ib_wc *in_wc,
                       const struct ib_grh *in_grh,
-                      const struct ib_mad *in_mad, struct ib_mad *out_mad);
+                      const struct ib_mad_hdr *in, size_t in_mad_size,
+                      struct ib_mad_hdr *out, size_t *out_mad_size,
+                      u16 *out_mad_pkey_index);
 #endif                         /* __OCRDMA_AH_H__ */
index 206b2050b247d1eb6dbcb25cbe2ec07c7622c1d0..05e3242d84425acd6229204e642084a4ce0f654d 100644 (file)
@@ -2402,11 +2402,18 @@ bail:
  */
 int qib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port,
                    const struct ib_wc *in_wc, const struct ib_grh *in_grh,
-                   const struct ib_mad *in_mad, struct ib_mad *out_mad)
+                   const struct ib_mad_hdr *in, size_t in_mad_size,
+                   struct ib_mad_hdr *out, size_t *out_mad_size,
+                   u16 *out_mad_pkey_index)
 {
        int ret;
        struct qib_ibport *ibp = to_iport(ibdev, port);
        struct qib_pportdata *ppd = ppd_from_ibp(ibp);
+       const struct ib_mad *in_mad = (const struct ib_mad *)in;
+       struct ib_mad *out_mad = (struct ib_mad *)out;
+
+       BUG_ON(in_mad_size != sizeof(*in_mad) ||
+              *out_mad_size != sizeof(*out_mad));
 
        switch (in_mad->mad_hdr.mgmt_class) {
        case IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE:
index 6e4e3d9bd86a1101a93ba3404a29aa4e29d9624a..1635572752ce5bb37e05b3059dc194c196031880 100644 (file)
@@ -873,7 +873,9 @@ void qib_sys_guid_chg(struct qib_ibport *ibp);
 void qib_node_desc_chg(struct qib_ibport *ibp);
 int qib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
                    const struct ib_wc *in_wc, const struct ib_grh *in_grh,
-                   const struct ib_mad *in_mad, struct ib_mad *out_mad);
+                   const struct ib_mad_hdr *in, size_t in_mad_size,
+                   struct ib_mad_hdr *out, size_t *out_mad_size,
+                   u16 *out_mad_pkey_index);
 int qib_create_agents(struct qib_ibdev *dev);
 void qib_free_agents(struct qib_ibdev *dev);
 
index 75c349969b6ecbfceccbb47ef88cc79b4c1781ca..46c8eb8f1bc741c0fc9ebbd12c8d18f2e3156080 100644 (file)
@@ -1463,7 +1463,7 @@ struct ib_flow {
        struct ib_uobject       *uobject;
 };
 
-struct ib_mad;
+struct ib_mad_hdr;
 struct ib_grh;
 
 enum ib_process_mad_flags {
@@ -1705,8 +1705,11 @@ struct ib_device {
                                                  u8 port_num,
                                                  const struct ib_wc *in_wc,
                                                  const struct ib_grh *in_grh,
-                                                 const struct ib_mad *in_mad,
-                                                 struct ib_mad *out_mad);
+                                                 const struct ib_mad_hdr *in_mad,
+                                                 size_t in_mad_size,
+                                                 struct ib_mad_hdr *out_mad,
+                                                 size_t *out_mad_size,
+                                                 u16 *out_mad_pkey_index);
        struct ib_xrcd *           (*alloc_xrcd)(struct ib_device *device,
                                                 struct ib_ucontext *ucontext,
                                                 struct ib_udata *udata);