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

IB/mad: Add support for additional MAD info to/from drivers

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>

authored by

Ira Weiny and committed by
Doug Ledford
4cd7c947 c9082e51

+120 -31
+12 -5
drivers/infiniband/core/mad.c
··· 761 761 struct ib_wc mad_wc; 762 762 struct ib_send_wr *send_wr = &mad_send_wr->send_wr; 763 763 size_t mad_size = port_mad_size(mad_agent_priv->qp_info->port_priv); 764 + u16 out_mad_pkey_index = 0; 764 765 765 766 if (device->node_type == RDMA_NODE_IB_SWITCH && 766 767 smp->mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) ··· 812 811 813 812 /* No GRH for DR SMP */ 814 813 ret = device->process_mad(device, 0, port_num, &mad_wc, NULL, 815 - (const struct ib_mad *)smp, 816 - (struct ib_mad *)mad_priv->mad); 814 + (const struct ib_mad_hdr *)smp, mad_size, 815 + (struct ib_mad_hdr *)mad_priv->mad, 816 + &mad_size, &out_mad_pkey_index); 817 817 switch (ret) 818 818 { 819 819 case IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY: ··· 2032 2030 struct ib_mad_agent_private *mad_agent; 2033 2031 int port_num; 2034 2032 int ret = IB_MAD_RESULT_SUCCESS; 2033 + size_t mad_size; 2034 + u16 resp_mad_pkey_index = 0; 2035 2035 2036 2036 mad_list = (struct ib_mad_list_head *)(unsigned long)wc->wr_id; 2037 2037 qp_info = mad_list->mad_queue->qp_info; ··· 2061 2057 if (!validate_mad((const struct ib_mad_hdr *)recv->mad, qp_info->qp->qp_num)) 2062 2058 goto out; 2063 2059 2064 - response = alloc_mad_private(recv->mad_size, GFP_ATOMIC); 2060 + mad_size = recv->mad_size; 2061 + response = alloc_mad_private(mad_size, GFP_KERNEL); 2065 2062 if (!response) { 2066 2063 dev_err(&port_priv->device->dev, 2067 2064 "ib_mad_recv_done_handler no memory for response buffer\n"); ··· 2087 2082 ret = port_priv->device->process_mad(port_priv->device, 0, 2088 2083 port_priv->port_num, 2089 2084 wc, &recv->grh, 2090 - (const struct ib_mad *)recv->mad, 2091 - (struct ib_mad *)response->mad); 2085 + (const struct ib_mad_hdr *)recv->mad, 2086 + recv->mad_size, 2087 + (struct ib_mad_hdr *)response->mad, 2088 + &mad_size, &resp_mad_pkey_index); 2092 2089 if (ret & IB_MAD_RESULT_SUCCESS) { 2093 2090 if (ret & IB_MAD_RESULT_CONSUMED) 2094 2091 goto out;
+6 -1
drivers/infiniband/core/sysfs.c
··· 326 326 int width = (tab_attr->index >> 16) & 0xff; 327 327 struct ib_mad *in_mad = NULL; 328 328 struct ib_mad *out_mad = NULL; 329 + size_t mad_size = sizeof(*out_mad); 330 + u16 out_mad_pkey_index = 0; 329 331 ssize_t ret; 330 332 331 333 if (!p->ibdev->process_mad) ··· 349 347 in_mad->data[41] = p->port_num; /* PortSelect field */ 350 348 351 349 if ((p->ibdev->process_mad(p->ibdev, IB_MAD_IGNORE_MKEY, 352 - p->port_num, NULL, NULL, in_mad, out_mad) & 350 + p->port_num, NULL, NULL, 351 + (const struct ib_mad_hdr *)in_mad, mad_size, 352 + (struct ib_mad_hdr *)out_mad, &mad_size, 353 + &out_mad_pkey_index) & 353 354 (IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY)) != 354 355 (IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY)) { 355 356 ret = -EINVAL;
+5 -1
drivers/infiniband/hw/amso1100/c2_provider.c
··· 592 592 u8 port_num, 593 593 const struct ib_wc *in_wc, 594 594 const struct ib_grh *in_grh, 595 - const struct ib_mad *in_mad, struct ib_mad *out_mad) 595 + const struct ib_mad_hdr *in_mad, 596 + size_t in_mad_size, 597 + struct ib_mad_hdr *out_mad, 598 + size_t *out_mad_size, 599 + u16 *out_mad_pkey_index) 596 600 { 597 601 pr_debug("%s:%u\n", __func__, __LINE__); 598 602 return -ENOSYS;
+5 -1
drivers/infiniband/hw/cxgb3/iwch_provider.c
··· 87 87 u8 port_num, 88 88 const struct ib_wc *in_wc, 89 89 const struct ib_grh *in_grh, 90 - const struct ib_mad *in_mad, struct ib_mad *out_mad) 90 + const struct ib_mad_hdr *in_mad, 91 + size_t in_mad_size, 92 + struct ib_mad_hdr *out_mad, 93 + size_t *out_mad_size, 94 + u16 *out_mad_pkey_index) 91 95 { 92 96 return -ENOSYS; 93 97 }
+5 -2
drivers/infiniband/hw/cxgb4/provider.c
··· 82 82 static int c4iw_process_mad(struct ib_device *ibdev, int mad_flags, 83 83 u8 port_num, const struct ib_wc *in_wc, 84 84 const struct ib_grh *in_grh, 85 - const struct ib_mad *in_mad, 86 - struct ib_mad *out_mad) 85 + const struct ib_mad_hdr *in_mad, 86 + size_t in_mad_size, 87 + struct ib_mad_hdr *out_mad, 88 + size_t *out_mad_size, 89 + u16 *out_mad_pkey_index) 87 90 { 88 91 return -ENOSYS; 89 92 }
+3 -2
drivers/infiniband/hw/ehca/ehca_iverbs.h
··· 194 194 195 195 int ehca_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, 196 196 const struct ib_wc *in_wc, const struct ib_grh *in_grh, 197 - const struct ib_mad *in_mad, 198 - struct ib_mad *out_mad); 197 + const struct ib_mad_hdr *in, size_t in_mad_size, 198 + struct ib_mad_hdr *out, size_t *out_mad_size, 199 + u16 *out_mad_pkey_index); 199 200 200 201 void ehca_poll_eqs(unsigned long data); 201 202
+8 -1
drivers/infiniband/hw/ehca/ehca_sqp.c
··· 218 218 219 219 int ehca_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, 220 220 const struct ib_wc *in_wc, const struct ib_grh *in_grh, 221 - const struct ib_mad *in_mad, struct ib_mad *out_mad) 221 + const struct ib_mad_hdr *in, size_t in_mad_size, 222 + struct ib_mad_hdr *out, size_t *out_mad_size, 223 + u16 *out_mad_pkey_index) 222 224 { 223 225 int ret; 226 + const struct ib_mad *in_mad = (const struct ib_mad *)in; 227 + struct ib_mad *out_mad = (struct ib_mad *)out; 228 + 229 + BUG_ON(in_mad_size != sizeof(*in_mad) || 230 + *out_mad_size != sizeof(*out_mad)); 224 231 225 232 if (!port_num || port_num > ibdev->phys_port_cnt || !in_wc) 226 233 return IB_MAD_RESULT_FAILURE;
+8 -1
drivers/infiniband/hw/ipath/ipath_mad.c
··· 1491 1491 */ 1492 1492 int ipath_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, 1493 1493 const struct ib_wc *in_wc, const struct ib_grh *in_grh, 1494 - const struct ib_mad *in_mad, struct ib_mad *out_mad) 1494 + const struct ib_mad_hdr *in, size_t in_mad_size, 1495 + struct ib_mad_hdr *out, size_t *out_mad_size, 1496 + u16 *out_mad_pkey_index) 1495 1497 { 1496 1498 int ret; 1499 + const struct ib_mad *in_mad = (const struct ib_mad *)in; 1500 + struct ib_mad *out_mad = (struct ib_mad *)out; 1501 + 1502 + BUG_ON(in_mad_size != sizeof(*in_mad) || 1503 + *out_mad_size != sizeof(*out_mad)); 1497 1504 1498 1505 switch (in_mad->mad_hdr.mgmt_class) { 1499 1506 case IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE:
+3 -1
drivers/infiniband/hw/ipath/ipath_verbs.h
··· 703 703 u8 port_num, 704 704 const struct ib_wc *in_wc, 705 705 const struct ib_grh *in_grh, 706 - const struct ib_mad *in_mad, struct ib_mad *out_mad); 706 + const struct ib_mad_hdr *in, size_t in_mad_size, 707 + struct ib_mad_hdr *out, size_t *out_mad_size, 708 + u16 *out_mad_pkey_index); 707 709 708 710 /* 709 711 * Compare the lower 24 bits of the two values.
+9 -1
drivers/infiniband/hw/mlx4/mad.c
··· 869 869 870 870 int mlx4_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, 871 871 const struct ib_wc *in_wc, const struct ib_grh *in_grh, 872 - const struct ib_mad *in_mad, struct ib_mad *out_mad) 872 + const struct ib_mad_hdr *in, size_t in_mad_size, 873 + struct ib_mad_hdr *out, size_t *out_mad_size, 874 + u16 *out_mad_pkey_index) 873 875 { 876 + const struct ib_mad *in_mad = (const struct ib_mad *)in; 877 + struct ib_mad *out_mad = (struct ib_mad *)out; 878 + 879 + BUG_ON(in_mad_size != sizeof(*in_mad) || 880 + *out_mad_size != sizeof(*out_mad)); 881 + 874 882 switch (rdma_port_get_link_layer(ibdev, port_num)) { 875 883 case IB_LINK_LAYER_INFINIBAND: 876 884 return ib_process_mad(ibdev, mad_flags, port_num, in_wc,
+3 -1
drivers/infiniband/hw/mlx4/mlx4_ib.h
··· 727 727 const void *in_mad, void *response_mad); 728 728 int mlx4_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, 729 729 const struct ib_wc *in_wc, const struct ib_grh *in_grh, 730 - const struct ib_mad *in_mad, struct ib_mad *out_mad); 730 + const struct ib_mad_hdr *in, size_t in_mad_size, 731 + struct ib_mad_hdr *out, size_t *out_mad_size, 732 + u16 *out_mad_pkey_index); 731 733 int mlx4_ib_mad_init(struct mlx4_ib_dev *dev); 732 734 void mlx4_ib_mad_cleanup(struct mlx4_ib_dev *dev); 733 735
+8 -1
drivers/infiniband/hw/mlx5/mad.c
··· 59 59 60 60 int mlx5_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, 61 61 const struct ib_wc *in_wc, const struct ib_grh *in_grh, 62 - const struct ib_mad *in_mad, struct ib_mad *out_mad) 62 + const struct ib_mad_hdr *in, size_t in_mad_size, 63 + struct ib_mad_hdr *out, size_t *out_mad_size, 64 + u16 *out_mad_pkey_index) 63 65 { 64 66 u16 slid; 65 67 int err; 68 + const struct ib_mad *in_mad = (const struct ib_mad *)in; 69 + struct ib_mad *out_mad = (struct ib_mad *)out; 70 + 71 + BUG_ON(in_mad_size != sizeof(*in_mad) || 72 + *out_mad_size != sizeof(*out_mad)); 66 73 67 74 slid = in_wc ? in_wc->slid : be16_to_cpu(IB_LID_PERMISSIVE); 68 75
+3 -1
drivers/infiniband/hw/mlx5/mlx5_ib.h
··· 588 588 int mlx5_ib_fmr_dealloc(struct ib_fmr *ibfmr); 589 589 int mlx5_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, 590 590 const struct ib_wc *in_wc, const struct ib_grh *in_grh, 591 - const struct ib_mad *in_mad, struct ib_mad *out_mad); 591 + const struct ib_mad_hdr *in, size_t in_mad_size, 592 + struct ib_mad_hdr *out, size_t *out_mad_size, 593 + u16 *out_mad_pkey_index); 592 594 struct ib_xrcd *mlx5_ib_alloc_xrcd(struct ib_device *ibdev, 593 595 struct ib_ucontext *context, 594 596 struct ib_udata *udata);
+3 -2
drivers/infiniband/hw/mthca/mthca_dev.h
··· 578 578 u8 port_num, 579 579 const struct ib_wc *in_wc, 580 580 const struct ib_grh *in_grh, 581 - const struct ib_mad *in_mad, 582 - struct ib_mad *out_mad); 581 + const struct ib_mad_hdr *in, size_t in_mad_size, 582 + struct ib_mad_hdr *out, size_t *out_mad_size, 583 + u16 *out_mad_pkey_index); 583 584 int mthca_create_agents(struct mthca_dev *dev); 584 585 void mthca_free_agents(struct mthca_dev *dev); 585 586
+8 -2
drivers/infiniband/hw/mthca/mthca_mad.c
··· 198 198 u8 port_num, 199 199 const struct ib_wc *in_wc, 200 200 const struct ib_grh *in_grh, 201 - const struct ib_mad *in_mad, 202 - struct ib_mad *out_mad) 201 + const struct ib_mad_hdr *in, size_t in_mad_size, 202 + struct ib_mad_hdr *out, size_t *out_mad_size, 203 + u16 *out_mad_pkey_index) 203 204 { 204 205 int err; 205 206 u16 slid = in_wc ? in_wc->slid : be16_to_cpu(IB_LID_PERMISSIVE); 206 207 u16 prev_lid = 0; 207 208 struct ib_port_attr pattr; 209 + const struct ib_mad *in_mad = (const struct ib_mad *)in; 210 + struct ib_mad *out_mad = (struct ib_mad *)out; 211 + 212 + BUG_ON(in_mad_size != sizeof(*in_mad) || 213 + *out_mad_size != sizeof(*out_mad)); 208 214 209 215 /* Forward locally generated traps to the SM */ 210 216 if (in_mad->mad_hdr.method == IB_MGMT_METHOD_TRAP &&
+3 -1
drivers/infiniband/hw/nes/nes_verbs.c
··· 3231 3231 */ 3232 3232 static int nes_process_mad(struct ib_device *ibdev, int mad_flags, 3233 3233 u8 port_num, const struct ib_wc *in_wc, const struct ib_grh *in_grh, 3234 - const struct ib_mad *in_mad, struct ib_mad *out_mad) 3234 + const struct ib_mad_hdr *in, size_t in_mad_size, 3235 + struct ib_mad_hdr *out, size_t *out_mad_size, 3236 + u16 *out_mad_pkey_index) 3235 3237 { 3236 3238 nes_debug(NES_DBG_INIT, "\n"); 3237 3239 return -ENOSYS;
+8 -1
drivers/infiniband/hw/ocrdma/ocrdma_ah.c
··· 198 198 u8 port_num, 199 199 const struct ib_wc *in_wc, 200 200 const struct ib_grh *in_grh, 201 - const struct ib_mad *in_mad, struct ib_mad *out_mad) 201 + const struct ib_mad_hdr *in, size_t in_mad_size, 202 + struct ib_mad_hdr *out, size_t *out_mad_size, 203 + u16 *out_mad_pkey_index) 202 204 { 203 205 int status; 204 206 struct ocrdma_dev *dev; 207 + const struct ib_mad *in_mad = (const struct ib_mad *)in; 208 + struct ib_mad *out_mad = (struct ib_mad *)out; 209 + 210 + BUG_ON(in_mad_size != sizeof(*in_mad) || 211 + *out_mad_size != sizeof(*out_mad)); 205 212 206 213 switch (in_mad->mad_hdr.mgmt_class) { 207 214 case IB_MGMT_CLASS_PERF_MGMT:
+3 -1
drivers/infiniband/hw/ocrdma/ocrdma_ah.h
··· 44 44 u8 port_num, 45 45 const struct ib_wc *in_wc, 46 46 const struct ib_grh *in_grh, 47 - const struct ib_mad *in_mad, struct ib_mad *out_mad); 47 + const struct ib_mad_hdr *in, size_t in_mad_size, 48 + struct ib_mad_hdr *out, size_t *out_mad_size, 49 + u16 *out_mad_pkey_index); 48 50 #endif /* __OCRDMA_AH_H__ */
+8 -1
drivers/infiniband/hw/qib/qib_mad.c
··· 2402 2402 */ 2403 2403 int qib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port, 2404 2404 const struct ib_wc *in_wc, const struct ib_grh *in_grh, 2405 - const struct ib_mad *in_mad, struct ib_mad *out_mad) 2405 + const struct ib_mad_hdr *in, size_t in_mad_size, 2406 + struct ib_mad_hdr *out, size_t *out_mad_size, 2407 + u16 *out_mad_pkey_index) 2406 2408 { 2407 2409 int ret; 2408 2410 struct qib_ibport *ibp = to_iport(ibdev, port); 2409 2411 struct qib_pportdata *ppd = ppd_from_ibp(ibp); 2412 + const struct ib_mad *in_mad = (const struct ib_mad *)in; 2413 + struct ib_mad *out_mad = (struct ib_mad *)out; 2414 + 2415 + BUG_ON(in_mad_size != sizeof(*in_mad) || 2416 + *out_mad_size != sizeof(*out_mad)); 2410 2417 2411 2418 switch (in_mad->mad_hdr.mgmt_class) { 2412 2419 case IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE:
+3 -1
drivers/infiniband/hw/qib/qib_verbs.h
··· 873 873 void qib_node_desc_chg(struct qib_ibport *ibp); 874 874 int qib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, 875 875 const struct ib_wc *in_wc, const struct ib_grh *in_grh, 876 - const struct ib_mad *in_mad, struct ib_mad *out_mad); 876 + const struct ib_mad_hdr *in, size_t in_mad_size, 877 + struct ib_mad_hdr *out, size_t *out_mad_size, 878 + u16 *out_mad_pkey_index); 877 879 int qib_create_agents(struct qib_ibdev *dev); 878 880 void qib_free_agents(struct qib_ibdev *dev); 879 881
+6 -3
include/rdma/ib_verbs.h
··· 1463 1463 struct ib_uobject *uobject; 1464 1464 }; 1465 1465 1466 - struct ib_mad; 1466 + struct ib_mad_hdr; 1467 1467 struct ib_grh; 1468 1468 1469 1469 enum ib_process_mad_flags { ··· 1705 1705 u8 port_num, 1706 1706 const struct ib_wc *in_wc, 1707 1707 const struct ib_grh *in_grh, 1708 - const struct ib_mad *in_mad, 1709 - struct ib_mad *out_mad); 1708 + const struct ib_mad_hdr *in_mad, 1709 + size_t in_mad_size, 1710 + struct ib_mad_hdr *out_mad, 1711 + size_t *out_mad_size, 1712 + u16 *out_mad_pkey_index); 1710 1713 struct ib_xrcd * (*alloc_xrcd)(struct ib_device *device, 1711 1714 struct ib_ucontext *ucontext, 1712 1715 struct ib_udata *udata);