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

IB/mad: add new ioctl to ABI to support new registration options

Registrations options are specified through flags. Definitions of flags will
be in subsequent patches.

Signed-off-by: Ira Weiny <ira.weiny@intel.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>

authored by

Ira Weiny and committed by
Roland Dreier
0f29b46d 9ad13a42

+186 -16
+9 -4
Documentation/infiniband/user_mad.txt
··· 26 26 ioctl. Also, all agents registered through a file descriptor will 27 27 be unregistered when the descriptor is closed. 28 28 29 + 2014 -- a new registration ioctl is now provided which allows additional 30 + fields to be provided during registration. 31 + Users of this registration call are implicitly setting the use of 32 + pkey_index (see below). 33 + 29 34 Receiving MADs 30 35 31 36 MADs are received using read(). The receive side now supports ··· 109 104 The old ib_umad interface did not allow setting the P_Key index for 110 105 MADs that are sent and did not provide a way for obtaining the P_Key 111 106 index of received MADs. A new layout for struct ib_user_mad_hdr 112 - with a pkey_index member has been defined; however, to preserve 113 - binary compatibility with older applications, this new layout will 114 - not be used unless the IB_USER_MAD_ENABLE_PKEY ioctl is called 115 - before a file descriptor is used for anything else. 107 + with a pkey_index member has been defined; however, to preserve binary 108 + compatibility with older applications, this new layout will not be used 109 + unless one of IB_USER_MAD_ENABLE_PKEY or IB_USER_MAD_REGISTER_AGENT2 ioctl's 110 + are called before a file descriptor is used for anything else. 116 111 117 112 In September 2008, the IB_USER_MAD_ABI_VERSION will be incremented 118 113 to 6, the new layout of struct ib_user_mad_hdr will be used by
+2 -2
drivers/infiniband/core/agent.c
··· 161 161 port_priv->agent[0] = ib_register_mad_agent(device, port_num, 162 162 IB_QPT_SMI, NULL, 0, 163 163 &agent_send_handler, 164 - NULL, NULL); 164 + NULL, NULL, 0); 165 165 if (IS_ERR(port_priv->agent[0])) { 166 166 ret = PTR_ERR(port_priv->agent[0]); 167 167 goto error2; ··· 172 172 port_priv->agent[1] = ib_register_mad_agent(device, port_num, 173 173 IB_QPT_GSI, NULL, 0, 174 174 &agent_send_handler, 175 - NULL, NULL); 175 + NULL, NULL, 0); 176 176 if (IS_ERR(port_priv->agent[1])) { 177 177 ret = PTR_ERR(port_priv->agent[1]); 178 178 goto error3;
+3 -2
drivers/infiniband/core/cm.c
··· 3753 3753 struct cm_port *port; 3754 3754 struct ib_mad_reg_req reg_req = { 3755 3755 .mgmt_class = IB_MGMT_CLASS_CM, 3756 - .mgmt_class_version = IB_CM_CLASS_VERSION 3756 + .mgmt_class_version = IB_CM_CLASS_VERSION, 3757 3757 }; 3758 3758 struct ib_port_modify port_modify = { 3759 3759 .set_port_cap_mask = IB_PORT_CM_SUP ··· 3801 3801 0, 3802 3802 cm_send_handler, 3803 3803 cm_recv_handler, 3804 - port); 3804 + port, 3805 + 0); 3805 3806 if (IS_ERR(port->mad_agent)) 3806 3807 goto error2; 3807 3808
+3 -1
drivers/infiniband/core/mad.c
··· 198 198 u8 rmpp_version, 199 199 ib_mad_send_handler send_handler, 200 200 ib_mad_recv_handler recv_handler, 201 - void *context) 201 + void *context, 202 + u32 registration_flags) 202 203 { 203 204 struct ib_mad_port_private *port_priv; 204 205 struct ib_mad_agent *ret = ERR_PTR(-EINVAL); ··· 360 359 mad_agent_priv->agent.context = context; 361 360 mad_agent_priv->agent.qp = port_priv->qp_info[qpn].qp; 362 361 mad_agent_priv->agent.port_num = port_num; 362 + mad_agent_priv->agent.flags = registration_flags; 363 363 spin_lock_init(&mad_agent_priv->lock); 364 364 INIT_LIST_HEAD(&mad_agent_priv->send_list); 365 365 INIT_LIST_HEAD(&mad_agent_priv->wait_list);
+1 -1
drivers/infiniband/core/sa_query.c
··· 1184 1184 sa_dev->port[i].agent = 1185 1185 ib_register_mad_agent(device, i + s, IB_QPT_GSI, 1186 1186 NULL, 0, send_handler, 1187 - recv_handler, sa_dev); 1187 + recv_handler, sa_dev, 0); 1188 1188 if (IS_ERR(sa_dev->port[i].agent)) 1189 1189 goto err; 1190 1190
+119 -1
drivers/infiniband/core/user_mad.c
··· 647 647 648 648 found: 649 649 if (ureq.mgmt_class) { 650 + memset(&req, 0, sizeof(req)); 650 651 req.mgmt_class = ureq.mgmt_class; 651 652 req.mgmt_class_version = ureq.mgmt_class_version; 652 653 memcpy(req.oui, ureq.oui, sizeof req.oui); ··· 668 667 ureq.qpn ? IB_QPT_GSI : IB_QPT_SMI, 669 668 ureq.mgmt_class ? &req : NULL, 670 669 ureq.rmpp_version, 671 - send_handler, recv_handler, file); 670 + send_handler, recv_handler, file, 0); 672 671 if (IS_ERR(agent)) { 673 672 ret = PTR_ERR(agent); 674 673 agent = NULL; ··· 705 704 706 705 return ret; 707 706 } 707 + 708 + static int ib_umad_reg_agent2(struct ib_umad_file *file, void __user *arg) 709 + { 710 + struct ib_user_mad_reg_req2 ureq; 711 + struct ib_mad_reg_req req; 712 + struct ib_mad_agent *agent = NULL; 713 + int agent_id; 714 + int ret; 715 + 716 + mutex_lock(&file->port->file_mutex); 717 + mutex_lock(&file->mutex); 718 + 719 + if (!file->port->ib_dev) { 720 + dev_notice(file->port->dev, 721 + "ib_umad_reg_agent2: invalid device\n"); 722 + ret = -EPIPE; 723 + goto out; 724 + } 725 + 726 + if (copy_from_user(&ureq, arg, sizeof(ureq))) { 727 + ret = -EFAULT; 728 + goto out; 729 + } 730 + 731 + if (ureq.qpn != 0 && ureq.qpn != 1) { 732 + dev_notice(file->port->dev, 733 + "ib_umad_reg_agent2: invalid QPN %d specified\n", 734 + ureq.qpn); 735 + ret = -EINVAL; 736 + goto out; 737 + } 738 + 739 + if (ureq.flags & ~IB_USER_MAD_REG_FLAGS_CAP) { 740 + dev_notice(file->port->dev, 741 + "ib_umad_reg_agent2 failed: invalid registration flags specified 0x%x; supported 0x%x\n", 742 + ureq.flags, IB_USER_MAD_REG_FLAGS_CAP); 743 + ret = -EINVAL; 744 + 745 + if (put_user((u32)IB_USER_MAD_REG_FLAGS_CAP, 746 + (u32 __user *) (arg + offsetof(struct 747 + ib_user_mad_reg_req2, flags)))) 748 + ret = -EFAULT; 749 + 750 + goto out; 751 + } 752 + 753 + for (agent_id = 0; agent_id < IB_UMAD_MAX_AGENTS; ++agent_id) 754 + if (!__get_agent(file, agent_id)) 755 + goto found; 756 + 757 + dev_notice(file->port->dev, 758 + "ib_umad_reg_agent2: Max Agents (%u) reached\n", 759 + IB_UMAD_MAX_AGENTS); 760 + ret = -ENOMEM; 761 + goto out; 762 + 763 + found: 764 + if (ureq.mgmt_class) { 765 + memset(&req, 0, sizeof(req)); 766 + req.mgmt_class = ureq.mgmt_class; 767 + req.mgmt_class_version = ureq.mgmt_class_version; 768 + if (ureq.oui & 0xff000000) { 769 + dev_notice(file->port->dev, 770 + "ib_umad_reg_agent2 failed: oui invalid 0x%08x\n", 771 + ureq.oui); 772 + ret = -EINVAL; 773 + goto out; 774 + } 775 + req.oui[2] = ureq.oui & 0x0000ff; 776 + req.oui[1] = (ureq.oui & 0x00ff00) >> 8; 777 + req.oui[0] = (ureq.oui & 0xff0000) >> 16; 778 + memcpy(req.method_mask, ureq.method_mask, 779 + sizeof(req.method_mask)); 780 + } 781 + 782 + agent = ib_register_mad_agent(file->port->ib_dev, file->port->port_num, 783 + ureq.qpn ? IB_QPT_GSI : IB_QPT_SMI, 784 + ureq.mgmt_class ? &req : NULL, 785 + ureq.rmpp_version, 786 + send_handler, recv_handler, file, 787 + ureq.flags); 788 + if (IS_ERR(agent)) { 789 + ret = PTR_ERR(agent); 790 + agent = NULL; 791 + goto out; 792 + } 793 + 794 + if (put_user(agent_id, 795 + (u32 __user *)(arg + 796 + offsetof(struct ib_user_mad_reg_req2, id)))) { 797 + ret = -EFAULT; 798 + goto out; 799 + } 800 + 801 + if (!file->already_used) { 802 + file->already_used = 1; 803 + file->use_pkey_index = 1; 804 + } 805 + 806 + file->agent[agent_id] = agent; 807 + ret = 0; 808 + 809 + out: 810 + mutex_unlock(&file->mutex); 811 + 812 + if (ret && agent) 813 + ib_unregister_mad_agent(agent); 814 + 815 + mutex_unlock(&file->port->file_mutex); 816 + 817 + return ret; 818 + } 819 + 708 820 709 821 static int ib_umad_unreg_agent(struct ib_umad_file *file, u32 __user *arg) 710 822 { ··· 874 760 return ib_umad_unreg_agent(filp->private_data, (__u32 __user *) arg); 875 761 case IB_USER_MAD_ENABLE_PKEY: 876 762 return ib_umad_enable_pkey(filp->private_data); 763 + case IB_USER_MAD_REGISTER_AGENT2: 764 + return ib_umad_reg_agent2(filp->private_data, (void __user *) arg); 877 765 default: 878 766 return -ENOIOCTLCMD; 879 767 } ··· 892 776 return ib_umad_unreg_agent(filp->private_data, compat_ptr(arg)); 893 777 case IB_USER_MAD_ENABLE_PKEY: 894 778 return ib_umad_enable_pkey(filp->private_data); 779 + case IB_USER_MAD_REGISTER_AGENT2: 780 + return ib_umad_reg_agent2(filp->private_data, compat_ptr(arg)); 895 781 default: 896 782 return -ENOIOCTLCMD; 897 783 }
+1 -1
drivers/infiniband/hw/mlx4/mad.c
··· 891 891 agent = ib_register_mad_agent(&dev->ib_dev, p + 1, 892 892 q ? IB_QPT_GSI : IB_QPT_SMI, 893 893 NULL, 0, send_handler, 894 - NULL, NULL); 894 + NULL, NULL, 0); 895 895 if (IS_ERR(agent)) { 896 896 ret = PTR_ERR(agent); 897 897 goto err;
+1 -1
drivers/infiniband/hw/mthca/mthca_mad.c
··· 294 294 agent = ib_register_mad_agent(&dev->ib_dev, p + 1, 295 295 q ? IB_QPT_GSI : IB_QPT_SMI, 296 296 NULL, 0, send_handler, 297 - NULL, NULL); 297 + NULL, NULL, 0); 298 298 if (IS_ERR(agent)) { 299 299 ret = PTR_ERR(agent); 300 300 goto err;
+1 -1
drivers/infiniband/hw/qib/qib_mad.c
··· 2476 2476 ibp = &dd->pport[p].ibport_data; 2477 2477 agent = ib_register_mad_agent(&dev->ibdev, p + 1, IB_QPT_SMI, 2478 2478 NULL, 0, send_handler, 2479 - NULL, NULL); 2479 + NULL, NULL, 0); 2480 2480 if (IS_ERR(agent)) { 2481 2481 ret = PTR_ERR(agent); 2482 2482 goto err;
+1 -1
drivers/infiniband/ulp/srpt/ib_srpt.c
··· 563 563 &reg_req, 0, 564 564 srpt_mad_send_handler, 565 565 srpt_mad_recv_handler, 566 - sport); 566 + sport, 0); 567 567 if (IS_ERR(sport->mad_agent)) { 568 568 ret = PTR_ERR(sport->mad_agent); 569 569 sport->mad_agent = NULL;
+6 -1
include/rdma/ib_mad.h
··· 355 355 * @hi_tid: Access layer assigned transaction ID for this client. 356 356 * Unsolicited MADs sent by this client will have the upper 32-bits 357 357 * of their TID set to this value. 358 + * @flags: registration flags 358 359 * @port_num: Port number on which QP is registered 359 360 * @rmpp_version: If set, indicates the RMPP version used by this agent. 360 361 */ ··· 368 367 ib_mad_snoop_handler snoop_handler; 369 368 void *context; 370 369 u32 hi_tid; 370 + u32 flags; 371 371 u8 port_num; 372 372 u8 rmpp_version; 373 373 }; ··· 428 426 * in the range from 0x30 to 0x4f. Otherwise not used. 429 427 * @method_mask: The caller will receive unsolicited MADs for any method 430 428 * where @method_mask = 1. 429 + * 431 430 */ 432 431 struct ib_mad_reg_req { 433 432 u8 mgmt_class; ··· 454 451 * @recv_handler: The completion callback routine invoked for a received 455 452 * MAD. 456 453 * @context: User specified context associated with the registration. 454 + * @registration_flags: Registration flags to set for this agent 457 455 */ 458 456 struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device, 459 457 u8 port_num, ··· 463 459 u8 rmpp_version, 464 460 ib_mad_send_handler send_handler, 465 461 ib_mad_recv_handler recv_handler, 466 - void *context); 462 + void *context, 463 + u32 registration_flags); 467 464 468 465 enum ib_mad_snoop_flags { 469 466 /*IB_MAD_SNOOP_POSTED_SENDS = 1,*/
+39
include/uapi/rdma/ib_user_mad.h
··· 191 191 __u8 rmpp_version; 192 192 }; 193 193 194 + /** 195 + * ib_user_mad_reg_req2 - MAD registration request 196 + * 197 + * @id - Set by the _kernel_; used by userspace to identify the 198 + * registered agent in future requests. 199 + * @qpn - Queue pair number; must be 0 or 1. 200 + * @mgmt_class - Indicates which management class of MADs should be 201 + * receive by the caller. This field is only required if 202 + * the user wishes to receive unsolicited MADs, otherwise 203 + * it should be 0. 204 + * @mgmt_class_version - Indicates which version of MADs for the given 205 + * management class to receive. 206 + * @res - Ignored. 207 + * @flags - additional registration flags; Must be in the set of 208 + * flags defined in IB_USER_MAD_REG_FLAGS_CAP 209 + * @method_mask - The caller wishes to receive unsolicited MADs for the 210 + * methods whose bit(s) is(are) set. 211 + * @oui - Indicates IEEE OUI to use when mgmt_class is a vendor 212 + * class in the range from 0x30 to 0x4f. Otherwise not 213 + * used. 214 + * @rmpp_version - If set, indicates the RMPP version to use. 215 + */ 216 + #define IB_USER_MAD_REG_FLAGS_CAP (0) 217 + struct ib_user_mad_reg_req2 { 218 + __u32 id; 219 + __u32 qpn; 220 + __u8 mgmt_class; 221 + __u8 mgmt_class_version; 222 + __u16 res; 223 + __u32 flags; 224 + __u64 method_mask[2]; 225 + __u32 oui; 226 + __u8 rmpp_version; 227 + __u8 reserved[3]; 228 + }; 229 + 194 230 #define IB_IOCTL_MAGIC 0x1b 195 231 196 232 #define IB_USER_MAD_REGISTER_AGENT _IOWR(IB_IOCTL_MAGIC, 1, \ ··· 235 199 #define IB_USER_MAD_UNREGISTER_AGENT _IOW(IB_IOCTL_MAGIC, 2, __u32) 236 200 237 201 #define IB_USER_MAD_ENABLE_PKEY _IO(IB_IOCTL_MAGIC, 3) 202 + 203 + #define IB_USER_MAD_REGISTER_AGENT2 _IOWR(IB_IOCTL_MAGIC, 4, \ 204 + struct ib_user_mad_reg_req2) 238 205 239 206 #endif /* IB_USER_MAD_H */