Pull rdma updates from Jason Gunthorpe: "Usual size of updates, a new driver, and most of the bulk focusing on rxe: - Usual typos, style, and language updates - Driver updates for mlx5, irdma, siw, rts, srp, hfi1, hns, erdma, mlx4, srp - Lots of RXE updates: * Improve reply error handling for bad MR operations * Code tidying * Debug printing uses common loggers * Remove half implemented RD related stuff * Support IBA's recently defined Atomic Write and Flush operations - erdma support for atomic operations - New driver 'mana' for Ethernet HW available in Azure VMs. This driver only supports DPDK" * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: (122 commits) IB/IPoIB: Fix queue count inconsistency for PKEY child interfaces RDMA: Add missed netdev_put() for the netdevice_tracker RDMA/rxe: Enable RDMA FLUSH capability for rxe device RDMA/cm: Make QP FLUSHABLE for supported device RDMA/rxe: Implement flush completion RDMA/rxe: Implement flush execution in responder side RDMA/rxe: Implement RC RDMA FLUSH service in requester side RDMA/rxe: Extend rxe packet format to support flush RDMA/rxe: Allow registering persistent flag for pmem MR only RDMA/rxe: Extend rxe user ABI to support flush RDMA: Extend RDMA kernel verbs ABI to support flush RDMA: Extend RDMA user ABI to support flush RDMA/rxe: Fix incorrect responder length checking RDMA/rxe: Fix oops with zero length reads RDMA/mlx5: Remove not-used IB_FLOW_SPEC_IB define RDMA/hns: Fix XRC caps on HIP08 RDMA/hns: Fix error code of CMD RDMA/hns: Fix page size cap from firmware RDMA/hns: Fix PBL page MTR find RDMA/hns: Fix AH attr queried by query_qp ...
Unified · Split
| @@ -13806,6 +13806,15 @@ F: drivers/scsi/smartpqi/smartpqi*.[ch] · 13805 unmodified lines | |||
| 13806 | F: include/linux/cciss*.h | 13806 | F: include/linux/cciss*.h |
| 13807 | F: include/uapi/linux/cciss*.h | 13807 | F: include/uapi/linux/cciss*.h |
| 13808 | 13808 | ||
| 13809 | MICROSOFT MANA RDMA DRIVER | ||
| 13810 | M: Long Li <longli@microsoft.com> | ||
| 13811 | M: Ajay Sharma <sharmaajay@microsoft.com> | ||
| 13812 | L: linux-rdma@vger.kernel.org | ||
| 13813 | S: Supported | ||
| 13814 | F: drivers/infiniband/hw/mana/ | ||
| 13815 | F: include/net/mana | ||
| 13816 | F: include/uapi/rdma/mana-abi.h | ||
| 13817 | |||
| 13809 | MICROSOFT SURFACE AGGREGATOR TABLET-MODE SWITCH | 13818 | MICROSOFT SURFACE AGGREGATOR TABLET-MODE SWITCH |
| 13810 | M: Maximilian Luz <luzmaximilian@gmail.com> | 13819 | M: Maximilian Luz <luzmaximilian@gmail.com> |
| 13811 | L: platform-driver-x86@vger.kernel.org | 13820 | L: platform-driver-x86@vger.kernel.org |
| @@ -78,6 +78,7 @@ config INFINIBAND_VIRT_DMA · 77 unmodified lines | |||
| 78 | def_bool !HIGHMEM | 78 | def_bool !HIGHMEM |
| 79 | 79 | ||
| 80 | if INFINIBAND_USER_ACCESS || !INFINIBAND_USER_ACCESS | 80 | if INFINIBAND_USER_ACCESS || !INFINIBAND_USER_ACCESS |
| 81 | if !UML | ||
| 81 | source "drivers/infiniband/hw/bnxt_re/Kconfig" | 82 | source "drivers/infiniband/hw/bnxt_re/Kconfig" |
| 82 | source "drivers/infiniband/hw/cxgb4/Kconfig" | 83 | source "drivers/infiniband/hw/cxgb4/Kconfig" |
| 83 | source "drivers/infiniband/hw/efa/Kconfig" | 84 | source "drivers/infiniband/hw/efa/Kconfig" |
| @@ -85,6 +86,7 @@ source "drivers/infiniband/hw/erdma/Kconfig" · 1 unmodified line | |||
| 85 | source "drivers/infiniband/hw/hfi1/Kconfig" | 86 | source "drivers/infiniband/hw/hfi1/Kconfig" |
| 86 | source "drivers/infiniband/hw/hns/Kconfig" | 87 | source "drivers/infiniband/hw/hns/Kconfig" |
| 87 | source "drivers/infiniband/hw/irdma/Kconfig" | 88 | source "drivers/infiniband/hw/irdma/Kconfig" |
| 89 | source "drivers/infiniband/hw/mana/Kconfig" | ||
| 88 | source "drivers/infiniband/hw/mlx4/Kconfig" | 90 | source "drivers/infiniband/hw/mlx4/Kconfig" |
| 89 | source "drivers/infiniband/hw/mlx5/Kconfig" | 91 | source "drivers/infiniband/hw/mlx5/Kconfig" |
| 90 | source "drivers/infiniband/hw/mthca/Kconfig" | 92 | source "drivers/infiniband/hw/mthca/Kconfig" |
| @@ -94,6 +96,7 @@ source "drivers/infiniband/hw/qib/Kconfig" · 3 unmodified lines | |||
| 94 | source "drivers/infiniband/hw/usnic/Kconfig" | 96 | source "drivers/infiniband/hw/usnic/Kconfig" |
| 95 | source "drivers/infiniband/hw/vmw_pvrdma/Kconfig" | 97 | source "drivers/infiniband/hw/vmw_pvrdma/Kconfig" |
| 96 | source "drivers/infiniband/sw/rdmavt/Kconfig" | 98 | source "drivers/infiniband/sw/rdmavt/Kconfig" |
| 99 | endif # !UML | ||
| 97 | source "drivers/infiniband/sw/rxe/Kconfig" | 100 | source "drivers/infiniband/sw/rxe/Kconfig" |
| 98 | source "drivers/infiniband/sw/siw/Kconfig" | 101 | source "drivers/infiniband/sw/siw/Kconfig" |
| 99 | endif | 102 | endif |
| @@ -1422,7 +1422,7 @@ int rdma_read_gid_l2_fields(const struct ib_gid_attr *attr, · 1421 unmodified lines | |||
| 1422 | *vlan_id = vlan_dev_vlan_id(ndev); | 1422 | *vlan_id = vlan_dev_vlan_id(ndev); |
| 1423 | } else { | 1423 | } else { |
| 1424 | /* If the netdev is upper device and if it's lower | 1424 | /* If the netdev is upper device and if it's lower |
| 1425 | * device is vlan device, consider vlan id of the | 1425 | * device is vlan device, consider vlan id of |
| 1426 | * the lower vlan device for this gid entry. | 1426 | * the lower vlan device for this gid entry. |
| 1427 | */ | 1427 | */ |
| 1428 | netdev_walk_all_lower_dev_rcu(attr->ndev, | 1428 | netdev_walk_all_lower_dev_rcu(attr->ndev, |
| @@ -4094,9 +4094,18 @@ static int cm_init_qp_init_attr(struct cm_id_private *cm_id_priv, · 4093 unmodified lines | |||
| 4094 | *qp_attr_mask = IB_QP_STATE | IB_QP_ACCESS_FLAGS | | 4094 | *qp_attr_mask = IB_QP_STATE | IB_QP_ACCESS_FLAGS | |
| 4095 | IB_QP_PKEY_INDEX | IB_QP_PORT; | 4095 | IB_QP_PKEY_INDEX | IB_QP_PORT; |
| 4096 | qp_attr->qp_access_flags = IB_ACCESS_REMOTE_WRITE; | 4096 | qp_attr->qp_access_flags = IB_ACCESS_REMOTE_WRITE; |
| 4097 | if (cm_id_priv->responder_resources) | 4097 | if (cm_id_priv->responder_resources) { |
| 4098 | struct ib_device *ib_dev = cm_id_priv->id.device; | ||
| 4099 | u64 support_flush = ib_dev->attrs.device_cap_flags & | ||
| 4100 | (IB_DEVICE_FLUSH_GLOBAL | IB_DEVICE_FLUSH_PERSISTENT); | ||
| 4101 | u32 flushable = support_flush ? | ||
| 4102 | (IB_ACCESS_FLUSH_GLOBAL | | ||
| 4103 | IB_ACCESS_FLUSH_PERSISTENT) : 0; | ||
| 4104 | |||
| 4098 | qp_attr->qp_access_flags |= IB_ACCESS_REMOTE_READ | | 4105 | qp_attr->qp_access_flags |= IB_ACCESS_REMOTE_READ | |
| 4099 | IB_ACCESS_REMOTE_ATOMIC; | 4106 | IB_ACCESS_REMOTE_ATOMIC | |
| 4107 | flushable; | ||
| 4108 | } | ||
| 4100 | qp_attr->pkey_index = cm_id_priv->av.pkey_index; | 4109 | qp_attr->pkey_index = cm_id_priv->av.pkey_index; |
| 4101 | if (cm_id_priv->av.port) | 4110 | if (cm_id_priv->av.port) |
| 4102 | qp_attr->port_num = cm_id_priv->av.port->port_num; | 4111 | qp_attr->port_num = cm_id_priv->av.port->port_num; |
| @@ -47,7 +47,7 @@ MODULE_LICENSE("Dual BSD/GPL"); · 46 unmodified lines | |||
| 47 | #define CMA_CM_RESPONSE_TIMEOUT 20 | 47 | #define CMA_CM_RESPONSE_TIMEOUT 20 |
| 48 | #define CMA_MAX_CM_RETRIES 15 | 48 | #define CMA_MAX_CM_RETRIES 15 |
| 49 | #define CMA_CM_MRA_SETTING (IB_CM_MRA_FLAG_DELAY | 24) | 49 | #define CMA_CM_MRA_SETTING (IB_CM_MRA_FLAG_DELAY | 24) |
| 50 | #define CMA_IBOE_PACKET_LIFETIME 18 | 50 | #define CMA_IBOE_PACKET_LIFETIME 16 |
| 51 | #define CMA_PREFERRED_ROCE_GID_TYPE IB_GID_TYPE_ROCE_UDP_ENCAP | 51 | #define CMA_PREFERRED_ROCE_GID_TYPE IB_GID_TYPE_ROCE_UDP_ENCAP |
| 52 | 52 | ||
| 53 | static const char * const cma_events[] = { | 53 | static const char * const cma_events[] = { |
| @@ -2159,14 +2159,16 @@ int ib_device_set_netdev(struct ib_device *ib_dev, struct net_device *ndev, · 2158 unmodified lines | |||
| 2159 | return 0; | 2159 | return 0; |
| 2160 | } | 2160 | } |
| 2161 | 2161 | ||
| 2162 | if (old_ndev) | ||
| 2163 | netdev_tracker_free(ndev, &pdata->netdev_tracker); | ||
| 2162 | if (ndev) | 2164 | if (ndev) |
| 2163 | dev_hold(ndev); | 2165 | netdev_hold(ndev, &pdata->netdev_tracker, GFP_ATOMIC); |
| 2164 | rcu_assign_pointer(pdata->netdev, ndev); | 2166 | rcu_assign_pointer(pdata->netdev, ndev); |
| 2165 | spin_unlock_irqrestore(&pdata->netdev_lock, flags); | 2167 | spin_unlock_irqrestore(&pdata->netdev_lock, flags); |
| 2166 | 2168 | ||
| 2167 | add_ndev_hash(pdata); | 2169 | add_ndev_hash(pdata); |
| 2168 | if (old_ndev) | 2170 | if (old_ndev) |
| 2169 | dev_put(old_ndev); | 2171 | __dev_put(old_ndev); |
| 2170 | 2172 | ||
| 2171 | return 0; | 2173 | return 0; |
| 2172 | } | 2174 | } |
| @@ -2199,7 +2201,7 @@ static void free_netdevs(struct ib_device *ib_dev) · 26 unmodified lines | |||
| 2199 | * comparisons after the put | 2201 | * comparisons after the put |
| 2200 | */ | 2202 | */ |
| 2201 | rcu_assign_pointer(pdata->netdev, NULL); | 2203 | rcu_assign_pointer(pdata->netdev, NULL); |
| 2202 | dev_put(ndev); | 2204 | netdev_put(ndev, &pdata->netdev_tracker); |
| 2203 | } | 2205 | } |
| 2204 | spin_unlock_irqrestore(&pdata->netdev_lock, flags); | 2206 | spin_unlock_irqrestore(&pdata->netdev_lock, flags); |
| 2205 | } | 2207 | } |
| @@ -2851,8 +2853,8 @@ err: · 645 unmodified lines | |||
| 2851 | static void __exit ib_core_cleanup(void) | 2853 | static void __exit ib_core_cleanup(void) |
| 2852 | { | 2854 | { |
| 2853 | roce_gid_mgmt_cleanup(); | 2855 | roce_gid_mgmt_cleanup(); |
| 2854 | nldev_exit(); | ||
| 2855 | rdma_nl_unregister(RDMA_NL_LS); | 2856 | rdma_nl_unregister(RDMA_NL_LS); |
| 2857 | nldev_exit(); | ||
| 2856 | unregister_pernet_device(&rdma_dev_net_ops); | 2858 | unregister_pernet_device(&rdma_dev_net_ops); |
| 2857 | unregister_blocking_lsm_notifier(&ibdev_lsm_nb); | 2859 | unregister_blocking_lsm_notifier(&ibdev_lsm_nb); |
| 2858 | ib_sa_cleanup(); | 2860 | ib_sa_cleanup(); |
| @@ -59,9 +59,6 @@ static void create_mad_addr_info(struct ib_mad_send_wr_private *mad_send_wr, · 58 unmodified lines | |||
| 59 | struct ib_mad_qp_info *qp_info, | 59 | struct ib_mad_qp_info *qp_info, |
| 60 | struct trace_event_raw_ib_mad_send_template *entry) | 60 | struct trace_event_raw_ib_mad_send_template *entry) |
| 61 | { | 61 | { |
| 62 | u16 pkey; | ||
| 63 | struct ib_device *dev = qp_info->port_priv->device; | ||
| 64 | u32 pnum = qp_info->port_priv->port_num; | ||
| 65 | struct ib_ud_wr *wr = &mad_send_wr->send_wr; | 62 | struct ib_ud_wr *wr = &mad_send_wr->send_wr; |
| 66 | struct rdma_ah_attr attr = {}; | 63 | struct rdma_ah_attr attr = {}; |
| 67 | 64 | ||
| @@ -69,8 +66,6 @@ static void create_mad_addr_info(struct ib_mad_send_wr_private *mad_send_wr, · 1 unmodified line | |||
| 69 | 66 | ||
| 70 | /* These are common */ | 67 | /* These are common */ |
| 71 | entry->sl = attr.sl; | 68 | entry->sl = attr.sl; |
| 72 | ib_query_pkey(dev, pnum, wr->pkey_index, &pkey); | ||
| 73 | entry->pkey = pkey; | ||
| 74 | entry->rqpn = wr->remote_qpn; | 69 | entry->rqpn = wr->remote_qpn; |
| 75 | entry->rqkey = wr->remote_qkey; | 70 | entry->rqkey = wr->remote_qkey; |
| 76 | entry->dlid = rdma_ah_get_dlid(&attr); | 71 | entry->dlid = rdma_ah_get_dlid(&attr); |
| @@ -513,7 +513,7 @@ static int fill_res_qp_entry(struct sk_buff *msg, bool has_cap_net_admin, · 512 unmodified lines | |||
| 513 | 513 | ||
| 514 | /* In create_qp() port is not set yet */ | 514 | /* In create_qp() port is not set yet */ |
| 515 | if (qp->port && nla_put_u32(msg, RDMA_NLDEV_ATTR_PORT_INDEX, qp->port)) | 515 | if (qp->port && nla_put_u32(msg, RDMA_NLDEV_ATTR_PORT_INDEX, qp->port)) |
| 516 | return -EINVAL; | 516 | return -EMSGSIZE; |
| 517 | 517 | ||
| 518 | ret = nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_LQPN, qp->qp_num); | 518 | ret = nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_LQPN, qp->qp_num); |
| 519 | if (ret) | 519 | if (ret) |
| @@ -552,7 +552,7 @@ static int fill_res_cm_id_entry(struct sk_buff *msg, bool has_cap_net_admin, · 32 unmodified lines | |||
| 552 | struct rdma_cm_id *cm_id = &id_priv->id; | 552 | struct rdma_cm_id *cm_id = &id_priv->id; |
| 553 | 553 | ||
| 554 | if (port && port != cm_id->port_num) | 554 | if (port && port != cm_id->port_num) |
| 555 | return 0; | 555 | return -EAGAIN; |
| 556 | 556 | ||
| 557 | if (cm_id->port_num && | 557 | if (cm_id->port_num && |
| 558 | nla_put_u32(msg, RDMA_NLDEV_ATTR_PORT_INDEX, cm_id->port_num)) | 558 | nla_put_u32(msg, RDMA_NLDEV_ATTR_PORT_INDEX, cm_id->port_num)) |
| @@ -894,6 +894,8 @@ static int fill_stat_counter_qps(struct sk_buff *msg, · 335 unmodified lines | |||
| 894 | int ret = 0; | 894 | int ret = 0; |
| 895 | 895 | ||
| 896 | table_attr = nla_nest_start(msg, RDMA_NLDEV_ATTR_RES_QP); | 896 | table_attr = nla_nest_start(msg, RDMA_NLDEV_ATTR_RES_QP); |
| 897 | if (!table_attr) | ||
| 898 | return -EMSGSIZE; | ||
| 897 | 899 | ||
| 898 | rt = &counter->device->res[RDMA_RESTRACK_QP]; | 900 | rt = &counter->device->res[RDMA_RESTRACK_QP]; |
| 899 | xa_lock(&rt->xa); | 901 | xa_lock(&rt->xa); |
| @@ -1041,6 +1043,10 @@ static int nldev_get_doit(struct sk_buff *skb, struct nlmsghdr *nlh, · 141 unmodified lines | |||
| 1041 | nlh = nlmsg_put(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq, | 1043 | nlh = nlmsg_put(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq, |
| 1042 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_GET), | 1044 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_GET), |
| 1043 | 0, 0); | 1045 | 0, 0); |
| 1046 | if (!nlh) { | ||
| 1047 | err = -EMSGSIZE; | ||
| 1048 | goto err_free; | ||
| 1049 | } | ||
| 1044 | 1050 | ||
| 1045 | err = fill_dev_info(msg, device); | 1051 | err = fill_dev_info(msg, device); |
| 1046 | if (err) | 1052 | if (err) |
| @@ -1126,7 +1132,7 @@ static int _nldev_get_dumpit(struct ib_device *device, · 79 unmodified lines | |||
| 1126 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_GET), | 1132 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_GET), |
| 1127 | 0, NLM_F_MULTI); | 1133 | 0, NLM_F_MULTI); |
| 1128 | 1134 | ||
| 1129 | if (fill_dev_info(skb, device)) { | 1135 | if (!nlh || fill_dev_info(skb, device)) { |
| 1130 | nlmsg_cancel(skb, nlh); | 1136 | nlmsg_cancel(skb, nlh); |
| 1131 | goto out; | 1137 | goto out; |
| 1132 | } | 1138 | } |
| @@ -1185,6 +1191,10 @@ static int nldev_port_get_doit(struct sk_buff *skb, struct nlmsghdr *nlh, · 52 unmodified lines | |||
| 1185 | nlh = nlmsg_put(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq, | 1191 | nlh = nlmsg_put(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq, |
| 1186 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_GET), | 1192 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_GET), |
| 1187 | 0, 0); | 1193 | 0, 0); |
| 1194 | if (!nlh) { | ||
| 1195 | err = -EMSGSIZE; | ||
| 1196 | goto err_free; | ||
| 1197 | } | ||
| 1188 | 1198 | ||
| 1189 | err = fill_port_info(msg, device, port, sock_net(skb->sk)); | 1199 | err = fill_port_info(msg, device, port, sock_net(skb->sk)); |
| 1190 | if (err) | 1200 | if (err) |
| @@ -1246,7 +1256,7 @@ static int nldev_port_get_dumpit(struct sk_buff *skb, · 55 unmodified lines | |||
| 1246 | RDMA_NLDEV_CMD_PORT_GET), | 1256 | RDMA_NLDEV_CMD_PORT_GET), |
| 1247 | 0, NLM_F_MULTI); | 1257 | 0, NLM_F_MULTI); |
| 1248 | 1258 | ||
| 1249 | if (fill_port_info(skb, device, p, sock_net(skb->sk))) { | 1259 | if (!nlh || fill_port_info(skb, device, p, sock_net(skb->sk))) { |
| 1250 | nlmsg_cancel(skb, nlh); | 1260 | nlmsg_cancel(skb, nlh); |
| 1251 | goto out; | 1261 | goto out; |
| 1252 | } | 1262 | } |
| @@ -1288,6 +1298,10 @@ static int nldev_res_get_doit(struct sk_buff *skb, struct nlmsghdr *nlh, · 35 unmodified lines | |||
| 1288 | nlh = nlmsg_put(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq, | 1298 | nlh = nlmsg_put(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq, |
| 1289 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_RES_GET), | 1299 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_RES_GET), |
| 1290 | 0, 0); | 1300 | 0, 0); |
| 1301 | if (!nlh) { | ||
| 1302 | ret = -EMSGSIZE; | ||
| 1303 | goto err_free; | ||
| 1304 | } | ||
| 1291 | 1305 | ||
| 1292 | ret = fill_res_info(msg, device); | 1306 | ret = fill_res_info(msg, device); |
| 1293 | if (ret) | 1307 | if (ret) |
| @@ -1319,7 +1333,7 @@ static int _nldev_res_get_dumpit(struct ib_device *device, · 25 unmodified lines | |||
| 1319 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_RES_GET), | 1333 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_RES_GET), |
| 1320 | 0, NLM_F_MULTI); | 1334 | 0, NLM_F_MULTI); |
| 1321 | 1335 | ||
| 1322 | if (fill_res_info(skb, device)) { | 1336 | if (!nlh || fill_res_info(skb, device)) { |
| 1323 | nlmsg_cancel(skb, nlh); | 1337 | nlmsg_cancel(skb, nlh); |
| 1324 | goto out; | 1338 | goto out; |
| 1325 | } | 1339 | } |
| @@ -1454,7 +1468,7 @@ static int res_get_common_doit(struct sk_buff *skb, struct nlmsghdr *nlh, · 128 unmodified lines | |||
| 1454 | RDMA_NL_GET_OP(nlh->nlmsg_type)), | 1468 | RDMA_NL_GET_OP(nlh->nlmsg_type)), |
| 1455 | 0, 0); | 1469 | 0, 0); |
| 1456 | 1470 | ||
| 1457 | if (fill_nldev_handle(msg, device)) { | 1471 | if (!nlh || fill_nldev_handle(msg, device)) { |
| 1458 | ret = -EMSGSIZE; | 1472 | ret = -EMSGSIZE; |
| 1459 | goto err_free; | 1473 | goto err_free; |
| 1460 | } | 1474 | } |
| @@ -1533,7 +1547,7 @@ static int res_get_common_dumpit(struct sk_buff *skb, · 72 unmodified lines | |||
| 1533 | RDMA_NL_GET_OP(cb->nlh->nlmsg_type)), | 1547 | RDMA_NL_GET_OP(cb->nlh->nlmsg_type)), |
| 1534 | 0, NLM_F_MULTI); | 1548 | 0, NLM_F_MULTI); |
| 1535 | 1549 | ||
| 1536 | if (fill_nldev_handle(skb, device)) { | 1550 | if (!nlh || fill_nldev_handle(skb, device)) { |
| 1537 | ret = -EMSGSIZE; | 1551 | ret = -EMSGSIZE; |
| 1538 | goto err; | 1552 | goto err; |
| 1539 | } | 1553 | } |
| @@ -1795,6 +1809,10 @@ static int nldev_get_chardev(struct sk_buff *skb, struct nlmsghdr *nlh, · 255 unmodified lines | |||
| 1795 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, | 1809 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, |
| 1796 | RDMA_NLDEV_CMD_GET_CHARDEV), | 1810 | RDMA_NLDEV_CMD_GET_CHARDEV), |
| 1797 | 0, 0); | 1811 | 0, 0); |
| 1812 | if (!nlh) { | ||
| 1813 | err = -EMSGSIZE; | ||
| 1814 | goto out_nlmsg; | ||
| 1815 | } | ||
| 1798 | 1816 | ||
| 1799 | data.nl_msg = msg; | 1817 | data.nl_msg = msg; |
| 1800 | err = ib_get_client_nl_info(ibdev, client_name, &data); | 1818 | err = ib_get_client_nl_info(ibdev, client_name, &data); |
| @@ -1852,6 +1870,10 @@ static int nldev_sys_get_doit(struct sk_buff *skb, struct nlmsghdr *nlh, · 51 unmodified lines | |||
| 1852 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, | 1870 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, |
| 1853 | RDMA_NLDEV_CMD_SYS_GET), | 1871 | RDMA_NLDEV_CMD_SYS_GET), |
| 1854 | 0, 0); | 1872 | 0, 0); |
| 1873 | if (!nlh) { | ||
| 1874 | nlmsg_free(msg); | ||
| 1875 | return -EMSGSIZE; | ||
| 1876 | } | ||
| 1855 | 1877 | ||
| 1856 | err = nla_put_u8(msg, RDMA_NLDEV_SYS_ATTR_NETNS_MODE, | 1878 | err = nla_put_u8(msg, RDMA_NLDEV_SYS_ATTR_NETNS_MODE, |
| 1857 | (u8)ib_devices_shared_netns); | 1879 | (u8)ib_devices_shared_netns); |
| @@ -2032,7 +2054,7 @@ static int nldev_stat_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh, · 174 unmodified lines | |||
| 2032 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, | 2054 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, |
| 2033 | RDMA_NLDEV_CMD_STAT_SET), | 2055 | RDMA_NLDEV_CMD_STAT_SET), |
| 2034 | 0, 0); | 2056 | 0, 0); |
| 2035 | if (fill_nldev_handle(msg, device) || | 2057 | if (!nlh || fill_nldev_handle(msg, device) || |
| 2036 | nla_put_u32(msg, RDMA_NLDEV_ATTR_PORT_INDEX, port)) { | 2058 | nla_put_u32(msg, RDMA_NLDEV_ATTR_PORT_INDEX, port)) { |
| 2037 | ret = -EMSGSIZE; | 2059 | ret = -EMSGSIZE; |
| 2038 | goto err_free_msg; | 2060 | goto err_free_msg; |
| @@ -2101,6 +2123,10 @@ static int nldev_stat_del_doit(struct sk_buff *skb, struct nlmsghdr *nlh, · 62 unmodified lines | |||
| 2101 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, | 2123 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, |
| 2102 | RDMA_NLDEV_CMD_STAT_SET), | 2124 | RDMA_NLDEV_CMD_STAT_SET), |
| 2103 | 0, 0); | 2125 | 0, 0); |
| 2126 | if (!nlh) { | ||
| 2127 | ret = -EMSGSIZE; | ||
| 2128 | goto err_fill; | ||
| 2129 | } | ||
| 2104 | 2130 | ||
| 2105 | cntn = nla_get_u32(tb[RDMA_NLDEV_ATTR_STAT_COUNTER_ID]); | 2131 | cntn = nla_get_u32(tb[RDMA_NLDEV_ATTR_STAT_COUNTER_ID]); |
| 2106 | qpn = nla_get_u32(tb[RDMA_NLDEV_ATTR_RES_LQPN]); | 2132 | qpn = nla_get_u32(tb[RDMA_NLDEV_ATTR_RES_LQPN]); |
| @@ -2171,7 +2197,7 @@ static int stat_get_doit_default_counter(struct sk_buff *skb, · 64 unmodified lines | |||
| 2171 | RDMA_NLDEV_CMD_STAT_GET), | 2197 | RDMA_NLDEV_CMD_STAT_GET), |
| 2172 | 0, 0); | 2198 | 0, 0); |
| 2173 | 2199 | ||
| 2174 | if (fill_nldev_handle(msg, device) || | 2200 | if (!nlh || fill_nldev_handle(msg, device) || |
| 2175 | nla_put_u32(msg, RDMA_NLDEV_ATTR_PORT_INDEX, port)) { | 2201 | nla_put_u32(msg, RDMA_NLDEV_ATTR_PORT_INDEX, port)) { |
| 2176 | ret = -EMSGSIZE; | 2202 | ret = -EMSGSIZE; |
| 2177 | goto err_msg; | 2203 | goto err_msg; |
| @@ -2259,6 +2285,10 @@ static int stat_get_doit_qp(struct sk_buff *skb, struct nlmsghdr *nlh, · 81 unmodified lines | |||
| 2259 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, | 2285 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, |
| 2260 | RDMA_NLDEV_CMD_STAT_GET), | 2286 | RDMA_NLDEV_CMD_STAT_GET), |
| 2261 | 0, 0); | 2287 | 0, 0); |
| 2288 | if (!nlh) { | ||
| 2289 | ret = -EMSGSIZE; | ||
| 2290 | goto err_msg; | ||
| 2291 | } | ||
| 2262 | 2292 | ||
| 2263 | ret = rdma_counter_get_mode(device, port, &mode, &mask); | 2293 | ret = rdma_counter_get_mode(device, port, &mode, &mask); |
| 2264 | if (ret) | 2294 | if (ret) |
| @@ -2391,7 +2421,7 @@ static int nldev_stat_get_counter_status_doit(struct sk_buff *skb, · 126 unmodified lines | |||
| 2391 | 0, 0); | 2421 | 0, 0); |
| 2392 | 2422 | ||
| 2393 | ret = -EMSGSIZE; | 2423 | ret = -EMSGSIZE; |
| 2394 | if (fill_nldev_handle(msg, device) || | 2424 | if (!nlh || fill_nldev_handle(msg, device) || |
| 2395 | nla_put_u32(msg, RDMA_NLDEV_ATTR_PORT_INDEX, port)) | 2425 | nla_put_u32(msg, RDMA_NLDEV_ATTR_PORT_INDEX, port)) |
| 2396 | goto err_msg; | 2426 | goto err_msg; |
| 2397 | 2427 | ||
| @@ -343,8 +343,6 @@ void rdma_restrack_del(struct rdma_restrack_entry *res) · 342 unmodified lines | |||
| 343 | rt = &dev->res[res->type]; | 343 | rt = &dev->res[res->type]; |
| 344 | 344 | ||
| 345 | old = xa_erase(&rt->xa, res->id); | 345 | old = xa_erase(&rt->xa, res->id); |
| 346 | if (res->type == RDMA_RESTRACK_MR) | ||
| 347 | return; | ||
| 348 | WARN_ON(old != res); | 346 | WARN_ON(old != res); |
| 349 | 347 | ||
| 350 | out: | 348 | out: |
| @@ -1213,6 +1213,9 @@ static struct ib_port *setup_port(struct ib_core_device *coredev, int port_num, · 1212 unmodified lines | |||
| 1213 | p->port_num = port_num; | 1213 | p->port_num = port_num; |
| 1214 | kobject_init(&p->kobj, &port_type); | 1214 | kobject_init(&p->kobj, &port_type); |
| 1215 | 1215 | ||
| 1216 | if (device->port_data && is_full_dev) | ||
| 1217 | device->port_data[port_num].sysfs = p; | ||
| 1218 | |||
| 1216 | cur_group = p->groups_list; | 1219 | cur_group = p->groups_list; |
| 1217 | ret = alloc_port_table_group("gids", &p->groups[0], p->attrs_list, | 1220 | ret = alloc_port_table_group("gids", &p->groups[0], p->attrs_list, |
| 1218 | attr->gid_tbl_len, show_port_gid); | 1221 | attr->gid_tbl_len, show_port_gid); |
| @@ -1258,9 +1261,6 @@ static struct ib_port *setup_port(struct ib_core_device *coredev, int port_num, · 39 unmodified lines | |||
| 1258 | } | 1261 | } |
| 1259 | 1262 | ||
| 1260 | list_add_tail(&p->kobj.entry, &coredev->port_list); | 1263 | list_add_tail(&p->kobj.entry, &coredev->port_list); |
| 1261 | if (device->port_data && is_full_dev) | ||
| 1262 | device->port_data[port_num].sysfs = p; | ||
| 1263 | |||
| 1264 | return p; | 1264 | return p; |
| 1265 | 1265 | ||
| 1266 | err_groups: | 1266 | err_groups: |
| @@ -1268,6 +1268,8 @@ err_groups: · 1 unmodified line | |||
| 1268 | err_del: | 1268 | err_del: |
| 1269 | kobject_del(&p->kobj); | 1269 | kobject_del(&p->kobj); |
| 1270 | err_put: | 1270 | err_put: |
| 1271 | if (device->port_data && is_full_dev) | ||
| 1272 | device->port_data[port_num].sysfs = NULL; | ||
| 1271 | kobject_put(&p->kobj); | 1273 | kobject_put(&p->kobj); |
| 1272 | return ERR_PTR(ret); | 1274 | return ERR_PTR(ret); |
| 1273 | } | 1275 | } |
| @@ -1276,14 +1278,17 @@ static void destroy_port(struct ib_core_device *coredev, struct ib_port *port) · 2 unmodified lines | |||
| 1276 | { | 1278 | { |
| 1277 | bool is_full_dev = &port->ibdev->coredev == coredev; | 1279 | bool is_full_dev = &port->ibdev->coredev == coredev; |
| 1278 | 1280 | ||
| 1279 | if (port->ibdev->port_data && | ||
| 1280 | port->ibdev->port_data[port->port_num].sysfs == port) | ||
| 1281 | port->ibdev->port_data[port->port_num].sysfs = NULL; | ||
| 1282 | list_del(&port->kobj.entry); | 1281 | list_del(&port->kobj.entry); |
| 1283 | if (is_full_dev) | 1282 | if (is_full_dev) |
| 1284 | sysfs_remove_groups(&port->kobj, port->ibdev->ops.port_groups); | 1283 | sysfs_remove_groups(&port->kobj, port->ibdev->ops.port_groups); |
| 1284 | |||
| 1285 | sysfs_remove_groups(&port->kobj, port->groups_list); | 1285 | sysfs_remove_groups(&port->kobj, port->groups_list); |
| 1286 | kobject_del(&port->kobj); | 1286 | kobject_del(&port->kobj); |
| 1287 | |||
| 1288 | if (port->ibdev->port_data && | ||
| 1289 | port->ibdev->port_data[port->port_num].sysfs == port) | ||
| 1290 | port->ibdev->port_data[port->port_num].sysfs = NULL; | ||
| 1291 | |||
| 1287 | kobject_put(&port->kobj); | 1292 | kobject_put(&port->kobj); |
| 1288 | } | 1293 | } |
| 1289 | 1294 | ||
| @@ -163,7 +163,7 @@ static int UVERBS_HANDLER(UVERBS_METHOD_QP_CREATE)( · 162 unmodified lines | |||
| 163 | UVERBS_ATTR_CREATE_QP_SRQ_HANDLE)) | 163 | UVERBS_ATTR_CREATE_QP_SRQ_HANDLE)) |
| 164 | return -EINVAL; | 164 | return -EINVAL; |
| 165 | 165 | ||
| 166 | /* send_cq is optinal */ | 166 | /* send_cq is optional */ |
| 167 | if (cap.max_send_wr) { | 167 | if (cap.max_send_wr) { |
| 168 | send_cq = uverbs_attr_get_obj(attrs, | 168 | send_cq = uverbs_attr_get_obj(attrs, |
| 169 | UVERBS_ATTR_CREATE_QP_SEND_CQ_HANDLE); | 169 | UVERBS_ATTR_CREATE_QP_SEND_CQ_HANDLE); |
| @@ -4,6 +4,7 @@ obj-$(CONFIG_INFINIBAND_QIB) += qib/ · 3 unmodified lines | |||
| 4 | obj-$(CONFIG_INFINIBAND_CXGB4) += cxgb4/ | 4 | obj-$(CONFIG_INFINIBAND_CXGB4) += cxgb4/ |
| 5 | obj-$(CONFIG_INFINIBAND_EFA) += efa/ | 5 | obj-$(CONFIG_INFINIBAND_EFA) += efa/ |
| 6 | obj-$(CONFIG_INFINIBAND_IRDMA) += irdma/ | 6 | obj-$(CONFIG_INFINIBAND_IRDMA) += irdma/ |
| 7 | obj-$(CONFIG_MANA_INFINIBAND) += mana/ | ||
| 7 | obj-$(CONFIG_MLX4_INFINIBAND) += mlx4/ | 8 | obj-$(CONFIG_MLX4_INFINIBAND) += mlx4/ |
| 8 | obj-$(CONFIG_MLX5_INFINIBAND) += mlx5/ | 9 | obj-$(CONFIG_MLX5_INFINIBAND) += mlx5/ |
| 9 | obj-$(CONFIG_INFINIBAND_OCRDMA) += ocrdma/ | 10 | obj-$(CONFIG_INFINIBAND_OCRDMA) += ocrdma/ |
| @@ -124,6 +124,7 @@ struct erdma_devattr { · 123 unmodified lines | |||
| 124 | u32 fw_version; | 124 | u32 fw_version; |
| 125 | 125 | ||
| 126 | unsigned char peer_addr[ETH_ALEN]; | 126 | unsigned char peer_addr[ETH_ALEN]; |
| 127 | unsigned long cap_flags; | ||
| 127 | 128 | ||
| 128 | int numa_node; | 129 | int numa_node; |
| 129 | enum erdma_cc_alg cc; | 130 | enum erdma_cc_alg cc; |
| @@ -189,6 +190,7 @@ struct erdma_dev { · 59 unmodified lines | |||
| 189 | struct net_device *netdev; | 190 | struct net_device *netdev; |
| 190 | struct pci_dev *pdev; | 191 | struct pci_dev *pdev; |
| 191 | struct notifier_block netdev_nb; | 192 | struct notifier_block netdev_nb; |
| 193 | struct workqueue_struct *reflush_wq; | ||
| 192 | 194 | ||
| 193 | resource_size_t func_bar_addr; | 195 | resource_size_t func_bar_addr; |
| 194 | resource_size_t func_bar_len; | 196 | resource_size_t func_bar_len; |
| @@ -218,7 +220,7 @@ struct erdma_dev { · 23 unmodified lines | |||
| 218 | DECLARE_BITMAP(sdb_page, ERDMA_DWQE_TYPE0_CNT); | 220 | DECLARE_BITMAP(sdb_page, ERDMA_DWQE_TYPE0_CNT); |
| 219 | /* | 221 | /* |
| 220 | * We provide max 496 uContexts that each has one SQ normal Db, | 222 | * We provide max 496 uContexts that each has one SQ normal Db, |
| 221 | * and one directWQE db。 | 223 | * and one directWQE db. |
| 222 | */ | 224 | */ |
| 223 | DECLARE_BITMAP(sdb_entry, ERDMA_DWQE_TYPE1_CNT); | 225 | DECLARE_BITMAP(sdb_entry, ERDMA_DWQE_TYPE1_CNT); |
| 224 | 226 | ||
| @@ -64,6 +64,8 @@ static const enum ib_wc_opcode wc_mapping_table[ERDMA_NUM_OPCODES] = { · 63 unmodified lines | |||
| 64 | [ERDMA_OP_REG_MR] = IB_WC_REG_MR, | 64 | [ERDMA_OP_REG_MR] = IB_WC_REG_MR, |
| 65 | [ERDMA_OP_LOCAL_INV] = IB_WC_LOCAL_INV, | 65 | [ERDMA_OP_LOCAL_INV] = IB_WC_LOCAL_INV, |
| 66 | [ERDMA_OP_READ_WITH_INV] = IB_WC_RDMA_READ, | 66 | [ERDMA_OP_READ_WITH_INV] = IB_WC_RDMA_READ, |
| 67 | [ERDMA_OP_ATOMIC_CAS] = IB_WC_COMP_SWAP, | ||
| 68 | [ERDMA_OP_ATOMIC_FAD] = IB_WC_FETCH_ADD, | ||
| 67 | }; | 69 | }; |
| 68 | 70 | ||
| 69 | static const struct { | 71 | static const struct { |
| @@ -145,6 +145,7 @@ enum CMDQ_RDMA_OPCODE { · 144 unmodified lines | |||
| 145 | CMDQ_OPCODE_MODIFY_QP = 3, | 145 | CMDQ_OPCODE_MODIFY_QP = 3, |
| 146 | CMDQ_OPCODE_CREATE_CQ = 4, | 146 | CMDQ_OPCODE_CREATE_CQ = 4, |
| 147 | CMDQ_OPCODE_DESTROY_CQ = 5, | 147 | CMDQ_OPCODE_DESTROY_CQ = 5, |
| 148 | CMDQ_OPCODE_REFLUSH = 6, | ||
| 148 | CMDQ_OPCODE_REG_MR = 8, | 149 | CMDQ_OPCODE_REG_MR = 8, |
| 149 | CMDQ_OPCODE_DEREG_MR = 9 | 150 | CMDQ_OPCODE_DEREG_MR = 9 |
| 150 | }; | 151 | }; |
| @@ -224,8 +225,7 @@ struct erdma_cmdq_create_cq_req { · 73 unmodified lines | |||
| 224 | /* regmr cfg1 */ | 225 | /* regmr cfg1 */ |
| 225 | #define ERDMA_CMD_REGMR_PD_MASK GENMASK(31, 12) | 226 | #define ERDMA_CMD_REGMR_PD_MASK GENMASK(31, 12) |
| 226 | #define ERDMA_CMD_REGMR_TYPE_MASK GENMASK(7, 6) | 227 | #define ERDMA_CMD_REGMR_TYPE_MASK GENMASK(7, 6) |
| 227 | #define ERDMA_CMD_REGMR_RIGHT_MASK GENMASK(5, 2) | 228 | #define ERDMA_CMD_REGMR_RIGHT_MASK GENMASK(5, 1) |
| 228 | #define ERDMA_CMD_REGMR_ACC_MODE_MASK GENMASK(1, 0) | ||
| 229 | 229 | ||
| 230 | /* regmr cfg2 */ | 230 | /* regmr cfg2 */ |
| 231 | #define ERDMA_CMD_REGMR_PAGESIZE_MASK GENMASK(31, 27) | 231 | #define ERDMA_CMD_REGMR_PAGESIZE_MASK GENMASK(31, 27) |
| @@ -302,8 +302,16 @@ struct erdma_cmdq_destroy_qp_req { · 70 unmodified lines | |||
| 302 | u32 qpn; | 302 | u32 qpn; |
| 303 | }; | 303 | }; |
| 304 | 304 | ||
| 305 | struct erdma_cmdq_reflush_req { | ||
| 306 | u64 hdr; | ||
| 307 | u32 qpn; | ||
| 308 | u32 sq_pi; | ||
| 309 | u32 rq_pi; | ||
| 310 | }; | ||
| 311 | |||
| 305 | /* cap qword 0 definition */ | 312 | /* cap qword 0 definition */ |
| 306 | #define ERDMA_CMD_DEV_CAP_MAX_CQE_MASK GENMASK_ULL(47, 40) | 313 | #define ERDMA_CMD_DEV_CAP_MAX_CQE_MASK GENMASK_ULL(47, 40) |
| 314 | #define ERDMA_CMD_DEV_CAP_FLAGS_MASK GENMASK_ULL(31, 24) | ||
| 307 | #define ERDMA_CMD_DEV_CAP_MAX_RECV_WR_MASK GENMASK_ULL(23, 16) | 315 | #define ERDMA_CMD_DEV_CAP_MAX_RECV_WR_MASK GENMASK_ULL(23, 16) |
| 308 | #define ERDMA_CMD_DEV_CAP_MAX_MR_SIZE_MASK GENMASK_ULL(7, 0) | 316 | #define ERDMA_CMD_DEV_CAP_MAX_MR_SIZE_MASK GENMASK_ULL(7, 0) |
| 309 | 317 | ||
| @@ -315,6 +323,10 @@ struct erdma_cmdq_destroy_qp_req { · 5 unmodified lines | |||
| 315 | 323 | ||
| 316 | #define ERDMA_NQP_PER_QBLOCK 1024 | 324 | #define ERDMA_NQP_PER_QBLOCK 1024 |
| 317 | 325 | ||
| 326 | enum { | ||
| 327 | ERDMA_DEV_CAP_FLAGS_ATOMIC = 1 << 7, | ||
| 328 | }; | ||
| 329 | |||
| 318 | #define ERDMA_CMD_INFO0_FW_VER_MASK GENMASK_ULL(31, 0) | 330 | #define ERDMA_CMD_INFO0_FW_VER_MASK GENMASK_ULL(31, 0) |
| 319 | 331 | ||
| 320 | /* CQE hdr */ | 332 | /* CQE hdr */ |
| @@ -340,9 +352,9 @@ struct erdma_cqe { · 19 unmodified lines | |||
| 340 | }; | 352 | }; |
| 341 | 353 | ||
| 342 | struct erdma_sge { | 354 | struct erdma_sge { |
| 343 | __aligned_le64 laddr; | 355 | __aligned_le64 addr; |
| 344 | __le32 length; | 356 | __le32 length; |
| 345 | __le32 lkey; | 357 | __le32 key; |
| 346 | }; | 358 | }; |
| 347 | 359 | ||
| 348 | /* Receive Queue Element */ | 360 | /* Receive Queue Element */ |
| @@ -370,8 +382,7 @@ struct erdma_rqe { · 21 unmodified lines | |||
| 370 | #define ERDMA_SQE_HDR_WQEBB_INDEX_MASK GENMASK_ULL(15, 0) | 382 | #define ERDMA_SQE_HDR_WQEBB_INDEX_MASK GENMASK_ULL(15, 0) |
| 371 | 383 | ||
| 372 | /* REG MR attrs */ | 384 | /* REG MR attrs */ |
| 373 | #define ERDMA_SQE_MR_MODE_MASK GENMASK(1, 0) | 385 | #define ERDMA_SQE_MR_ACCESS_MASK GENMASK(5, 1) |
| 374 | #define ERDMA_SQE_MR_ACCESS_MASK GENMASK(5, 2) | ||
| 375 | #define ERDMA_SQE_MR_MTT_TYPE_MASK GENMASK(7, 6) | 386 | #define ERDMA_SQE_MR_MTT_TYPE_MASK GENMASK(7, 6) |
| 376 | #define ERDMA_SQE_MR_MTT_CNT_MASK GENMASK(31, 12) | 387 | #define ERDMA_SQE_MR_MTT_CNT_MASK GENMASK(31, 12) |
| 377 | 388 | ||
| @@ -410,6 +421,16 @@ struct erdma_readreq_sqe { · 32 unmodified lines | |||
| 410 | __le32 rsvd; | 421 | __le32 rsvd; |
| 411 | }; | 422 | }; |
| 412 | 423 | ||
| 424 | struct erdma_atomic_sqe { | ||
| 425 | __le64 hdr; | ||
| 426 | __le64 rsvd; | ||
| 427 | __le64 fetchadd_swap_data; | ||
| 428 | __le64 cmp_data; | ||
| 429 | |||
| 430 | struct erdma_sge remote; | ||
| 431 | struct erdma_sge sgl; | ||
| 432 | }; | ||
| 433 | |||
| 413 | struct erdma_reg_mr_sqe { | 434 | struct erdma_reg_mr_sqe { |
| 414 | __le64 hdr; | 435 | __le64 hdr; |
| 415 | __le64 addr; | 436 | __le64 addr; |
| @@ -469,7 +490,9 @@ enum erdma_opcode { · 53 unmodified lines | |||
| 469 | ERDMA_OP_REG_MR = 14, | 490 | ERDMA_OP_REG_MR = 14, |
| 470 | ERDMA_OP_LOCAL_INV = 15, | 491 | ERDMA_OP_LOCAL_INV = 15, |
| 471 | ERDMA_OP_READ_WITH_INV = 16, | 492 | ERDMA_OP_READ_WITH_INV = 16, |
| 472 | ERDMA_NUM_OPCODES = 17, | 493 | ERDMA_OP_ATOMIC_CAS = 17, |
| 494 | ERDMA_OP_ATOMIC_FAD = 18, | ||
| 495 | ERDMA_NUM_OPCODES = 19, | ||
| 473 | ERDMA_OP_INVALID = ERDMA_NUM_OPCODES + 1 | 496 | ERDMA_OP_INVALID = ERDMA_NUM_OPCODES + 1 |
| 474 | }; | 497 | }; |
| 475 | 498 | ||
| @@ -374,6 +374,7 @@ static int erdma_dev_attrs_init(struct erdma_dev *dev) · 373 unmodified lines | |||
| 374 | dev->attrs.max_qp = ERDMA_NQP_PER_QBLOCK * ERDMA_GET_CAP(QBLOCK, cap1); | 374 | dev->attrs.max_qp = ERDMA_NQP_PER_QBLOCK * ERDMA_GET_CAP(QBLOCK, cap1); |
| 375 | dev->attrs.max_mr = dev->attrs.max_qp << 1; | 375 | dev->attrs.max_mr = dev->attrs.max_qp << 1; |
| 376 | dev->attrs.max_cq = dev->attrs.max_qp << 1; | 376 | dev->attrs.max_cq = dev->attrs.max_qp << 1; |
| 377 | dev->attrs.cap_flags = ERDMA_GET_CAP(FLAGS, cap0); | ||
| 377 | 378 | ||
| 378 | dev->attrs.max_send_wr = ERDMA_MAX_SEND_WR; | 379 | dev->attrs.max_send_wr = ERDMA_MAX_SEND_WR; |
| 379 | dev->attrs.max_ord = ERDMA_MAX_ORD; | 380 | dev->attrs.max_ord = ERDMA_MAX_ORD; |
| @@ -520,13 +521,22 @@ static int erdma_ib_device_add(struct pci_dev *pdev) · 140 unmodified lines | |||
| 520 | 521 | ||
| 521 | u64_to_ether_addr(mac, dev->attrs.peer_addr); | 522 | u64_to_ether_addr(mac, dev->attrs.peer_addr); |
| 522 | 523 | ||
| 524 | dev->reflush_wq = alloc_workqueue("erdma-reflush-wq", WQ_UNBOUND, | ||
| 525 | WQ_UNBOUND_MAX_ACTIVE); | ||
| 526 | if (!dev->reflush_wq) { | ||
| 527 | ret = -ENOMEM; | ||
| 528 | goto err_alloc_workqueue; | ||
| 529 | } | ||
| 530 | |||
| 523 | ret = erdma_device_register(dev); | 531 | ret = erdma_device_register(dev); |
| 524 | if (ret) | 532 | if (ret) |
| 525 | goto err_out; | 533 | goto err_register; |
| 526 | 534 | ||
| 527 | return 0; | 535 | return 0; |
| 528 | 536 | ||
| 529 | err_out: | 537 | err_register: |
| 538 | destroy_workqueue(dev->reflush_wq); | ||
| 539 | err_alloc_workqueue: | ||
| 530 | xa_destroy(&dev->qp_xa); | 540 | xa_destroy(&dev->qp_xa); |
| 531 | xa_destroy(&dev->cq_xa); | 541 | xa_destroy(&dev->cq_xa); |
| 532 | 542 | ||
| @@ -542,6 +552,7 @@ static void erdma_ib_device_remove(struct pci_dev *pdev) · 9 unmodified lines | |||
| 542 | unregister_netdevice_notifier(&dev->netdev_nb); | 552 | unregister_netdevice_notifier(&dev->netdev_nb); |
| 543 | ib_unregister_device(&dev->ibdev); | 553 | ib_unregister_device(&dev->ibdev); |
| 544 | 554 | ||
| 555 | destroy_workqueue(dev->reflush_wq); | ||
| 545 | erdma_res_cb_free(dev); | 556 | erdma_res_cb_free(dev); |
| 546 | xa_destroy(&dev->qp_xa); | 557 | xa_destroy(&dev->qp_xa); |
| 547 | xa_destroy(&dev->cq_xa); | 558 | xa_destroy(&dev->cq_xa); |
| @@ -120,6 +120,7 @@ static int erdma_modify_qp_state_to_stop(struct erdma_qp *qp, · 119 unmodified lines | |||
| 120 | int erdma_modify_qp_internal(struct erdma_qp *qp, struct erdma_qp_attrs *attrs, | 120 | int erdma_modify_qp_internal(struct erdma_qp *qp, struct erdma_qp_attrs *attrs, |
| 121 | enum erdma_qp_attr_mask mask) | 121 | enum erdma_qp_attr_mask mask) |
| 122 | { | 122 | { |
| 123 | bool need_reflush = false; | ||
| 123 | int drop_conn, ret = 0; | 124 | int drop_conn, ret = 0; |
| 124 | 125 | ||
| 125 | if (!mask) | 126 | if (!mask) |
| @@ -135,6 +136,7 @@ int erdma_modify_qp_internal(struct erdma_qp *qp, struct erdma_qp_attrs *attrs, · 9 unmodified lines | |||
| 135 | ret = erdma_modify_qp_state_to_rts(qp, attrs, mask); | 136 | ret = erdma_modify_qp_state_to_rts(qp, attrs, mask); |
| 136 | } else if (attrs->state == ERDMA_QP_STATE_ERROR) { | 137 | } else if (attrs->state == ERDMA_QP_STATE_ERROR) { |
| 137 | qp->attrs.state = ERDMA_QP_STATE_ERROR; | 138 | qp->attrs.state = ERDMA_QP_STATE_ERROR; |
| 139 | need_reflush = true; | ||
| 138 | if (qp->cep) { | 140 | if (qp->cep) { |
| 139 | erdma_cep_put(qp->cep); | 141 | erdma_cep_put(qp->cep); |
| 140 | qp->cep = NULL; | 142 | qp->cep = NULL; |
| @@ -145,17 +147,12 @@ int erdma_modify_qp_internal(struct erdma_qp *qp, struct erdma_qp_attrs *attrs, · 4 unmodified lines | |||
| 145 | case ERDMA_QP_STATE_RTS: | 147 | case ERDMA_QP_STATE_RTS: |
| 146 | drop_conn = 0; | 148 | drop_conn = 0; |
| 147 | 149 | ||
| 148 | if (attrs->state == ERDMA_QP_STATE_CLOSING) { | 150 | if (attrs->state == ERDMA_QP_STATE_CLOSING || |
| 151 | attrs->state == ERDMA_QP_STATE_TERMINATE || | ||
| 152 | attrs->state == ERDMA_QP_STATE_ERROR) { | ||
| 149 | ret = erdma_modify_qp_state_to_stop(qp, attrs, mask); | 153 | ret = erdma_modify_qp_state_to_stop(qp, attrs, mask); |
| 150 | drop_conn = 1; | 154 | drop_conn = 1; |
| 151 | } else if (attrs->state == ERDMA_QP_STATE_TERMINATE) { | 155 | need_reflush = true; |
| 152 | qp->attrs.state = ERDMA_QP_STATE_TERMINATE; | ||
| 153 | ret = erdma_modify_qp_state_to_stop(qp, attrs, mask); | ||
| 154 | drop_conn = 1; | ||
| 155 | } else if (attrs->state == ERDMA_QP_STATE_ERROR) { | ||
| 156 | ret = erdma_modify_qp_state_to_stop(qp, attrs, mask); | ||
| 157 | qp->attrs.state = ERDMA_QP_STATE_ERROR; | ||
| 158 | drop_conn = 1; | ||
| 159 | } | 156 | } |
| 160 | 157 | ||
| 161 | if (drop_conn) | 158 | if (drop_conn) |
| @@ -180,6 +177,12 @@ int erdma_modify_qp_internal(struct erdma_qp *qp, struct erdma_qp_attrs *attrs, · 18 unmodified lines | |||
| 180 | break; | 177 | break; |
| 181 | } | 178 | } |
| 182 | 179 | ||
| 180 | if (need_reflush && !ret && rdma_is_kernel_res(&qp->ibqp.res)) { | ||
| 181 | qp->flags |= ERDMA_QP_IN_FLUSHING; | ||
| 182 | mod_delayed_work(qp->dev->reflush_wq, &qp->reflush_dwork, | ||
| 183 | usecs_to_jiffies(100)); | ||
| 184 | } | ||
| 185 | |||
| 183 | return ret; | 186 | return ret; |
| 184 | } | 187 | } |
| 185 | 188 | ||
| @@ -285,15 +288,16 @@ static int erdma_push_one_sqe(struct erdma_qp *qp, u16 *pi, · 99 unmodified lines | |||
| 285 | u32 wqe_size, wqebb_cnt, hw_op, flags, sgl_offset; | 288 | u32 wqe_size, wqebb_cnt, hw_op, flags, sgl_offset; |
| 286 | u32 idx = *pi & (qp->attrs.sq_size - 1); | 289 | u32 idx = *pi & (qp->attrs.sq_size - 1); |
| 287 | enum ib_wr_opcode op = send_wr->opcode; | 290 | enum ib_wr_opcode op = send_wr->opcode; |
| 291 | struct erdma_atomic_sqe *atomic_sqe; | ||
| 288 | struct erdma_readreq_sqe *read_sqe; | 292 | struct erdma_readreq_sqe *read_sqe; |
| 289 | struct erdma_reg_mr_sqe *regmr_sge; | 293 | struct erdma_reg_mr_sqe *regmr_sge; |
| 290 | struct erdma_write_sqe *write_sqe; | 294 | struct erdma_write_sqe *write_sqe; |
| 291 | struct erdma_send_sqe *send_sqe; | 295 | struct erdma_send_sqe *send_sqe; |
| 292 | struct ib_rdma_wr *rdma_wr; | 296 | struct ib_rdma_wr *rdma_wr; |
| 293 | struct erdma_mr *mr; | 297 | struct erdma_sge *sge; |
| 294 | __le32 *length_field; | 298 | __le32 *length_field; |
| 299 | struct erdma_mr *mr; | ||
| 295 | u64 wqe_hdr, *entry; | 300 | u64 wqe_hdr, *entry; |
| 296 | struct ib_sge *sge; | ||
| 297 | u32 attrs; | 301 | u32 attrs; |
| 298 | int ret; | 302 | int ret; |
| 299 | 303 | ||
| @@ -360,9 +364,9 @@ static int erdma_push_one_sqe(struct erdma_qp *qp, u16 *pi, · 60 unmodified lines | |||
| 360 | 364 | ||
| 361 | sge = get_queue_entry(qp->kern_qp.sq_buf, idx + 1, | 365 | sge = get_queue_entry(qp->kern_qp.sq_buf, idx + 1, |
| 362 | qp->attrs.sq_size, SQEBB_SHIFT); | 366 | qp->attrs.sq_size, SQEBB_SHIFT); |
| 363 | sge->addr = rdma_wr->remote_addr; | 367 | sge->addr = cpu_to_le64(rdma_wr->remote_addr); |
| 364 | sge->lkey = rdma_wr->rkey; | 368 | sge->key = cpu_to_le32(rdma_wr->rkey); |
| 365 | sge->length = send_wr->sg_list[0].length; | 369 | sge->length = cpu_to_le32(send_wr->sg_list[0].length); |
| 366 | wqe_size = sizeof(struct erdma_readreq_sqe) + | 370 | wqe_size = sizeof(struct erdma_readreq_sqe) + |
| 367 | send_wr->num_sge * sizeof(struct ib_sge); | 371 | send_wr->num_sge * sizeof(struct ib_sge); |
| 368 | 372 | ||
| @@ -397,8 +401,7 @@ static int erdma_push_one_sqe(struct erdma_qp *qp, u16 *pi, · 28 unmodified lines | |||
| 397 | regmr_sge->addr = cpu_to_le64(mr->ibmr.iova); | 401 | regmr_sge->addr = cpu_to_le64(mr->ibmr.iova); |
| 398 | regmr_sge->length = cpu_to_le32(mr->ibmr.length); | 402 | regmr_sge->length = cpu_to_le32(mr->ibmr.length); |
| 399 | regmr_sge->stag = cpu_to_le32(reg_wr(send_wr)->key); | 403 | regmr_sge->stag = cpu_to_le32(reg_wr(send_wr)->key); |
| 400 | attrs = FIELD_PREP(ERDMA_SQE_MR_MODE_MASK, 0) | | 404 | attrs = FIELD_PREP(ERDMA_SQE_MR_ACCESS_MASK, mr->access) | |
| 401 | FIELD_PREP(ERDMA_SQE_MR_ACCESS_MASK, mr->access) | | ||
| 402 | FIELD_PREP(ERDMA_SQE_MR_MTT_CNT_MASK, | 405 | FIELD_PREP(ERDMA_SQE_MR_MTT_CNT_MASK, |
| 403 | mr->mem.mtt_nents); | 406 | mr->mem.mtt_nents); |
| 404 | 407 | ||
| @@ -424,6 +427,35 @@ static int erdma_push_one_sqe(struct erdma_qp *qp, u16 *pi, · 19 unmodified lines | |||
| 424 | regmr_sge->stag = cpu_to_le32(send_wr->ex.invalidate_rkey); | 427 | regmr_sge->stag = cpu_to_le32(send_wr->ex.invalidate_rkey); |
| 425 | wqe_size = sizeof(struct erdma_reg_mr_sqe); | 428 | wqe_size = sizeof(struct erdma_reg_mr_sqe); |
| 426 | goto out; | 429 | goto out; |
| 430 | case IB_WR_ATOMIC_CMP_AND_SWP: | ||
| 431 | case IB_WR_ATOMIC_FETCH_AND_ADD: | ||
| 432 | atomic_sqe = (struct erdma_atomic_sqe *)entry; | ||
| 433 | if (op == IB_WR_ATOMIC_CMP_AND_SWP) { | ||
| 434 | wqe_hdr |= FIELD_PREP(ERDMA_SQE_HDR_OPCODE_MASK, | ||
| 435 | ERDMA_OP_ATOMIC_CAS); | ||
| 436 | atomic_sqe->fetchadd_swap_data = | ||
| 437 | cpu_to_le64(atomic_wr(send_wr)->swap); | ||
| 438 | atomic_sqe->cmp_data = | ||
| 439 | cpu_to_le64(atomic_wr(send_wr)->compare_add); | ||
| 440 | } else { | ||
| 441 | wqe_hdr |= FIELD_PREP(ERDMA_SQE_HDR_OPCODE_MASK, | ||
| 442 | ERDMA_OP_ATOMIC_FAD); | ||
| 443 | atomic_sqe->fetchadd_swap_data = | ||
| 444 | cpu_to_le64(atomic_wr(send_wr)->compare_add); | ||
| 445 | } | ||
| 446 | |||
| 447 | sge = get_queue_entry(qp->kern_qp.sq_buf, idx + 1, | ||
| 448 | qp->attrs.sq_size, SQEBB_SHIFT); | ||
| 449 | sge->addr = cpu_to_le64(atomic_wr(send_wr)->remote_addr); | ||
| 450 | sge->key = cpu_to_le32(atomic_wr(send_wr)->rkey); | ||
| 451 | sge++; | ||
| 452 | |||
| 453 | sge->addr = cpu_to_le64(send_wr->sg_list[0].addr); | ||
| 454 | sge->key = cpu_to_le32(send_wr->sg_list[0].lkey); | ||
| 455 | sge->length = cpu_to_le32(send_wr->sg_list[0].length); | ||
| 456 | |||
| 457 | wqe_size = sizeof(*atomic_sqe); | ||
| 458 | goto out; | ||
| 427 | default: | 459 | default: |
| 428 | return -EOPNOTSUPP; | 460 | return -EOPNOTSUPP; |
| 429 | } | 461 | } |
| @@ -498,6 +530,10 @@ int erdma_post_send(struct ib_qp *ibqp, const struct ib_send_wr *send_wr, · 68 unmodified lines | |||
| 498 | } | 530 | } |
| 499 | spin_unlock_irqrestore(&qp->lock, flags); | 531 | spin_unlock_irqrestore(&qp->lock, flags); |
| 500 | 532 | ||
| 533 | if (unlikely(qp->flags & ERDMA_QP_IN_FLUSHING)) | ||
| 534 | mod_delayed_work(qp->dev->reflush_wq, &qp->reflush_dwork, | ||
| 535 | usecs_to_jiffies(100)); | ||
| 536 | |||
| 501 | return ret; | 537 | return ret; |
| 502 | } | 538 | } |
| 503 | 539 | ||
| @@ -551,5 +587,10 @@ int erdma_post_recv(struct ib_qp *ibqp, const struct ib_recv_wr *recv_wr, · 47 unmodified lines | |||
| 551 | } | 587 | } |
| 552 | 588 | ||
| 553 | spin_unlock_irqrestore(&qp->lock, flags); | 589 | spin_unlock_irqrestore(&qp->lock, flags); |
| 590 | |||
| 591 | if (unlikely(qp->flags & ERDMA_QP_IN_FLUSHING)) | ||
| 592 | mod_delayed_work(qp->dev->reflush_wq, &qp->reflush_dwork, | ||
| 593 | usecs_to_jiffies(100)); | ||
| 594 | |||
| 554 | return ret; | 595 | return ret; |
| 555 | } | 596 | } |
| @@ -118,8 +118,7 @@ static int regmr_cmd(struct erdma_dev *dev, struct erdma_mr *mr) · 117 unmodified lines | |||
| 118 | FIELD_PREP(ERDMA_CMD_MR_MPT_IDX_MASK, mr->ibmr.lkey >> 8); | 118 | FIELD_PREP(ERDMA_CMD_MR_MPT_IDX_MASK, mr->ibmr.lkey >> 8); |
| 119 | req.cfg1 = FIELD_PREP(ERDMA_CMD_REGMR_PD_MASK, pd->pdn) | | 119 | req.cfg1 = FIELD_PREP(ERDMA_CMD_REGMR_PD_MASK, pd->pdn) | |
| 120 | FIELD_PREP(ERDMA_CMD_REGMR_TYPE_MASK, mr->type) | | 120 | FIELD_PREP(ERDMA_CMD_REGMR_TYPE_MASK, mr->type) | |
| 121 | FIELD_PREP(ERDMA_CMD_REGMR_RIGHT_MASK, mr->access) | | 121 | FIELD_PREP(ERDMA_CMD_REGMR_RIGHT_MASK, mr->access); |
| 122 | FIELD_PREP(ERDMA_CMD_REGMR_ACC_MODE_MASK, 0); | ||
| 123 | req.cfg2 = FIELD_PREP(ERDMA_CMD_REGMR_PAGESIZE_MASK, | 122 | req.cfg2 = FIELD_PREP(ERDMA_CMD_REGMR_PAGESIZE_MASK, |
| 124 | ilog2(mr->mem.page_size)) | | 123 | ilog2(mr->mem.page_size)) | |
| 125 | FIELD_PREP(ERDMA_CMD_REGMR_MTT_TYPE_MASK, mr->mem.mtt_type) | | 124 | FIELD_PREP(ERDMA_CMD_REGMR_MTT_TYPE_MASK, mr->mem.mtt_type) | |
| @@ -289,6 +288,10 @@ int erdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr, · 163 unmodified lines | |||
| 289 | attr->max_mw = dev->attrs.max_mw; | 288 | attr->max_mw = dev->attrs.max_mw; |
| 290 | attr->max_fast_reg_page_list_len = ERDMA_MAX_FRMR_PA; | 289 | attr->max_fast_reg_page_list_len = ERDMA_MAX_FRMR_PA; |
| 291 | attr->page_size_cap = ERDMA_PAGE_SIZE_SUPPORT; | 290 | attr->page_size_cap = ERDMA_PAGE_SIZE_SUPPORT; |
| 291 | |||
| 292 | if (dev->attrs.cap_flags & ERDMA_DEV_CAP_FLAGS_ATOMIC) | ||
| 293 | attr->atomic_cap = IB_ATOMIC_GLOB; | ||
| 294 | |||
| 292 | attr->fw_ver = dev->attrs.fw_version; | 295 | attr->fw_ver = dev->attrs.fw_version; |
| 293 | 296 | ||
| 294 | if (dev->netdev) | 297 | if (dev->netdev) |
| @@ -376,6 +379,21 @@ int erdma_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata) · 81 unmodified lines | |||
| 376 | return 0; | 379 | return 0; |
| 377 | } | 380 | } |
| 378 | 381 | ||
| 382 | static void erdma_flush_worker(struct work_struct *work) | ||
| 383 | { | ||
| 384 | struct delayed_work *dwork = to_delayed_work(work); | ||
| 385 | struct erdma_qp *qp = | ||
| 386 | container_of(dwork, struct erdma_qp, reflush_dwork); | ||
| 387 | struct erdma_cmdq_reflush_req req; | ||
| 388 | |||
| 389 | erdma_cmdq_build_reqhdr(&req.hdr, CMDQ_SUBMOD_RDMA, | ||
| 390 | CMDQ_OPCODE_REFLUSH); | ||
| 391 | req.qpn = QP_ID(qp); | ||
| 392 | req.sq_pi = qp->kern_qp.sq_pi; | ||
| 393 | req.rq_pi = qp->kern_qp.rq_pi; | ||
| 394 | erdma_post_cmd_wait(&qp->dev->cmdq, &req, sizeof(req), NULL, NULL); | ||
| 395 | } | ||
| 396 | |||
| 379 | static int erdma_qp_validate_cap(struct erdma_dev *dev, | 397 | static int erdma_qp_validate_cap(struct erdma_dev *dev, |
| 380 | struct ib_qp_init_attr *attrs) | 398 | struct ib_qp_init_attr *attrs) |
| 381 | { | 399 | { |
| @@ -732,6 +750,7 @@ int erdma_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs, · 350 unmodified lines | |||
| 732 | qp->attrs.max_send_sge = attrs->cap.max_send_sge; | 750 | qp->attrs.max_send_sge = attrs->cap.max_send_sge; |
| 733 | qp->attrs.max_recv_sge = attrs->cap.max_recv_sge; | 751 | qp->attrs.max_recv_sge = attrs->cap.max_recv_sge; |
| 734 | qp->attrs.state = ERDMA_QP_STATE_IDLE; | 752 | qp->attrs.state = ERDMA_QP_STATE_IDLE; |
| 753 | INIT_DELAYED_WORK(&qp->reflush_dwork, erdma_flush_worker); | ||
| 735 | 754 | ||
| 736 | ret = create_qp_cmd(dev, qp); | 755 | ret = create_qp_cmd(dev, qp); |
| 737 | if (ret) | 756 | if (ret) |
| @@ -1025,6 +1044,8 @@ int erdma_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata) · 287 unmodified lines | |||
| 1025 | erdma_modify_qp_internal(qp, &qp_attrs, ERDMA_QP_ATTR_STATE); | 1044 | erdma_modify_qp_internal(qp, &qp_attrs, ERDMA_QP_ATTR_STATE); |
| 1026 | up_write(&qp->state_lock); | 1045 | up_write(&qp->state_lock); |
| 1027 | 1046 | ||
| 1047 | cancel_delayed_work_sync(&qp->reflush_dwork); | ||
| 1048 | |||
| 1028 | erdma_cmdq_build_reqhdr(&req.hdr, CMDQ_SUBMOD_RDMA, | 1049 | erdma_cmdq_build_reqhdr(&req.hdr, CMDQ_SUBMOD_RDMA, |
| 1029 | CMDQ_OPCODE_DESTROY_QP); | 1050 | CMDQ_OPCODE_DESTROY_QP); |
| 1030 | req.qpn = QP_ID(qp); | 1051 | req.qpn = QP_ID(qp); |
| @@ -71,16 +71,18 @@ struct erdma_pd { · 70 unmodified lines | |||
| 71 | #define ERDMA_MR_INLINE_MTT 0 | 71 | #define ERDMA_MR_INLINE_MTT 0 |
| 72 | #define ERDMA_MR_INDIRECT_MTT 1 | 72 | #define ERDMA_MR_INDIRECT_MTT 1 |
| 73 | 73 | ||
| 74 | #define ERDMA_MR_ACC_LR BIT(0) | 74 | #define ERDMA_MR_ACC_RA BIT(0) |
| 75 | #define ERDMA_MR_ACC_LW BIT(1) | 75 | #define ERDMA_MR_ACC_LR BIT(1) |
| 76 | #define ERDMA_MR_ACC_RR BIT(2) | 76 | #define ERDMA_MR_ACC_LW BIT(2) |
| 77 | #define ERDMA_MR_ACC_RW BIT(3) | 77 | #define ERDMA_MR_ACC_RR BIT(3) |
| 78 | #define ERDMA_MR_ACC_RW BIT(4) | ||
| 78 | 79 | ||
| 79 | static inline u8 to_erdma_access_flags(int access) | 80 | static inline u8 to_erdma_access_flags(int access) |
| 80 | { | 81 | { |
| 81 | return (access & IB_ACCESS_REMOTE_READ ? ERDMA_MR_ACC_RR : 0) | | 82 | return (access & IB_ACCESS_REMOTE_READ ? ERDMA_MR_ACC_RR : 0) | |
| 82 | (access & IB_ACCESS_LOCAL_WRITE ? ERDMA_MR_ACC_LW : 0) | | 83 | (access & IB_ACCESS_LOCAL_WRITE ? ERDMA_MR_ACC_LW : 0) | |
| 83 | (access & IB_ACCESS_REMOTE_WRITE ? ERDMA_MR_ACC_RW : 0); | 84 | (access & IB_ACCESS_REMOTE_WRITE ? ERDMA_MR_ACC_RW : 0) | |
| 85 | (access & IB_ACCESS_REMOTE_ATOMIC ? ERDMA_MR_ACC_RA : 0); | ||
| 84 | } | 86 | } |
| 85 | 87 | ||
| 86 | struct erdma_mem { | 88 | struct erdma_mem { |
| @@ -171,6 +173,10 @@ enum erdma_qp_attr_mask { · 84 unmodified lines | |||
| 171 | ERDMA_QP_ATTR_MPA = (1 << 7) | 173 | ERDMA_QP_ATTR_MPA = (1 << 7) |
| 172 | }; | 174 | }; |
| 173 | 175 | ||
| 176 | enum erdma_qp_flags { | ||
| 177 | ERDMA_QP_IN_FLUSHING = (1 << 0), | ||
| 178 | }; | ||
| 179 | |||
| 174 | struct erdma_qp_attrs { | 180 | struct erdma_qp_attrs { |
| 175 | enum erdma_qp_state state; | 181 | enum erdma_qp_state state; |
| 176 | enum erdma_cc_alg cc; /* Congestion control algorithm */ | 182 | enum erdma_cc_alg cc; /* Congestion control algorithm */ |
| @@ -195,6 +201,9 @@ struct erdma_qp { · 18 unmodified lines | |||
| 195 | struct erdma_cep *cep; | 201 | struct erdma_cep *cep; |
| 196 | struct rw_semaphore state_lock; | 202 | struct rw_semaphore state_lock; |
| 197 | 203 | ||
| 204 | unsigned long flags; | ||
| 205 | struct delayed_work reflush_dwork; | ||
| 206 | |||
| 198 | union { | 207 | union { |
| 199 | struct erdma_kqp kern_qp; | 208 | struct erdma_kqp kern_qp; |
| 200 | struct erdma_uqp user_qp; | 209 | struct erdma_uqp user_qp; |
| @@ -177,6 +177,8 @@ out: · 176 unmodified lines | |||
| 177 | for (node = 0; node < node_affinity.num_possible_nodes; node++) | 177 | for (node = 0; node < node_affinity.num_possible_nodes; node++) |
| 178 | hfi1_per_node_cntr[node] = 1; | 178 | hfi1_per_node_cntr[node] = 1; |
| 179 | 179 | ||
| 180 | pci_dev_put(dev); | ||
| 181 | |||
| 180 | return 0; | 182 | return 0; |
| 181 | } | 183 | } |
| 182 | 184 | ||
| @@ -112,7 +112,7 @@ static int hfi1_caps_get(char *buffer, const struct kernel_param *kp) · 111 unmodified lines | |||
| 112 | cap_mask &= ~HFI1_CAP_LOCKED_SMASK; | 112 | cap_mask &= ~HFI1_CAP_LOCKED_SMASK; |
| 113 | cap_mask |= ((cap_mask & HFI1_CAP_K2U) << HFI1_CAP_USER_SHIFT); | 113 | cap_mask |= ((cap_mask & HFI1_CAP_K2U) << HFI1_CAP_USER_SHIFT); |
| 114 | 114 | ||
| 115 | return scnprintf(buffer, PAGE_SIZE, "0x%lx", cap_mask); | 115 | return sysfs_emit(buffer, "0x%lx\n", cap_mask); |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | struct pci_dev *get_pci_dev(struct rvt_dev_info *rdi) | 118 | struct pci_dev *get_pci_dev(struct rvt_dev_info *rdi) |
| @@ -1743,6 +1743,7 @@ int parse_platform_config(struct hfi1_devdata *dd) · 1742 unmodified lines | |||
| 1743 | 1743 | ||
| 1744 | if (!dd->platform_config.data) { | 1744 | if (!dd->platform_config.data) { |
| 1745 | dd_dev_err(dd, "%s: Missing config file\n", __func__); | 1745 | dd_dev_err(dd, "%s: Missing config file\n", __func__); |
| 1746 | ret = -EINVAL; | ||
| 1746 | goto bail; | 1747 | goto bail; |
| 1747 | } | 1748 | } |
| 1748 | ptr = (u32 *)dd->platform_config.data; | 1749 | ptr = (u32 *)dd->platform_config.data; |
| @@ -1751,6 +1752,7 @@ int parse_platform_config(struct hfi1_devdata *dd) · 2 unmodified lines | |||
| 1751 | ptr++; | 1752 | ptr++; |
| 1752 | if (magic_num != PLATFORM_CONFIG_MAGIC_NUM) { | 1753 | if (magic_num != PLATFORM_CONFIG_MAGIC_NUM) { |
| 1753 | dd_dev_err(dd, "%s: Bad config file\n", __func__); | 1754 | dd_dev_err(dd, "%s: Bad config file\n", __func__); |
| 1755 | ret = -EINVAL; | ||
| 1754 | goto bail; | 1756 | goto bail; |
| 1755 | } | 1757 | } |
| 1756 | 1758 | ||
| @@ -1774,6 +1776,7 @@ int parse_platform_config(struct hfi1_devdata *dd) · 17 unmodified lines | |||
| 1774 | if (file_length > dd->platform_config.size) { | 1776 | if (file_length > dd->platform_config.size) { |
| 1775 | dd_dev_info(dd, "%s:File claims to be larger than read size\n", | 1777 | dd_dev_info(dd, "%s:File claims to be larger than read size\n", |
| 1776 | __func__); | 1778 | __func__); |
| 1779 | ret = -EINVAL; | ||
| 1777 | goto bail; | 1780 | goto bail; |
| 1778 | } else if (file_length < dd->platform_config.size) { | 1781 | } else if (file_length < dd->platform_config.size) { |
| 1779 | dd_dev_info(dd, | 1782 | dd_dev_info(dd, |
| @@ -1794,6 +1797,7 @@ int parse_platform_config(struct hfi1_devdata *dd) · 14 unmodified lines | |||
| 1794 | dd_dev_err(dd, "%s: Failed validation at offset %ld\n", | 1797 | dd_dev_err(dd, "%s: Failed validation at offset %ld\n", |
| 1795 | __func__, (ptr - (u32 *) | 1798 | __func__, (ptr - (u32 *) |
| 1796 | dd->platform_config.data)); | 1799 | dd->platform_config.data)); |
| 1800 | ret = -EINVAL; | ||
| 1797 | goto bail; | 1801 | goto bail; |
| 1798 | } | 1802 | } |
| 1799 | 1803 | ||
| @@ -1837,6 +1841,7 @@ int parse_platform_config(struct hfi1_devdata *dd) · 37 unmodified lines | |||
| 1837 | __func__, table_type, | 1841 | __func__, table_type, |
| 1838 | (ptr - (u32 *) | 1842 | (ptr - (u32 *) |
| 1839 | dd->platform_config.data)); | 1843 | dd->platform_config.data)); |
| 1844 | ret = -EINVAL; | ||
| 1840 | goto bail; /* We don't trust this file now */ | 1845 | goto bail; /* We don't trust this file now */ |
| 1841 | } | 1846 | } |
| 1842 | pcfgcache->config_tables[table_type].table = ptr; | 1847 | pcfgcache->config_tables[table_type].table = ptr; |
| @@ -1856,6 +1861,7 @@ int parse_platform_config(struct hfi1_devdata *dd) · 13 unmodified lines | |||
| 1856 | __func__, table_type, | 1861 | __func__, table_type, |
| 1857 | (ptr - | 1862 | (ptr - |
| 1858 | (u32 *)dd->platform_config.data)); | 1863 | (u32 *)dd->platform_config.data)); |
| 1864 | ret = -EINVAL; | ||
| 1859 | goto bail; /* We don't trust this file now */ | 1865 | goto bail; /* We don't trust this file now */ |
| 1860 | } | 1866 | } |
| 1861 | pcfgcache->config_tables[table_type].table_metadata = | 1867 | pcfgcache->config_tables[table_type].table_metadata = |
| @@ -2437,9 +2437,9 @@ struct opa_port_data_counters_msg { · 2436 unmodified lines | |||
| 2437 | __be64 port_vl_xmit_wait_data; | 2437 | __be64 port_vl_xmit_wait_data; |
| 2438 | __be64 port_vl_rcv_bubble; | 2438 | __be64 port_vl_rcv_bubble; |
| 2439 | __be64 port_vl_mark_fecn; | 2439 | __be64 port_vl_mark_fecn; |
| 2440 | } vls[0]; | 2440 | } vls[]; |
| 2441 | /* array size defined by #bits set in vl_select_mask*/ | 2441 | /* array size defined by #bits set in vl_select_mask*/ |
| 2442 | } port[1]; /* array size defined by #ports in attribute modifier */ | 2442 | } port; |
| 2443 | }; | 2443 | }; |
| 2444 | 2444 | ||
| 2445 | struct opa_port_error_counters64_msg { | 2445 | struct opa_port_error_counters64_msg { |
| @@ -2470,9 +2470,9 @@ struct opa_port_error_counters64_msg { · 24 unmodified lines | |||
| 2470 | u8 reserved3[7]; | 2470 | u8 reserved3[7]; |
| 2471 | struct _vls_ectrs { | 2471 | struct _vls_ectrs { |
| 2472 | __be64 port_vl_xmit_discards; | 2472 | __be64 port_vl_xmit_discards; |
| 2473 | } vls[0]; | 2473 | } vls[]; |
| 2474 | /* array size defined by #bits set in vl_select_mask */ | 2474 | /* array size defined by #bits set in vl_select_mask */ |
| 2475 | } port[1]; /* array size defined by #ports in attribute modifier */ | 2475 | } port; |
| 2476 | }; | 2476 | }; |
| 2477 | 2477 | ||
| 2478 | struct opa_port_error_info_msg { | 2478 | struct opa_port_error_info_msg { |
| @@ -2543,7 +2543,7 @@ struct opa_port_error_info_msg { · 64 unmodified lines | |||
| 2543 | u8 error_info; | 2543 | u8 error_info; |
| 2544 | } __packed fm_config_ei; | 2544 | } __packed fm_config_ei; |
| 2545 | __u32 reserved9; | 2545 | __u32 reserved9; |
| 2546 | } port[1]; /* actual array size defined by #ports in attr modifier */ | 2546 | } port; |
| 2547 | }; | 2547 | }; |
| 2548 | 2548 | ||
| 2549 | /* opa_port_error_info_msg error_info_select_mask bit definitions */ | 2549 | /* opa_port_error_info_msg error_info_select_mask bit definitions */ |
| @@ -2966,7 +2966,7 @@ static int pma_get_opa_datacounters(struct opa_pma_mad *pmp, · 416 unmodified lines | |||
| 2966 | } | 2966 | } |
| 2967 | 2967 | ||
| 2968 | /* Sanity check */ | 2968 | /* Sanity check */ |
| 2969 | response_data_size = struct_size(req, port[0].vls, num_vls); | 2969 | response_data_size = struct_size(req, port.vls, num_vls); |
| 2970 | 2970 | ||
| 2971 | if (response_data_size > sizeof(pmp->data)) { | 2971 | if (response_data_size > sizeof(pmp->data)) { |
| 2972 | pmp->mad_hdr.status |= IB_SMP_INVALID_FIELD; | 2972 | pmp->mad_hdr.status |= IB_SMP_INVALID_FIELD; |
| @@ -2986,7 +2986,7 @@ static int pma_get_opa_datacounters(struct opa_pma_mad *pmp, · 13 unmodified lines | |||
| 2986 | return reply((struct ib_mad_hdr *)pmp); | 2986 | return reply((struct ib_mad_hdr *)pmp); |
| 2987 | } | 2987 | } |
| 2988 | 2988 | ||
| 2989 | rsp = &req->port[0]; | 2989 | rsp = &req->port; |
| 2990 | memset(rsp, 0, sizeof(*rsp)); | 2990 | memset(rsp, 0, sizeof(*rsp)); |
| 2991 | 2991 | ||
| 2992 | rsp->port_number = port; | 2992 | rsp->port_number = port; |
| @@ -3182,7 +3182,7 @@ static int pma_get_opa_porterrors(struct opa_pma_mad *pmp, · 189 unmodified lines | |||
| 3182 | return reply((struct ib_mad_hdr *)pmp); | 3182 | return reply((struct ib_mad_hdr *)pmp); |
| 3183 | } | 3183 | } |
| 3184 | 3184 | ||
| 3185 | response_data_size = struct_size(req, port[0].vls, num_vls); | 3185 | response_data_size = struct_size(req, port.vls, num_vls); |
| 3186 | 3186 | ||
| 3187 | if (response_data_size > sizeof(pmp->data)) { | 3187 | if (response_data_size > sizeof(pmp->data)) { |
| 3188 | pmp->mad_hdr.status |= IB_SMP_INVALID_FIELD; | 3188 | pmp->mad_hdr.status |= IB_SMP_INVALID_FIELD; |
| @@ -3201,7 +3201,7 @@ static int pma_get_opa_porterrors(struct opa_pma_mad *pmp, · 12 unmodified lines | |||
| 3201 | return reply((struct ib_mad_hdr *)pmp); | 3201 | return reply((struct ib_mad_hdr *)pmp); |
| 3202 | } | 3202 | } |
| 3203 | 3203 | ||
| 3204 | rsp = &req->port[0]; | 3204 | rsp = &req->port; |
| 3205 | 3205 | ||
| 3206 | ibp = to_iport(ibdev, port_num); | 3206 | ibp = to_iport(ibdev, port_num); |
| 3207 | ppd = ppd_from_ibp(ibp); | 3207 | ppd = ppd_from_ibp(ibp); |
| @@ -3340,7 +3340,7 @@ static int pma_get_opa_errorinfo(struct opa_pma_mad *pmp, · 132 unmodified lines | |||
| 3340 | u64 reg; | 3340 | u64 reg; |
| 3341 | 3341 | ||
| 3342 | req = (struct opa_port_error_info_msg *)pmp->data; | 3342 | req = (struct opa_port_error_info_msg *)pmp->data; |
| 3343 | rsp = &req->port[0]; | 3343 | rsp = &req->port; |
| 3344 | 3344 | ||
| 3345 | num_ports = OPA_AM_NPORT(be32_to_cpu(pmp->mad_hdr.attr_mod)); | 3345 | num_ports = OPA_AM_NPORT(be32_to_cpu(pmp->mad_hdr.attr_mod)); |
| 3346 | num_pslm = hweight64(be64_to_cpu(req->port_select_mask[3])); | 3346 | num_pslm = hweight64(be64_to_cpu(req->port_select_mask[3])); |
| @@ -3590,7 +3590,7 @@ static int pma_set_opa_errorinfo(struct opa_pma_mad *pmp, · 243 unmodified lines | |||
| 3590 | u32 error_info_select; | 3590 | u32 error_info_select; |
| 3591 | 3591 | ||
| 3592 | req = (struct opa_port_error_info_msg *)pmp->data; | 3592 | req = (struct opa_port_error_info_msg *)pmp->data; |
| 3593 | rsp = &req->port[0]; | 3593 | rsp = &req->port; |
| 3594 | 3594 | ||
| 3595 | num_ports = OPA_AM_NPORT(be32_to_cpu(pmp->mad_hdr.attr_mod)); | 3595 | num_ports = OPA_AM_NPORT(be32_to_cpu(pmp->mad_hdr.attr_mod)); |
| 3596 | num_pslm = hweight64(be64_to_cpu(req->port_select_mask[3])); | 3596 | num_pslm = hweight64(be64_to_cpu(req->port_select_mask[3])); |
| @@ -216,7 +216,7 @@ static int hfi1_netdev_rxq_init(struct hfi1_netdev_rx *rx) · 215 unmodified lines | |||
| 216 | * right now. | 216 | * right now. |
| 217 | */ | 217 | */ |
| 218 | set_bit(NAPI_STATE_NO_BUSY_POLL, &rxq->napi.state); | 218 | set_bit(NAPI_STATE_NO_BUSY_POLL, &rxq->napi.state); |
| 219 | netif_napi_add_weight(dev, &rxq->napi, hfi1_netdev_rx_napi, 64); | 219 | netif_napi_add(dev, &rxq->napi, hfi1_netdev_rx_napi); |
| 220 | rc = msix_netdev_request_rcd_irq(rxq->rcd); | 220 | rc = msix_netdev_request_rcd_irq(rxq->rcd); |
| 221 | if (rc) | 221 | if (rc) |
| 222 | goto bail_context_irq_failure; | 222 | goto bail_context_irq_failure; |
| @@ -202,6 +202,7 @@ struct hns_roce_ucontext { · 201 unmodified lines | |||
| 202 | struct list_head page_list; | 202 | struct list_head page_list; |
| 203 | struct mutex page_mutex; | 203 | struct mutex page_mutex; |
| 204 | struct hns_user_mmap_entry *db_mmap_entry; | 204 | struct hns_user_mmap_entry *db_mmap_entry; |
| 205 | u32 config; | ||
| 205 | }; | 206 | }; |
| 206 | 207 | ||
| 207 | struct hns_roce_pd { | 208 | struct hns_roce_pd { |
| @@ -334,6 +335,7 @@ struct hns_roce_wq { · 126 unmodified lines | |||
| 334 | u32 head; | 335 | u32 head; |
| 335 | u32 tail; | 336 | u32 tail; |
| 336 | void __iomem *db_reg; | 337 | void __iomem *db_reg; |
| 338 | u32 ext_sge_cnt; | ||
| 337 | }; | 339 | }; |
| 338 | 340 | ||
| 339 | struct hns_roce_sge { | 341 | struct hns_roce_sge { |
| @@ -635,6 +637,7 @@ struct hns_roce_qp { · 295 unmodified lines | |||
| 635 | struct list_head rq_node; /* all recv qps are on a list */ | 637 | struct list_head rq_node; /* all recv qps are on a list */ |
| 636 | struct list_head sq_node; /* all send qps are on a list */ | 638 | struct list_head sq_node; /* all send qps are on a list */ |
| 637 | struct hns_user_mmap_entry *dwqe_mmap_entry; | 639 | struct hns_user_mmap_entry *dwqe_mmap_entry; |
| 640 | u32 config; | ||
| 638 | }; | 641 | }; |
| 639 | 642 | ||
| 640 | struct hns_roce_ib_iboe { | 643 | struct hns_roce_ib_iboe { |
| @@ -192,7 +192,6 @@ static int fill_ext_sge_inl_data(struct hns_roce_qp *qp, · 191 unmodified lines | |||
| 192 | unsigned int *sge_idx, u32 msg_len) | 192 | unsigned int *sge_idx, u32 msg_len) |
| 193 | { | 193 | { |
| 194 | struct ib_device *ibdev = &(to_hr_dev(qp->ibqp.device))->ib_dev; | 194 | struct ib_device *ibdev = &(to_hr_dev(qp->ibqp.device))->ib_dev; |
| 195 | unsigned int ext_sge_sz = qp->sq.max_gs * HNS_ROCE_SGE_SIZE; | ||
| 196 | unsigned int left_len_in_pg; | 195 | unsigned int left_len_in_pg; |
| 197 | unsigned int idx = *sge_idx; | 196 | unsigned int idx = *sge_idx; |
| 198 | unsigned int i = 0; | 197 | unsigned int i = 0; |
| @@ -200,7 +199,7 @@ static int fill_ext_sge_inl_data(struct hns_roce_qp *qp, · 1 unmodified line | |||
| 200 | void *addr; | 199 | void *addr; |
| 201 | void *dseg; | 200 | void *dseg; |
| 202 | 201 | ||
| 203 | if (msg_len > ext_sge_sz) { | 202 | if (msg_len > qp->sq.ext_sge_cnt * HNS_ROCE_SGE_SIZE) { |
| 204 | ibdev_err(ibdev, | 203 | ibdev_err(ibdev, |
| 205 | "no enough extended sge space for inline data.\n"); | 204 | "no enough extended sge space for inline data.\n"); |
| 206 | return -EINVAL; | 205 | return -EINVAL; |
| @@ -1274,6 +1273,30 @@ static void update_cmdq_status(struct hns_roce_dev *hr_dev) · 1067 unmodified lines | |||
| 1274 | hr_dev->cmd.state = HNS_ROCE_CMDQ_STATE_FATAL_ERR; | 1273 | hr_dev->cmd.state = HNS_ROCE_CMDQ_STATE_FATAL_ERR; |
| 1275 | } | 1274 | } |
| 1276 | 1275 | ||
| 1276 | static int hns_roce_cmd_err_convert_errno(u16 desc_ret) | ||
| 1277 | { | ||
| 1278 | struct hns_roce_cmd_errcode errcode_table[] = { | ||
| 1279 | {CMD_EXEC_SUCCESS, 0}, | ||
| 1280 | {CMD_NO_AUTH, -EPERM}, | ||
| 1281 | {CMD_NOT_EXIST, -EOPNOTSUPP}, | ||
| 1282 | {CMD_CRQ_FULL, -EXFULL}, | ||
| 1283 | {CMD_NEXT_ERR, -ENOSR}, | ||
| 1284 | {CMD_NOT_EXEC, -ENOTBLK}, | ||
| 1285 | {CMD_PARA_ERR, -EINVAL}, | ||
| 1286 | {CMD_RESULT_ERR, -ERANGE}, | ||
| 1287 | {CMD_TIMEOUT, -ETIME}, | ||
| 1288 | {CMD_HILINK_ERR, -ENOLINK}, | ||
| 1289 | {CMD_INFO_ILLEGAL, -ENXIO}, | ||
| 1290 | {CMD_INVALID, -EBADR}, | ||
| 1291 | }; | ||
| 1292 | u16 i; | ||
| 1293 | |||
| 1294 | for (i = 0; i < ARRAY_SIZE(errcode_table); i++) | ||
| 1295 | if (desc_ret == errcode_table[i].return_status) | ||
| 1296 | return errcode_table[i].errno; | ||
| 1297 | return -EIO; | ||
| 1298 | } | ||
| 1299 | |||
| 1277 | static int __hns_roce_cmq_send(struct hns_roce_dev *hr_dev, | 1300 | static int __hns_roce_cmq_send(struct hns_roce_dev *hr_dev, |
| 1278 | struct hns_roce_cmq_desc *desc, int num) | 1301 | struct hns_roce_cmq_desc *desc, int num) |
| 1279 | { | 1302 | { |
| @@ -1319,7 +1342,7 @@ static int __hns_roce_cmq_send(struct hns_roce_dev *hr_dev, · 39 unmodified lines | |||
| 1319 | dev_err_ratelimited(hr_dev->dev, | 1342 | dev_err_ratelimited(hr_dev->dev, |
| 1320 | "Cmdq IO error, opcode = 0x%x, return = 0x%x.\n", | 1343 | "Cmdq IO error, opcode = 0x%x, return = 0x%x.\n", |
| 1321 | desc->opcode, desc_ret); | 1344 | desc->opcode, desc_ret); |
| 1322 | ret = -EIO; | 1345 | ret = hns_roce_cmd_err_convert_errno(desc_ret); |
| 1323 | } | 1346 | } |
| 1324 | } else { | 1347 | } else { |
| 1325 | /* FW/HW reset or incorrect number of desc */ | 1348 | /* FW/HW reset or incorrect number of desc */ |
| @@ -2024,13 +2047,14 @@ static void set_default_caps(struct hns_roce_dev *hr_dev) · 698 unmodified lines | |||
| 2024 | 2047 | ||
| 2025 | caps->flags |= HNS_ROCE_CAP_FLAG_ATOMIC | HNS_ROCE_CAP_FLAG_MW | | 2048 | caps->flags |= HNS_ROCE_CAP_FLAG_ATOMIC | HNS_ROCE_CAP_FLAG_MW | |
| 2026 | HNS_ROCE_CAP_FLAG_SRQ | HNS_ROCE_CAP_FLAG_FRMR | | 2049 | HNS_ROCE_CAP_FLAG_SRQ | HNS_ROCE_CAP_FLAG_FRMR | |
| 2027 | HNS_ROCE_CAP_FLAG_QP_FLOW_CTRL | HNS_ROCE_CAP_FLAG_XRC; | 2050 | HNS_ROCE_CAP_FLAG_QP_FLOW_CTRL; |
| 2028 | 2051 | ||
| 2029 | caps->gid_table_len[0] = HNS_ROCE_V2_GID_INDEX_NUM; | 2052 | caps->gid_table_len[0] = HNS_ROCE_V2_GID_INDEX_NUM; |
| 2030 | 2053 | ||
| 2031 | if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP09) { | 2054 | if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP09) { |
| 2032 | caps->flags |= HNS_ROCE_CAP_FLAG_STASH | | 2055 | caps->flags |= HNS_ROCE_CAP_FLAG_STASH | |
| 2033 | HNS_ROCE_CAP_FLAG_DIRECT_WQE; | 2056 | HNS_ROCE_CAP_FLAG_DIRECT_WQE | |
| 2057 | HNS_ROCE_CAP_FLAG_XRC; | ||
| 2034 | caps->max_sq_inline = HNS_ROCE_V3_MAX_SQ_INLINE; | 2058 | caps->max_sq_inline = HNS_ROCE_V3_MAX_SQ_INLINE; |
| 2035 | } else { | 2059 | } else { |
| 2036 | caps->max_sq_inline = HNS_ROCE_V2_MAX_SQ_INLINE; | 2060 | caps->max_sq_inline = HNS_ROCE_V2_MAX_SQ_INLINE; |
| @@ -2342,6 +2366,9 @@ static int hns_roce_query_pf_caps(struct hns_roce_dev *hr_dev) · 305 unmodified lines | |||
| 2342 | caps->wqe_sge_hop_num = hr_reg_read(resp_d, PF_CAPS_D_EX_SGE_HOP_NUM); | 2366 | caps->wqe_sge_hop_num = hr_reg_read(resp_d, PF_CAPS_D_EX_SGE_HOP_NUM); |
| 2343 | caps->wqe_rq_hop_num = hr_reg_read(resp_d, PF_CAPS_D_RQWQE_HOP_NUM); | 2367 | caps->wqe_rq_hop_num = hr_reg_read(resp_d, PF_CAPS_D_RQWQE_HOP_NUM); |
| 2344 | 2368 | ||
| 2369 | if (!(caps->page_size_cap & PAGE_SIZE)) | ||
| 2370 | caps->page_size_cap = HNS_ROCE_V2_PAGE_SIZE_SUPPORTED; | ||
| 2371 | |||
| 2345 | return 0; | 2372 | return 0; |
| 2346 | } | 2373 | } |
| 2347 | 2374 | ||
| @@ -2631,31 +2658,124 @@ static void free_dip_list(struct hns_roce_dev *hr_dev) · 283 unmodified lines | |||
| 2631 | spin_unlock_irqrestore(&hr_dev->dip_list_lock, flags); | 2658 | spin_unlock_irqrestore(&hr_dev->dip_list_lock, flags); |
| 2632 | } | 2659 | } |
| 2633 | 2660 | ||
| 2634 | static void free_mr_exit(struct hns_roce_dev *hr_dev) | 2661 | static struct ib_pd *free_mr_init_pd(struct hns_roce_dev *hr_dev) |
| 2662 | { | ||
| 2663 | struct hns_roce_v2_priv *priv = hr_dev->priv; | ||
| 2664 | struct hns_roce_v2_free_mr *free_mr = &priv->free_mr; | ||
| 2665 | struct ib_device *ibdev = &hr_dev->ib_dev; | ||
| 2666 | struct hns_roce_pd *hr_pd; | ||
| 2667 | struct ib_pd *pd; | ||
| 2668 | |||
| 2669 | hr_pd = kzalloc(sizeof(*hr_pd), GFP_KERNEL); | ||
| 2670 | if (ZERO_OR_NULL_PTR(hr_pd)) | ||
| 2671 | return NULL; | ||
| 2672 | pd = &hr_pd->ibpd; | ||
| 2673 | pd->device = ibdev; | ||
| 2674 | |||
| 2675 | if (hns_roce_alloc_pd(pd, NULL)) { | ||
| 2676 | ibdev_err(ibdev, "failed to create pd for free mr.\n"); | ||
| 2677 | kfree(hr_pd); | ||
| 2678 | return NULL; | ||
| 2679 | } | ||
| 2680 | free_mr->rsv_pd = to_hr_pd(pd); | ||
| 2681 | free_mr->rsv_pd->ibpd.device = &hr_dev->ib_dev; | ||
| 2682 | free_mr->rsv_pd->ibpd.uobject = NULL; | ||
| 2683 | free_mr->rsv_pd->ibpd.__internal_mr = NULL; | ||
| 2684 | atomic_set(&free_mr->rsv_pd->ibpd.usecnt, 0); | ||
| 2685 | |||
| 2686 | return pd; | ||
| 2687 | } | ||
| 2688 | |||
| 2689 | static struct ib_cq *free_mr_init_cq(struct hns_roce_dev *hr_dev) | ||
| 2635 | { | 2690 | { |
| 2636 | struct hns_roce_v2_priv *priv = hr_dev->priv; | 2691 | struct hns_roce_v2_priv *priv = hr_dev->priv; |
| 2637 | struct hns_roce_v2_free_mr *free_mr = &priv->free_mr; | 2692 | struct hns_roce_v2_free_mr *free_mr = &priv->free_mr; |
| 2693 | struct ib_device *ibdev = &hr_dev->ib_dev; | ||
| 2694 | struct ib_cq_init_attr cq_init_attr = {}; | ||
| 2695 | struct hns_roce_cq *hr_cq; | ||
| 2696 | struct ib_cq *cq; | ||
| 2697 | |||
| 2698 | cq_init_attr.cqe = HNS_ROCE_FREE_MR_USED_CQE_NUM; | ||
| 2699 | |||
| 2700 | hr_cq = kzalloc(sizeof(*hr_cq), GFP_KERNEL); | ||
| 2701 | if (ZERO_OR_NULL_PTR(hr_cq)) | ||
| 2702 | return NULL; | ||
| 2703 | |||
| 2704 | cq = &hr_cq->ib_cq; | ||
| 2705 | cq->device = ibdev; | ||
| 2706 | |||
| 2707 | if (hns_roce_create_cq(cq, &cq_init_attr, NULL)) { | ||
| 2708 | ibdev_err(ibdev, "failed to create cq for free mr.\n"); | ||
| 2709 | kfree(hr_cq); | ||
| 2710 | return NULL; | ||
| 2711 | } | ||
| 2712 | free_mr->rsv_cq = to_hr_cq(cq); | ||
| 2713 | free_mr->rsv_cq->ib_cq.device = &hr_dev->ib_dev; | ||
| 2714 | free_mr->rsv_cq->ib_cq.uobject = NULL; | ||
| 2715 | free_mr->rsv_cq->ib_cq.comp_handler = NULL; | ||
| 2716 | free_mr->rsv_cq->ib_cq.event_handler = NULL; | ||
| 2717 | free_mr->rsv_cq->ib_cq.cq_context = NULL; | ||
| 2718 | atomic_set(&free_mr->rsv_cq->ib_cq.usecnt, 0); | ||
| 2719 | |||
| 2720 | return cq; | ||
| 2721 | } | ||
| 2722 | |||
| 2723 | static int free_mr_init_qp(struct hns_roce_dev *hr_dev, struct ib_cq *cq, | ||
| 2724 | struct ib_qp_init_attr *init_attr, int i) | ||
| 2725 | { | ||
| 2726 | struct hns_roce_v2_priv *priv = hr_dev->priv; | ||
| 2727 | struct hns_roce_v2_free_mr *free_mr = &priv->free_mr; | ||
| 2728 | struct ib_device *ibdev = &hr_dev->ib_dev; | ||
| 2729 | struct hns_roce_qp *hr_qp; | ||
| 2730 | struct ib_qp *qp; | ||
| 2638 | int ret; | 2731 | int ret; |
| 2732 | |||
| 2733 | hr_qp = kzalloc(sizeof(*hr_qp), GFP_KERNEL); | ||
| 2734 | if (ZERO_OR_NULL_PTR(hr_qp)) | ||
| 2735 | return -ENOMEM; | ||
| 2736 | |||
| 2737 | qp = &hr_qp->ibqp; | ||
| 2738 | qp->device = ibdev; | ||
| 2739 | |||
| 2740 | ret = hns_roce_create_qp(qp, init_attr, NULL); | ||
| 2741 | if (ret) { | ||
| 2742 | ibdev_err(ibdev, "failed to create qp for free mr.\n"); | ||
| 2743 | kfree(hr_qp); | ||
| 2744 | return ret; | ||
| 2745 | } | ||
| 2746 | |||
| 2747 | free_mr->rsv_qp[i] = hr_qp; | ||
| 2748 | free_mr->rsv_qp[i]->ibqp.recv_cq = cq; | ||
| 2749 | free_mr->rsv_qp[i]->ibqp.send_cq = cq; | ||
| 2750 | |||
| 2751 | return 0; | ||
| 2752 | } | ||
| 2753 | |||
| 2754 | static void free_mr_exit(struct hns_roce_dev *hr_dev) | ||
| 2755 | { | ||
| 2756 | struct hns_roce_v2_priv *priv = hr_dev->priv; | ||
| 2757 | struct hns_roce_v2_free_mr *free_mr = &priv->free_mr; | ||
| 2758 | struct ib_qp *qp; | ||
| 2639 | int i; | 2759 | int i; |
| 2640 | 2760 | ||
| 2641 | for (i = 0; i < ARRAY_SIZE(free_mr->rsv_qp); i++) { | 2761 | for (i = 0; i < ARRAY_SIZE(free_mr->rsv_qp); i++) { |
| 2642 | if (free_mr->rsv_qp[i]) { | 2762 | if (free_mr->rsv_qp[i]) { |
| 2643 | ret = ib_destroy_qp(free_mr->rsv_qp[i]); | 2763 | qp = &free_mr->rsv_qp[i]->ibqp; |
| 2644 | if (ret) | 2764 | hns_roce_v2_destroy_qp(qp, NULL); |
| 2645 | ibdev_err(&hr_dev->ib_dev, | 2765 | kfree(free_mr->rsv_qp[i]); |
| 2646 | "failed to destroy qp in free mr.\n"); | ||
| 2647 | |||
| 2648 | free_mr->rsv_qp[i] = NULL; | 2766 | free_mr->rsv_qp[i] = NULL; |
| 2649 | } | 2767 | } |
| 2650 | } | 2768 | } |
| 2651 | 2769 | ||
| 2652 | if (free_mr->rsv_cq) { | 2770 | if (free_mr->rsv_cq) { |
| 2653 | ib_destroy_cq(free_mr->rsv_cq); | 2771 | hns_roce_destroy_cq(&free_mr->rsv_cq->ib_cq, NULL); |
| 2772 | kfree(free_mr->rsv_cq); | ||
| 2654 | free_mr->rsv_cq = NULL; | 2773 | free_mr->rsv_cq = NULL; |
| 2655 | } | 2774 | } |
| 2656 | 2775 | ||
| 2657 | if (free_mr->rsv_pd) { | 2776 | if (free_mr->rsv_pd) { |
| 2658 | ib_dealloc_pd(free_mr->rsv_pd); | 2777 | hns_roce_dealloc_pd(&free_mr->rsv_pd->ibpd, NULL); |
| 2778 | kfree(free_mr->rsv_pd); | ||
| 2659 | free_mr->rsv_pd = NULL; | 2779 | free_mr->rsv_pd = NULL; |
| 2660 | } | 2780 | } |
| 2661 | } | 2781 | } |
| @@ -2664,55 +2784,46 @@ static int free_mr_alloc_res(struct hns_roce_dev *hr_dev) · 2 unmodified lines | |||
| 2664 | { | 2784 | { |
| 2665 | struct hns_roce_v2_priv *priv = hr_dev->priv; | 2785 | struct hns_roce_v2_priv *priv = hr_dev->priv; |
| 2666 | struct hns_roce_v2_free_mr *free_mr = &priv->free_mr; | 2786 | struct hns_roce_v2_free_mr *free_mr = &priv->free_mr; |
| 2667 | struct ib_device *ibdev = &hr_dev->ib_dev; | ||
| 2668 | struct ib_cq_init_attr cq_init_attr = {}; | ||
| 2669 | struct ib_qp_init_attr qp_init_attr = {}; | 2787 | struct ib_qp_init_attr qp_init_attr = {}; |
| 2670 | struct ib_pd *pd; | 2788 | struct ib_pd *pd; |
| 2671 | struct ib_cq *cq; | 2789 | struct ib_cq *cq; |
| 2672 | struct ib_qp *qp; | ||
| 2673 | int ret; | 2790 | int ret; |
| 2674 | int i; | 2791 | int i; |
| 2675 | 2792 | ||
| 2676 | pd = ib_alloc_pd(ibdev, 0); | 2793 | pd = free_mr_init_pd(hr_dev); |
| 2677 | if (IS_ERR(pd)) { | 2794 | if (!pd) |
| 2678 | ibdev_err(ibdev, "failed to create pd for free mr.\n"); | 2795 | return -ENOMEM; |
| 2679 | return PTR_ERR(pd); | ||
| 2680 | } | ||
| 2681 | free_mr->rsv_pd = pd; | ||
| 2682 | 2796 | ||
| 2683 | cq_init_attr.cqe = HNS_ROCE_FREE_MR_USED_CQE_NUM; | 2797 | cq = free_mr_init_cq(hr_dev); |
| 2684 | cq = ib_create_cq(ibdev, NULL, NULL, NULL, &cq_init_attr); | 2798 | if (!cq) { |
| 2685 | if (IS_ERR(cq)) { | 2799 | ret = -ENOMEM; |
| 2686 | ibdev_err(ibdev, "failed to create cq for free mr.\n"); | 2800 | goto create_failed_cq; |
| 2687 | ret = PTR_ERR(cq); | ||
| 2688 | goto create_failed; | ||
| 2689 | } | 2801 | } |
| 2690 | free_mr->rsv_cq = cq; | ||
| 2691 | 2802 | ||
| 2692 | qp_init_attr.qp_type = IB_QPT_RC; | 2803 | qp_init_attr.qp_type = IB_QPT_RC; |
| 2693 | qp_init_attr.sq_sig_type = IB_SIGNAL_ALL_WR; | 2804 | qp_init_attr.sq_sig_type = IB_SIGNAL_ALL_WR; |
| 2694 | qp_init_attr.send_cq = free_mr->rsv_cq; | 2805 | qp_init_attr.send_cq = cq; |
| 2695 | qp_init_attr.recv_cq = free_mr->rsv_cq; | 2806 | qp_init_attr.recv_cq = cq; |
| 2696 | for (i = 0; i < ARRAY_SIZE(free_mr->rsv_qp); i++) { | 2807 | for (i = 0; i < ARRAY_SIZE(free_mr->rsv_qp); i++) { |
| 2697 | qp_init_attr.cap.max_send_wr = HNS_ROCE_FREE_MR_USED_SQWQE_NUM; | 2808 | qp_init_attr.cap.max_send_wr = HNS_ROCE_FREE_MR_USED_SQWQE_NUM; |
| 2698 | qp_init_attr.cap.max_send_sge = HNS_ROCE_FREE_MR_USED_SQSGE_NUM; | 2809 | qp_init_attr.cap.max_send_sge = HNS_ROCE_FREE_MR_USED_SQSGE_NUM; |
| 2699 | qp_init_attr.cap.max_recv_wr = HNS_ROCE_FREE_MR_USED_RQWQE_NUM; | 2810 | qp_init_attr.cap.max_recv_wr = HNS_ROCE_FREE_MR_USED_RQWQE_NUM; |
| 2700 | qp_init_attr.cap.max_recv_sge = HNS_ROCE_FREE_MR_USED_RQSGE_NUM; | 2811 | qp_init_attr.cap.max_recv_sge = HNS_ROCE_FREE_MR_USED_RQSGE_NUM; |
| 2701 | 2812 | ||
| 2702 | qp = ib_create_qp(free_mr->rsv_pd, &qp_init_attr); | 2813 | ret = free_mr_init_qp(hr_dev, cq, &qp_init_attr, i); |
| 2703 | if (IS_ERR(qp)) { | 2814 | if (ret) |
| 2704 | ibdev_err(ibdev, "failed to create qp for free mr.\n"); | 2815 | goto create_failed_qp; |
| 2705 | ret = PTR_ERR(qp); | ||
| 2706 | goto create_failed; | ||
| 2707 | } | ||
| 2708 | |||
| 2709 | free_mr->rsv_qp[i] = qp; | ||
| 2710 | } | 2816 | } |
| 2711 | 2817 | ||
| 2712 | return 0; | 2818 | return 0; |
| 2713 | 2819 | ||
| 2714 | create_failed: | 2820 | create_failed_qp: |
| 2715 | free_mr_exit(hr_dev); | 2821 | hns_roce_destroy_cq(cq, NULL); |
| 2822 | kfree(cq); | ||
| 2823 | |||
| 2824 | create_failed_cq: | ||
| 2825 | hns_roce_dealloc_pd(pd, NULL); | ||
| 2826 | kfree(pd); | ||
| 2716 | 2827 | ||
| 2717 | return ret; | 2828 | return ret; |
| 2718 | } | 2829 | } |
| @@ -2728,14 +2839,17 @@ static int free_mr_modify_rsv_qp(struct hns_roce_dev *hr_dev, · 9 unmodified lines | |||
| 2728 | int mask; | 2839 | int mask; |
| 2729 | int ret; | 2840 | int ret; |
| 2730 | 2841 | ||
| 2731 | hr_qp = to_hr_qp(free_mr->rsv_qp[sl_num]); | 2842 | hr_qp = to_hr_qp(&free_mr->rsv_qp[sl_num]->ibqp); |
| 2732 | hr_qp->free_mr_en = 1; | 2843 | hr_qp->free_mr_en = 1; |
| 2844 | hr_qp->ibqp.device = ibdev; | ||
| 2845 | hr_qp->ibqp.qp_type = IB_QPT_RC; | ||
| 2733 | 2846 | ||
| 2734 | mask = IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_PORT | IB_QP_ACCESS_FLAGS; | 2847 | mask = IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_PORT | IB_QP_ACCESS_FLAGS; |
| 2735 | attr->qp_state = IB_QPS_INIT; | 2848 | attr->qp_state = IB_QPS_INIT; |
| 2736 | attr->port_num = 1; | 2849 | attr->port_num = 1; |
| 2737 | attr->qp_access_flags = IB_ACCESS_REMOTE_WRITE; | 2850 | attr->qp_access_flags = IB_ACCESS_REMOTE_WRITE; |
| 2738 | ret = ib_modify_qp(&hr_qp->ibqp, attr, mask); | 2851 | ret = hr_dev->hw->modify_qp(&hr_qp->ibqp, attr, mask, IB_QPS_INIT, |
| 2852 | IB_QPS_INIT); | ||
| 2739 | if (ret) { | 2853 | if (ret) { |
| 2740 | ibdev_err(ibdev, "failed to modify qp to init, ret = %d.\n", | 2854 | ibdev_err(ibdev, "failed to modify qp to init, ret = %d.\n", |
| 2741 | ret); | 2855 | ret); |
| @@ -2756,7 +2870,8 @@ static int free_mr_modify_rsv_qp(struct hns_roce_dev *hr_dev, · 14 unmodified lines | |||
| 2756 | 2870 | ||
| 2757 | rdma_ah_set_sl(&attr->ah_attr, (u8)sl_num); | 2871 | rdma_ah_set_sl(&attr->ah_attr, (u8)sl_num); |
| 2758 | 2872 | ||
| 2759 | ret = ib_modify_qp(&hr_qp->ibqp, attr, mask); | 2873 | ret = hr_dev->hw->modify_qp(&hr_qp->ibqp, attr, mask, IB_QPS_INIT, |
| 2874 | IB_QPS_RTR); | ||
| 2760 | hr_dev->loop_idc = loopback; | 2875 | hr_dev->loop_idc = loopback; |
| 2761 | if (ret) { | 2876 | if (ret) { |
| 2762 | ibdev_err(ibdev, "failed to modify qp to rtr, ret = %d.\n", | 2877 | ibdev_err(ibdev, "failed to modify qp to rtr, ret = %d.\n", |
| @@ -2770,7 +2885,8 @@ static int free_mr_modify_rsv_qp(struct hns_roce_dev *hr_dev, · 7 unmodified lines | |||
| 2770 | attr->sq_psn = HNS_ROCE_FREE_MR_USED_PSN; | 2885 | attr->sq_psn = HNS_ROCE_FREE_MR_USED_PSN; |
| 2771 | attr->retry_cnt = HNS_ROCE_FREE_MR_USED_QP_RETRY_CNT; | 2886 | attr->retry_cnt = HNS_ROCE_FREE_MR_USED_QP_RETRY_CNT; |
| 2772 | attr->timeout = HNS_ROCE_FREE_MR_USED_QP_TIMEOUT; | 2887 | attr->timeout = HNS_ROCE_FREE_MR_USED_QP_TIMEOUT; |
| 2773 | ret = ib_modify_qp(&hr_qp->ibqp, attr, mask); | 2888 | ret = hr_dev->hw->modify_qp(&hr_qp->ibqp, attr, mask, IB_QPS_RTR, |
| 2889 | IB_QPS_RTS); | ||
| 2774 | if (ret) | 2890 | if (ret) |
| 2775 | ibdev_err(ibdev, "failed to modify qp to rts, ret = %d.\n", | 2891 | ibdev_err(ibdev, "failed to modify qp to rts, ret = %d.\n", |
| 2776 | ret); | 2892 | ret); |
| @@ -3186,7 +3302,8 @@ static int set_mtpt_pbl(struct hns_roce_dev *hr_dev, · 409 unmodified lines | |||
| 3186 | int i, count; | 3302 | int i, count; |
| 3187 | 3303 | ||
| 3188 | count = hns_roce_mtr_find(hr_dev, &mr->pbl_mtr, 0, pages, | 3304 | count = hns_roce_mtr_find(hr_dev, &mr->pbl_mtr, 0, pages, |
| 3189 | ARRAY_SIZE(pages), &pbl_ba); | 3305 | min_t(int, ARRAY_SIZE(pages), mr->npages), |
| 3306 | &pbl_ba); | ||
| 3190 | if (count < 1) { | 3307 | if (count < 1) { |
| 3191 | ibdev_err(ibdev, "failed to find PBL mtr, count = %d.\n", | 3308 | ibdev_err(ibdev, "failed to find PBL mtr, count = %d.\n", |
| 3192 | count); | 3309 | count); |
| @@ -3414,7 +3531,7 @@ static void free_mr_send_cmd_to_hw(struct hns_roce_dev *hr_dev) · 221 unmodified lines | |||
| 3414 | mutex_lock(&free_mr->mutex); | 3531 | mutex_lock(&free_mr->mutex); |
| 3415 | 3532 | ||
| 3416 | for (i = 0; i < ARRAY_SIZE(free_mr->rsv_qp); i++) { | 3533 | for (i = 0; i < ARRAY_SIZE(free_mr->rsv_qp); i++) { |
| 3417 | hr_qp = to_hr_qp(free_mr->rsv_qp[i]); | 3534 | hr_qp = free_mr->rsv_qp[i]; |
| 3418 | 3535 | ||
| 3419 | ret = free_mr_post_send_lp_wqe(hr_qp); | 3536 | ret = free_mr_post_send_lp_wqe(hr_qp); |
| 3420 | if (ret) { | 3537 | if (ret) { |
| @@ -3429,7 +3546,7 @@ static void free_mr_send_cmd_to_hw(struct hns_roce_dev *hr_dev) · 8 unmodified lines | |||
| 3429 | 3546 | ||
| 3430 | end = msecs_to_jiffies(HNS_ROCE_V2_FREE_MR_TIMEOUT) + jiffies; | 3547 | end = msecs_to_jiffies(HNS_ROCE_V2_FREE_MR_TIMEOUT) + jiffies; |
| 3431 | while (cqe_cnt) { | 3548 | while (cqe_cnt) { |
| 3432 | npolled = hns_roce_v2_poll_cq(free_mr->rsv_cq, cqe_cnt, wc); | 3549 | npolled = hns_roce_v2_poll_cq(&free_mr->rsv_cq->ib_cq, cqe_cnt, wc); |
| 3433 | if (npolled < 0) { | 3550 | if (npolled < 0) { |
| 3434 | ibdev_err(ibdev, | 3551 | ibdev_err(ibdev, |
| 3435 | "failed to poll cqe for free mr, remain %d cqe.\n", | 3552 | "failed to poll cqe for free mr, remain %d cqe.\n", |
| @@ -5375,6 +5492,8 @@ static int hns_roce_v2_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, · 1939 unmodified lines | |||
| 5375 | 5492 | ||
| 5376 | rdma_ah_set_sl(&qp_attr->ah_attr, | 5493 | rdma_ah_set_sl(&qp_attr->ah_attr, |
| 5377 | hr_reg_read(&context, QPC_SL)); | 5494 | hr_reg_read(&context, QPC_SL)); |
| 5495 | rdma_ah_set_port_num(&qp_attr->ah_attr, hr_qp->port + 1); | ||
| 5496 | rdma_ah_set_ah_flags(&qp_attr->ah_attr, IB_AH_GRH); | ||
| 5378 | grh->flow_label = hr_reg_read(&context, QPC_FL); | 5497 | grh->flow_label = hr_reg_read(&context, QPC_FL); |
| 5379 | grh->sgid_index = hr_reg_read(&context, QPC_GMV_IDX); | 5498 | grh->sgid_index = hr_reg_read(&context, QPC_GMV_IDX); |
| 5380 | grh->hop_limit = hr_reg_read(&context, QPC_HOPLIMIT); | 5499 | grh->hop_limit = hr_reg_read(&context, QPC_HOPLIMIT); |
| @@ -5468,7 +5587,7 @@ static int hns_roce_v2_destroy_qp_common(struct hns_roce_dev *hr_dev, · 87 unmodified lines | |||
| 5468 | return ret; | 5587 | return ret; |
| 5469 | } | 5588 | } |
| 5470 | 5589 | ||
| 5471 | static int hns_roce_v2_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata) | 5590 | int hns_roce_v2_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata) |
| 5472 | { | 5591 | { |
| 5473 | struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device); | 5592 | struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device); |
| 5474 | struct hns_roce_qp *hr_qp = to_hr_qp(ibqp); | 5593 | struct hns_roce_qp *hr_qp = to_hr_qp(ibqp); |
| @@ -272,6 +272,11 @@ enum hns_roce_cmd_return_status { · 271 unmodified lines | |||
| 272 | CMD_OTHER_ERR = 0xff | 272 | CMD_OTHER_ERR = 0xff |
| 273 | }; | 273 | }; |
| 274 | 274 | ||
| 275 | struct hns_roce_cmd_errcode { | ||
| 276 | enum hns_roce_cmd_return_status return_status; | ||
| 277 | int errno; | ||
| 278 | }; | ||
| 279 | |||
| 275 | enum hns_roce_sgid_type { | 280 | enum hns_roce_sgid_type { |
| 276 | GID_TYPE_FLAG_ROCE_V1 = 0, | 281 | GID_TYPE_FLAG_ROCE_V1 = 0, |
| 277 | GID_TYPE_FLAG_ROCE_V2_IPV4, | 282 | GID_TYPE_FLAG_ROCE_V2_IPV4, |
| @@ -1327,9 +1332,9 @@ struct hns_roce_link_table { · 1049 unmodified lines | |||
| 1327 | #define HNS_ROCE_EXT_LLM_MIN_PAGES(que_num) ((que_num) * 4 + 2) | 1332 | #define HNS_ROCE_EXT_LLM_MIN_PAGES(que_num) ((que_num) * 4 + 2) |
| 1328 | 1333 | ||
| 1329 | struct hns_roce_v2_free_mr { | 1334 | struct hns_roce_v2_free_mr { |
| 1330 | struct ib_qp *rsv_qp[HNS_ROCE_FREE_MR_USED_QP_NUM]; | 1335 | struct hns_roce_qp *rsv_qp[HNS_ROCE_FREE_MR_USED_QP_NUM]; |
| 1331 | struct ib_cq *rsv_cq; | 1336 | struct hns_roce_cq *rsv_cq; |
| 1332 | struct ib_pd *rsv_pd; | 1337 | struct hns_roce_pd *rsv_pd; |
| 1333 | struct mutex mutex; | 1338 | struct mutex mutex; |
| 1334 | }; | 1339 | }; |
| 1335 | 1340 | ||
| @@ -1459,6 +1464,8 @@ struct hns_roce_sccc_clr_done { · 123 unmodified lines | |||
| 1459 | __le32 rsv[5]; | 1464 | __le32 rsv[5]; |
| 1460 | }; | 1465 | }; |
| 1461 | 1466 | ||
| 1467 | int hns_roce_v2_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata); | ||
| 1468 | |||
| 1462 | static inline void hns_roce_write64(struct hns_roce_dev *hr_dev, __le32 val[2], | 1469 | static inline void hns_roce_write64(struct hns_roce_dev *hr_dev, __le32 val[2], |
| 1463 | void __iomem *dest) | 1470 | void __iomem *dest) |
| 1464 | { | 1471 | { |
| @@ -354,10 +354,11 @@ static int hns_roce_alloc_uar_entry(struct ib_ucontext *uctx) · 353 unmodified lines | |||
| 354 | static int hns_roce_alloc_ucontext(struct ib_ucontext *uctx, | 354 | static int hns_roce_alloc_ucontext(struct ib_ucontext *uctx, |
| 355 | struct ib_udata *udata) | 355 | struct ib_udata *udata) |
| 356 | { | 356 | { |
| 357 | int ret; | ||
| 358 | struct hns_roce_ucontext *context = to_hr_ucontext(uctx); | 357 | struct hns_roce_ucontext *context = to_hr_ucontext(uctx); |
| 359 | struct hns_roce_ib_alloc_ucontext_resp resp = {}; | ||
| 360 | struct hns_roce_dev *hr_dev = to_hr_dev(uctx->device); | 358 | struct hns_roce_dev *hr_dev = to_hr_dev(uctx->device); |
| 359 | struct hns_roce_ib_alloc_ucontext_resp resp = {}; | ||
| 360 | struct hns_roce_ib_alloc_ucontext ucmd = {}; | ||
| 361 | int ret; | ||
| 361 | 362 | ||
| 362 | if (!hr_dev->active) | 363 | if (!hr_dev->active) |
| 363 | return -EAGAIN; | 364 | return -EAGAIN; |
| @@ -365,6 +366,19 @@ static int hns_roce_alloc_ucontext(struct ib_ucontext *uctx, · 1 unmodified line | |||
| 365 | resp.qp_tab_size = hr_dev->caps.num_qps; | 366 | resp.qp_tab_size = hr_dev->caps.num_qps; |
| 366 | resp.srq_tab_size = hr_dev->caps.num_srqs; | 367 | resp.srq_tab_size = hr_dev->caps.num_srqs; |
| 367 | 368 | ||
| 369 | ret = ib_copy_from_udata(&ucmd, udata, | ||
| 370 | min(udata->inlen, sizeof(ucmd))); | ||
| 371 | if (ret) | ||
| 372 | return ret; | ||
| 373 | |||
| 374 | if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP09) | ||
| 375 | context->config = ucmd.config & HNS_ROCE_EXSGE_FLAGS; | ||
| 376 | |||
| 377 | if (context->config & HNS_ROCE_EXSGE_FLAGS) { | ||
| 378 | resp.config |= HNS_ROCE_RSP_EXSGE_FLAGS; | ||
| 379 | resp.max_inline_data = hr_dev->caps.max_sq_inline; | ||
| 380 | } | ||
| 381 | |||
| 368 | ret = hns_roce_uar_alloc(hr_dev, &context->uar); | 382 | ret = hns_roce_uar_alloc(hr_dev, &context->uar); |
| 369 | if (ret) | 383 | if (ret) |
| 370 | goto error_fail_uar_alloc; | 384 | goto error_fail_uar_alloc; |
| @@ -392,10 +392,10 @@ struct ib_mr *hns_roce_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type, · 391 unmodified lines | |||
| 392 | 392 | ||
| 393 | return &mr->ibmr; | 393 | return &mr->ibmr; |
| 394 | 394 | ||
| 395 | err_key: | ||
| 396 | free_mr_key(hr_dev, mr); | ||
| 397 | err_pbl: | 395 | err_pbl: |
| 398 | free_mr_pbl(hr_dev, mr); | 396 | free_mr_pbl(hr_dev, mr); |
| 397 | err_key: | ||
| 398 | free_mr_key(hr_dev, mr); | ||
| 399 | err_free: | 399 | err_free: |
| 400 | kfree(mr); | 400 | kfree(mr); |
| 401 | return ERR_PTR(ret); | 401 | return ERR_PTR(ret); |
| @@ -476,38 +476,109 @@ static int set_rq_size(struct hns_roce_dev *hr_dev, struct ib_qp_cap *cap, · 475 unmodified lines | |||
| 476 | return 0; | 476 | return 0; |
| 477 | } | 477 | } |
| 478 | 478 | ||
| 479 | static u32 get_wqe_ext_sge_cnt(struct hns_roce_qp *qp) | 479 | static u32 get_max_inline_data(struct hns_roce_dev *hr_dev, |
| 480 | struct ib_qp_cap *cap) | ||
| 480 | { | 481 | { |
| 481 | /* GSI/UD QP only has extended sge */ | 482 | if (cap->max_inline_data) { |
| 482 | if (qp->ibqp.qp_type == IB_QPT_GSI || qp->ibqp.qp_type == IB_QPT_UD) | 483 | cap->max_inline_data = roundup_pow_of_two(cap->max_inline_data); |
| 483 | return qp->sq.max_gs; | 484 | return min(cap->max_inline_data, |
| 484 | 485 | hr_dev->caps.max_sq_inline); | |
| 485 | if (qp->sq.max_gs > HNS_ROCE_SGE_IN_WQE) | 486 | } |
| 486 | return qp->sq.max_gs - HNS_ROCE_SGE_IN_WQE; | ||
| 487 | 487 | ||
| 488 | return 0; | 488 | return 0; |
| 489 | } | 489 | } |
| 490 | 490 | ||
| 491 | static void update_inline_data(struct hns_roce_qp *hr_qp, | ||
| 492 | struct ib_qp_cap *cap) | ||
| 493 | { | ||
| 494 | u32 sge_num = hr_qp->sq.ext_sge_cnt; | ||
| 495 | |||
| 496 | if (hr_qp->config & HNS_ROCE_EXSGE_FLAGS) { | ||
| 497 | if (!(hr_qp->ibqp.qp_type == IB_QPT_GSI || | ||
| 498 | hr_qp->ibqp.qp_type == IB_QPT_UD)) | ||
| 499 | sge_num = max((u32)HNS_ROCE_SGE_IN_WQE, sge_num); | ||
| 500 | |||
| 501 | cap->max_inline_data = max(cap->max_inline_data, | ||
| 502 | sge_num * HNS_ROCE_SGE_SIZE); | ||
| 503 | } | ||
| 504 | |||
| 505 | hr_qp->max_inline_data = cap->max_inline_data; | ||
| 506 | } | ||
| 507 | |||
| 508 | static u32 get_sge_num_from_max_send_sge(bool is_ud_or_gsi, | ||
| 509 | u32 max_send_sge) | ||
| 510 | { | ||
| 511 | unsigned int std_sge_num; | ||
| 512 | unsigned int min_sge; | ||
| 513 | |||
| 514 | std_sge_num = is_ud_or_gsi ? 0 : HNS_ROCE_SGE_IN_WQE; | ||
| 515 | min_sge = is_ud_or_gsi ? 1 : 0; | ||
| 516 | return max_send_sge > std_sge_num ? (max_send_sge - std_sge_num) : | ||
| 517 | min_sge; | ||
| 518 | } | ||
| 519 | |||
| 520 | static unsigned int get_sge_num_from_max_inl_data(bool is_ud_or_gsi, | ||
| 521 | u32 max_inline_data) | ||
| 522 | { | ||
| 523 | unsigned int inline_sge; | ||
| 524 | |||
| 525 | inline_sge = roundup_pow_of_two(max_inline_data) / HNS_ROCE_SGE_SIZE; | ||
| 526 | |||
| 527 | /* | ||
| 528 | * if max_inline_data less than | ||
| 529 | * HNS_ROCE_SGE_IN_WQE * HNS_ROCE_SGE_SIZE, | ||
| 530 | * In addition to ud's mode, no need to extend sge. | ||
| 531 | */ | ||
| 532 | if (!is_ud_or_gsi && inline_sge <= HNS_ROCE_SGE_IN_WQE) | ||
| 533 | inline_sge = 0; | ||
| 534 | |||
| 535 | return inline_sge; | ||
| 536 | } | ||
| 537 | |||
| 491 | static void set_ext_sge_param(struct hns_roce_dev *hr_dev, u32 sq_wqe_cnt, | 538 | static void set_ext_sge_param(struct hns_roce_dev *hr_dev, u32 sq_wqe_cnt, |
| 492 | struct hns_roce_qp *hr_qp, struct ib_qp_cap *cap) | 539 | struct hns_roce_qp *hr_qp, struct ib_qp_cap *cap) |
| 493 | { | 540 | { |
| 541 | bool is_ud_or_gsi = (hr_qp->ibqp.qp_type == IB_QPT_GSI || | ||
| 542 | hr_qp->ibqp.qp_type == IB_QPT_UD); | ||
| 543 | unsigned int std_sge_num; | ||
| 544 | u32 inline_ext_sge = 0; | ||
| 545 | u32 ext_wqe_sge_cnt; | ||
| 494 | u32 total_sge_cnt; | 546 | u32 total_sge_cnt; |
| 495 | u32 wqe_sge_cnt; | 547 | |
| 548 | cap->max_inline_data = get_max_inline_data(hr_dev, cap); | ||
| 496 | 549 | ||
| 497 | hr_qp->sge.sge_shift = HNS_ROCE_SGE_SHIFT; | 550 | hr_qp->sge.sge_shift = HNS_ROCE_SGE_SHIFT; |
| 551 | std_sge_num = is_ud_or_gsi ? 0 : HNS_ROCE_SGE_IN_WQE; | ||
| 552 | ext_wqe_sge_cnt = get_sge_num_from_max_send_sge(is_ud_or_gsi, | ||
| 553 | cap->max_send_sge); | ||
| 498 | 554 | ||
| 499 | hr_qp->sq.max_gs = max(1U, cap->max_send_sge); | 555 | if (hr_qp->config & HNS_ROCE_EXSGE_FLAGS) { |
| 556 | inline_ext_sge = max(ext_wqe_sge_cnt, | ||
| 557 | get_sge_num_from_max_inl_data(is_ud_or_gsi, | ||
| 558 | cap->max_inline_data)); | ||
| 559 | hr_qp->sq.ext_sge_cnt = inline_ext_sge ? | ||
| 560 | roundup_pow_of_two(inline_ext_sge) : 0; | ||
| 500 | 561 | ||
| 501 | wqe_sge_cnt = get_wqe_ext_sge_cnt(hr_qp); | 562 | hr_qp->sq.max_gs = max(1U, (hr_qp->sq.ext_sge_cnt + std_sge_num)); |
| 563 | hr_qp->sq.max_gs = min(hr_qp->sq.max_gs, hr_dev->caps.max_sq_sg); | ||
| 564 | |||
| 565 | ext_wqe_sge_cnt = hr_qp->sq.ext_sge_cnt; | ||
| 566 | } else { | ||
| 567 | hr_qp->sq.max_gs = max(1U, cap->max_send_sge); | ||
| 568 | hr_qp->sq.max_gs = min(hr_qp->sq.max_gs, hr_dev->caps.max_sq_sg); | ||
| 569 | hr_qp->sq.ext_sge_cnt = hr_qp->sq.max_gs; | ||
| 570 | } | ||
| 502 | 571 | ||
| 503 | /* If the number of extended sge is not zero, they MUST use the | 572 | /* If the number of extended sge is not zero, they MUST use the |
| 504 | * space of HNS_HW_PAGE_SIZE at least. | 573 | * space of HNS_HW_PAGE_SIZE at least. |
| 505 | */ | 574 | */ |
| 506 | if (wqe_sge_cnt) { | 575 | if (ext_wqe_sge_cnt) { |
| 507 | total_sge_cnt = roundup_pow_of_two(sq_wqe_cnt * wqe_sge_cnt); | 576 | total_sge_cnt = roundup_pow_of_two(sq_wqe_cnt * ext_wqe_sge_cnt); |
| 508 | hr_qp->sge.sge_cnt = max(total_sge_cnt, | 577 | hr_qp->sge.sge_cnt = max(total_sge_cnt, |
| 509 | (u32)HNS_HW_PAGE_SIZE / HNS_ROCE_SGE_SIZE); | 578 | (u32)HNS_HW_PAGE_SIZE / HNS_ROCE_SGE_SIZE); |
| 510 | } | 579 | } |
| 580 | |||
| 581 | update_inline_data(hr_qp, cap); | ||
| 511 | } | 582 | } |
| 512 | 583 | ||
| 513 | static int check_sq_size_with_integrity(struct hns_roce_dev *hr_dev, | 584 | static int check_sq_size_with_integrity(struct hns_roce_dev *hr_dev, |
| @@ -556,6 +627,7 @@ static int set_user_sq_size(struct hns_roce_dev *hr_dev, · 42 unmodified lines | |||
| 556 | 627 | ||
| 557 | hr_qp->sq.wqe_shift = ucmd->log_sq_stride; | 628 | hr_qp->sq.wqe_shift = ucmd->log_sq_stride; |
| 558 | hr_qp->sq.wqe_cnt = cnt; | 629 | hr_qp->sq.wqe_cnt = cnt; |
| 630 | cap->max_send_sge = hr_qp->sq.max_gs; | ||
| 559 | 631 | ||
| 560 | return 0; | 632 | return 0; |
| 561 | } | 633 | } |
| @@ -986,13 +1058,9 @@ static int set_qp_param(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp, · 424 unmodified lines | |||
| 986 | struct hns_roce_ib_create_qp *ucmd) | 1058 | struct hns_roce_ib_create_qp *ucmd) |
| 987 | { | 1059 | { |
| 988 | struct ib_device *ibdev = &hr_dev->ib_dev; | 1060 | struct ib_device *ibdev = &hr_dev->ib_dev; |
| 1061 | struct hns_roce_ucontext *uctx; | ||
| 989 | int ret; | 1062 | int ret; |
| 990 | 1063 | ||
| 991 | if (init_attr->cap.max_inline_data > hr_dev->caps.max_sq_inline) | ||
| 992 | init_attr->cap.max_inline_data = hr_dev->caps.max_sq_inline; | ||
| 993 | |||
| 994 | hr_qp->max_inline_data = init_attr->cap.max_inline_data; | ||
| 995 | |||
| 996 | if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) | 1064 | if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) |
| 997 | hr_qp->sq_signal_bits = IB_SIGNAL_ALL_WR; | 1065 | hr_qp->sq_signal_bits = IB_SIGNAL_ALL_WR; |
| 998 | else | 1066 | else |
| @@ -1015,12 +1083,17 @@ static int set_qp_param(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp, · 16 unmodified lines | |||
| 1015 | return ret; | 1083 | return ret; |
| 1016 | } | 1084 | } |
| 1017 | 1085 | ||
| 1086 | uctx = rdma_udata_to_drv_context(udata, struct hns_roce_ucontext, | ||
| 1087 | ibucontext); | ||
| 1088 | hr_qp->config = uctx->config; | ||
| 1018 | ret = set_user_sq_size(hr_dev, &init_attr->cap, hr_qp, ucmd); | 1089 | ret = set_user_sq_size(hr_dev, &init_attr->cap, hr_qp, ucmd); |
| 1019 | if (ret) | 1090 | if (ret) |
| 1020 | ibdev_err(ibdev, | 1091 | ibdev_err(ibdev, |
| 1021 | "failed to set user SQ size, ret = %d.\n", | 1092 | "failed to set user SQ size, ret = %d.\n", |
| 1022 | ret); | 1093 | ret); |
| 1023 | } else { | 1094 | } else { |
| 1095 | if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP09) | ||
| 1096 | hr_qp->config = HNS_ROCE_EXSGE_FLAGS; | ||
| 1024 | ret = set_kernel_sq_size(hr_dev, &init_attr->cap, hr_qp); | 1097 | ret = set_kernel_sq_size(hr_dev, &init_attr->cap, hr_qp); |
| 1025 | if (ret) | 1098 | if (ret) |
| 1026 | ibdev_err(ibdev, | 1099 | ibdev_err(ibdev, |
| @@ -566,21 +566,37 @@ static void irdma_set_mw_bind_wqe_gen_1(__le64 *wqe, · 565 unmodified lines | |||
| 566 | 566 | ||
| 567 | /** | 567 | /** |
| 568 | * irdma_copy_inline_data_gen_1 - Copy inline data to wqe | 568 | * irdma_copy_inline_data_gen_1 - Copy inline data to wqe |
| 569 | * @dest: pointer to wqe | 569 | * @wqe: pointer to wqe |
| 570 | * @src: pointer to inline data | 570 | * @sge_list: table of pointers to inline data |
| 571 | * @len: length of inline data to copy | 571 | * @num_sges: Total inline data length |
| 572 | * @polarity: compatibility parameter | 572 | * @polarity: compatibility parameter |
| 573 | */ | 573 | */ |
| 574 | static void irdma_copy_inline_data_gen_1(u8 *dest, u8 *src, u32 len, | 574 | static void irdma_copy_inline_data_gen_1(u8 *wqe, struct ib_sge *sge_list, |
| 575 | u8 polarity) | 575 | u32 num_sges, u8 polarity) |
| 576 | { | 576 | { |
| 577 | if (len <= 16) { | 577 | u32 quanta_bytes_remaining = 16; |
| 578 | memcpy(dest, src, len); | 578 | int i; |
| 579 | } else { | 579 | |
| 580 | memcpy(dest, src, 16); | 580 | for (i = 0; i < num_sges; i++) { |
| 581 | src += 16; | 581 | u8 *cur_sge = (u8 *)(uintptr_t)sge_list[i].addr; |
| 582 | dest = dest + 32; | 582 | u32 sge_len = sge_list[i].length; |
| 583 | memcpy(dest, src, len - 16); | 583 | |
| 584 | while (sge_len) { | ||
| 585 | u32 bytes_copied; | ||
| 586 | |||
| 587 | bytes_copied = min(sge_len, quanta_bytes_remaining); | ||
| 588 | memcpy(wqe, cur_sge, bytes_copied); | ||
| 589 | wqe += bytes_copied; | ||
| 590 | cur_sge += bytes_copied; | ||
| 591 | quanta_bytes_remaining -= bytes_copied; | ||
| 592 | sge_len -= bytes_copied; | ||
| 593 | |||
| 594 | if (!quanta_bytes_remaining) { | ||
| 595 | /* Remaining inline bytes reside after hdr */ | ||
| 596 | wqe += 16; | ||
| 597 | quanta_bytes_remaining = 32; | ||
| 598 | } | ||
| 599 | } | ||
| 584 | } | 600 | } |
| 585 | } | 601 | } |
| 586 | 602 | ||
| @@ -612,35 +628,51 @@ static void irdma_set_mw_bind_wqe(__le64 *wqe, · 25 unmodified lines | |||
| 612 | 628 | ||
| 613 | /** | 629 | /** |
| 614 | * irdma_copy_inline_data - Copy inline data to wqe | 630 | * irdma_copy_inline_data - Copy inline data to wqe |
| 615 | * @dest: pointer to wqe | 631 | * @wqe: pointer to wqe |
| 616 | * @src: pointer to inline data | 632 | * @sge_list: table of pointers to inline data |
| 617 | * @len: length of inline data to copy | 633 | * @num_sges: number of SGE's |
| 618 | * @polarity: polarity of wqe valid bit | 634 | * @polarity: polarity of wqe valid bit |
| 619 | */ | 635 | */ |
| 620 | static void irdma_copy_inline_data(u8 *dest, u8 *src, u32 len, u8 polarity) | 636 | static void irdma_copy_inline_data(u8 *wqe, struct ib_sge *sge_list, |
| 637 | u32 num_sges, u8 polarity) | ||
| 621 | { | 638 | { |
| 622 | u8 inline_valid = polarity << IRDMA_INLINE_VALID_S; | 639 | u8 inline_valid = polarity << IRDMA_INLINE_VALID_S; |
| 623 | u32 copy_size; | 640 | u32 quanta_bytes_remaining = 8; |
| 624 | 641 | bool first_quanta = true; | |
| 625 | dest += 8; | 642 | int i; |
| 626 | if (len <= 8) { | 643 | |
| 627 | memcpy(dest, src, len); | 644 | wqe += 8; |
| 628 | return; | 645 | |
| 629 | } | 646 | for (i = 0; i < num_sges; i++) { |
| 630 | 647 | u8 *cur_sge = (u8 *)(uintptr_t)sge_list[i].addr; | |
| 631 | *((u64 *)dest) = *((u64 *)src); | 648 | u32 sge_len = sge_list[i].length; |
| 632 | len -= 8; | 649 | |
| 633 | src += 8; | 650 | while (sge_len) { |
| 634 | dest += 24; /* point to additional 32 byte quanta */ | 651 | u32 bytes_copied; |
| 635 | 652 | ||
| 636 | while (len) { | 653 | bytes_copied = min(sge_len, quanta_bytes_remaining); |
| 637 | copy_size = len < 31 ? len : 31; | 654 | memcpy(wqe, cur_sge, bytes_copied); |
| 638 | memcpy(dest, src, copy_size); | 655 | wqe += bytes_copied; |
| 639 | *(dest + 31) = inline_valid; | 656 | cur_sge += bytes_copied; |
| 640 | len -= copy_size; | 657 | quanta_bytes_remaining -= bytes_copied; |
| 641 | dest += 32; | 658 | sge_len -= bytes_copied; |
| 642 | src += copy_size; | 659 | |
| 660 | if (!quanta_bytes_remaining) { | ||
| 661 | quanta_bytes_remaining = 31; | ||
| 662 | |||
| 663 | /* Remaining inline bytes reside after hdr */ | ||
| 664 | if (first_quanta) { | ||
| 665 | first_quanta = false; | ||
| 666 | wqe += 16; | ||
| 667 | } else { | ||
| 668 | *wqe = inline_valid; | ||
| 669 | wqe++; | ||
| 670 | } | ||
| 671 | } | ||
| 672 | } | ||
| 643 | } | 673 | } |
| 674 | if (!first_quanta && quanta_bytes_remaining < 31) | ||
| 675 | *(wqe + quanta_bytes_remaining) = inline_valid; | ||
| 644 | } | 676 | } |
| 645 | 677 | ||
| 646 | /** | 678 | /** |
| @@ -679,20 +711,27 @@ int irdma_uk_inline_rdma_write(struct irdma_qp_uk *qp, · 32 unmodified lines | |||
| 679 | struct irdma_post_sq_info *info, bool post_sq) | 711 | struct irdma_post_sq_info *info, bool post_sq) |
| 680 | { | 712 | { |
| 681 | __le64 *wqe; | 713 | __le64 *wqe; |
| 682 | struct irdma_inline_rdma_write *op_info; | 714 | struct irdma_rdma_write *op_info; |
| 683 | u64 hdr = 0; | 715 | u64 hdr = 0; |
| 684 | u32 wqe_idx; | 716 | u32 wqe_idx; |
| 685 | bool read_fence = false; | 717 | bool read_fence = false; |
| 718 | u32 i, total_size = 0; | ||
| 686 | u16 quanta; | 719 | u16 quanta; |
| 687 | 720 | ||
| 688 | info->push_wqe = qp->push_db ? true : false; | 721 | info->push_wqe = qp->push_db ? true : false; |
| 689 | op_info = &info->op.inline_rdma_write; | 722 | op_info = &info->op.rdma_write; |
| 723 | |||
| 724 | if (unlikely(qp->max_sq_frag_cnt < op_info->num_lo_sges)) | ||
| 725 | return -EINVAL; | ||
| 726 | |||
| 727 | for (i = 0; i < op_info->num_lo_sges; i++) | ||
| 728 | total_size += op_info->lo_sg_list[i].length; | ||
| 690 | 729 | ||
| 691 | if (op_info->len > qp->max_inline_data) | 730 | if (unlikely(total_size > qp->max_inline_data)) |
| 692 | return -EINVAL; | 731 | return -EINVAL; |
| 693 | 732 | ||
| 694 | quanta = qp->wqe_ops.iw_inline_data_size_to_quanta(op_info->len); | 733 | quanta = qp->wqe_ops.iw_inline_data_size_to_quanta(total_size); |
| 695 | wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, quanta, op_info->len, | 734 | wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, quanta, total_size, |
| 696 | info); | 735 | info); |
| 697 | if (!wqe) | 736 | if (!wqe) |
| 698 | return -ENOMEM; | 737 | return -ENOMEM; |
| @@ -705,7 +744,7 @@ int irdma_uk_inline_rdma_write(struct irdma_qp_uk *qp, · 6 unmodified lines | |||
| 705 | 744 | ||
| 706 | hdr = FIELD_PREP(IRDMAQPSQ_REMSTAG, op_info->rem_addr.lkey) | | 745 | hdr = FIELD_PREP(IRDMAQPSQ_REMSTAG, op_info->rem_addr.lkey) | |
| 707 | FIELD_PREP(IRDMAQPSQ_OPCODE, info->op_type) | | 746 | FIELD_PREP(IRDMAQPSQ_OPCODE, info->op_type) | |
| 708 | FIELD_PREP(IRDMAQPSQ_INLINEDATALEN, op_info->len) | | 747 | FIELD_PREP(IRDMAQPSQ_INLINEDATALEN, total_size) | |
| 709 | FIELD_PREP(IRDMAQPSQ_REPORTRTT, info->report_rtt ? 1 : 0) | | 748 | FIELD_PREP(IRDMAQPSQ_REPORTRTT, info->report_rtt ? 1 : 0) | |
| 710 | FIELD_PREP(IRDMAQPSQ_INLINEDATAFLAG, 1) | | 749 | FIELD_PREP(IRDMAQPSQ_INLINEDATAFLAG, 1) | |
| 711 | FIELD_PREP(IRDMAQPSQ_IMMDATAFLAG, info->imm_data_valid ? 1 : 0) | | 750 | FIELD_PREP(IRDMAQPSQ_IMMDATAFLAG, info->imm_data_valid ? 1 : 0) | |
| @@ -719,7 +758,8 @@ int irdma_uk_inline_rdma_write(struct irdma_qp_uk *qp, · 7 unmodified lines | |||
| 719 | set_64bit_val(wqe, 0, | 758 | set_64bit_val(wqe, 0, |
| 720 | FIELD_PREP(IRDMAQPSQ_IMMDATA, info->imm_data)); | 759 | FIELD_PREP(IRDMAQPSQ_IMMDATA, info->imm_data)); |
| 721 | 760 | ||
| 722 | qp->wqe_ops.iw_copy_inline_data((u8 *)wqe, op_info->data, op_info->len, | 761 | qp->wqe_ops.iw_copy_inline_data((u8 *)wqe, op_info->lo_sg_list, |
| 762 | op_info->num_lo_sges, | ||
| 723 | qp->swqe_polarity); | 763 | qp->swqe_polarity); |
| 724 | dma_wmb(); /* make sure WQE is populated before valid bit is set */ | 764 | dma_wmb(); /* make sure WQE is populated before valid bit is set */ |
| 725 | 765 | ||
| @@ -745,20 +785,27 @@ int irdma_uk_inline_send(struct irdma_qp_uk *qp, · 19 unmodified lines | |||
| 745 | struct irdma_post_sq_info *info, bool post_sq) | 785 | struct irdma_post_sq_info *info, bool post_sq) |
| 746 | { | 786 | { |
| 747 | __le64 *wqe; | 787 | __le64 *wqe; |
| 748 | struct irdma_post_inline_send *op_info; | 788 | struct irdma_post_send *op_info; |
| 749 | u64 hdr; | 789 | u64 hdr; |
| 750 | u32 wqe_idx; | 790 | u32 wqe_idx; |
| 751 | bool read_fence = false; | 791 | bool read_fence = false; |
| 792 | u32 i, total_size = 0; | ||
| 752 | u16 quanta; | 793 | u16 quanta; |
| 753 | 794 | ||
| 754 | info->push_wqe = qp->push_db ? true : false; | 795 | info->push_wqe = qp->push_db ? true : false; |
| 755 | op_info = &info->op.inline_send; | 796 | op_info = &info->op.send; |
| 797 | |||
| 798 | if (unlikely(qp->max_sq_frag_cnt < op_info->num_sges)) | ||
| 799 | return -EINVAL; | ||
| 756 | 800 | ||
| 757 | if (op_info->len > qp->max_inline_data) | 801 | for (i = 0; i < op_info->num_sges; i++) |
| 802 | total_size += op_info->sg_list[i].length; | ||
| 803 | |||
| 804 | if (unlikely(total_size > qp->max_inline_data)) | ||
| 758 | return -EINVAL; | 805 | return -EINVAL; |
| 759 | 806 | ||
| 760 | quanta = qp->wqe_ops.iw_inline_data_size_to_quanta(op_info->len); | 807 | quanta = qp->wqe_ops.iw_inline_data_size_to_quanta(total_size); |
| 761 | wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, quanta, op_info->len, | 808 | wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, quanta, total_size, |
| 762 | info); | 809 | info); |
| 763 | if (!wqe) | 810 | if (!wqe) |
| 764 | return -ENOMEM; | 811 | return -ENOMEM; |
| @@ -773,7 +820,7 @@ int irdma_uk_inline_send(struct irdma_qp_uk *qp, · 8 unmodified lines | |||
| 773 | hdr = FIELD_PREP(IRDMAQPSQ_REMSTAG, info->stag_to_inv) | | 820 | hdr = FIELD_PREP(IRDMAQPSQ_REMSTAG, info->stag_to_inv) | |
| 774 | FIELD_PREP(IRDMAQPSQ_AHID, op_info->ah_id) | | 821 | FIELD_PREP(IRDMAQPSQ_AHID, op_info->ah_id) | |
| 775 | FIELD_PREP(IRDMAQPSQ_OPCODE, info->op_type) | | 822 | FIELD_PREP(IRDMAQPSQ_OPCODE, info->op_type) | |
| 776 | FIELD_PREP(IRDMAQPSQ_INLINEDATALEN, op_info->len) | | 823 | FIELD_PREP(IRDMAQPSQ_INLINEDATALEN, total_size) | |
| 777 | FIELD_PREP(IRDMAQPSQ_IMMDATAFLAG, | 824 | FIELD_PREP(IRDMAQPSQ_IMMDATAFLAG, |
| 778 | (info->imm_data_valid ? 1 : 0)) | | 825 | (info->imm_data_valid ? 1 : 0)) | |
| 779 | FIELD_PREP(IRDMAQPSQ_REPORTRTT, (info->report_rtt ? 1 : 0)) | | 826 | FIELD_PREP(IRDMAQPSQ_REPORTRTT, (info->report_rtt ? 1 : 0)) | |
| @@ -789,8 +836,8 @@ int irdma_uk_inline_send(struct irdma_qp_uk *qp, · 9 unmodified lines | |||
| 789 | if (info->imm_data_valid) | 836 | if (info->imm_data_valid) |
| 790 | set_64bit_val(wqe, 0, | 837 | set_64bit_val(wqe, 0, |
| 791 | FIELD_PREP(IRDMAQPSQ_IMMDATA, info->imm_data)); | 838 | FIELD_PREP(IRDMAQPSQ_IMMDATA, info->imm_data)); |
| 792 | qp->wqe_ops.iw_copy_inline_data((u8 *)wqe, op_info->data, op_info->len, | 839 | qp->wqe_ops.iw_copy_inline_data((u8 *)wqe, op_info->sg_list, |
| 793 | qp->swqe_polarity); | 840 | op_info->num_sges, qp->swqe_polarity); |
| 794 | 841 | ||
| 795 | dma_wmb(); /* make sure WQE is populated before valid bit is set */ | 842 | dma_wmb(); /* make sure WQE is populated before valid bit is set */ |
| 796 | 843 | ||
| @@ -1002,11 +1049,10 @@ int irdma_uk_cq_poll_cmpl(struct irdma_cq_uk *cq, · 205 unmodified lines | |||
| 1002 | __le64 *cqe; | 1049 | __le64 *cqe; |
| 1003 | struct irdma_qp_uk *qp; | 1050 | struct irdma_qp_uk *qp; |
| 1004 | struct irdma_ring *pring = NULL; | 1051 | struct irdma_ring *pring = NULL; |
| 1005 | u32 wqe_idx, q_type; | 1052 | u32 wqe_idx; |
| 1006 | int ret_code; | 1053 | int ret_code; |
| 1007 | bool move_cq_head = true; | 1054 | bool move_cq_head = true; |
| 1008 | u8 polarity; | 1055 | u8 polarity; |
| 1009 | u8 op_type; | ||
| 1010 | bool ext_valid; | 1056 | bool ext_valid; |
| 1011 | __le64 *ext_cqe; | 1057 | __le64 *ext_cqe; |
| 1012 | 1058 | ||
| @@ -1074,7 +1120,7 @@ int irdma_uk_cq_poll_cmpl(struct irdma_cq_uk *cq, · 61 unmodified lines | |||
| 1074 | info->ud_vlan_valid = false; | 1120 | info->ud_vlan_valid = false; |
| 1075 | } | 1121 | } |
| 1076 | 1122 | ||
| 1077 | q_type = (u8)FIELD_GET(IRDMA_CQ_SQ, qword3); | 1123 | info->q_type = (u8)FIELD_GET(IRDMA_CQ_SQ, qword3); |
| 1078 | info->error = (bool)FIELD_GET(IRDMA_CQ_ERROR, qword3); | 1124 | info->error = (bool)FIELD_GET(IRDMA_CQ_ERROR, qword3); |
| 1079 | info->push_dropped = (bool)FIELD_GET(IRDMACQ_PSHDROP, qword3); | 1125 | info->push_dropped = (bool)FIELD_GET(IRDMACQ_PSHDROP, qword3); |
| 1080 | info->ipv4 = (bool)FIELD_GET(IRDMACQ_IPV4, qword3); | 1126 | info->ipv4 = (bool)FIELD_GET(IRDMACQ_IPV4, qword3); |
| @@ -1113,8 +1159,9 @@ int irdma_uk_cq_poll_cmpl(struct irdma_cq_uk *cq, · 32 unmodified lines | |||
| 1113 | } | 1159 | } |
| 1114 | wqe_idx = (u32)FIELD_GET(IRDMA_CQ_WQEIDX, qword3); | 1160 | wqe_idx = (u32)FIELD_GET(IRDMA_CQ_WQEIDX, qword3); |
| 1115 | info->qp_handle = (irdma_qp_handle)(unsigned long)qp; | 1161 | info->qp_handle = (irdma_qp_handle)(unsigned long)qp; |
| 1162 | info->op_type = (u8)FIELD_GET(IRDMA_CQ_SQ, qword3); | ||
| 1116 | 1163 | ||
| 1117 | if (q_type == IRDMA_CQE_QTYPE_RQ) { | 1164 | if (info->q_type == IRDMA_CQE_QTYPE_RQ) { |
| 1118 | u32 array_idx; | 1165 | u32 array_idx; |
| 1119 | 1166 | ||
| 1120 | array_idx = wqe_idx / qp->rq_wqe_size_multiplier; | 1167 | array_idx = wqe_idx / qp->rq_wqe_size_multiplier; |
| @@ -1134,10 +1181,6 @@ int irdma_uk_cq_poll_cmpl(struct irdma_cq_uk *cq, · 13 unmodified lines | |||
| 1134 | 1181 | ||
| 1135 | info->bytes_xfered = (u32)FIELD_GET(IRDMACQ_PAYLDLEN, qword0); | 1182 | info->bytes_xfered = (u32)FIELD_GET(IRDMACQ_PAYLDLEN, qword0); |
| 1136 | 1183 | ||
| 1137 | if (info->imm_valid) | ||
| 1138 | info->op_type = IRDMA_OP_TYPE_REC_IMM; | ||
| 1139 | else | ||
| 1140 | info->op_type = IRDMA_OP_TYPE_REC; | ||
| 1141 | if (qword3 & IRDMACQ_STAG) { | 1184 | if (qword3 & IRDMACQ_STAG) { |
| 1142 | info->stag_invalid_set = true; | 1185 | info->stag_invalid_set = true; |
| 1143 | info->inv_stag = (u32)FIELD_GET(IRDMACQ_INVSTAG, qword2); | 1186 | info->inv_stag = (u32)FIELD_GET(IRDMACQ_INVSTAG, qword2); |
| @@ -1195,17 +1238,18 @@ int irdma_uk_cq_poll_cmpl(struct irdma_cq_uk *cq, · 51 unmodified lines | |||
| 1195 | sw_wqe = qp->sq_base[tail].elem; | 1238 | sw_wqe = qp->sq_base[tail].elem; |
| 1196 | get_64bit_val(sw_wqe, 24, | 1239 | get_64bit_val(sw_wqe, 24, |
| 1197 | &wqe_qword); | 1240 | &wqe_qword); |
| 1198 | op_type = (u8)FIELD_GET(IRDMAQPSQ_OPCODE, wqe_qword); | 1241 | info->op_type = (u8)FIELD_GET(IRDMAQPSQ_OPCODE, |
| 1199 | info->op_type = op_type; | 1242 | wqe_qword); |
| 1200 | IRDMA_RING_SET_TAIL(qp->sq_ring, | 1243 | IRDMA_RING_SET_TAIL(qp->sq_ring, |
| 1201 | tail + qp->sq_wrtrk_array[tail].quanta); | 1244 | tail + qp->sq_wrtrk_array[tail].quanta); |
| 1202 | if (op_type != IRDMAQP_OP_NOP) { | 1245 | if (info->op_type != IRDMAQP_OP_NOP) { |
| 1203 | info->wr_id = qp->sq_wrtrk_array[tail].wrid; | 1246 | info->wr_id = qp->sq_wrtrk_array[tail].wrid; |
| 1204 | info->bytes_xfered = qp->sq_wrtrk_array[tail].wr_len; | 1247 | info->bytes_xfered = qp->sq_wrtrk_array[tail].wr_len; |
| 1205 | break; | 1248 | break; |
| 1206 | } | 1249 | } |
| 1207 | } while (1); | 1250 | } while (1); |
| 1208 | if (op_type == IRDMA_OP_TYPE_BIND_MW && info->minor_err == FLUSH_PROT_ERR) | 1251 | if (info->op_type == IRDMA_OP_TYPE_BIND_MW && |
| 1252 | info->minor_err == FLUSH_PROT_ERR) | ||
| 1209 | info->minor_err = FLUSH_MW_BIND_ERR; | 1253 | info->minor_err = FLUSH_MW_BIND_ERR; |
| 1210 | qp->sq_flush_seen = true; | 1254 | qp->sq_flush_seen = true; |
| 1211 | if (!IRDMA_RING_MORE_WORK(qp->sq_ring)) | 1255 | if (!IRDMA_RING_MORE_WORK(qp->sq_ring)) |
| @@ -173,14 +173,6 @@ struct irdma_post_send { · 172 unmodified lines | |||
| 173 | u32 ah_id; | 173 | u32 ah_id; |
| 174 | }; | 174 | }; |
| 175 | 175 | ||
| 176 | struct irdma_post_inline_send { | ||
| 177 | void *data; | ||
| 178 | u32 len; | ||
| 179 | u32 qkey; | ||
| 180 | u32 dest_qp; | ||
| 181 | u32 ah_id; | ||
| 182 | }; | ||
| 183 | |||
| 184 | struct irdma_post_rq_info { | 176 | struct irdma_post_rq_info { |
| 185 | u64 wr_id; | 177 | u64 wr_id; |
| 186 | struct ib_sge *sg_list; | 178 | struct ib_sge *sg_list; |
| @@ -193,12 +185,6 @@ struct irdma_rdma_write { · 6 unmodified lines | |||
| 193 | struct ib_sge rem_addr; | 185 | struct ib_sge rem_addr; |
| 194 | }; | 186 | }; |
| 195 | 187 | ||
| 196 | struct irdma_inline_rdma_write { | ||
| 197 | void *data; | ||
| 198 | u32 len; | ||
| 199 | struct ib_sge rem_addr; | ||
| 200 | }; | ||
| 201 | |||
| 202 | struct irdma_rdma_read { | 188 | struct irdma_rdma_read { |
| 203 | struct ib_sge *lo_sg_list; | 189 | struct ib_sge *lo_sg_list; |
| 204 | u32 num_lo_sges; | 190 | u32 num_lo_sges; |
| @@ -241,8 +227,6 @@ struct irdma_post_sq_info { · 36 unmodified lines | |||
| 241 | struct irdma_rdma_read rdma_read; | 227 | struct irdma_rdma_read rdma_read; |
| 242 | struct irdma_bind_window bind_window; | 228 | struct irdma_bind_window bind_window; |
| 243 | struct irdma_inv_local_stag inv_local_stag; | 229 | struct irdma_inv_local_stag inv_local_stag; |
| 244 | struct irdma_inline_rdma_write inline_rdma_write; | ||
| 245 | struct irdma_post_inline_send inline_send; | ||
| 246 | } op; | 230 | } op; |
| 247 | }; | 231 | }; |
| 248 | 232 | ||
| @@ -261,6 +245,7 @@ struct irdma_cq_poll_info { · 12 unmodified lines | |||
| 261 | u16 ud_vlan; | 245 | u16 ud_vlan; |
| 262 | u8 ud_smac[6]; | 246 | u8 ud_smac[6]; |
| 263 | u8 op_type; | 247 | u8 op_type; |
| 248 | u8 q_type; | ||
| 264 | bool stag_invalid_set:1; /* or L_R_Key set */ | 249 | bool stag_invalid_set:1; /* or L_R_Key set */ |
| 265 | bool push_dropped:1; | 250 | bool push_dropped:1; |
| 266 | bool error:1; | 251 | bool error:1; |
| @@ -291,7 +276,8 @@ int irdma_uk_stag_local_invalidate(struct irdma_qp_uk *qp, · 24 unmodified lines | |||
| 291 | bool post_sq); | 276 | bool post_sq); |
| 292 | 277 | ||
| 293 | struct irdma_wqe_uk_ops { | 278 | struct irdma_wqe_uk_ops { |
| 294 | void (*iw_copy_inline_data)(u8 *dest, u8 *src, u32 len, u8 polarity); | 279 | void (*iw_copy_inline_data)(u8 *dest, struct ib_sge *sge_list, |
| 280 | u32 num_sges, u8 polarity); | ||
| 295 | u16 (*iw_inline_data_size_to_quanta)(u32 data_size); | 281 | u16 (*iw_inline_data_size_to_quanta)(u32 data_size); |
| 296 | void (*iw_set_fragment)(__le64 *wqe, u32 offset, struct ib_sge *sge, | 282 | void (*iw_set_fragment)(__le64 *wqe, u32 offset, struct ib_sge *sge, |
| 297 | u8 valid); | 283 | u8 valid); |
| @@ -2591,6 +2591,7 @@ void irdma_generate_flush_completions(struct irdma_qp *iwqp) · 2590 unmodified lines | |||
| 2591 | sw_wqe = qp->sq_base[wqe_idx].elem; | 2591 | sw_wqe = qp->sq_base[wqe_idx].elem; |
| 2592 | get_64bit_val(sw_wqe, 24, &wqe_qword); | 2592 | get_64bit_val(sw_wqe, 24, &wqe_qword); |
| 2593 | cmpl->cpi.op_type = (u8)FIELD_GET(IRDMAQPSQ_OPCODE, IRDMAQPSQ_OPCODE); | 2593 | cmpl->cpi.op_type = (u8)FIELD_GET(IRDMAQPSQ_OPCODE, IRDMAQPSQ_OPCODE); |
| 2594 | cmpl->cpi.q_type = IRDMA_CQE_QTYPE_SQ; | ||
| 2594 | /* remove the SQ WR by moving SQ tail*/ | 2595 | /* remove the SQ WR by moving SQ tail*/ |
| 2595 | IRDMA_RING_SET_TAIL(*sq_ring, | 2596 | IRDMA_RING_SET_TAIL(*sq_ring, |
| 2596 | sq_ring->tail + qp->sq_wrtrk_array[sq_ring->tail].quanta); | 2597 | sq_ring->tail + qp->sq_wrtrk_array[sq_ring->tail].quanta); |
| @@ -2629,6 +2630,7 @@ void irdma_generate_flush_completions(struct irdma_qp *iwqp) · 32 unmodified lines | |||
| 2629 | 2630 | ||
| 2630 | cmpl->cpi.wr_id = qp->rq_wrid_array[wqe_idx]; | 2631 | cmpl->cpi.wr_id = qp->rq_wrid_array[wqe_idx]; |
| 2631 | cmpl->cpi.op_type = IRDMA_OP_TYPE_REC; | 2632 | cmpl->cpi.op_type = IRDMA_OP_TYPE_REC; |
| 2633 | cmpl->cpi.q_type = IRDMA_CQE_QTYPE_RQ; | ||
| 2632 | /* remove the RQ WR by moving RQ tail */ | 2634 | /* remove the RQ WR by moving RQ tail */ |
| 2633 | IRDMA_RING_SET_TAIL(*rq_ring, rq_ring->tail + 1); | 2635 | IRDMA_RING_SET_TAIL(*rq_ring, rq_ring->tail + 1); |
| 2634 | ibdev_dbg(iwqp->iwrcq->ibcq.device, | 2636 | ibdev_dbg(iwqp->iwrcq->ibcq.device, |
| @@ -63,36 +63,6 @@ static int irdma_query_device(struct ib_device *ibdev, · 62 unmodified lines | |||
| 63 | return 0; | 63 | return 0; |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | /** | ||
| 67 | * irdma_get_eth_speed_and_width - Get IB port speed and width from netdev speed | ||
| 68 | * @link_speed: netdev phy link speed | ||
| 69 | * @active_speed: IB port speed | ||
| 70 | * @active_width: IB port width | ||
| 71 | */ | ||
| 72 | static void irdma_get_eth_speed_and_width(u32 link_speed, u16 *active_speed, | ||
| 73 | u8 *active_width) | ||
| 74 | { | ||
| 75 | if (link_speed <= SPEED_1000) { | ||
| 76 | *active_width = IB_WIDTH_1X; | ||
| 77 | *active_speed = IB_SPEED_SDR; | ||
| 78 | } else if (link_speed <= SPEED_10000) { | ||
| 79 | *active_width = IB_WIDTH_1X; | ||
| 80 | *active_speed = IB_SPEED_FDR10; | ||
| 81 | } else if (link_speed <= SPEED_20000) { | ||
| 82 | *active_width = IB_WIDTH_4X; | ||
| 83 | *active_speed = IB_SPEED_DDR; | ||
| 84 | } else if (link_speed <= SPEED_25000) { | ||
| 85 | *active_width = IB_WIDTH_1X; | ||
| 86 | *active_speed = IB_SPEED_EDR; | ||
| 87 | } else if (link_speed <= SPEED_40000) { | ||
| 88 | *active_width = IB_WIDTH_4X; | ||
| 89 | *active_speed = IB_SPEED_FDR10; | ||
| 90 | } else { | ||
| 91 | *active_width = IB_WIDTH_4X; | ||
| 92 | *active_speed = IB_SPEED_EDR; | ||
| 93 | } | ||
| 94 | } | ||
| 95 | |||
| 96 | /** | 66 | /** |
| 97 | * irdma_query_port - get port attributes | 67 | * irdma_query_port - get port attributes |
| 98 | * @ibdev: device pointer from stack | 68 | * @ibdev: device pointer from stack |
| @@ -120,8 +90,9 @@ static int irdma_query_port(struct ib_device *ibdev, u32 port, · 21 unmodified lines | |||
| 120 | props->state = IB_PORT_DOWN; | 90 | props->state = IB_PORT_DOWN; |
| 121 | props->phys_state = IB_PORT_PHYS_STATE_DISABLED; | 91 | props->phys_state = IB_PORT_PHYS_STATE_DISABLED; |
| 122 | } | 92 | } |
| 123 | irdma_get_eth_speed_and_width(SPEED_100000, &props->active_speed, | 93 | |
| 124 | &props->active_width); | 94 | ib_get_eth_speed(ibdev, port, &props->active_speed, |
| 95 | &props->active_width); | ||
| 125 | 96 | ||
| 126 | if (rdma_protocol_roce(ibdev, 1)) { | 97 | if (rdma_protocol_roce(ibdev, 1)) { |
| 127 | props->gid_tbl_len = 32; | 98 | props->gid_tbl_len = 32; |
| @@ -1242,6 +1213,7 @@ int irdma_modify_qp_roce(struct ib_qp *ibqp, struct ib_qp_attr *attr, · 1114 unmodified lines | |||
| 1242 | av->attrs = attr->ah_attr; | 1213 | av->attrs = attr->ah_attr; |
| 1243 | rdma_gid2ip((struct sockaddr *)&av->sgid_addr, &sgid_attr->gid); | 1214 | rdma_gid2ip((struct sockaddr *)&av->sgid_addr, &sgid_attr->gid); |
| 1244 | rdma_gid2ip((struct sockaddr *)&av->dgid_addr, &attr->ah_attr.grh.dgid); | 1215 | rdma_gid2ip((struct sockaddr *)&av->dgid_addr, &attr->ah_attr.grh.dgid); |
| 1216 | av->net_type = rdma_gid_attr_network_type(sgid_attr); | ||
| 1245 | if (av->net_type == RDMA_NETWORK_IPV6) { | 1217 | if (av->net_type == RDMA_NETWORK_IPV6) { |
| 1246 | __be32 *daddr = | 1218 | __be32 *daddr = |
| 1247 | av->dgid_addr.saddr_in6.sin6_addr.in6_u.u6_addr32; | 1219 | av->dgid_addr.saddr_in6.sin6_addr.in6_u.u6_addr32; |
| @@ -2358,9 +2330,10 @@ static bool irdma_check_mr_contiguous(struct irdma_pble_alloc *palloc, · 1110 unmodified lines | |||
| 2358 | * @rf: RDMA PCI function | 2330 | * @rf: RDMA PCI function |
| 2359 | * @iwmr: mr pointer for this memory registration | 2331 | * @iwmr: mr pointer for this memory registration |
| 2360 | * @use_pbles: flag if to use pble's | 2332 | * @use_pbles: flag if to use pble's |
| 2333 | * @lvl_1_only: request only level 1 pble if true | ||
| 2361 | */ | 2334 | */ |
| 2362 | static int irdma_setup_pbles(struct irdma_pci_f *rf, struct irdma_mr *iwmr, | 2335 | static int irdma_setup_pbles(struct irdma_pci_f *rf, struct irdma_mr *iwmr, |
| 2363 | bool use_pbles) | 2336 | bool use_pbles, bool lvl_1_only) |
| 2364 | { | 2337 | { |
| 2365 | struct irdma_pbl *iwpbl = &iwmr->iwpbl; | 2338 | struct irdma_pbl *iwpbl = &iwmr->iwpbl; |
| 2366 | struct irdma_pble_alloc *palloc = &iwpbl->pble_alloc; | 2339 | struct irdma_pble_alloc *palloc = &iwpbl->pble_alloc; |
| @@ -2371,7 +2344,7 @@ static int irdma_setup_pbles(struct irdma_pci_f *rf, struct irdma_mr *iwmr, · 4 unmodified lines | |||
| 2371 | 2344 | ||
| 2372 | if (use_pbles) { | 2345 | if (use_pbles) { |
| 2373 | status = irdma_get_pble(rf->pble_rsrc, palloc, iwmr->page_cnt, | 2346 | status = irdma_get_pble(rf->pble_rsrc, palloc, iwmr->page_cnt, |
| 2374 | false); | 2347 | lvl_1_only); |
| 2375 | if (status) | 2348 | if (status) |
| 2376 | return status; | 2349 | return status; |
| 2377 | 2350 | ||
| @@ -2414,16 +2387,10 @@ static int irdma_handle_q_mem(struct irdma_device *iwdev, · 36 unmodified lines | |||
| 2414 | bool ret = true; | 2387 | bool ret = true; |
| 2415 | 2388 | ||
| 2416 | pg_size = iwmr->page_size; | 2389 | pg_size = iwmr->page_size; |
| 2417 | err = irdma_setup_pbles(iwdev->rf, iwmr, use_pbles); | 2390 | err = irdma_setup_pbles(iwdev->rf, iwmr, use_pbles, true); |
| 2418 | if (err) | 2391 | if (err) |
| 2419 | return err; | 2392 | return err; |
| 2420 | 2393 | ||
| 2421 | if (use_pbles && palloc->level != PBLE_LEVEL_1) { | ||
| 2422 | irdma_free_pble(iwdev->rf->pble_rsrc, palloc); | ||
| 2423 | iwpbl->pbl_allocated = false; | ||
| 2424 | return -ENOMEM; | ||
| 2425 | } | ||
| 2426 | |||
| 2427 | if (use_pbles) | 2394 | if (use_pbles) |
| 2428 | arr = palloc->level1.addr; | 2395 | arr = palloc->level1.addr; |
| 2429 | 2396 | ||
| @@ -2899,7 +2866,7 @@ static struct ib_mr *irdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 len, · 469 unmodified lines | |||
| 2899 | case IRDMA_MEMREG_TYPE_MEM: | 2866 | case IRDMA_MEMREG_TYPE_MEM: |
| 2900 | use_pbles = (iwmr->page_cnt != 1); | 2867 | use_pbles = (iwmr->page_cnt != 1); |
| 2901 | 2868 | ||
| 2902 | err = irdma_setup_pbles(iwdev->rf, iwmr, use_pbles); | 2869 | err = irdma_setup_pbles(iwdev->rf, iwmr, use_pbles, false); |
| 2903 | if (err) | 2870 | if (err) |
| 2904 | goto error; | 2871 | goto error; |
| 2905 | 2872 | ||
| @@ -3165,30 +3132,20 @@ static int irdma_post_send(struct ib_qp *ibqp, · 259 unmodified lines | |||
| 3165 | info.stag_to_inv = ib_wr->ex.invalidate_rkey; | 3132 | info.stag_to_inv = ib_wr->ex.invalidate_rkey; |
| 3166 | } | 3133 | } |
| 3167 | 3134 | ||
| 3168 | if (ib_wr->send_flags & IB_SEND_INLINE) { | 3135 | info.op.send.num_sges = ib_wr->num_sge; |
| 3169 | info.op.inline_send.data = (void *)(unsigned long) | 3136 | info.op.send.sg_list = ib_wr->sg_list; |
| 3170 | ib_wr->sg_list[0].addr; | 3137 | if (iwqp->ibqp.qp_type == IB_QPT_UD || |
| 3171 | info.op.inline_send.len = ib_wr->sg_list[0].length; | 3138 | iwqp->ibqp.qp_type == IB_QPT_GSI) { |
| 3172 | if (iwqp->ibqp.qp_type == IB_QPT_UD || | 3139 | ah = to_iwah(ud_wr(ib_wr)->ah); |
| 3173 | iwqp->ibqp.qp_type == IB_QPT_GSI) { | 3140 | info.op.send.ah_id = ah->sc_ah.ah_info.ah_idx; |
| 3174 | ah = to_iwah(ud_wr(ib_wr)->ah); | 3141 | info.op.send.qkey = ud_wr(ib_wr)->remote_qkey; |
| 3175 | info.op.inline_send.ah_id = ah->sc_ah.ah_info.ah_idx; | 3142 | info.op.send.dest_qp = ud_wr(ib_wr)->remote_qpn; |
| 3176 | info.op.inline_send.qkey = ud_wr(ib_wr)->remote_qkey; | 3143 | } |
| 3177 | info.op.inline_send.dest_qp = ud_wr(ib_wr)->remote_qpn; | 3144 | |
| 3178 | } | 3145 | if (ib_wr->send_flags & IB_SEND_INLINE) |
| 3179 | err = irdma_uk_inline_send(ukqp, &info, false); | 3146 | err = irdma_uk_inline_send(ukqp, &info, false); |
| 3180 | } else { | 3147 | else |
| 3181 | info.op.send.num_sges = ib_wr->num_sge; | ||
| 3182 | info.op.send.sg_list = ib_wr->sg_list; | ||
| 3183 | if (iwqp->ibqp.qp_type == IB_QPT_UD || | ||
| 3184 | iwqp->ibqp.qp_type == IB_QPT_GSI) { | ||
| 3185 | ah = to_iwah(ud_wr(ib_wr)->ah); | ||
| 3186 | info.op.send.ah_id = ah->sc_ah.ah_info.ah_idx; | ||
| 3187 | info.op.send.qkey = ud_wr(ib_wr)->remote_qkey; | ||
| 3188 | info.op.send.dest_qp = ud_wr(ib_wr)->remote_qpn; | ||
| 3189 | } | ||
| 3190 | err = irdma_uk_send(ukqp, &info, false); | 3148 | err = irdma_uk_send(ukqp, &info, false); |
| 3191 | } | ||
| 3192 | break; | 3149 | break; |
| 3193 | case IB_WR_RDMA_WRITE_WITH_IMM: | 3150 | case IB_WR_RDMA_WRITE_WITH_IMM: |
| 3194 | if (ukqp->qp_caps & IRDMA_WRITE_WITH_IMM) { | 3151 | if (ukqp->qp_caps & IRDMA_WRITE_WITH_IMM) { |
| @@ -3205,22 +3162,15 @@ static int irdma_post_send(struct ib_qp *ibqp, · 10 unmodified lines | |||
| 3205 | else | 3162 | else |
| 3206 | info.op_type = IRDMA_OP_TYPE_RDMA_WRITE; | 3163 | info.op_type = IRDMA_OP_TYPE_RDMA_WRITE; |
| 3207 | 3164 | ||
| 3208 | if (ib_wr->send_flags & IB_SEND_INLINE) { | 3165 | info.op.rdma_write.num_lo_sges = ib_wr->num_sge; |
| 3209 | info.op.inline_rdma_write.data = (void *)(uintptr_t)ib_wr->sg_list[0].addr; | 3166 | info.op.rdma_write.lo_sg_list = ib_wr->sg_list; |
| 3210 | info.op.inline_rdma_write.len = | 3167 | info.op.rdma_write.rem_addr.addr = |
| 3211 | ib_wr->sg_list[0].length; | 3168 | rdma_wr(ib_wr)->remote_addr; |
| 3212 | info.op.inline_rdma_write.rem_addr.addr = | 3169 | info.op.rdma_write.rem_addr.lkey = rdma_wr(ib_wr)->rkey; |
| 3213 | rdma_wr(ib_wr)->remote_addr; | 3170 | if (ib_wr->send_flags & IB_SEND_INLINE) |
| 3214 | info.op.inline_rdma_write.rem_addr.lkey = | ||
| 3215 | rdma_wr(ib_wr)->rkey; | ||
| 3216 | err = irdma_uk_inline_rdma_write(ukqp, &info, false); | 3171 | err = irdma_uk_inline_rdma_write(ukqp, &info, false); |
| 3217 | } else { | 3172 | else |
| 3218 | info.op.rdma_write.lo_sg_list = (void *)ib_wr->sg_list; | ||
| 3219 | info.op.rdma_write.num_lo_sges = ib_wr->num_sge; | ||
| 3220 | info.op.rdma_write.rem_addr.addr = rdma_wr(ib_wr)->remote_addr; | ||
| 3221 | info.op.rdma_write.rem_addr.lkey = rdma_wr(ib_wr)->rkey; | ||
| 3222 | err = irdma_uk_rdma_write(ukqp, &info, false); | 3173 | err = irdma_uk_rdma_write(ukqp, &info, false); |
| 3223 | } | ||
| 3224 | break; | 3174 | break; |
| 3225 | case IB_WR_RDMA_READ_WITH_INV: | 3175 | case IB_WR_RDMA_READ_WITH_INV: |
| 3226 | inv_stag = true; | 3176 | inv_stag = true; |
| @@ -3380,7 +3330,6 @@ static enum ib_wc_status irdma_flush_err_to_ib_wc_status(enum irdma_flush_opcode · 153 unmodified lines | |||
| 3380 | static void irdma_process_cqe(struct ib_wc *entry, | 3330 | static void irdma_process_cqe(struct ib_wc *entry, |
| 3381 | struct irdma_cq_poll_info *cq_poll_info) | 3331 | struct irdma_cq_poll_info *cq_poll_info) |
| 3382 | { | 3332 | { |
| 3383 | struct irdma_qp *iwqp; | ||
| 3384 | struct irdma_sc_qp *qp; | 3333 | struct irdma_sc_qp *qp; |
| 3385 | 3334 | ||
| 3386 | entry->wc_flags = 0; | 3335 | entry->wc_flags = 0; |
| @@ -3388,7 +3337,6 @@ static void irdma_process_cqe(struct ib_wc *entry, · 1 unmodified line | |||
| 3388 | entry->wr_id = cq_poll_info->wr_id; | 3337 | entry->wr_id = cq_poll_info->wr_id; |
| 3389 | 3338 | ||
| 3390 | qp = cq_poll_info->qp_handle; | 3339 | qp = cq_poll_info->qp_handle; |
| 3391 | iwqp = qp->qp_uk.back_qp; | ||
| 3392 | entry->qp = qp->qp_uk.back_qp; | 3340 | entry->qp = qp->qp_uk.back_qp; |
| 3393 | 3341 | ||
| 3394 | if (cq_poll_info->error) { | 3342 | if (cq_poll_info->error) { |
| @@ -3421,42 +3369,17 @@ static void irdma_process_cqe(struct ib_wc *entry, · 26 unmodified lines | |||
| 3421 | } | 3369 | } |
| 3422 | } | 3370 | } |
| 3423 | 3371 | ||
| 3424 | switch (cq_poll_info->op_type) { | 3372 | if (cq_poll_info->q_type == IRDMA_CQE_QTYPE_SQ) { |
| 3425 | case IRDMA_OP_TYPE_RDMA_WRITE: | 3373 | set_ib_wc_op_sq(cq_poll_info, entry); |
| 3426 | case IRDMA_OP_TYPE_RDMA_WRITE_SOL: | 3374 | } else { |
| 3427 | entry->opcode = IB_WC_RDMA_WRITE; | 3375 | set_ib_wc_op_rq(cq_poll_info, entry, |
| 3428 | break; | 3376 | qp->qp_uk.qp_caps & IRDMA_SEND_WITH_IMM ? |
| 3429 | case IRDMA_OP_TYPE_RDMA_READ_INV_STAG: | 3377 | true : false); |
| 3430 | case IRDMA_OP_TYPE_RDMA_READ: | ||
| 3431 | entry->opcode = IB_WC_RDMA_READ; | ||
| 3432 | break; | ||
| 3433 | case IRDMA_OP_TYPE_SEND_INV: | ||
| 3434 | case IRDMA_OP_TYPE_SEND_SOL: | ||
| 3435 | case IRDMA_OP_TYPE_SEND_SOL_INV: | ||
| 3436 | case IRDMA_OP_TYPE_SEND: | ||
| 3437 | entry->opcode = IB_WC_SEND; | ||
| 3438 | break; | ||
| 3439 | case IRDMA_OP_TYPE_FAST_REG_NSMR: | ||
| 3440 | entry->opcode = IB_WC_REG_MR; | ||
| 3441 | break; | ||
| 3442 | case IRDMA_OP_TYPE_INV_STAG: | ||
| 3443 | entry->opcode = IB_WC_LOCAL_INV; | ||
| 3444 | break; | ||
| 3445 | case IRDMA_OP_TYPE_REC_IMM: | ||
| 3446 | case IRDMA_OP_TYPE_REC: | ||
| 3447 | entry->opcode = cq_poll_info->op_type == IRDMA_OP_TYPE_REC_IMM ? | ||
| 3448 | IB_WC_RECV_RDMA_WITH_IMM : IB_WC_RECV; | ||
| 3449 | if (qp->qp_uk.qp_type != IRDMA_QP_TYPE_ROCE_UD && | 3378 | if (qp->qp_uk.qp_type != IRDMA_QP_TYPE_ROCE_UD && |
| 3450 | cq_poll_info->stag_invalid_set) { | 3379 | cq_poll_info->stag_invalid_set) { |
| 3451 | entry->ex.invalidate_rkey = cq_poll_info->inv_stag; | 3380 | entry->ex.invalidate_rkey = cq_poll_info->inv_stag; |
| 3452 | entry->wc_flags |= IB_WC_WITH_INVALIDATE; | 3381 | entry->wc_flags |= IB_WC_WITH_INVALIDATE; |
| 3453 | } | 3382 | } |
| 3454 | break; | ||
| 3455 | default: | ||
| 3456 | ibdev_err(&iwqp->iwdev->ibdev, | ||
| 3457 | "Invalid opcode = %d in CQE\n", cq_poll_info->op_type); | ||
| 3458 | entry->status = IB_WC_GENERAL_ERR; | ||
| 3459 | return; | ||
| 3460 | } | 3383 | } |
| 3461 | 3384 | ||
| 3462 | if (qp->qp_uk.qp_type == IRDMA_QP_TYPE_ROCE_UD) { | 3385 | if (qp->qp_uk.qp_type == IRDMA_QP_TYPE_ROCE_UD) { |
| @@ -232,6 +232,59 @@ static inline u16 irdma_fw_minor_ver(struct irdma_sc_dev *dev) · 231 unmodified lines | |||
| 232 | return (u16)FIELD_GET(IRDMA_FW_VER_MINOR, dev->feature_info[IRDMA_FEATURE_FW_INFO]); | 232 | return (u16)FIELD_GET(IRDMA_FW_VER_MINOR, dev->feature_info[IRDMA_FEATURE_FW_INFO]); |
| 233 | } | 233 | } |
| 234 | 234 | ||
| 235 | static inline void set_ib_wc_op_sq(struct irdma_cq_poll_info *cq_poll_info, | ||
| 236 | struct ib_wc *entry) | ||
| 237 | { | ||
| 238 | switch (cq_poll_info->op_type) { | ||
| 239 | case IRDMA_OP_TYPE_RDMA_WRITE: | ||
| 240 | case IRDMA_OP_TYPE_RDMA_WRITE_SOL: | ||
| 241 | entry->opcode = IB_WC_RDMA_WRITE; | ||
| 242 | break; | ||
| 243 | case IRDMA_OP_TYPE_RDMA_READ_INV_STAG: | ||
| 244 | case IRDMA_OP_TYPE_RDMA_READ: | ||
| 245 | entry->opcode = IB_WC_RDMA_READ; | ||
| 246 | break; | ||
| 247 | case IRDMA_OP_TYPE_SEND_SOL: | ||
| 248 | case IRDMA_OP_TYPE_SEND_SOL_INV: | ||
| 249 | case IRDMA_OP_TYPE_SEND_INV: | ||
| 250 | case IRDMA_OP_TYPE_SEND: | ||
| 251 | entry->opcode = IB_WC_SEND; | ||
| 252 | break; | ||
| 253 | case IRDMA_OP_TYPE_FAST_REG_NSMR: | ||
| 254 | entry->opcode = IB_WC_REG_MR; | ||
| 255 | break; | ||
| 256 | case IRDMA_OP_TYPE_INV_STAG: | ||
| 257 | entry->opcode = IB_WC_LOCAL_INV; | ||
| 258 | break; | ||
| 259 | default: | ||
| 260 | entry->status = IB_WC_GENERAL_ERR; | ||
| 261 | } | ||
| 262 | } | ||
| 263 | |||
| 264 | static inline void set_ib_wc_op_rq(struct irdma_cq_poll_info *cq_poll_info, | ||
| 265 | struct ib_wc *entry, bool send_imm_support) | ||
| 266 | { | ||
| 267 | /** | ||
| 268 | * iWARP does not support sendImm, so the presence of Imm data | ||
| 269 | * must be WriteImm. | ||
| 270 | */ | ||
| 271 | if (!send_imm_support) { | ||
| 272 | entry->opcode = cq_poll_info->imm_valid ? | ||
| 273 | IB_WC_RECV_RDMA_WITH_IMM : | ||
| 274 | IB_WC_RECV; | ||
| 275 | return; | ||
| 276 | } | ||
| 277 | |||
| 278 | switch (cq_poll_info->op_type) { | ||
| 279 | case IB_OPCODE_RDMA_WRITE_ONLY_WITH_IMMEDIATE: | ||
| 280 | case IB_OPCODE_RDMA_WRITE_LAST_WITH_IMMEDIATE: | ||
| 281 | entry->opcode = IB_WC_RECV_RDMA_WITH_IMM; | ||
| 282 | break; | ||
| 283 | default: | ||
| 284 | entry->opcode = IB_WC_RECV; | ||
| 285 | } | ||
| 286 | } | ||
| 287 | |||
| 235 | void irdma_mcast_mac(u32 *ip_addr, u8 *mac, bool ipv4); | 288 | void irdma_mcast_mac(u32 *ip_addr, u8 *mac, bool ipv4); |
| 236 | int irdma_ib_register_device(struct irdma_device *iwdev); | 289 | int irdma_ib_register_device(struct irdma_device *iwdev); |
| 237 | void irdma_ib_unregister_device(struct irdma_device *iwdev); | 290 | void irdma_ib_unregister_device(struct irdma_device *iwdev); |
| @@ -0,0 +1,10 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | config MANA_INFINIBAND | ||
| 3 | tristate "Microsoft Azure Network Adapter support" | ||
| 4 | depends on NETDEVICES && ETHERNET && PCI && MICROSOFT_MANA | ||
| 5 | help | ||
| 6 | This driver provides low-level RDMA support for Microsoft Azure | ||
| 7 | Network Adapter (MANA). MANA supports RDMA features that can be used | ||
| 8 | for workloads (e.g. DPDK, MPI etc) that uses RDMA verbs to directly | ||
| 9 | access hardware from user-mode processes in Microsoft Azure cloud | ||
| 10 | environment. | ||
| @@ -0,0 +1,4 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | obj-$(CONFIG_MANA_INFINIBAND) += mana_ib.o | ||
| 3 | |||
| 4 | mana_ib-y := device.o main.o wq.o qp.o cq.o mr.o | ||
| @@ -0,0 +1,79 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | /* | ||
| 3 | * Copyright (c) 2022, Microsoft Corporation. All rights reserved. | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include "mana_ib.h" | ||
| 7 | |||
| 8 | int mana_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr, | ||
| 9 | struct ib_udata *udata) | ||
| 10 | { | ||
| 11 | struct mana_ib_cq *cq = container_of(ibcq, struct mana_ib_cq, ibcq); | ||
| 12 | struct ib_device *ibdev = ibcq->device; | ||
| 13 | struct mana_ib_create_cq ucmd = {}; | ||
| 14 | struct mana_ib_dev *mdev; | ||
| 15 | int err; | ||
| 16 | |||
| 17 | mdev = container_of(ibdev, struct mana_ib_dev, ib_dev); | ||
| 18 | |||
| 19 | if (udata->inlen < sizeof(ucmd)) | ||
| 20 | return -EINVAL; | ||
| 21 | |||
| 22 | err = ib_copy_from_udata(&ucmd, udata, min(sizeof(ucmd), udata->inlen)); | ||
| 23 | if (err) { | ||
| 24 | ibdev_dbg(ibdev, | ||
| 25 | "Failed to copy from udata for create cq, %d\n", err); | ||
| 26 | return err; | ||
| 27 | } | ||
| 28 | |||
| 29 | if (attr->cqe > MAX_SEND_BUFFERS_PER_QUEUE) { | ||
| 30 | ibdev_dbg(ibdev, "CQE %d exceeding limit\n", attr->cqe); | ||
| 31 | return -EINVAL; | ||
| 32 | } | ||
| 33 | |||
| 34 | cq->cqe = attr->cqe; | ||
| 35 | cq->umem = ib_umem_get(ibdev, ucmd.buf_addr, cq->cqe * COMP_ENTRY_SIZE, | ||
| 36 | IB_ACCESS_LOCAL_WRITE); | ||
| 37 | if (IS_ERR(cq->umem)) { | ||
| 38 | err = PTR_ERR(cq->umem); | ||
| 39 | ibdev_dbg(ibdev, "Failed to get umem for create cq, err %d\n", | ||
| 40 | err); | ||
| 41 | return err; | ||
| 42 | } | ||
| 43 | |||
| 44 | err = mana_ib_gd_create_dma_region(mdev, cq->umem, &cq->gdma_region); | ||
| 45 | if (err) { | ||
| 46 | ibdev_dbg(ibdev, | ||
| 47 | "Failed to create dma region for create cq, %d\n", | ||
| 48 | err); | ||
| 49 | goto err_release_umem; | ||
| 50 | } | ||
| 51 | |||
| 52 | ibdev_dbg(ibdev, | ||
| 53 | "mana_ib_gd_create_dma_region ret %d gdma_region 0x%llx\n", | ||
| 54 | err, cq->gdma_region); | ||
| 55 | |||
| 56 | /* | ||
| 57 | * The CQ ID is not known at this time. The ID is generated at create_qp | ||
| 58 | */ | ||
| 59 | |||
| 60 | return 0; | ||
| 61 | |||
| 62 | err_release_umem: | ||
| 63 | ib_umem_release(cq->umem); | ||
| 64 | return err; | ||
| 65 | } | ||
| 66 | |||
| 67 | int mana_ib_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata) | ||
| 68 | { | ||
| 69 | struct mana_ib_cq *cq = container_of(ibcq, struct mana_ib_cq, ibcq); | ||
| 70 | struct ib_device *ibdev = ibcq->device; | ||
| 71 | struct mana_ib_dev *mdev; | ||
| 72 | |||
| 73 | mdev = container_of(ibdev, struct mana_ib_dev, ib_dev); | ||
| 74 | |||
| 75 | mana_ib_gd_destroy_dma_region(mdev, cq->gdma_region); | ||
| 76 | ib_umem_release(cq->umem); | ||
| 77 | |||
| 78 | return 0; | ||
| 79 | } | ||
| @@ -0,0 +1,117 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | /* | ||
| 3 | * Copyright (c) 2022, Microsoft Corporation. All rights reserved. | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include "mana_ib.h" | ||
| 7 | #include <net/mana/mana_auxiliary.h> | ||
| 8 | |||
| 9 | MODULE_DESCRIPTION("Microsoft Azure Network Adapter IB driver"); | ||
| 10 | MODULE_LICENSE("GPL"); | ||
| 11 | MODULE_IMPORT_NS(NET_MANA); | ||
| 12 | |||
| 13 | static const struct ib_device_ops mana_ib_dev_ops = { | ||
| 14 | .owner = THIS_MODULE, | ||
| 15 | .driver_id = RDMA_DRIVER_MANA, | ||
| 16 | .uverbs_abi_ver = MANA_IB_UVERBS_ABI_VERSION, | ||
| 17 | |||
| 18 | .alloc_pd = mana_ib_alloc_pd, | ||
| 19 | .alloc_ucontext = mana_ib_alloc_ucontext, | ||
| 20 | .create_cq = mana_ib_create_cq, | ||
| 21 | .create_qp = mana_ib_create_qp, | ||
| 22 | .create_rwq_ind_table = mana_ib_create_rwq_ind_table, | ||
| 23 | .create_wq = mana_ib_create_wq, | ||
| 24 | .dealloc_pd = mana_ib_dealloc_pd, | ||
| 25 | .dealloc_ucontext = mana_ib_dealloc_ucontext, | ||
| 26 | .dereg_mr = mana_ib_dereg_mr, | ||
| 27 | .destroy_cq = mana_ib_destroy_cq, | ||
| 28 | .destroy_qp = mana_ib_destroy_qp, | ||
| 29 | .destroy_rwq_ind_table = mana_ib_destroy_rwq_ind_table, | ||
| 30 | .destroy_wq = mana_ib_destroy_wq, | ||
| 31 | .disassociate_ucontext = mana_ib_disassociate_ucontext, | ||
| 32 | .get_port_immutable = mana_ib_get_port_immutable, | ||
| 33 | .mmap = mana_ib_mmap, | ||
| 34 | .modify_qp = mana_ib_modify_qp, | ||
| 35 | .modify_wq = mana_ib_modify_wq, | ||
| 36 | .query_device = mana_ib_query_device, | ||
| 37 | .query_gid = mana_ib_query_gid, | ||
| 38 | .query_port = mana_ib_query_port, | ||
| 39 | .reg_user_mr = mana_ib_reg_user_mr, | ||
| 40 | |||
| 41 | INIT_RDMA_OBJ_SIZE(ib_cq, mana_ib_cq, ibcq), | ||
| 42 | INIT_RDMA_OBJ_SIZE(ib_pd, mana_ib_pd, ibpd), | ||
| 43 | INIT_RDMA_OBJ_SIZE(ib_qp, mana_ib_qp, ibqp), | ||
| 44 | INIT_RDMA_OBJ_SIZE(ib_ucontext, mana_ib_ucontext, ibucontext), | ||
| 45 | INIT_RDMA_OBJ_SIZE(ib_rwq_ind_table, mana_ib_rwq_ind_table, | ||
| 46 | ib_ind_table), | ||
| 47 | }; | ||
| 48 | |||
| 49 | static int mana_ib_probe(struct auxiliary_device *adev, | ||
| 50 | const struct auxiliary_device_id *id) | ||
| 51 | { | ||
| 52 | struct mana_adev *madev = container_of(adev, struct mana_adev, adev); | ||
| 53 | struct gdma_dev *mdev = madev->mdev; | ||
| 54 | struct mana_context *mc; | ||
| 55 | struct mana_ib_dev *dev; | ||
| 56 | int ret; | ||
| 57 | |||
| 58 | mc = mdev->driver_data; | ||
| 59 | |||
| 60 | dev = ib_alloc_device(mana_ib_dev, ib_dev); | ||
| 61 | if (!dev) | ||
| 62 | return -ENOMEM; | ||
| 63 | |||
| 64 | ib_set_device_ops(&dev->ib_dev, &mana_ib_dev_ops); | ||
| 65 | |||
| 66 | dev->ib_dev.phys_port_cnt = mc->num_ports; | ||
| 67 | |||
| 68 | ibdev_dbg(&dev->ib_dev, "mdev=%p id=%d num_ports=%d\n", mdev, | ||
| 69 | mdev->dev_id.as_uint32, dev->ib_dev.phys_port_cnt); | ||
| 70 | |||
| 71 | dev->gdma_dev = mdev; | ||
| 72 | dev->ib_dev.node_type = RDMA_NODE_IB_CA; | ||
| 73 | |||
| 74 | /* | ||
| 75 | * num_comp_vectors needs to set to the max MSIX index | ||
| 76 | * when interrupts and event queues are implemented | ||
| 77 | */ | ||
| 78 | dev->ib_dev.num_comp_vectors = 1; | ||
| 79 | dev->ib_dev.dev.parent = mdev->gdma_context->dev; | ||
| 80 | |||
| 81 | ret = ib_register_device(&dev->ib_dev, "mana_%d", | ||
| 82 | mdev->gdma_context->dev); | ||
| 83 | if (ret) { | ||
| 84 | ib_dealloc_device(&dev->ib_dev); | ||
| 85 | return ret; | ||
| 86 | } | ||
| 87 | |||
| 88 | dev_set_drvdata(&adev->dev, dev); | ||
| 89 | |||
| 90 | return 0; | ||
| 91 | } | ||
| 92 | |||
| 93 | static void mana_ib_remove(struct auxiliary_device *adev) | ||
| 94 | { | ||
| 95 | struct mana_ib_dev *dev = dev_get_drvdata(&adev->dev); | ||
| 96 | |||
| 97 | ib_unregister_device(&dev->ib_dev); | ||
| 98 | ib_dealloc_device(&dev->ib_dev); | ||
| 99 | } | ||
| 100 | |||
| 101 | static const struct auxiliary_device_id mana_id_table[] = { | ||
| 102 | { | ||
| 103 | .name = "mana.rdma", | ||
| 104 | }, | ||
| 105 | {}, | ||
| 106 | }; | ||
| 107 | |||
| 108 | MODULE_DEVICE_TABLE(auxiliary, mana_id_table); | ||
| 109 | |||
| 110 | static struct auxiliary_driver mana_driver = { | ||
| 111 | .name = "rdma", | ||
| 112 | .probe = mana_ib_probe, | ||
| 113 | .remove = mana_ib_remove, | ||
| 114 | .id_table = mana_id_table, | ||
| 115 | }; | ||
| 116 | |||
| 117 | module_auxiliary_driver(mana_driver); | ||
| @@ -0,0 +1,521 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | /* | ||
| 3 | * Copyright (c) 2022, Microsoft Corporation. All rights reserved. | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include "mana_ib.h" | ||
| 7 | |||
| 8 | void mana_ib_uncfg_vport(struct mana_ib_dev *dev, struct mana_ib_pd *pd, | ||
| 9 | u32 port) | ||
| 10 | { | ||
| 11 | struct gdma_dev *gd = dev->gdma_dev; | ||
| 12 | struct mana_port_context *mpc; | ||
| 13 | struct net_device *ndev; | ||
| 14 | struct mana_context *mc; | ||
| 15 | |||
| 16 | mc = gd->driver_data; | ||
| 17 | ndev = mc->ports[port]; | ||
| 18 | mpc = netdev_priv(ndev); | ||
| 19 | |||
| 20 | mutex_lock(&pd->vport_mutex); | ||
| 21 | |||
| 22 | pd->vport_use_count--; | ||
| 23 | WARN_ON(pd->vport_use_count < 0); | ||
| 24 | |||
| 25 | if (!pd->vport_use_count) | ||
| 26 | mana_uncfg_vport(mpc); | ||
| 27 | |||
| 28 | mutex_unlock(&pd->vport_mutex); | ||
| 29 | } | ||
| 30 | |||
| 31 | int mana_ib_cfg_vport(struct mana_ib_dev *dev, u32 port, struct mana_ib_pd *pd, | ||
| 32 | u32 doorbell_id) | ||
| 33 | { | ||
| 34 | struct gdma_dev *mdev = dev->gdma_dev; | ||
| 35 | struct mana_port_context *mpc; | ||
| 36 | struct mana_context *mc; | ||
| 37 | struct net_device *ndev; | ||
| 38 | int err; | ||
| 39 | |||
| 40 | mc = mdev->driver_data; | ||
| 41 | ndev = mc->ports[port]; | ||
| 42 | mpc = netdev_priv(ndev); | ||
| 43 | |||
| 44 | mutex_lock(&pd->vport_mutex); | ||
| 45 | |||
| 46 | pd->vport_use_count++; | ||
| 47 | if (pd->vport_use_count > 1) { | ||
| 48 | ibdev_dbg(&dev->ib_dev, | ||
| 49 | "Skip as this PD is already configured vport\n"); | ||
| 50 | mutex_unlock(&pd->vport_mutex); | ||
| 51 | return 0; | ||
| 52 | } | ||
| 53 | |||
| 54 | err = mana_cfg_vport(mpc, pd->pdn, doorbell_id); | ||
| 55 | if (err) { | ||
| 56 | pd->vport_use_count--; | ||
| 57 | mutex_unlock(&pd->vport_mutex); | ||
| 58 | |||
| 59 | ibdev_dbg(&dev->ib_dev, "Failed to configure vPort %d\n", err); | ||
| 60 | return err; | ||
| 61 | } | ||
| 62 | |||
| 63 | mutex_unlock(&pd->vport_mutex); | ||
| 64 | |||
| 65 | pd->tx_shortform_allowed = mpc->tx_shortform_allowed; | ||
| 66 | pd->tx_vp_offset = mpc->tx_vp_offset; | ||
| 67 | |||
| 68 | ibdev_dbg(&dev->ib_dev, "vport handle %llx pdid %x doorbell_id %x\n", | ||
| 69 | mpc->port_handle, pd->pdn, doorbell_id); | ||
| 70 | |||
| 71 | return 0; | ||
| 72 | } | ||
| 73 | |||
| 74 | int mana_ib_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata) | ||
| 75 | { | ||
| 76 | struct mana_ib_pd *pd = container_of(ibpd, struct mana_ib_pd, ibpd); | ||
| 77 | struct ib_device *ibdev = ibpd->device; | ||
| 78 | struct gdma_create_pd_resp resp = {}; | ||
| 79 | struct gdma_create_pd_req req = {}; | ||
| 80 | enum gdma_pd_flags flags = 0; | ||
| 81 | struct mana_ib_dev *dev; | ||
| 82 | struct gdma_dev *mdev; | ||
| 83 | int err; | ||
| 84 | |||
| 85 | dev = container_of(ibdev, struct mana_ib_dev, ib_dev); | ||
| 86 | mdev = dev->gdma_dev; | ||
| 87 | |||
| 88 | mana_gd_init_req_hdr(&req.hdr, GDMA_CREATE_PD, sizeof(req), | ||
| 89 | sizeof(resp)); | ||
| 90 | |||
| 91 | req.flags = flags; | ||
| 92 | err = mana_gd_send_request(mdev->gdma_context, sizeof(req), &req, | ||
| 93 | sizeof(resp), &resp); | ||
| 94 | |||
| 95 | if (err || resp.hdr.status) { | ||
| 96 | ibdev_dbg(&dev->ib_dev, | ||
| 97 | "Failed to get pd_id err %d status %u\n", err, | ||
| 98 | resp.hdr.status); | ||
| 99 | if (!err) | ||
| 100 | err = -EPROTO; | ||
| 101 | |||
| 102 | return err; | ||
| 103 | } | ||
| 104 | |||
| 105 | pd->pd_handle = resp.pd_handle; | ||
| 106 | pd->pdn = resp.pd_id; | ||
| 107 | ibdev_dbg(&dev->ib_dev, "pd_handle 0x%llx pd_id %d\n", | ||
| 108 | pd->pd_handle, pd->pdn); | ||
| 109 | |||
| 110 | mutex_init(&pd->vport_mutex); | ||
| 111 | pd->vport_use_count = 0; | ||
| 112 | return 0; | ||
| 113 | } | ||
| 114 | |||
| 115 | int mana_ib_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata) | ||
| 116 | { | ||
| 117 | struct mana_ib_pd *pd = container_of(ibpd, struct mana_ib_pd, ibpd); | ||
| 118 | struct ib_device *ibdev = ibpd->device; | ||
| 119 | struct gdma_destory_pd_resp resp = {}; | ||
| 120 | struct gdma_destroy_pd_req req = {}; | ||
| 121 | struct mana_ib_dev *dev; | ||
| 122 | struct gdma_dev *mdev; | ||
| 123 | int err; | ||
| 124 | |||
| 125 | dev = container_of(ibdev, struct mana_ib_dev, ib_dev); | ||
| 126 | mdev = dev->gdma_dev; | ||
| 127 | |||
| 128 | mana_gd_init_req_hdr(&req.hdr, GDMA_DESTROY_PD, sizeof(req), | ||
| 129 | sizeof(resp)); | ||
| 130 | |||
| 131 | req.pd_handle = pd->pd_handle; | ||
| 132 | err = mana_gd_send_request(mdev->gdma_context, sizeof(req), &req, | ||
| 133 | sizeof(resp), &resp); | ||
| 134 | |||
| 135 | if (err || resp.hdr.status) { | ||
| 136 | ibdev_dbg(&dev->ib_dev, | ||
| 137 | "Failed to destroy pd_handle 0x%llx err %d status %u", | ||
| 138 | pd->pd_handle, err, resp.hdr.status); | ||
| 139 | if (!err) | ||
| 140 | err = -EPROTO; | ||
| 141 | } | ||
| 142 | |||
| 143 | return err; | ||
| 144 | } | ||
| 145 | |||
| 146 | static int mana_gd_destroy_doorbell_page(struct gdma_context *gc, | ||
| 147 | int doorbell_page) | ||
| 148 | { | ||
| 149 | struct gdma_destroy_resource_range_req req = {}; | ||
| 150 | struct gdma_resp_hdr resp = {}; | ||
| 151 | int err; | ||
| 152 | |||
| 153 | mana_gd_init_req_hdr(&req.hdr, GDMA_DESTROY_RESOURCE_RANGE, | ||
| 154 | sizeof(req), sizeof(resp)); | ||
| 155 | |||
| 156 | req.resource_type = GDMA_RESOURCE_DOORBELL_PAGE; | ||
| 157 | req.num_resources = 1; | ||
| 158 | req.allocated_resources = doorbell_page; | ||
| 159 | |||
| 160 | err = mana_gd_send_request(gc, sizeof(req), &req, sizeof(resp), &resp); | ||
| 161 | if (err || resp.status) { | ||
| 162 | dev_err(gc->dev, | ||
| 163 | "Failed to destroy doorbell page: ret %d, 0x%x\n", | ||
| 164 | err, resp.status); | ||
| 165 | return err ?: -EPROTO; | ||
| 166 | } | ||
| 167 | |||
| 168 | return 0; | ||
| 169 | } | ||
| 170 | |||
| 171 | static int mana_gd_allocate_doorbell_page(struct gdma_context *gc, | ||
| 172 | int *doorbell_page) | ||
| 173 | { | ||
| 174 | struct gdma_allocate_resource_range_req req = {}; | ||
| 175 | struct gdma_allocate_resource_range_resp resp = {}; | ||
| 176 | int err; | ||
| 177 | |||
| 178 | mana_gd_init_req_hdr(&req.hdr, GDMA_ALLOCATE_RESOURCE_RANGE, | ||
| 179 | sizeof(req), sizeof(resp)); | ||
| 180 | |||
| 181 | req.resource_type = GDMA_RESOURCE_DOORBELL_PAGE; | ||
| 182 | req.num_resources = 1; | ||
| 183 | req.alignment = 1; | ||
| 184 | |||
| 185 | /* Have GDMA start searching from 0 */ | ||
| 186 | req.allocated_resources = 0; | ||
| 187 | |||
| 188 | err = mana_gd_send_request(gc, sizeof(req), &req, sizeof(resp), &resp); | ||
| 189 | if (err || resp.hdr.status) { | ||
| 190 | dev_err(gc->dev, | ||
| 191 | "Failed to allocate doorbell page: ret %d, 0x%x\n", | ||
| 192 | err, resp.hdr.status); | ||
| 193 | return err ?: -EPROTO; | ||
| 194 | } | ||
| 195 | |||
| 196 | *doorbell_page = resp.allocated_resources; | ||
| 197 | |||
| 198 | return 0; | ||
| 199 | } | ||
| 200 | |||
| 201 | int mana_ib_alloc_ucontext(struct ib_ucontext *ibcontext, | ||
| 202 | struct ib_udata *udata) | ||
| 203 | { | ||
| 204 | struct mana_ib_ucontext *ucontext = | ||
| 205 | container_of(ibcontext, struct mana_ib_ucontext, ibucontext); | ||
| 206 | struct ib_device *ibdev = ibcontext->device; | ||
| 207 | struct mana_ib_dev *mdev; | ||
| 208 | struct gdma_context *gc; | ||
| 209 | struct gdma_dev *dev; | ||
| 210 | int doorbell_page; | ||
| 211 | int ret; | ||
| 212 | |||
| 213 | mdev = container_of(ibdev, struct mana_ib_dev, ib_dev); | ||
| 214 | dev = mdev->gdma_dev; | ||
| 215 | gc = dev->gdma_context; | ||
| 216 | |||
| 217 | /* Allocate a doorbell page index */ | ||
| 218 | ret = mana_gd_allocate_doorbell_page(gc, &doorbell_page); | ||
| 219 | if (ret) { | ||
| 220 | ibdev_dbg(ibdev, "Failed to allocate doorbell page %d\n", ret); | ||
| 221 | return ret; | ||
| 222 | } | ||
| 223 | |||
| 224 | ibdev_dbg(ibdev, "Doorbell page allocated %d\n", doorbell_page); | ||
| 225 | |||
| 226 | ucontext->doorbell = doorbell_page; | ||
| 227 | |||
| 228 | return 0; | ||
| 229 | } | ||
| 230 | |||
| 231 | void mana_ib_dealloc_ucontext(struct ib_ucontext *ibcontext) | ||
| 232 | { | ||
| 233 | struct mana_ib_ucontext *mana_ucontext = | ||
| 234 | container_of(ibcontext, struct mana_ib_ucontext, ibucontext); | ||
| 235 | struct ib_device *ibdev = ibcontext->device; | ||
| 236 | struct mana_ib_dev *mdev; | ||
| 237 | struct gdma_context *gc; | ||
| 238 | int ret; | ||
| 239 | |||
| 240 | mdev = container_of(ibdev, struct mana_ib_dev, ib_dev); | ||
| 241 | gc = mdev->gdma_dev->gdma_context; | ||
| 242 | |||
| 243 | ret = mana_gd_destroy_doorbell_page(gc, mana_ucontext->doorbell); | ||
| 244 | if (ret) | ||
| 245 | ibdev_dbg(ibdev, "Failed to destroy doorbell page %d\n", ret); | ||
| 246 | } | ||
| 247 | |||
| 248 | static int | ||
| 249 | mana_ib_gd_first_dma_region(struct mana_ib_dev *dev, | ||
| 250 | struct gdma_context *gc, | ||
| 251 | struct gdma_create_dma_region_req *create_req, | ||
| 252 | size_t num_pages, mana_handle_t *gdma_region) | ||
| 253 | { | ||
| 254 | struct gdma_create_dma_region_resp create_resp = {}; | ||
| 255 | unsigned int create_req_msg_size; | ||
| 256 | int err; | ||
| 257 | |||
| 258 | create_req_msg_size = | ||
| 259 | struct_size(create_req, page_addr_list, num_pages); | ||
| 260 | create_req->page_addr_list_len = num_pages; | ||
| 261 | |||
| 262 | err = mana_gd_send_request(gc, create_req_msg_size, create_req, | ||
| 263 | sizeof(create_resp), &create_resp); | ||
| 264 | if (err || create_resp.hdr.status) { | ||
| 265 | ibdev_dbg(&dev->ib_dev, | ||
| 266 | "Failed to create DMA region: %d, 0x%x\n", | ||
| 267 | err, create_resp.hdr.status); | ||
| 268 | if (!err) | ||
| 269 | err = -EPROTO; | ||
| 270 | |||
| 271 | return err; | ||
| 272 | } | ||
| 273 | |||
| 274 | *gdma_region = create_resp.dma_region_handle; | ||
| 275 | ibdev_dbg(&dev->ib_dev, "Created DMA region handle 0x%llx\n", | ||
| 276 | *gdma_region); | ||
| 277 | |||
| 278 | return 0; | ||
| 279 | } | ||
| 280 | |||
| 281 | static int | ||
| 282 | mana_ib_gd_add_dma_region(struct mana_ib_dev *dev, struct gdma_context *gc, | ||
| 283 | struct gdma_dma_region_add_pages_req *add_req, | ||
| 284 | unsigned int num_pages, u32 expected_status) | ||
| 285 | { | ||
| 286 | unsigned int add_req_msg_size = | ||
| 287 | struct_size(add_req, page_addr_list, num_pages); | ||
| 288 | struct gdma_general_resp add_resp = {}; | ||
| 289 | int err; | ||
| 290 | |||
| 291 | mana_gd_init_req_hdr(&add_req->hdr, GDMA_DMA_REGION_ADD_PAGES, | ||
| 292 | add_req_msg_size, sizeof(add_resp)); | ||
| 293 | add_req->page_addr_list_len = num_pages; | ||
| 294 | |||
| 295 | err = mana_gd_send_request(gc, add_req_msg_size, add_req, | ||
| 296 | sizeof(add_resp), &add_resp); | ||
| 297 | if (err || add_resp.hdr.status != expected_status) { | ||
| 298 | ibdev_dbg(&dev->ib_dev, | ||
| 299 | "Failed to create DMA region: %d, 0x%x\n", | ||
| 300 | err, add_resp.hdr.status); | ||
| 301 | |||
| 302 | if (!err) | ||
| 303 | err = -EPROTO; | ||
| 304 | |||
| 305 | return err; | ||
| 306 | } | ||
| 307 | |||
| 308 | return 0; | ||
| 309 | } | ||
| 310 | |||
| 311 | int mana_ib_gd_create_dma_region(struct mana_ib_dev *dev, struct ib_umem *umem, | ||
| 312 | mana_handle_t *gdma_region) | ||
| 313 | { | ||
| 314 | struct gdma_dma_region_add_pages_req *add_req = NULL; | ||
| 315 | size_t num_pages_processed = 0, num_pages_to_handle; | ||
| 316 | struct gdma_create_dma_region_req *create_req; | ||
| 317 | unsigned int create_req_msg_size; | ||
| 318 | struct hw_channel_context *hwc; | ||
| 319 | struct ib_block_iter biter; | ||
| 320 | size_t max_pgs_add_cmd = 0; | ||
| 321 | size_t max_pgs_create_cmd; | ||
| 322 | struct gdma_context *gc; | ||
| 323 | size_t num_pages_total; | ||
| 324 | struct gdma_dev *mdev; | ||
| 325 | unsigned long page_sz; | ||
| 326 | unsigned int tail = 0; | ||
| 327 | u64 *page_addr_list; | ||
| 328 | void *request_buf; | ||
| 329 | int err; | ||
| 330 | |||
| 331 | mdev = dev->gdma_dev; | ||
| 332 | gc = mdev->gdma_context; | ||
| 333 | hwc = gc->hwc.driver_data; | ||
| 334 | |||
| 335 | /* Hardware requires dma region to align to chosen page size */ | ||
| 336 | page_sz = ib_umem_find_best_pgsz(umem, PAGE_SZ_BM, 0); | ||
| 337 | if (!page_sz) { | ||
| 338 | ibdev_dbg(&dev->ib_dev, "failed to find page size.\n"); | ||
| 339 | return -ENOMEM; | ||
| 340 | } | ||
| 341 | num_pages_total = ib_umem_num_dma_blocks(umem, page_sz); | ||
| 342 | |||
| 343 | max_pgs_create_cmd = | ||
| 344 | (hwc->max_req_msg_size - sizeof(*create_req)) / sizeof(u64); | ||
| 345 | num_pages_to_handle = | ||
| 346 | min_t(size_t, num_pages_total, max_pgs_create_cmd); | ||
| 347 | create_req_msg_size = | ||
| 348 | struct_size(create_req, page_addr_list, num_pages_to_handle); | ||
| 349 | |||
| 350 | request_buf = kzalloc(hwc->max_req_msg_size, GFP_KERNEL); | ||
| 351 | if (!request_buf) | ||
| 352 | return -ENOMEM; | ||
| 353 | |||
| 354 | create_req = request_buf; | ||
| 355 | mana_gd_init_req_hdr(&create_req->hdr, GDMA_CREATE_DMA_REGION, | ||
| 356 | create_req_msg_size, | ||
| 357 | sizeof(struct gdma_create_dma_region_resp)); | ||
| 358 | |||
| 359 | create_req->length = umem->length; | ||
| 360 | create_req->offset_in_page = umem->address & (page_sz - 1); | ||
| 361 | create_req->gdma_page_type = order_base_2(page_sz) - PAGE_SHIFT; | ||
| 362 | create_req->page_count = num_pages_total; | ||
| 363 | |||
| 364 | ibdev_dbg(&dev->ib_dev, "size_dma_region %lu num_pages_total %lu\n", | ||
| 365 | umem->length, num_pages_total); | ||
| 366 | |||
| 367 | ibdev_dbg(&dev->ib_dev, "page_sz %lu offset_in_page %u\n", | ||
| 368 | page_sz, create_req->offset_in_page); | ||
| 369 | |||
| 370 | ibdev_dbg(&dev->ib_dev, "num_pages_to_handle %lu, gdma_page_type %u", | ||
| 371 | num_pages_to_handle, create_req->gdma_page_type); | ||
| 372 | |||
| 373 | page_addr_list = create_req->page_addr_list; | ||
| 374 | rdma_umem_for_each_dma_block(umem, &biter, page_sz) { | ||
| 375 | page_addr_list[tail++] = rdma_block_iter_dma_address(&biter); | ||
| 376 | if (tail < num_pages_to_handle) | ||
| 377 | continue; | ||
| 378 | |||
| 379 | if (!num_pages_processed) { | ||
| 380 | /* First create message */ | ||
| 381 | err = mana_ib_gd_first_dma_region(dev, gc, create_req, | ||
| 382 | tail, gdma_region); | ||
| 383 | if (err) | ||
| 384 | goto out; | ||
| 385 | |||
| 386 | max_pgs_add_cmd = (hwc->max_req_msg_size - | ||
| 387 | sizeof(*add_req)) / sizeof(u64); | ||
| 388 | |||
| 389 | add_req = request_buf; | ||
| 390 | add_req->dma_region_handle = *gdma_region; | ||
| 391 | add_req->reserved3 = 0; | ||
| 392 | page_addr_list = add_req->page_addr_list; | ||
| 393 | } else { | ||
| 394 | /* Subsequent create messages */ | ||
| 395 | u32 expected_s = 0; | ||
| 396 | |||
| 397 | if (num_pages_processed + num_pages_to_handle < | ||
| 398 | num_pages_total) | ||
| 399 | expected_s = GDMA_STATUS_MORE_ENTRIES; | ||
| 400 | |||
| 401 | err = mana_ib_gd_add_dma_region(dev, gc, add_req, tail, | ||
| 402 | expected_s); | ||
| 403 | if (err) | ||
| 404 | break; | ||
| 405 | } | ||
| 406 | |||
| 407 | num_pages_processed += tail; | ||
| 408 | tail = 0; | ||
| 409 | |||
| 410 | /* The remaining pages to create */ | ||
| 411 | num_pages_to_handle = | ||
| 412 | min_t(size_t, | ||
| 413 | num_pages_total - num_pages_processed, | ||
| 414 | max_pgs_add_cmd); | ||
| 415 | } | ||
| 416 | |||
| 417 | if (err) | ||
| 418 | mana_ib_gd_destroy_dma_region(dev, *gdma_region); | ||
| 419 | |||
| 420 | out: | ||
| 421 | kfree(request_buf); | ||
| 422 | return err; | ||
| 423 | } | ||
| 424 | |||
| 425 | int mana_ib_gd_destroy_dma_region(struct mana_ib_dev *dev, u64 gdma_region) | ||
| 426 | { | ||
| 427 | struct gdma_dev *mdev = dev->gdma_dev; | ||
| 428 | struct gdma_context *gc; | ||
| 429 | |||
| 430 | gc = mdev->gdma_context; | ||
| 431 | ibdev_dbg(&dev->ib_dev, "destroy dma region 0x%llx\n", gdma_region); | ||
| 432 | |||
| 433 | return mana_gd_destroy_dma_region(gc, gdma_region); | ||
| 434 | } | ||
| 435 | |||
| 436 | int mana_ib_mmap(struct ib_ucontext *ibcontext, struct vm_area_struct *vma) | ||
| 437 | { | ||
| 438 | struct mana_ib_ucontext *mana_ucontext = | ||
| 439 | container_of(ibcontext, struct mana_ib_ucontext, ibucontext); | ||
| 440 | struct ib_device *ibdev = ibcontext->device; | ||
| 441 | struct mana_ib_dev *mdev; | ||
| 442 | struct gdma_context *gc; | ||
| 443 | phys_addr_t pfn; | ||
| 444 | pgprot_t prot; | ||
| 445 | int ret; | ||
| 446 | |||
| 447 | mdev = container_of(ibdev, struct mana_ib_dev, ib_dev); | ||
| 448 | gc = mdev->gdma_dev->gdma_context; | ||
| 449 | |||
| 450 | if (vma->vm_pgoff != 0) { | ||
| 451 | ibdev_dbg(ibdev, "Unexpected vm_pgoff %lu\n", vma->vm_pgoff); | ||
| 452 | return -EINVAL; | ||
| 453 | } | ||
| 454 | |||
| 455 | /* Map to the page indexed by ucontext->doorbell */ | ||
| 456 | pfn = (gc->phys_db_page_base + | ||
| 457 | gc->db_page_size * mana_ucontext->doorbell) >> | ||
| 458 | PAGE_SHIFT; | ||
| 459 | prot = pgprot_writecombine(vma->vm_page_prot); | ||
| 460 | |||
| 461 | ret = rdma_user_mmap_io(ibcontext, vma, pfn, gc->db_page_size, prot, | ||
| 462 | NULL); | ||
| 463 | if (ret) | ||
| 464 | ibdev_dbg(ibdev, "can't rdma_user_mmap_io ret %d\n", ret); | ||
| 465 | else | ||
| 466 | ibdev_dbg(ibdev, "mapped I/O pfn 0x%llx page_size %u, ret %d\n", | ||
| 467 | pfn, gc->db_page_size, ret); | ||
| 468 | |||
| 469 | return ret; | ||
| 470 | } | ||
| 471 | |||
| 472 | int mana_ib_get_port_immutable(struct ib_device *ibdev, u32 port_num, | ||
| 473 | struct ib_port_immutable *immutable) | ||
| 474 | { | ||
| 475 | /* | ||
| 476 | * This version only support RAW_PACKET | ||
| 477 | * other values need to be filled for other types | ||
| 478 | */ | ||
| 479 | immutable->core_cap_flags = RDMA_CORE_PORT_RAW_PACKET; | ||
| 480 | |||
| 481 | return 0; | ||
| 482 | } | ||
| 483 | |||
| 484 | int mana_ib_query_device(struct ib_device *ibdev, struct ib_device_attr *props, | ||
| 485 | struct ib_udata *uhw) | ||
| 486 | { | ||
| 487 | props->max_qp = MANA_MAX_NUM_QUEUES; | ||
| 488 | props->max_qp_wr = MAX_SEND_BUFFERS_PER_QUEUE; | ||
| 489 | |||
| 490 | /* | ||
| 491 | * max_cqe could be potentially much bigger. | ||
| 492 | * As this version of driver only support RAW QP, set it to the same | ||
| 493 | * value as max_qp_wr | ||
| 494 | */ | ||
| 495 | props->max_cqe = MAX_SEND_BUFFERS_PER_QUEUE; | ||
| 496 | |||
| 497 | props->max_mr_size = MANA_IB_MAX_MR_SIZE; | ||
| 498 | props->max_mr = MANA_IB_MAX_MR; | ||
| 499 | props->max_send_sge = MAX_TX_WQE_SGL_ENTRIES; | ||
| 500 | props->max_recv_sge = MAX_RX_WQE_SGL_ENTRIES; | ||
| 501 | |||
| 502 | return 0; | ||
| 503 | } | ||
| 504 | |||
| 505 | int mana_ib_query_port(struct ib_device *ibdev, u32 port, | ||
| 506 | struct ib_port_attr *props) | ||
| 507 | { | ||
| 508 | /* This version doesn't return port properties */ | ||
| 509 | return 0; | ||
| 510 | } | ||
| 511 | |||
| 512 | int mana_ib_query_gid(struct ib_device *ibdev, u32 port, int index, | ||
| 513 | union ib_gid *gid) | ||
| 514 | { | ||
| 515 | /* This version doesn't return GID properties */ | ||
| 516 | return 0; | ||
| 517 | } | ||
| 518 | |||
| 519 | void mana_ib_disassociate_ucontext(struct ib_ucontext *ibcontext) | ||
| 520 | { | ||
| 521 | } | ||
| @@ -0,0 +1,162 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
| 2 | /* | ||
| 3 | * Copyright (c) 2022 Microsoft Corporation. All rights reserved. | ||
| 4 | */ | ||
| 5 | |||
| 6 | #ifndef _MANA_IB_H_ | ||
| 7 | #define _MANA_IB_H_ | ||
| 8 | |||
| 9 | #include <rdma/ib_verbs.h> | ||
| 10 | #include <rdma/ib_mad.h> | ||
| 11 | #include <rdma/ib_umem.h> | ||
| 12 | #include <rdma/mana-abi.h> | ||
| 13 | #include <rdma/uverbs_ioctl.h> | ||
| 14 | |||
| 15 | #include <net/mana/mana.h> | ||
| 16 | |||
| 17 | #define PAGE_SZ_BM \ | ||
| 18 | (SZ_4K | SZ_8K | SZ_16K | SZ_32K | SZ_64K | SZ_128K | SZ_256K | \ | ||
| 19 | SZ_512K | SZ_1M | SZ_2M) | ||
| 20 | |||
| 21 | /* MANA doesn't have any limit for MR size */ | ||
| 22 | #define MANA_IB_MAX_MR_SIZE U64_MAX | ||
| 23 | |||
| 24 | /* | ||
| 25 | * The hardware limit of number of MRs is greater than maximum number of MRs | ||
| 26 | * that can possibly represent in 24 bits | ||
| 27 | */ | ||
| 28 | #define MANA_IB_MAX_MR 0xFFFFFFu | ||
| 29 | |||
| 30 | struct mana_ib_dev { | ||
| 31 | struct ib_device ib_dev; | ||
| 32 | struct gdma_dev *gdma_dev; | ||
| 33 | }; | ||
| 34 | |||
| 35 | struct mana_ib_wq { | ||
| 36 | struct ib_wq ibwq; | ||
| 37 | struct ib_umem *umem; | ||
| 38 | int wqe; | ||
| 39 | u32 wq_buf_size; | ||
| 40 | u64 gdma_region; | ||
| 41 | u64 id; | ||
| 42 | mana_handle_t rx_object; | ||
| 43 | }; | ||
| 44 | |||
| 45 | struct mana_ib_pd { | ||
| 46 | struct ib_pd ibpd; | ||
| 47 | u32 pdn; | ||
| 48 | mana_handle_t pd_handle; | ||
| 49 | |||
| 50 | /* Mutex for sharing access to vport_use_count */ | ||
| 51 | struct mutex vport_mutex; | ||
| 52 | int vport_use_count; | ||
| 53 | |||
| 54 | bool tx_shortform_allowed; | ||
| 55 | u32 tx_vp_offset; | ||
| 56 | }; | ||
| 57 | |||
| 58 | struct mana_ib_mr { | ||
| 59 | struct ib_mr ibmr; | ||
| 60 | struct ib_umem *umem; | ||
| 61 | mana_handle_t mr_handle; | ||
| 62 | }; | ||
| 63 | |||
| 64 | struct mana_ib_cq { | ||
| 65 | struct ib_cq ibcq; | ||
| 66 | struct ib_umem *umem; | ||
| 67 | int cqe; | ||
| 68 | u64 gdma_region; | ||
| 69 | u64 id; | ||
| 70 | }; | ||
| 71 | |||
| 72 | struct mana_ib_qp { | ||
| 73 | struct ib_qp ibqp; | ||
| 74 | |||
| 75 | /* Work queue info */ | ||
| 76 | struct ib_umem *sq_umem; | ||
| 77 | int sqe; | ||
| 78 | u64 sq_gdma_region; | ||
| 79 | u64 sq_id; | ||
| 80 | mana_handle_t tx_object; | ||
| 81 | |||
| 82 | /* The port on the IB device, starting with 1 */ | ||
| 83 | u32 port; | ||
| 84 | }; | ||
| 85 | |||
| 86 | struct mana_ib_ucontext { | ||
| 87 | struct ib_ucontext ibucontext; | ||
| 88 | u32 doorbell; | ||
| 89 | }; | ||
| 90 | |||
| 91 | struct mana_ib_rwq_ind_table { | ||
| 92 | struct ib_rwq_ind_table ib_ind_table; | ||
| 93 | }; | ||
| 94 | |||
| 95 | int mana_ib_gd_create_dma_region(struct mana_ib_dev *dev, struct ib_umem *umem, | ||
| 96 | mana_handle_t *gdma_region); | ||
| 97 | |||
| 98 | int mana_ib_gd_destroy_dma_region(struct mana_ib_dev *dev, | ||
| 99 | mana_handle_t gdma_region); | ||
| 100 | |||
| 101 | struct ib_wq *mana_ib_create_wq(struct ib_pd *pd, | ||
| 102 | struct ib_wq_init_attr *init_attr, | ||
| 103 | struct ib_udata *udata); | ||
| 104 | |||
| 105 | int mana_ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *wq_attr, | ||
| 106 | u32 wq_attr_mask, struct ib_udata *udata); | ||
| 107 | |||
| 108 | int mana_ib_destroy_wq(struct ib_wq *ibwq, struct ib_udata *udata); | ||
| 109 | |||
| 110 | int mana_ib_create_rwq_ind_table(struct ib_rwq_ind_table *ib_rwq_ind_table, | ||
| 111 | struct ib_rwq_ind_table_init_attr *init_attr, | ||
| 112 | struct ib_udata *udata); | ||
| 113 | |||
| 114 | int mana_ib_destroy_rwq_ind_table(struct ib_rwq_ind_table *ib_rwq_ind_tbl); | ||
| 115 | |||
| 116 | struct ib_mr *mana_ib_get_dma_mr(struct ib_pd *ibpd, int access_flags); | ||
| 117 | |||
| 118 | struct ib_mr *mana_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, | ||
| 119 | u64 iova, int access_flags, | ||
| 120 | struct ib_udata *udata); | ||
| 121 | |||
| 122 | int mana_ib_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata); | ||
| 123 | |||
| 124 | int mana_ib_create_qp(struct ib_qp *qp, struct ib_qp_init_attr *qp_init_attr, | ||
| 125 | struct ib_udata *udata); | ||
| 126 | |||
| 127 | int mana_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, | ||
| 128 | int attr_mask, struct ib_udata *udata); | ||
| 129 | |||
| 130 | int mana_ib_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata); | ||
| 131 | |||
| 132 | int mana_ib_cfg_vport(struct mana_ib_dev *dev, u32 port_id, | ||
| 133 | struct mana_ib_pd *pd, u32 doorbell_id); | ||
| 134 | void mana_ib_uncfg_vport(struct mana_ib_dev *dev, struct mana_ib_pd *pd, | ||
| 135 | u32 port); | ||
| 136 | |||
| 137 | int mana_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr, | ||
| 138 | struct ib_udata *udata); | ||
| 139 | |||
| 140 | int mana_ib_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata); | ||
| 141 | |||
| 142 | int mana_ib_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata); | ||
| 143 | int mana_ib_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata); | ||
| 144 | |||
| 145 | int mana_ib_alloc_ucontext(struct ib_ucontext *ibcontext, | ||
| 146 | struct ib_udata *udata); | ||
| 147 | void mana_ib_dealloc_ucontext(struct ib_ucontext *ibcontext); | ||
| 148 | |||
| 149 | int mana_ib_mmap(struct ib_ucontext *ibcontext, struct vm_area_struct *vma); | ||
| 150 | |||
| 151 | int mana_ib_get_port_immutable(struct ib_device *ibdev, u32 port_num, | ||
| 152 | struct ib_port_immutable *immutable); | ||
| 153 | int mana_ib_query_device(struct ib_device *ibdev, struct ib_device_attr *props, | ||
| 154 | struct ib_udata *uhw); | ||
| 155 | int mana_ib_query_port(struct ib_device *ibdev, u32 port, | ||
| 156 | struct ib_port_attr *props); | ||
| 157 | int mana_ib_query_gid(struct ib_device *ibdev, u32 port, int index, | ||
| 158 | union ib_gid *gid); | ||
| 159 | |||
| 160 | void mana_ib_disassociate_ucontext(struct ib_ucontext *ibcontext); | ||
| 161 | |||
| 162 | #endif | ||
| @@ -0,0 +1,197 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | /* | ||
| 3 | * Copyright (c) 2022, Microsoft Corporation. All rights reserved. | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include "mana_ib.h" | ||
| 7 | |||
| 8 | #define VALID_MR_FLAGS \ | ||
| 9 | (IB_ACCESS_LOCAL_WRITE | IB_ACCESS_REMOTE_WRITE | IB_ACCESS_REMOTE_READ) | ||
| 10 | |||
| 11 | static enum gdma_mr_access_flags | ||
| 12 | mana_ib_verbs_to_gdma_access_flags(int access_flags) | ||
| 13 | { | ||
| 14 | enum gdma_mr_access_flags flags = GDMA_ACCESS_FLAG_LOCAL_READ; | ||
| 15 | |||
| 16 | if (access_flags & IB_ACCESS_LOCAL_WRITE) | ||
| 17 | flags |= GDMA_ACCESS_FLAG_LOCAL_WRITE; | ||
| 18 | |||
| 19 | if (access_flags & IB_ACCESS_REMOTE_WRITE) | ||
| 20 | flags |= GDMA_ACCESS_FLAG_REMOTE_WRITE; | ||
| 21 | |||
| 22 | if (access_flags & IB_ACCESS_REMOTE_READ) | ||
| 23 | flags |= GDMA_ACCESS_FLAG_REMOTE_READ; | ||
| 24 | |||
| 25 | return flags; | ||
| 26 | } | ||
| 27 | |||
| 28 | static int mana_ib_gd_create_mr(struct mana_ib_dev *dev, struct mana_ib_mr *mr, | ||
| 29 | struct gdma_create_mr_params *mr_params) | ||
| 30 | { | ||
| 31 | struct gdma_create_mr_response resp = {}; | ||
| 32 | struct gdma_create_mr_request req = {}; | ||
| 33 | struct gdma_dev *mdev = dev->gdma_dev; | ||
| 34 | struct gdma_context *gc; | ||
| 35 | int err; | ||
| 36 | |||
| 37 | gc = mdev->gdma_context; | ||
| 38 | |||
| 39 | mana_gd_init_req_hdr(&req.hdr, GDMA_CREATE_MR, sizeof(req), | ||
| 40 | sizeof(resp)); | ||
| 41 | req.pd_handle = mr_params->pd_handle; | ||
| 42 | req.mr_type = mr_params->mr_type; | ||
| 43 | |||
| 44 | switch (mr_params->mr_type) { | ||
| 45 | case GDMA_MR_TYPE_GVA: | ||
| 46 | req.gva.dma_region_handle = mr_params->gva.dma_region_handle; | ||
| 47 | req.gva.virtual_address = mr_params->gva.virtual_address; | ||
| 48 | req.gva.access_flags = mr_params->gva.access_flags; | ||
| 49 | break; | ||
| 50 | |||
| 51 | default: | ||
| 52 | ibdev_dbg(&dev->ib_dev, | ||
| 53 | "invalid param (GDMA_MR_TYPE) passed, type %d\n", | ||
| 54 | req.mr_type); | ||
| 55 | return -EINVAL; | ||
| 56 | } | ||
| 57 | |||
| 58 | err = mana_gd_send_request(gc, sizeof(req), &req, sizeof(resp), &resp); | ||
| 59 | |||
| 60 | if (err || resp.hdr.status) { | ||
| 61 | ibdev_dbg(&dev->ib_dev, "Failed to create mr %d, %u", err, | ||
| 62 | resp.hdr.status); | ||
| 63 | if (!err) | ||
| 64 | err = -EPROTO; | ||
| 65 | |||
| 66 | return err; | ||
| 67 | } | ||
| 68 | |||
| 69 | mr->ibmr.lkey = resp.lkey; | ||
| 70 | mr->ibmr.rkey = resp.rkey; | ||
| 71 | mr->mr_handle = resp.mr_handle; | ||
| 72 | |||
| 73 | return 0; | ||
| 74 | } | ||
| 75 | |||
| 76 | static int mana_ib_gd_destroy_mr(struct mana_ib_dev *dev, u64 mr_handle) | ||
| 77 | { | ||
| 78 | struct gdma_destroy_mr_response resp = {}; | ||
| 79 | struct gdma_destroy_mr_request req = {}; | ||
| 80 | struct gdma_dev *mdev = dev->gdma_dev; | ||
| 81 | struct gdma_context *gc; | ||
| 82 | int err; | ||
| 83 | |||
| 84 | gc = mdev->gdma_context; | ||
| 85 | |||
| 86 | mana_gd_init_req_hdr(&req.hdr, GDMA_DESTROY_MR, sizeof(req), | ||
| 87 | sizeof(resp)); | ||
| 88 | |||
| 89 | req.mr_handle = mr_handle; | ||
| 90 | |||
| 91 | err = mana_gd_send_request(gc, sizeof(req), &req, sizeof(resp), &resp); | ||
| 92 | if (err || resp.hdr.status) { | ||
| 93 | dev_err(gc->dev, "Failed to destroy MR: %d, 0x%x\n", err, | ||
| 94 | resp.hdr.status); | ||
| 95 | if (!err) | ||
| 96 | err = -EPROTO; | ||
| 97 | return err; | ||
| 98 | } | ||
| 99 | |||
| 100 | return 0; | ||
| 101 | } | ||
| 102 | |||
| 103 | struct ib_mr *mana_ib_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 length, | ||
| 104 | u64 iova, int access_flags, | ||
| 105 | struct ib_udata *udata) | ||
| 106 | { | ||
| 107 | struct mana_ib_pd *pd = container_of(ibpd, struct mana_ib_pd, ibpd); | ||
| 108 | struct gdma_create_mr_params mr_params = {}; | ||
| 109 | struct ib_device *ibdev = ibpd->device; | ||
| 110 | struct mana_ib_dev *dev; | ||
| 111 | struct mana_ib_mr *mr; | ||
| 112 | u64 dma_region_handle; | ||
| 113 | int err; | ||
| 114 | |||
| 115 | dev = container_of(ibdev, struct mana_ib_dev, ib_dev); | ||
| 116 | |||
| 117 | ibdev_dbg(ibdev, | ||
| 118 | "start 0x%llx, iova 0x%llx length 0x%llx access_flags 0x%x", | ||
| 119 | start, iova, length, access_flags); | ||
| 120 | |||
| 121 | if (access_flags & ~VALID_MR_FLAGS) | ||
| 122 | return ERR_PTR(-EINVAL); | ||
| 123 | |||
| 124 | mr = kzalloc(sizeof(*mr), GFP_KERNEL); | ||
| 125 | if (!mr) | ||
| 126 | return ERR_PTR(-ENOMEM); | ||
| 127 | |||
| 128 | mr->umem = ib_umem_get(ibdev, start, length, access_flags); | ||
| 129 | if (IS_ERR(mr->umem)) { | ||
| 130 | err = PTR_ERR(mr->umem); | ||
| 131 | ibdev_dbg(ibdev, | ||
| 132 | "Failed to get umem for register user-mr, %d\n", err); | ||
| 133 | goto err_free; | ||
| 134 | } | ||
| 135 | |||
| 136 | err = mana_ib_gd_create_dma_region(dev, mr->umem, &dma_region_handle); | ||
| 137 | if (err) { | ||
| 138 | ibdev_dbg(ibdev, "Failed create dma region for user-mr, %d\n", | ||
| 139 | err); | ||
| 140 | goto err_umem; | ||
| 141 | } | ||
| 142 | |||
| 143 | ibdev_dbg(ibdev, | ||
| 144 | "mana_ib_gd_create_dma_region ret %d gdma_region %llx\n", err, | ||
| 145 | dma_region_handle); | ||
| 146 | |||
| 147 | mr_params.pd_handle = pd->pd_handle; | ||
| 148 | mr_params.mr_type = GDMA_MR_TYPE_GVA; | ||
| 149 | mr_params.gva.dma_region_handle = dma_region_handle; | ||
| 150 | mr_params.gva.virtual_address = iova; | ||
| 151 | mr_params.gva.access_flags = | ||
| 152 | mana_ib_verbs_to_gdma_access_flags(access_flags); | ||
| 153 | |||
| 154 | err = mana_ib_gd_create_mr(dev, mr, &mr_params); | ||
| 155 | if (err) | ||
| 156 | goto err_dma_region; | ||
| 157 | |||
| 158 | /* | ||
| 159 | * There is no need to keep track of dma_region_handle after MR is | ||
| 160 | * successfully created. The dma_region_handle is tracked in the PF | ||
| 161 | * as part of the lifecycle of this MR. | ||
| 162 | */ | ||
| 163 | |||
| 164 | return &mr->ibmr; | ||
| 165 | |||
| 166 | err_dma_region: | ||
| 167 | mana_gd_destroy_dma_region(dev->gdma_dev->gdma_context, | ||
| 168 | dma_region_handle); | ||
| 169 | |||
| 170 | err_umem: | ||
| 171 | ib_umem_release(mr->umem); | ||
| 172 | |||
| 173 | err_free: | ||
| 174 | kfree(mr); | ||
| 175 | return ERR_PTR(err); | ||
| 176 | } | ||
| 177 | |||
| 178 | int mana_ib_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata) | ||
| 179 | { | ||
| 180 | struct mana_ib_mr *mr = container_of(ibmr, struct mana_ib_mr, ibmr); | ||
| 181 | struct ib_device *ibdev = ibmr->device; | ||
| 182 | struct mana_ib_dev *dev; | ||
| 183 | int err; | ||
| 184 | |||
| 185 | dev = container_of(ibdev, struct mana_ib_dev, ib_dev); | ||
| 186 | |||
| 187 | err = mana_ib_gd_destroy_mr(dev, mr->mr_handle); | ||
| 188 | if (err) | ||
| 189 | return err; | ||
| 190 | |||
| 191 | if (mr->umem) | ||
| 192 | ib_umem_release(mr->umem); | ||
| 193 | |||
| 194 | kfree(mr); | ||
| 195 | |||
| 196 | return 0; | ||
| 197 | } | ||
| @@ -0,0 +1,506 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | /* | ||
| 3 | * Copyright (c) 2022, Microsoft Corporation. All rights reserved. | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include "mana_ib.h" | ||
| 7 | |||
| 8 | static int mana_ib_cfg_vport_steering(struct mana_ib_dev *dev, | ||
| 9 | struct net_device *ndev, | ||
| 10 | mana_handle_t default_rxobj, | ||
| 11 | mana_handle_t ind_table[], | ||
| 12 | u32 log_ind_tbl_size, u32 rx_hash_key_len, | ||
| 13 | u8 *rx_hash_key) | ||
| 14 | { | ||
| 15 | struct mana_port_context *mpc = netdev_priv(ndev); | ||
| 16 | struct mana_cfg_rx_steer_req *req = NULL; | ||
| 17 | struct mana_cfg_rx_steer_resp resp = {}; | ||
| 18 | mana_handle_t *req_indir_tab; | ||
| 19 | struct gdma_context *gc; | ||
| 20 | struct gdma_dev *mdev; | ||
| 21 | u32 req_buf_size; | ||
| 22 | int i, err; | ||
| 23 | |||
| 24 | mdev = dev->gdma_dev; | ||
| 25 | gc = mdev->gdma_context; | ||
| 26 | |||
| 27 | req_buf_size = | ||
| 28 | sizeof(*req) + sizeof(mana_handle_t) * MANA_INDIRECT_TABLE_SIZE; | ||
| 29 | req = kzalloc(req_buf_size, GFP_KERNEL); | ||
| 30 | if (!req) | ||
| 31 | return -ENOMEM; | ||
| 32 | |||
| 33 | mana_gd_init_req_hdr(&req->hdr, MANA_CONFIG_VPORT_RX, req_buf_size, | ||
| 34 | sizeof(resp)); | ||
| 35 | |||
| 36 | req->vport = mpc->port_handle; | ||
| 37 | req->rx_enable = 1; | ||
| 38 | req->update_default_rxobj = 1; | ||
| 39 | req->default_rxobj = default_rxobj; | ||
| 40 | req->hdr.dev_id = mdev->dev_id; | ||
| 41 | |||
| 42 | /* If there are more than 1 entries in indirection table, enable RSS */ | ||
| 43 | if (log_ind_tbl_size) | ||
| 44 | req->rss_enable = true; | ||
| 45 | |||
| 46 | req->num_indir_entries = MANA_INDIRECT_TABLE_SIZE; | ||
| 47 | req->indir_tab_offset = sizeof(*req); | ||
| 48 | req->update_indir_tab = true; | ||
| 49 | |||
| 50 | req_indir_tab = (mana_handle_t *)(req + 1); | ||
| 51 | /* The ind table passed to the hardware must have | ||
| 52 | * MANA_INDIRECT_TABLE_SIZE entries. Adjust the verb | ||
| 53 | * ind_table to MANA_INDIRECT_TABLE_SIZE if required | ||
| 54 | */ | ||
| 55 | ibdev_dbg(&dev->ib_dev, "ind table size %u\n", 1 << log_ind_tbl_size); | ||
| 56 | for (i = 0; i < MANA_INDIRECT_TABLE_SIZE; i++) { | ||
| 57 | req_indir_tab[i] = ind_table[i % (1 << log_ind_tbl_size)]; | ||
| 58 | ibdev_dbg(&dev->ib_dev, "index %u handle 0x%llx\n", i, | ||
| 59 | req_indir_tab[i]); | ||
| 60 | } | ||
| 61 | |||
| 62 | req->update_hashkey = true; | ||
| 63 | if (rx_hash_key_len) | ||
| 64 | memcpy(req->hashkey, rx_hash_key, rx_hash_key_len); | ||
| 65 | else | ||
| 66 | netdev_rss_key_fill(req->hashkey, MANA_HASH_KEY_SIZE); | ||
| 67 | |||
| 68 | ibdev_dbg(&dev->ib_dev, "vport handle %llu default_rxobj 0x%llx\n", | ||
| 69 | req->vport, default_rxobj); | ||
| 70 | |||
| 71 | err = mana_gd_send_request(gc, req_buf_size, req, sizeof(resp), &resp); | ||
| 72 | if (err) { | ||
| 73 | netdev_err(ndev, "Failed to configure vPort RX: %d\n", err); | ||
| 74 | goto out; | ||
| 75 | } | ||
| 76 | |||
| 77 | if (resp.hdr.status) { | ||
| 78 | netdev_err(ndev, "vPort RX configuration failed: 0x%x\n", | ||
| 79 | resp.hdr.status); | ||
| 80 | err = -EPROTO; | ||
| 81 | goto out; | ||
| 82 | } | ||
| 83 | |||
| 84 | netdev_info(ndev, "Configured steering vPort %llu log_entries %u\n", | ||
| 85 | mpc->port_handle, log_ind_tbl_size); | ||
| 86 | |||
| 87 | out: | ||
| 88 | kfree(req); | ||
| 89 | return err; | ||
| 90 | } | ||
| 91 | |||
| 92 | static int mana_ib_create_qp_rss(struct ib_qp *ibqp, struct ib_pd *pd, | ||
| 93 | struct ib_qp_init_attr *attr, | ||
| 94 | struct ib_udata *udata) | ||
| 95 | { | ||
| 96 | struct mana_ib_qp *qp = container_of(ibqp, struct mana_ib_qp, ibqp); | ||
| 97 | struct mana_ib_dev *mdev = | ||
| 98 | container_of(pd->device, struct mana_ib_dev, ib_dev); | ||
| 99 | struct ib_rwq_ind_table *ind_tbl = attr->rwq_ind_tbl; | ||
| 100 | struct mana_ib_create_qp_rss_resp resp = {}; | ||
| 101 | struct mana_ib_create_qp_rss ucmd = {}; | ||
| 102 | struct gdma_dev *gd = mdev->gdma_dev; | ||
| 103 | mana_handle_t *mana_ind_table; | ||
| 104 | struct mana_port_context *mpc; | ||
| 105 | struct mana_context *mc; | ||
| 106 | struct net_device *ndev; | ||
| 107 | struct mana_ib_cq *cq; | ||
| 108 | struct mana_ib_wq *wq; | ||
| 109 | unsigned int ind_tbl_size; | ||
| 110 | struct ib_cq *ibcq; | ||
| 111 | struct ib_wq *ibwq; | ||
| 112 | int i = 0; | ||
| 113 | u32 port; | ||
| 114 | int ret; | ||
| 115 | |||
| 116 | mc = gd->driver_data; | ||
| 117 | |||
| 118 | if (!udata || udata->inlen < sizeof(ucmd)) | ||
| 119 | return -EINVAL; | ||
| 120 | |||
| 121 | ret = ib_copy_from_udata(&ucmd, udata, min(sizeof(ucmd), udata->inlen)); | ||
| 122 | if (ret) { | ||
| 123 | ibdev_dbg(&mdev->ib_dev, | ||
| 124 | "Failed copy from udata for create rss-qp, err %d\n", | ||
| 125 | ret); | ||
| 126 | return ret; | ||
| 127 | } | ||
| 128 | |||
| 129 | if (attr->cap.max_recv_wr > MAX_SEND_BUFFERS_PER_QUEUE) { | ||
| 130 | ibdev_dbg(&mdev->ib_dev, | ||
| 131 | "Requested max_recv_wr %d exceeding limit\n", | ||
| 132 | attr->cap.max_recv_wr); | ||
| 133 | return -EINVAL; | ||
| 134 | } | ||
| 135 | |||
| 136 | if (attr->cap.max_recv_sge > MAX_RX_WQE_SGL_ENTRIES) { | ||
| 137 | ibdev_dbg(&mdev->ib_dev, | ||
| 138 | "Requested max_recv_sge %d exceeding limit\n", | ||
| 139 | attr->cap.max_recv_sge); | ||
| 140 | return -EINVAL; | ||
| 141 | } | ||
| 142 | |||
| 143 | ind_tbl_size = 1 << ind_tbl->log_ind_tbl_size; | ||
| 144 | if (ind_tbl_size > MANA_INDIRECT_TABLE_SIZE) { | ||
| 145 | ibdev_dbg(&mdev->ib_dev, | ||
| 146 | "Indirect table size %d exceeding limit\n", | ||
| 147 | ind_tbl_size); | ||
| 148 | return -EINVAL; | ||
| 149 | } | ||
| 150 | |||
| 151 | if (ucmd.rx_hash_function != MANA_IB_RX_HASH_FUNC_TOEPLITZ) { | ||
| 152 | ibdev_dbg(&mdev->ib_dev, | ||
| 153 | "RX Hash function is not supported, %d\n", | ||
| 154 | ucmd.rx_hash_function); | ||
| 155 | return -EINVAL; | ||
| 156 | } | ||
| 157 | |||
| 158 | /* IB ports start with 1, MANA start with 0 */ | ||
| 159 | port = ucmd.port; | ||
| 160 | if (port < 1 || port > mc->num_ports) { | ||
| 161 | ibdev_dbg(&mdev->ib_dev, "Invalid port %u in creating qp\n", | ||
| 162 | port); | ||
| 163 | return -EINVAL; | ||
| 164 | } | ||
| 165 | ndev = mc->ports[port - 1]; | ||
| 166 | mpc = netdev_priv(ndev); | ||
| 167 | |||
| 168 | ibdev_dbg(&mdev->ib_dev, "rx_hash_function %d port %d\n", | ||
| 169 | ucmd.rx_hash_function, port); | ||
| 170 | |||
| 171 | mana_ind_table = kcalloc(ind_tbl_size, sizeof(mana_handle_t), | ||
| 172 | GFP_KERNEL); | ||
| 173 | if (!mana_ind_table) { | ||
| 174 | ret = -ENOMEM; | ||
| 175 | goto fail; | ||
| 176 | } | ||
| 177 | |||
| 178 | qp->port = port; | ||
| 179 | |||
| 180 | for (i = 0; i < ind_tbl_size; i++) { | ||
| 181 | struct mana_obj_spec wq_spec = {}; | ||
| 182 | struct mana_obj_spec cq_spec = {}; | ||
| 183 | |||
| 184 | ibwq = ind_tbl->ind_tbl[i]; | ||
| 185 | wq = container_of(ibwq, struct mana_ib_wq, ibwq); | ||
| 186 | |||
| 187 | ibcq = ibwq->cq; | ||
| 188 | cq = container_of(ibcq, struct mana_ib_cq, ibcq); | ||
| 189 | |||
| 190 | wq_spec.gdma_region = wq->gdma_region; | ||
| 191 | wq_spec.queue_size = wq->wq_buf_size; | ||
| 192 | |||
| 193 | cq_spec.gdma_region = cq->gdma_region; | ||
| 194 | cq_spec.queue_size = cq->cqe * COMP_ENTRY_SIZE; | ||
| 195 | cq_spec.modr_ctx_id = 0; | ||
| 196 | cq_spec.attached_eq = GDMA_CQ_NO_EQ; | ||
| 197 | |||
| 198 | ret = mana_create_wq_obj(mpc, mpc->port_handle, GDMA_RQ, | ||
| 199 | &wq_spec, &cq_spec, &wq->rx_object); | ||
| 200 | if (ret) | ||
| 201 | goto fail; | ||
| 202 | |||
| 203 | /* The GDMA regions are now owned by the WQ object */ | ||
| 204 | wq->gdma_region = GDMA_INVALID_DMA_REGION; | ||
| 205 | cq->gdma_region = GDMA_INVALID_DMA_REGION; | ||
| 206 | |||
| 207 | wq->id = wq_spec.queue_index; | ||
| 208 | cq->id = cq_spec.queue_index; | ||
| 209 | |||
| 210 | ibdev_dbg(&mdev->ib_dev, | ||
| 211 | "ret %d rx_object 0x%llx wq id %llu cq id %llu\n", | ||
| 212 | ret, wq->rx_object, wq->id, cq->id); | ||
| 213 | |||
| 214 | resp.entries[i].cqid = cq->id; | ||
| 215 | resp.entries[i].wqid = wq->id; | ||
| 216 | |||
| 217 | mana_ind_table[i] = wq->rx_object; | ||
| 218 | } | ||
| 219 | resp.num_entries = i; | ||
| 220 | |||
| 221 | ret = mana_ib_cfg_vport_steering(mdev, ndev, wq->rx_object, | ||
| 222 | mana_ind_table, | ||
| 223 | ind_tbl->log_ind_tbl_size, | ||
| 224 | ucmd.rx_hash_key_len, | ||
| 225 | ucmd.rx_hash_key); | ||
| 226 | if (ret) | ||
| 227 | goto fail; | ||
| 228 | |||
| 229 | ret = ib_copy_to_udata(udata, &resp, sizeof(resp)); | ||
| 230 | if (ret) { | ||
| 231 | ibdev_dbg(&mdev->ib_dev, | ||
| 232 | "Failed to copy to udata create rss-qp, %d\n", | ||
| 233 | ret); | ||
| 234 | goto fail; | ||
| 235 | } | ||
| 236 | |||
| 237 | kfree(mana_ind_table); | ||
| 238 | |||
| 239 | return 0; | ||
| 240 | |||
| 241 | fail: | ||
| 242 | while (i-- > 0) { | ||
| 243 | ibwq = ind_tbl->ind_tbl[i]; | ||
| 244 | wq = container_of(ibwq, struct mana_ib_wq, ibwq); | ||
| 245 | mana_destroy_wq_obj(mpc, GDMA_RQ, wq->rx_object); | ||
| 246 | } | ||
| 247 | |||
| 248 | kfree(mana_ind_table); | ||
| 249 | |||
| 250 | return ret; | ||
| 251 | } | ||
| 252 | |||
| 253 | static int mana_ib_create_qp_raw(struct ib_qp *ibqp, struct ib_pd *ibpd, | ||
| 254 | struct ib_qp_init_attr *attr, | ||
| 255 | struct ib_udata *udata) | ||
| 256 | { | ||
| 257 | struct mana_ib_pd *pd = container_of(ibpd, struct mana_ib_pd, ibpd); | ||
| 258 | struct mana_ib_qp *qp = container_of(ibqp, struct mana_ib_qp, ibqp); | ||
| 259 | struct mana_ib_dev *mdev = | ||
| 260 | container_of(ibpd->device, struct mana_ib_dev, ib_dev); | ||
| 261 | struct mana_ib_cq *send_cq = | ||
| 262 | container_of(attr->send_cq, struct mana_ib_cq, ibcq); | ||
| 263 | struct mana_ib_ucontext *mana_ucontext = | ||
| 264 | rdma_udata_to_drv_context(udata, struct mana_ib_ucontext, | ||
| 265 | ibucontext); | ||
| 266 | struct mana_ib_create_qp_resp resp = {}; | ||
| 267 | struct gdma_dev *gd = mdev->gdma_dev; | ||
| 268 | struct mana_ib_create_qp ucmd = {}; | ||
| 269 | struct mana_obj_spec wq_spec = {}; | ||
| 270 | struct mana_obj_spec cq_spec = {}; | ||
| 271 | struct mana_port_context *mpc; | ||
| 272 | struct mana_context *mc; | ||
| 273 | struct net_device *ndev; | ||
| 274 | struct ib_umem *umem; | ||
| 275 | int err; | ||
| 276 | u32 port; | ||
| 277 | |||
| 278 | mc = gd->driver_data; | ||
| 279 | |||
| 280 | if (!mana_ucontext || udata->inlen < sizeof(ucmd)) | ||
| 281 | return -EINVAL; | ||
| 282 | |||
| 283 | err = ib_copy_from_udata(&ucmd, udata, min(sizeof(ucmd), udata->inlen)); | ||
| 284 | if (err) { | ||
| 285 | ibdev_dbg(&mdev->ib_dev, | ||
| 286 | "Failed to copy from udata create qp-raw, %d\n", err); | ||
| 287 | return err; | ||
| 288 | } | ||
| 289 | |||
| 290 | /* IB ports start with 1, MANA Ethernet ports start with 0 */ | ||
| 291 | port = ucmd.port; | ||
| 292 | if (ucmd.port > mc->num_ports) | ||
| 293 | return -EINVAL; | ||
| 294 | |||
| 295 | if (attr->cap.max_send_wr > MAX_SEND_BUFFERS_PER_QUEUE) { | ||
| 296 | ibdev_dbg(&mdev->ib_dev, | ||
| 297 | "Requested max_send_wr %d exceeding limit\n", | ||
| 298 | attr->cap.max_send_wr); | ||
| 299 | return -EINVAL; | ||
| 300 | } | ||
| 301 | |||
| 302 | if (attr->cap.max_send_sge > MAX_TX_WQE_SGL_ENTRIES) { | ||
| 303 | ibdev_dbg(&mdev->ib_dev, | ||
| 304 | "Requested max_send_sge %d exceeding limit\n", | ||
| 305 | attr->cap.max_send_sge); | ||
| 306 | return -EINVAL; | ||
| 307 | } | ||
| 308 | |||
| 309 | ndev = mc->ports[port - 1]; | ||
| 310 | mpc = netdev_priv(ndev); | ||
| 311 | ibdev_dbg(&mdev->ib_dev, "port %u ndev %p mpc %p\n", port, ndev, mpc); | ||
| 312 | |||
| 313 | err = mana_ib_cfg_vport(mdev, port - 1, pd, mana_ucontext->doorbell); | ||
| 314 | if (err) | ||
| 315 | return -ENODEV; | ||
| 316 | |||
| 317 | qp->port = port; | ||
| 318 | |||
| 319 | ibdev_dbg(&mdev->ib_dev, "ucmd sq_buf_addr 0x%llx port %u\n", | ||
| 320 | ucmd.sq_buf_addr, ucmd.port); | ||
| 321 | |||
| 322 | umem = ib_umem_get(ibpd->device, ucmd.sq_buf_addr, ucmd.sq_buf_size, | ||
| 323 | IB_ACCESS_LOCAL_WRITE); | ||
| 324 | if (IS_ERR(umem)) { | ||
| 325 | err = PTR_ERR(umem); | ||
| 326 | ibdev_dbg(&mdev->ib_dev, | ||
| 327 | "Failed to get umem for create qp-raw, err %d\n", | ||
| 328 | err); | ||
| 329 | goto err_free_vport; | ||
| 330 | } | ||
| 331 | qp->sq_umem = umem; | ||
| 332 | |||
| 333 | err = mana_ib_gd_create_dma_region(mdev, qp->sq_umem, | ||
| 334 | &qp->sq_gdma_region); | ||
| 335 | if (err) { | ||
| 336 | ibdev_dbg(&mdev->ib_dev, | ||
| 337 | "Failed to create dma region for create qp-raw, %d\n", | ||
| 338 | err); | ||
| 339 | goto err_release_umem; | ||
| 340 | } | ||
| 341 | |||
| 342 | ibdev_dbg(&mdev->ib_dev, | ||
| 343 | "mana_ib_gd_create_dma_region ret %d gdma_region 0x%llx\n", | ||
| 344 | err, qp->sq_gdma_region); | ||
| 345 | |||
| 346 | /* Create a WQ on the same port handle used by the Ethernet */ | ||
| 347 | wq_spec.gdma_region = qp->sq_gdma_region; | ||
| 348 | wq_spec.queue_size = ucmd.sq_buf_size; | ||
| 349 | |||
| 350 | cq_spec.gdma_region = send_cq->gdma_region; | ||
| 351 | cq_spec.queue_size = send_cq->cqe * COMP_ENTRY_SIZE; | ||
| 352 | cq_spec.modr_ctx_id = 0; | ||
| 353 | cq_spec.attached_eq = GDMA_CQ_NO_EQ; | ||
| 354 | |||
| 355 | err = mana_create_wq_obj(mpc, mpc->port_handle, GDMA_SQ, &wq_spec, | ||
| 356 | &cq_spec, &qp->tx_object); | ||
| 357 | if (err) { | ||
| 358 | ibdev_dbg(&mdev->ib_dev, | ||
| 359 | "Failed to create wq for create raw-qp, err %d\n", | ||
| 360 | err); | ||
| 361 | goto err_destroy_dma_region; | ||
| 362 | } | ||
| 363 | |||
| 364 | /* The GDMA regions are now owned by the WQ object */ | ||
| 365 | qp->sq_gdma_region = GDMA_INVALID_DMA_REGION; | ||
| 366 | send_cq->gdma_region = GDMA_INVALID_DMA_REGION; | ||
| 367 | |||
| 368 | qp->sq_id = wq_spec.queue_index; | ||
| 369 | send_cq->id = cq_spec.queue_index; | ||
| 370 | |||
| 371 | ibdev_dbg(&mdev->ib_dev, | ||
| 372 | "ret %d qp->tx_object 0x%llx sq id %llu cq id %llu\n", err, | ||
| 373 | qp->tx_object, qp->sq_id, send_cq->id); | ||
| 374 | |||
| 375 | resp.sqid = qp->sq_id; | ||
| 376 | resp.cqid = send_cq->id; | ||
| 377 | resp.tx_vp_offset = pd->tx_vp_offset; | ||
| 378 | |||
| 379 | err = ib_copy_to_udata(udata, &resp, sizeof(resp)); | ||
| 380 | if (err) { | ||
| 381 | ibdev_dbg(&mdev->ib_dev, | ||
| 382 | "Failed copy udata for create qp-raw, %d\n", | ||
| 383 | err); | ||
| 384 | goto err_destroy_wq_obj; | ||
| 385 | } | ||
| 386 | |||
| 387 | return 0; | ||
| 388 | |||
| 389 | err_destroy_wq_obj: | ||
| 390 | mana_destroy_wq_obj(mpc, GDMA_SQ, qp->tx_object); | ||
| 391 | |||
| 392 | err_destroy_dma_region: | ||
| 393 | mana_ib_gd_destroy_dma_region(mdev, qp->sq_gdma_region); | ||
| 394 | |||
| 395 | err_release_umem: | ||
| 396 | ib_umem_release(umem); | ||
| 397 | |||
| 398 | err_free_vport: | ||
| 399 | mana_ib_uncfg_vport(mdev, pd, port - 1); | ||
| 400 | |||
| 401 | return err; | ||
| 402 | } | ||
| 403 | |||
| 404 | int mana_ib_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attr, | ||
| 405 | struct ib_udata *udata) | ||
| 406 | { | ||
| 407 | switch (attr->qp_type) { | ||
| 408 | case IB_QPT_RAW_PACKET: | ||
| 409 | /* When rwq_ind_tbl is used, it's for creating WQs for RSS */ | ||
| 410 | if (attr->rwq_ind_tbl) | ||
| 411 | return mana_ib_create_qp_rss(ibqp, ibqp->pd, attr, | ||
| 412 | udata); | ||
| 413 | |||
| 414 | return mana_ib_create_qp_raw(ibqp, ibqp->pd, attr, udata); | ||
| 415 | default: | ||
| 416 | /* Creating QP other than IB_QPT_RAW_PACKET is not supported */ | ||
| 417 | ibdev_dbg(ibqp->device, "Creating QP type %u not supported\n", | ||
| 418 | attr->qp_type); | ||
| 419 | } | ||
| 420 | |||
| 421 | return -EINVAL; | ||
| 422 | } | ||
| 423 | |||
| 424 | int mana_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, | ||
| 425 | int attr_mask, struct ib_udata *udata) | ||
| 426 | { | ||
| 427 | /* modify_qp is not supported by this version of the driver */ | ||
| 428 | return -EOPNOTSUPP; | ||
| 429 | } | ||
| 430 | |||
| 431 | static int mana_ib_destroy_qp_rss(struct mana_ib_qp *qp, | ||
| 432 | struct ib_rwq_ind_table *ind_tbl, | ||
| 433 | struct ib_udata *udata) | ||
| 434 | { | ||
| 435 | struct mana_ib_dev *mdev = | ||
| 436 | container_of(qp->ibqp.device, struct mana_ib_dev, ib_dev); | ||
| 437 | struct gdma_dev *gd = mdev->gdma_dev; | ||
| 438 | struct mana_port_context *mpc; | ||
| 439 | struct mana_context *mc; | ||
| 440 | struct net_device *ndev; | ||
| 441 | struct mana_ib_wq *wq; | ||
| 442 | struct ib_wq *ibwq; | ||
| 443 | int i; | ||
| 444 | |||
| 445 | mc = gd->driver_data; | ||
| 446 | ndev = mc->ports[qp->port - 1]; | ||
| 447 | mpc = netdev_priv(ndev); | ||
| 448 | |||
| 449 | for (i = 0; i < (1 << ind_tbl->log_ind_tbl_size); i++) { | ||
| 450 | ibwq = ind_tbl->ind_tbl[i]; | ||
| 451 | wq = container_of(ibwq, struct mana_ib_wq, ibwq); | ||
| 452 | ibdev_dbg(&mdev->ib_dev, "destroying wq->rx_object %llu\n", | ||
| 453 | wq->rx_object); | ||
| 454 | mana_destroy_wq_obj(mpc, GDMA_RQ, wq->rx_object); | ||
| 455 | } | ||
| 456 | |||
| 457 | return 0; | ||
| 458 | } | ||
| 459 | |||
| 460 | static int mana_ib_destroy_qp_raw(struct mana_ib_qp *qp, struct ib_udata *udata) | ||
| 461 | { | ||
| 462 | struct mana_ib_dev *mdev = | ||
| 463 | container_of(qp->ibqp.device, struct mana_ib_dev, ib_dev); | ||
| 464 | struct gdma_dev *gd = mdev->gdma_dev; | ||
| 465 | struct ib_pd *ibpd = qp->ibqp.pd; | ||
| 466 | struct mana_port_context *mpc; | ||
| 467 | struct mana_context *mc; | ||
| 468 | struct net_device *ndev; | ||
| 469 | struct mana_ib_pd *pd; | ||
| 470 | |||
| 471 | mc = gd->driver_data; | ||
| 472 | ndev = mc->ports[qp->port - 1]; | ||
| 473 | mpc = netdev_priv(ndev); | ||
| 474 | pd = container_of(ibpd, struct mana_ib_pd, ibpd); | ||
| 475 | |||
| 476 | mana_destroy_wq_obj(mpc, GDMA_SQ, qp->tx_object); | ||
| 477 | |||
| 478 | if (qp->sq_umem) { | ||
| 479 | mana_ib_gd_destroy_dma_region(mdev, qp->sq_gdma_region); | ||
| 480 | ib_umem_release(qp->sq_umem); | ||
| 481 | } | ||
| 482 | |||
| 483 | mana_ib_uncfg_vport(mdev, pd, qp->port - 1); | ||
| 484 | |||
| 485 | return 0; | ||
| 486 | } | ||
| 487 | |||
| 488 | int mana_ib_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata) | ||
| 489 | { | ||
| 490 | struct mana_ib_qp *qp = container_of(ibqp, struct mana_ib_qp, ibqp); | ||
| 491 | |||
| 492 | switch (ibqp->qp_type) { | ||
| 493 | case IB_QPT_RAW_PACKET: | ||
| 494 | if (ibqp->rwq_ind_tbl) | ||
| 495 | return mana_ib_destroy_qp_rss(qp, ibqp->rwq_ind_tbl, | ||
| 496 | udata); | ||
| 497 | |||
| 498 | return mana_ib_destroy_qp_raw(qp, udata); | ||
| 499 | |||
| 500 | default: | ||
| 501 | ibdev_dbg(ibqp->device, "Unexpected QP type %u\n", | ||
| 502 | ibqp->qp_type); | ||
| 503 | } | ||
| 504 | |||
| 505 | return -ENOENT; | ||
| 506 | } | ||
| @@ -0,0 +1,115 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | /* | ||
| 3 | * Copyright (c) 2022, Microsoft Corporation. All rights reserved. | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include "mana_ib.h" | ||
| 7 | |||
| 8 | struct ib_wq *mana_ib_create_wq(struct ib_pd *pd, | ||
| 9 | struct ib_wq_init_attr *init_attr, | ||
| 10 | struct ib_udata *udata) | ||
| 11 | { | ||
| 12 | struct mana_ib_dev *mdev = | ||
| 13 | container_of(pd->device, struct mana_ib_dev, ib_dev); | ||
| 14 | struct mana_ib_create_wq ucmd = {}; | ||
| 15 | struct mana_ib_wq *wq; | ||
| 16 | struct ib_umem *umem; | ||
| 17 | int err; | ||
| 18 | |||
| 19 | if (udata->inlen < sizeof(ucmd)) | ||
| 20 | return ERR_PTR(-EINVAL); | ||
| 21 | |||
| 22 | err = ib_copy_from_udata(&ucmd, udata, min(sizeof(ucmd), udata->inlen)); | ||
| 23 | if (err) { | ||
| 24 | ibdev_dbg(&mdev->ib_dev, | ||
| 25 | "Failed to copy from udata for create wq, %d\n", err); | ||
| 26 | return ERR_PTR(err); | ||
| 27 | } | ||
| 28 | |||
| 29 | wq = kzalloc(sizeof(*wq), GFP_KERNEL); | ||
| 30 | if (!wq) | ||
| 31 | return ERR_PTR(-ENOMEM); | ||
| 32 | |||
| 33 | ibdev_dbg(&mdev->ib_dev, "ucmd wq_buf_addr 0x%llx\n", ucmd.wq_buf_addr); | ||
| 34 | |||
| 35 | umem = ib_umem_get(pd->device, ucmd.wq_buf_addr, ucmd.wq_buf_size, | ||
| 36 | IB_ACCESS_LOCAL_WRITE); | ||
| 37 | if (IS_ERR(umem)) { | ||
| 38 | err = PTR_ERR(umem); | ||
| 39 | ibdev_dbg(&mdev->ib_dev, | ||
| 40 | "Failed to get umem for create wq, err %d\n", err); | ||
| 41 | goto err_free_wq; | ||
| 42 | } | ||
| 43 | |||
| 44 | wq->umem = umem; | ||
| 45 | wq->wqe = init_attr->max_wr; | ||
| 46 | wq->wq_buf_size = ucmd.wq_buf_size; | ||
| 47 | wq->rx_object = INVALID_MANA_HANDLE; | ||
| 48 | |||
| 49 | err = mana_ib_gd_create_dma_region(mdev, wq->umem, &wq->gdma_region); | ||
| 50 | if (err) { | ||
| 51 | ibdev_dbg(&mdev->ib_dev, | ||
| 52 | "Failed to create dma region for create wq, %d\n", | ||
| 53 | err); | ||
| 54 | goto err_release_umem; | ||
| 55 | } | ||
| 56 | |||
| 57 | ibdev_dbg(&mdev->ib_dev, | ||
| 58 | "mana_ib_gd_create_dma_region ret %d gdma_region 0x%llx\n", | ||
| 59 | err, wq->gdma_region); | ||
| 60 | |||
| 61 | /* WQ ID is returned at wq_create time, doesn't know the value yet */ | ||
| 62 | |||
| 63 | return &wq->ibwq; | ||
| 64 | |||
| 65 | err_release_umem: | ||
| 66 | ib_umem_release(umem); | ||
| 67 | |||
| 68 | err_free_wq: | ||
| 69 | kfree(wq); | ||
| 70 | |||
| 71 | return ERR_PTR(err); | ||
| 72 | } | ||
| 73 | |||
| 74 | int mana_ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *wq_attr, | ||
| 75 | u32 wq_attr_mask, struct ib_udata *udata) | ||
| 76 | { | ||
| 77 | /* modify_wq is not supported by this version of the driver */ | ||
| 78 | return -EOPNOTSUPP; | ||
| 79 | } | ||
| 80 | |||
| 81 | int mana_ib_destroy_wq(struct ib_wq *ibwq, struct ib_udata *udata) | ||
| 82 | { | ||
| 83 | struct mana_ib_wq *wq = container_of(ibwq, struct mana_ib_wq, ibwq); | ||
| 84 | struct ib_device *ib_dev = ibwq->device; | ||
| 85 | struct mana_ib_dev *mdev; | ||
| 86 | |||
| 87 | mdev = container_of(ib_dev, struct mana_ib_dev, ib_dev); | ||
| 88 | |||
| 89 | mana_ib_gd_destroy_dma_region(mdev, wq->gdma_region); | ||
| 90 | ib_umem_release(wq->umem); | ||
| 91 | |||
| 92 | kfree(wq); | ||
| 93 | |||
| 94 | return 0; | ||
| 95 | } | ||
| 96 | |||
| 97 | int mana_ib_create_rwq_ind_table(struct ib_rwq_ind_table *ib_rwq_ind_table, | ||
| 98 | struct ib_rwq_ind_table_init_attr *init_attr, | ||
| 99 | struct ib_udata *udata) | ||
| 100 | { | ||
| 101 | /* | ||
| 102 | * There is no additional data in ind_table to be maintained by this | ||
| 103 | * driver, do nothing | ||
| 104 | */ | ||
| 105 | return 0; | ||
| 106 | } | ||
| 107 | |||
| 108 | int mana_ib_destroy_rwq_ind_table(struct ib_rwq_ind_table *ib_rwq_ind_tbl) | ||
| 109 | { | ||
| 110 | /* | ||
| 111 | * There is no additional data in ind_table to be maintained by this | ||
| 112 | * driver, do nothing | ||
| 113 | */ | ||
| 114 | return 0; | ||
| 115 | } | ||
| @@ -144,8 +144,7 @@ static struct net_device *mlx4_ib_get_netdev(struct ib_device *device, · 143 unmodified lines | |||
| 144 | } | 144 | } |
| 145 | } | 145 | } |
| 146 | } | 146 | } |
| 147 | if (dev) | 147 | dev_hold(dev); |
| 148 | dev_hold(dev); | ||
| 149 | 148 | ||
| 150 | rcu_read_unlock(); | 149 | rcu_read_unlock(); |
| 151 | return dev; | 150 | return dev; |
| @@ -1307,8 +1306,7 @@ int mlx4_ib_add_mc(struct mlx4_ib_dev *mdev, struct mlx4_ib_qp *mqp, · 1155 unmodified lines | |||
| 1307 | 1306 | ||
| 1308 | spin_lock_bh(&mdev->iboe.lock); | 1307 | spin_lock_bh(&mdev->iboe.lock); |
| 1309 | ndev = mdev->iboe.netdevs[mqp->port - 1]; | 1308 | ndev = mdev->iboe.netdevs[mqp->port - 1]; |
| 1310 | if (ndev) | 1309 | dev_hold(ndev); |
| 1311 | dev_hold(ndev); | ||
| 1312 | spin_unlock_bh(&mdev->iboe.lock); | 1310 | spin_unlock_bh(&mdev->iboe.lock); |
| 1313 | 1311 | ||
| 1314 | if (ndev) { | 1312 | if (ndev) { |
| @@ -1955,11 +1953,9 @@ static int mlx4_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) · 640 unmodified lines | |||
| 1955 | if (ge) { | 1953 | if (ge) { |
| 1956 | spin_lock_bh(&mdev->iboe.lock); | 1954 | spin_lock_bh(&mdev->iboe.lock); |
| 1957 | ndev = ge->added ? mdev->iboe.netdevs[ge->port - 1] : NULL; | 1955 | ndev = ge->added ? mdev->iboe.netdevs[ge->port - 1] : NULL; |
| 1958 | if (ndev) | 1956 | dev_hold(ndev); |
| 1959 | dev_hold(ndev); | ||
| 1960 | spin_unlock_bh(&mdev->iboe.lock); | 1957 | spin_unlock_bh(&mdev->iboe.lock); |
| 1961 | if (ndev) | 1958 | dev_put(ndev); |
| 1962 | dev_put(ndev); | ||
| 1963 | list_del(&ge->list); | 1959 | list_del(&ge->list); |
| 1964 | kfree(ge); | 1960 | kfree(ge); |
| 1965 | } else | 1961 | } else |
| @@ -267,17 +267,20 @@ static void handle_responder(struct ib_wc *wc, struct mlx5_cqe64 *cqe, · 266 unmodified lines | |||
| 267 | wc->wc_flags |= IB_WC_WITH_NETWORK_HDR_TYPE; | 267 | wc->wc_flags |= IB_WC_WITH_NETWORK_HDR_TYPE; |
| 268 | } | 268 | } |
| 269 | 269 | ||
| 270 | static void dump_cqe(struct mlx5_ib_dev *dev, struct mlx5_err_cqe *cqe) | 270 | static void dump_cqe(struct mlx5_ib_dev *dev, struct mlx5_err_cqe *cqe, |
| 271 | struct ib_wc *wc, const char *level) | ||
| 271 | { | 272 | { |
| 272 | mlx5_ib_warn(dev, "dump error cqe\n"); | 273 | mlx5_ib_log(level, dev, "WC error: %d, Message: %s\n", wc->status, |
| 273 | mlx5_dump_err_cqe(dev->mdev, cqe); | 274 | ib_wc_status_msg(wc->status)); |
| 275 | print_hex_dump(level, "cqe_dump: ", DUMP_PREFIX_OFFSET, 16, 1, | ||
| 276 | cqe, sizeof(*cqe), false); | ||
| 274 | } | 277 | } |
| 275 | 278 | ||
| 276 | static void mlx5_handle_error_cqe(struct mlx5_ib_dev *dev, | 279 | static void mlx5_handle_error_cqe(struct mlx5_ib_dev *dev, |
| 277 | struct mlx5_err_cqe *cqe, | 280 | struct mlx5_err_cqe *cqe, |
| 278 | struct ib_wc *wc) | 281 | struct ib_wc *wc) |
| 279 | { | 282 | { |
| 280 | int dump = 1; | 283 | const char *dump = KERN_WARNING; |
| 281 | 284 | ||
| 282 | switch (cqe->syndrome) { | 285 | switch (cqe->syndrome) { |
| 283 | case MLX5_CQE_SYNDROME_LOCAL_LENGTH_ERR: | 286 | case MLX5_CQE_SYNDROME_LOCAL_LENGTH_ERR: |
| @@ -287,10 +290,11 @@ static void mlx5_handle_error_cqe(struct mlx5_ib_dev *dev, · 3 unmodified lines | |||
| 287 | wc->status = IB_WC_LOC_QP_OP_ERR; | 290 | wc->status = IB_WC_LOC_QP_OP_ERR; |
| 288 | break; | 291 | break; |
| 289 | case MLX5_CQE_SYNDROME_LOCAL_PROT_ERR: | 292 | case MLX5_CQE_SYNDROME_LOCAL_PROT_ERR: |
| 293 | dump = KERN_DEBUG; | ||
| 290 | wc->status = IB_WC_LOC_PROT_ERR; | 294 | wc->status = IB_WC_LOC_PROT_ERR; |
| 291 | break; | 295 | break; |
| 292 | case MLX5_CQE_SYNDROME_WR_FLUSH_ERR: | 296 | case MLX5_CQE_SYNDROME_WR_FLUSH_ERR: |
| 293 | dump = 0; | 297 | dump = NULL; |
| 294 | wc->status = IB_WC_WR_FLUSH_ERR; | 298 | wc->status = IB_WC_WR_FLUSH_ERR; |
| 295 | break; | 299 | break; |
| 296 | case MLX5_CQE_SYNDROME_MW_BIND_ERR: | 300 | case MLX5_CQE_SYNDROME_MW_BIND_ERR: |
| @@ -306,18 +310,20 @@ static void mlx5_handle_error_cqe(struct mlx5_ib_dev *dev, · 9 unmodified lines | |||
| 306 | wc->status = IB_WC_REM_INV_REQ_ERR; | 310 | wc->status = IB_WC_REM_INV_REQ_ERR; |
| 307 | break; | 311 | break; |
| 308 | case MLX5_CQE_SYNDROME_REMOTE_ACCESS_ERR: | 312 | case MLX5_CQE_SYNDROME_REMOTE_ACCESS_ERR: |
| 313 | dump = KERN_DEBUG; | ||
| 309 | wc->status = IB_WC_REM_ACCESS_ERR; | 314 | wc->status = IB_WC_REM_ACCESS_ERR; |
| 310 | break; | 315 | break; |
| 311 | case MLX5_CQE_SYNDROME_REMOTE_OP_ERR: | 316 | case MLX5_CQE_SYNDROME_REMOTE_OP_ERR: |
| 317 | dump = KERN_DEBUG; | ||
| 312 | wc->status = IB_WC_REM_OP_ERR; | 318 | wc->status = IB_WC_REM_OP_ERR; |
| 313 | break; | 319 | break; |
| 314 | case MLX5_CQE_SYNDROME_TRANSPORT_RETRY_EXC_ERR: | 320 | case MLX5_CQE_SYNDROME_TRANSPORT_RETRY_EXC_ERR: |
| 321 | dump = NULL; | ||
| 315 | wc->status = IB_WC_RETRY_EXC_ERR; | 322 | wc->status = IB_WC_RETRY_EXC_ERR; |
| 316 | dump = 0; | ||
| 317 | break; | 323 | break; |
| 318 | case MLX5_CQE_SYNDROME_RNR_RETRY_EXC_ERR: | 324 | case MLX5_CQE_SYNDROME_RNR_RETRY_EXC_ERR: |
| 325 | dump = NULL; | ||
| 319 | wc->status = IB_WC_RNR_RETRY_EXC_ERR; | 326 | wc->status = IB_WC_RNR_RETRY_EXC_ERR; |
| 320 | dump = 0; | ||
| 321 | break; | 327 | break; |
| 322 | case MLX5_CQE_SYNDROME_REMOTE_ABORTED_ERR: | 328 | case MLX5_CQE_SYNDROME_REMOTE_ABORTED_ERR: |
| 323 | wc->status = IB_WC_REM_ABORT_ERR; | 329 | wc->status = IB_WC_REM_ABORT_ERR; |
| @@ -328,11 +334,8 @@ static void mlx5_handle_error_cqe(struct mlx5_ib_dev *dev, · 4 unmodified lines | |||
| 328 | } | 334 | } |
| 329 | 335 | ||
| 330 | wc->vendor_err = cqe->vendor_err_synd; | 336 | wc->vendor_err = cqe->vendor_err_synd; |
| 331 | if (dump) { | 337 | if (dump) |
| 332 | mlx5_ib_warn(dev, "WC error: %d, Message: %s\n", wc->status, | 338 | dump_cqe(dev, cqe, wc, dump); |
| 333 | ib_wc_status_msg(wc->status)); | ||
| 334 | dump_cqe(dev, cqe); | ||
| 335 | } | ||
| 336 | } | 339 | } |
| 337 | 340 | ||
| 338 | static void handle_atomics(struct mlx5_ib_qp *qp, struct mlx5_cqe64 *cqe64, | 341 | static void handle_atomics(struct mlx5_ib_qp *qp, struct mlx5_cqe64 *cqe64, |
| @@ -127,7 +127,6 @@ static int check_mpls_supp_fields(u32 field_support, const __be32 *set_mask) · 126 unmodified lines | |||
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | #define LAST_ETH_FIELD vlan_tag | 129 | #define LAST_ETH_FIELD vlan_tag |
| 130 | #define LAST_IB_FIELD sl | ||
| 131 | #define LAST_IPV4_FIELD tos | 130 | #define LAST_IPV4_FIELD tos |
| 132 | #define LAST_IPV6_FIELD traffic_class | 131 | #define LAST_IPV6_FIELD traffic_class |
| 133 | #define LAST_TCP_UDP_FIELD src_port | 132 | #define LAST_TCP_UDP_FIELD src_port |
| @@ -38,6 +38,10 @@ · 37 unmodified lines | |||
| 38 | dev_warn(&(_dev)->ib_dev.dev, "%s:%d:(pid %d): " format, __func__, \ | 38 | dev_warn(&(_dev)->ib_dev.dev, "%s:%d:(pid %d): " format, __func__, \ |
| 39 | __LINE__, current->pid, ##arg) | 39 | __LINE__, current->pid, ##arg) |
| 40 | 40 | ||
| 41 | #define mlx5_ib_log(lvl, _dev, format, arg...) \ | ||
| 42 | dev_printk(lvl, &(_dev)->ib_dev.dev, "%s:%d:(pid %d): " format, \ | ||
| 43 | __func__, __LINE__, current->pid, ##arg) | ||
| 44 | |||
| 41 | #define MLX5_IB_DEFAULT_UIDX 0xffffff | 45 | #define MLX5_IB_DEFAULT_UIDX 0xffffff |
| 42 | #define MLX5_USER_ASSIGNED_UIDX_MASK __mlx5_mask(qpc, user_index) | 46 | #define MLX5_USER_ASSIGNED_UIDX_MASK __mlx5_mask(qpc, user_index) |
| 43 | 47 | ||
| @@ -1929,10 +1929,8 @@ int mlx5_ib_alloc_mw(struct ib_mw *ibmw, struct ib_udata *udata) · 1928 unmodified lines | |||
| 1929 | ndescs = req.num_klms ? roundup(req.num_klms, 4) : roundup(1, 4); | 1929 | ndescs = req.num_klms ? roundup(req.num_klms, 4) : roundup(1, 4); |
| 1930 | 1930 | ||
| 1931 | in = kzalloc(inlen, GFP_KERNEL); | 1931 | in = kzalloc(inlen, GFP_KERNEL); |
| 1932 | if (!in) { | 1932 | if (!in) |
| 1933 | err = -ENOMEM; | 1933 | return -ENOMEM; |
| 1934 | goto free; | ||
| 1935 | } | ||
| 1936 | 1934 | ||
| 1937 | mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry); | 1935 | mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry); |
| 1938 | 1936 | ||
| @@ -479,7 +479,7 @@ static irqreturn_t qedr_irq_handler(int irq, void *handle) · 478 unmodified lines | |||
| 479 | /* The CQ's CNQ notification counter is checked before | 479 | /* The CQ's CNQ notification counter is checked before |
| 480 | * destroying the CQ in a busy-wait loop that waits for all of | 480 | * destroying the CQ in a busy-wait loop that waits for all of |
| 481 | * the CQ's CNQ interrupts to be processed. It is increased | 481 | * the CQ's CNQ interrupts to be processed. It is increased |
| 482 | * here, only after the completion handler, to ensure that the | 482 | * here, only after the completion handler, to ensure that |
| 483 | * the handler is not running when the CQ is destroyed. | 483 | * the handler is not running when the CQ is destroyed. |
| 484 | */ | 484 | */ |
| 485 | cq->cnq_notif++; | 485 | cq->cnq_notif++; |
| @@ -799,12 +799,9 @@ static void qib_handle_6120_hwerrors(struct qib_devdata *dd, char *msg, · 798 unmodified lines | |||
| 799 | hwerrs &= ~TXE_PIO_PARITY; | 799 | hwerrs &= ~TXE_PIO_PARITY; |
| 800 | } | 800 | } |
| 801 | 801 | ||
| 802 | if (!hwerrs) { | 802 | if (!hwerrs) |
| 803 | static u32 freeze_cnt; | ||
| 804 | |||
| 805 | freeze_cnt++; | ||
| 806 | qib_6120_clear_freeze(dd); | 803 | qib_6120_clear_freeze(dd); |
| 807 | } else | 804 | else |
| 808 | isfatal = 1; | 805 | isfatal = 1; |
| 809 | } | 806 | } |
| 810 | 807 | ||
| @@ -82,7 +82,6 @@ int qib_disarm_piobufs_ifneeded(struct qib_ctxtdata *rcd) · 81 unmodified lines | |||
| 82 | struct qib_devdata *dd = rcd->dd; | 82 | struct qib_devdata *dd = rcd->dd; |
| 83 | unsigned i; | 83 | unsigned i; |
| 84 | unsigned last; | 84 | unsigned last; |
| 85 | unsigned n = 0; | ||
| 86 | 85 | ||
| 87 | last = rcd->pio_base + rcd->piocnt; | 86 | last = rcd->pio_base + rcd->piocnt; |
| 88 | /* | 87 | /* |
| @@ -102,10 +101,8 @@ int qib_disarm_piobufs_ifneeded(struct qib_ctxtdata *rcd) · 13 unmodified lines | |||
| 102 | } | 101 | } |
| 103 | spin_lock_irq(&dd->pioavail_lock); | 102 | spin_lock_irq(&dd->pioavail_lock); |
| 104 | for (i = rcd->pio_base; i < last; i++) { | 103 | for (i = rcd->pio_base; i < last; i++) { |
| 105 | if (__test_and_clear_bit(i, dd->pio_need_disarm)) { | 104 | if (__test_and_clear_bit(i, dd->pio_need_disarm)) |
| 106 | n++; | ||
| 107 | dd->f_sendctrl(rcd->ppd, QIB_SENDCTRL_DISARM_BUF(i)); | 105 | dd->f_sendctrl(rcd->ppd, QIB_SENDCTRL_DISARM_BUF(i)); |
| 108 | } | ||
| 109 | } | 106 | } |
| 110 | spin_unlock_irq(&dd->pioavail_lock); | 107 | spin_unlock_irq(&dd->pioavail_lock); |
| 111 | return 0; | 108 | return 0; |
| @@ -851,7 +851,7 @@ static int qib_user_sdma_queue_pkts(const struct qib_devdata *dd, · 850 unmodified lines | |||
| 851 | } | 851 | } |
| 852 | 852 | ||
| 853 | /* | 853 | /* |
| 854 | * This assignment is a bit strange. it's because the | 854 | * This assignment is a bit strange. it's because |
| 855 | * the pbc counts the number of 32 bit words in the full | 855 | * the pbc counts the number of 32 bit words in the full |
| 856 | * packet _except_ the first word of the pbc itself... | 856 | * packet _except_ the first word of the pbc itself... |
| 857 | */ | 857 | */ |
| @@ -187,14 +187,14 @@ static int rxe_newlink(const char *ibdev_name, struct net_device *ndev) · 186 unmodified lines | |||
| 187 | exists = rxe_get_dev_from_net(ndev); | 187 | exists = rxe_get_dev_from_net(ndev); |
| 188 | if (exists) { | 188 | if (exists) { |
| 189 | ib_device_put(&exists->ib_dev); | 189 | ib_device_put(&exists->ib_dev); |
| 190 | pr_err("already configured on %s\n", ndev->name); | 190 | rxe_dbg(exists, "already configured on %s\n", ndev->name); |
| 191 | err = -EEXIST; | 191 | err = -EEXIST; |
| 192 | goto err; | 192 | goto err; |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | err = rxe_net_add(ibdev_name, ndev); | 195 | err = rxe_net_add(ibdev_name, ndev); |
| 196 | if (err) { | 196 | if (err) { |
| 197 | pr_err("failed to add %s\n", ndev->name); | 197 | rxe_dbg(exists, "failed to add %s\n", ndev->name); |
| 198 | goto err; | 198 | goto err; |
| 199 | } | 199 | } |
| 200 | err: | 200 | err: |
| @@ -38,6 +38,25 @@ · 37 unmodified lines | |||
| 38 | 38 | ||
| 39 | #define RXE_ROCE_V2_SPORT (0xc000) | 39 | #define RXE_ROCE_V2_SPORT (0xc000) |
| 40 | 40 | ||
| 41 | #define rxe_dbg(rxe, fmt, ...) ibdev_dbg(&(rxe)->ib_dev, \ | ||
| 42 | "%s: " fmt, __func__, ##__VA_ARGS__) | ||
| 43 | #define rxe_dbg_uc(uc, fmt, ...) ibdev_dbg((uc)->ibuc.device, \ | ||
| 44 | "uc#%d %s: " fmt, (uc)->elem.index, __func__, ##__VA_ARGS__) | ||
| 45 | #define rxe_dbg_pd(pd, fmt, ...) ibdev_dbg((pd)->ibpd.device, \ | ||
| 46 | "pd#%d %s: " fmt, (pd)->elem.index, __func__, ##__VA_ARGS__) | ||
| 47 | #define rxe_dbg_ah(ah, fmt, ...) ibdev_dbg((ah)->ibah.device, \ | ||
| 48 | "ah#%d %s: " fmt, (ah)->elem.index, __func__, ##__VA_ARGS__) | ||
| 49 | #define rxe_dbg_srq(srq, fmt, ...) ibdev_dbg((srq)->ibsrq.device, \ | ||
| 50 | "srq#%d %s: " fmt, (srq)->elem.index, __func__, ##__VA_ARGS__) | ||
| 51 | #define rxe_dbg_qp(qp, fmt, ...) ibdev_dbg((qp)->ibqp.device, \ | ||
| 52 | "qp#%d %s: " fmt, (qp)->elem.index, __func__, ##__VA_ARGS__) | ||
| 53 | #define rxe_dbg_cq(cq, fmt, ...) ibdev_dbg((cq)->ibcq.device, \ | ||
| 54 | "cq#%d %s: " fmt, (cq)->elem.index, __func__, ##__VA_ARGS__) | ||
| 55 | #define rxe_dbg_mr(mr, fmt, ...) ibdev_dbg((mr)->ibmr.device, \ | ||
| 56 | "mr#%d %s: " fmt, (mr)->elem.index, __func__, ##__VA_ARGS__) | ||
| 57 | #define rxe_dbg_mw(mw, fmt, ...) ibdev_dbg((mw)->ibmw.device, \ | ||
| 58 | "mw#%d %s: " fmt, (mw)->elem.index, __func__, ##__VA_ARGS__) | ||
| 59 | |||
| 41 | void rxe_set_mtu(struct rxe_dev *rxe, unsigned int dev_mtu); | 60 | void rxe_set_mtu(struct rxe_dev *rxe, unsigned int dev_mtu); |
| 42 | 61 | ||
| 43 | int rxe_add(struct rxe_dev *rxe, unsigned int mtu, const char *ibdev_name); | 62 | int rxe_add(struct rxe_dev *rxe, unsigned int mtu, const char *ibdev_name); |
| @@ -14,26 +14,45 @@ void rxe_init_av(struct rdma_ah_attr *attr, struct rxe_av *av) · 13 unmodified lines | |||
| 14 | memcpy(av->dmac, attr->roce.dmac, ETH_ALEN); | 14 | memcpy(av->dmac, attr->roce.dmac, ETH_ALEN); |
| 15 | } | 15 | } |
| 16 | 16 | ||
| 17 | int rxe_av_chk_attr(struct rxe_dev *rxe, struct rdma_ah_attr *attr) | 17 | static int chk_attr(void *obj, struct rdma_ah_attr *attr, bool obj_is_ah) |
| 18 | { | 18 | { |
| 19 | const struct ib_global_route *grh = rdma_ah_read_grh(attr); | 19 | const struct ib_global_route *grh = rdma_ah_read_grh(attr); |
| 20 | struct rxe_port *port; | 20 | struct rxe_port *port; |
| 21 | struct rxe_dev *rxe; | ||
| 22 | struct rxe_qp *qp; | ||
| 23 | struct rxe_ah *ah; | ||
| 21 | int type; | 24 | int type; |
| 22 | 25 | ||
| 26 | if (obj_is_ah) { | ||
| 27 | ah = obj; | ||
| 28 | rxe = to_rdev(ah->ibah.device); | ||
| 29 | } else { | ||
| 30 | qp = obj; | ||
| 31 | rxe = to_rdev(qp->ibqp.device); | ||
| 32 | } | ||
| 33 | |||
| 23 | port = &rxe->port; | 34 | port = &rxe->port; |
| 24 | 35 | ||
| 25 | if (rdma_ah_get_ah_flags(attr) & IB_AH_GRH) { | 36 | if (rdma_ah_get_ah_flags(attr) & IB_AH_GRH) { |
| 26 | if (grh->sgid_index > port->attr.gid_tbl_len) { | 37 | if (grh->sgid_index > port->attr.gid_tbl_len) { |
| 27 | pr_warn("invalid sgid index = %d\n", | 38 | if (obj_is_ah) |
| 28 | grh->sgid_index); | 39 | rxe_dbg_ah(ah, "invalid sgid index = %d\n", |
| 40 | grh->sgid_index); | ||
| 41 | else | ||
| 42 | rxe_dbg_qp(qp, "invalid sgid index = %d\n", | ||
| 43 | grh->sgid_index); | ||
| 29 | return -EINVAL; | 44 | return -EINVAL; |
| 30 | } | 45 | } |
| 31 | 46 | ||
| 32 | type = rdma_gid_attr_network_type(grh->sgid_attr); | 47 | type = rdma_gid_attr_network_type(grh->sgid_attr); |
| 33 | if (type < RDMA_NETWORK_IPV4 || | 48 | if (type < RDMA_NETWORK_IPV4 || |
| 34 | type > RDMA_NETWORK_IPV6) { | 49 | type > RDMA_NETWORK_IPV6) { |
| 35 | pr_warn("invalid network type for rdma_rxe = %d\n", | 50 | if (obj_is_ah) |
| 36 | type); | 51 | rxe_dbg_ah(ah, "invalid network type for rdma_rxe = %d\n", |
| 52 | type); | ||
| 53 | else | ||
| 54 | rxe_dbg_qp(qp, "invalid network type for rdma_rxe = %d\n", | ||
| 55 | type); | ||
| 37 | return -EINVAL; | 56 | return -EINVAL; |
| 38 | } | 57 | } |
| 39 | } | 58 | } |
| @@ -41,6 +60,16 @@ int rxe_av_chk_attr(struct rxe_dev *rxe, struct rdma_ah_attr *attr) · 1 unmodified line | |||
| 41 | return 0; | 60 | return 0; |
| 42 | } | 61 | } |
| 43 | 62 | ||
| 63 | int rxe_av_chk_attr(struct rxe_qp *qp, struct rdma_ah_attr *attr) | ||
| 64 | { | ||
| 65 | return chk_attr(qp, attr, false); | ||
| 66 | } | ||
| 67 | |||
| 68 | int rxe_ah_chk_attr(struct rxe_ah *ah, struct rdma_ah_attr *attr) | ||
| 69 | { | ||
| 70 | return chk_attr(ah, attr, true); | ||
| 71 | } | ||
| 72 | |||
| 44 | void rxe_av_from_attr(u8 port_num, struct rxe_av *av, | 73 | void rxe_av_from_attr(u8 port_num, struct rxe_av *av, |
| 45 | struct rdma_ah_attr *attr) | 74 | struct rdma_ah_attr *attr) |
| 46 | { | 75 | { |
| @@ -121,12 +150,12 @@ struct rxe_av *rxe_get_av(struct rxe_pkt_info *pkt, struct rxe_ah **ahp) · 74 unmodified lines | |||
| 121 | /* only new user provider or kernel client */ | 150 | /* only new user provider or kernel client */ |
| 122 | ah = rxe_pool_get_index(&pkt->rxe->ah_pool, ah_num); | 151 | ah = rxe_pool_get_index(&pkt->rxe->ah_pool, ah_num); |
| 123 | if (!ah) { | 152 | if (!ah) { |
| 124 | pr_warn("Unable to find AH matching ah_num\n"); | 153 | rxe_dbg_qp(pkt->qp, "Unable to find AH matching ah_num\n"); |
| 125 | return NULL; | 154 | return NULL; |
| 126 | } | 155 | } |
| 127 | 156 | ||
| 128 | if (rxe_ah_pd(ah) != pkt->qp->pd) { | 157 | if (rxe_ah_pd(ah) != pkt->qp->pd) { |
| 129 | pr_warn("PDs don't match for AH and QP\n"); | 158 | rxe_dbg_qp(pkt->qp, "PDs don't match for AH and QP\n"); |
| 130 | rxe_put(ah); | 159 | rxe_put(ah); |
| 131 | return NULL; | 160 | return NULL; |
| 132 | } | 161 | } |
| @@ -104,6 +104,8 @@ static enum ib_wc_opcode wr_to_wc_opcode(enum ib_wr_opcode opcode) · 103 unmodified lines | |||
| 104 | case IB_WR_LOCAL_INV: return IB_WC_LOCAL_INV; | 104 | case IB_WR_LOCAL_INV: return IB_WC_LOCAL_INV; |
| 105 | case IB_WR_REG_MR: return IB_WC_REG_MR; | 105 | case IB_WR_REG_MR: return IB_WC_REG_MR; |
| 106 | case IB_WR_BIND_MW: return IB_WC_BIND_MW; | 106 | case IB_WR_BIND_MW: return IB_WC_BIND_MW; |
| 107 | case IB_WR_ATOMIC_WRITE: return IB_WC_ATOMIC_WRITE; | ||
| 108 | case IB_WR_FLUSH: return IB_WC_FLUSH; | ||
| 107 | 109 | ||
| 108 | default: | 110 | default: |
| 109 | return 0xff; | 111 | return 0xff; |
| @@ -114,11 +116,11 @@ void retransmit_timer(struct timer_list *t) · 4 unmodified lines | |||
| 114 | { | 116 | { |
| 115 | struct rxe_qp *qp = from_timer(qp, t, retrans_timer); | 117 | struct rxe_qp *qp = from_timer(qp, t, retrans_timer); |
| 116 | 118 | ||
| 117 | pr_debug("%s: fired for qp#%d\n", __func__, qp->elem.index); | 119 | rxe_dbg_qp(qp, "retransmit timer fired\n"); |
| 118 | 120 | ||
| 119 | if (qp->valid) { | 121 | if (qp->valid) { |
| 120 | qp->comp.timeout = 1; | 122 | qp->comp.timeout = 1; |
| 121 | rxe_run_task(&qp->comp.task, 1); | 123 | rxe_sched_task(&qp->comp.task); |
| 122 | } | 124 | } |
| 123 | } | 125 | } |
| 124 | 126 | ||
| @@ -132,7 +134,10 @@ void rxe_comp_queue_pkt(struct rxe_qp *qp, struct sk_buff *skb) · 7 unmodified lines | |||
| 132 | if (must_sched != 0) | 134 | if (must_sched != 0) |
| 133 | rxe_counter_inc(SKB_TO_PKT(skb)->rxe, RXE_CNT_COMPLETER_SCHED); | 135 | rxe_counter_inc(SKB_TO_PKT(skb)->rxe, RXE_CNT_COMPLETER_SCHED); |
| 134 | 136 | ||
| 135 | rxe_run_task(&qp->comp.task, must_sched); | 137 | if (must_sched) |
| 138 | rxe_sched_task(&qp->comp.task); | ||
| 139 | else | ||
| 140 | rxe_run_task(&qp->comp.task); | ||
| 136 | } | 141 | } |
| 137 | 142 | ||
| 138 | static inline enum comp_state get_wqe(struct rxe_qp *qp, | 143 | static inline enum comp_state get_wqe(struct rxe_qp *qp, |
| @@ -200,6 +205,10 @@ static inline enum comp_state check_psn(struct rxe_qp *qp, · 61 unmodified lines | |||
| 200 | */ | 205 | */ |
| 201 | if (pkt->psn == wqe->last_psn) | 206 | if (pkt->psn == wqe->last_psn) |
| 202 | return COMPST_COMP_ACK; | 207 | return COMPST_COMP_ACK; |
| 208 | else if (pkt->opcode == IB_OPCODE_RC_ACKNOWLEDGE && | ||
| 209 | (qp->comp.opcode == IB_OPCODE_RC_RDMA_READ_RESPONSE_FIRST || | ||
| 210 | qp->comp.opcode == IB_OPCODE_RC_RDMA_READ_RESPONSE_MIDDLE)) | ||
| 211 | return COMPST_CHECK_ACK; | ||
| 203 | else | 212 | else |
| 204 | return COMPST_DONE; | 213 | return COMPST_DONE; |
| 205 | } else if ((diff > 0) && (wqe->mask & WR_ATOMIC_OR_READ_MASK)) { | 214 | } else if ((diff > 0) && (wqe->mask & WR_ATOMIC_OR_READ_MASK)) { |
| @@ -228,6 +237,10 @@ static inline enum comp_state check_ack(struct rxe_qp *qp, · 22 unmodified lines | |||
| 228 | 237 | ||
| 229 | case IB_OPCODE_RC_RDMA_READ_RESPONSE_FIRST: | 238 | case IB_OPCODE_RC_RDMA_READ_RESPONSE_FIRST: |
| 230 | case IB_OPCODE_RC_RDMA_READ_RESPONSE_MIDDLE: | 239 | case IB_OPCODE_RC_RDMA_READ_RESPONSE_MIDDLE: |
| 240 | /* Check NAK code to handle a remote error */ | ||
| 241 | if (pkt->opcode == IB_OPCODE_RC_ACKNOWLEDGE) | ||
| 242 | break; | ||
| 243 | |||
| 231 | if (pkt->opcode != IB_OPCODE_RC_RDMA_READ_RESPONSE_MIDDLE && | 244 | if (pkt->opcode != IB_OPCODE_RC_RDMA_READ_RESPONSE_MIDDLE && |
| 232 | pkt->opcode != IB_OPCODE_RC_RDMA_READ_RESPONSE_LAST) { | 245 | pkt->opcode != IB_OPCODE_RC_RDMA_READ_RESPONSE_LAST) { |
| 233 | /* read retries of partial data may restart from | 246 | /* read retries of partial data may restart from |
| @@ -258,12 +271,16 @@ static inline enum comp_state check_ack(struct rxe_qp *qp, · 24 unmodified lines | |||
| 258 | if ((syn & AETH_TYPE_MASK) != AETH_ACK) | 271 | if ((syn & AETH_TYPE_MASK) != AETH_ACK) |
| 259 | return COMPST_ERROR; | 272 | return COMPST_ERROR; |
| 260 | 273 | ||
| 274 | if (wqe->wr.opcode == IB_WR_ATOMIC_WRITE) | ||
| 275 | return COMPST_WRITE_SEND; | ||
| 276 | |||
| 261 | fallthrough; | 277 | fallthrough; |
| 262 | /* (IB_OPCODE_RC_RDMA_READ_RESPONSE_MIDDLE doesn't have an AETH) | 278 | /* (IB_OPCODE_RC_RDMA_READ_RESPONSE_MIDDLE doesn't have an AETH) |
| 263 | */ | 279 | */ |
| 264 | case IB_OPCODE_RC_RDMA_READ_RESPONSE_MIDDLE: | 280 | case IB_OPCODE_RC_RDMA_READ_RESPONSE_MIDDLE: |
| 265 | if (wqe->wr.opcode != IB_WR_RDMA_READ && | 281 | if (wqe->wr.opcode != IB_WR_RDMA_READ && |
| 266 | wqe->wr.opcode != IB_WR_RDMA_READ_WITH_INV) { | 282 | wqe->wr.opcode != IB_WR_RDMA_READ_WITH_INV && |
| 283 | wqe->wr.opcode != IB_WR_FLUSH) { | ||
| 267 | wqe->status = IB_WC_FATAL_ERR; | 284 | wqe->status = IB_WC_FATAL_ERR; |
| 268 | return COMPST_ERROR; | 285 | return COMPST_ERROR; |
| 269 | } | 286 | } |
| @@ -305,7 +322,7 @@ static inline enum comp_state check_ack(struct rxe_qp *qp, · 35 unmodified lines | |||
| 305 | qp->comp.psn = pkt->psn; | 322 | qp->comp.psn = pkt->psn; |
| 306 | if (qp->req.wait_psn) { | 323 | if (qp->req.wait_psn) { |
| 307 | qp->req.wait_psn = 0; | 324 | qp->req.wait_psn = 0; |
| 308 | rxe_run_task(&qp->req.task, 0); | 325 | rxe_run_task(&qp->req.task); |
| 309 | } | 326 | } |
| 310 | } | 327 | } |
| 311 | return COMPST_ERROR_RETRY; | 328 | return COMPST_ERROR_RETRY; |
| @@ -323,7 +340,7 @@ static inline enum comp_state check_ack(struct rxe_qp *qp, · 11 unmodified lines | |||
| 323 | return COMPST_ERROR; | 340 | return COMPST_ERROR; |
| 324 | 341 | ||
| 325 | default: | 342 | default: |
| 326 | pr_warn("unexpected nak %x\n", syn); | 343 | rxe_dbg_qp(qp, "unexpected nak %x\n", syn); |
| 327 | wqe->status = IB_WC_REM_OP_ERR; | 344 | wqe->status = IB_WC_REM_OP_ERR; |
| 328 | return COMPST_ERROR; | 345 | return COMPST_ERROR; |
| 329 | } | 346 | } |
| @@ -334,7 +351,7 @@ static inline enum comp_state check_ack(struct rxe_qp *qp, · 4 unmodified lines | |||
| 334 | break; | 351 | break; |
| 335 | 352 | ||
| 336 | default: | 353 | default: |
| 337 | pr_warn("unexpected opcode\n"); | 354 | rxe_dbg_qp(qp, "unexpected opcode\n"); |
| 338 | } | 355 | } |
| 339 | 356 | ||
| 340 | return COMPST_ERROR; | 357 | return COMPST_ERROR; |
| @@ -452,7 +469,7 @@ static void do_complete(struct rxe_qp *qp, struct rxe_send_wqe *wqe) · 111 unmodified lines | |||
| 452 | */ | 469 | */ |
| 453 | if (qp->req.wait_fence) { | 470 | if (qp->req.wait_fence) { |
| 454 | qp->req.wait_fence = 0; | 471 | qp->req.wait_fence = 0; |
| 455 | rxe_run_task(&qp->req.task, 0); | 472 | rxe_run_task(&qp->req.task); |
| 456 | } | 473 | } |
| 457 | } | 474 | } |
| 458 | 475 | ||
| @@ -466,7 +483,7 @@ static inline enum comp_state complete_ack(struct rxe_qp *qp, · 7 unmodified lines | |||
| 466 | if (qp->req.need_rd_atomic) { | 483 | if (qp->req.need_rd_atomic) { |
| 467 | qp->comp.timeout_retry = 0; | 484 | qp->comp.timeout_retry = 0; |
| 468 | qp->req.need_rd_atomic = 0; | 485 | qp->req.need_rd_atomic = 0; |
| 469 | rxe_run_task(&qp->req.task, 0); | 486 | rxe_run_task(&qp->req.task); |
| 470 | } | 487 | } |
| 471 | } | 488 | } |
| 472 | 489 | ||
| @@ -512,7 +529,7 @@ static inline enum comp_state complete_wqe(struct rxe_qp *qp, · 39 unmodified lines | |||
| 512 | 529 | ||
| 513 | if (qp->req.wait_psn) { | 530 | if (qp->req.wait_psn) { |
| 514 | qp->req.wait_psn = 0; | 531 | qp->req.wait_psn = 0; |
| 515 | rxe_run_task(&qp->req.task, 1); | 532 | rxe_sched_task(&qp->req.task); |
| 516 | } | 533 | } |
| 517 | } | 534 | } |
| 518 | 535 | ||
| @@ -587,8 +604,7 @@ int rxe_completer(void *arg) · 68 unmodified lines | |||
| 587 | state = COMPST_GET_ACK; | 604 | state = COMPST_GET_ACK; |
| 588 | 605 | ||
| 589 | while (1) { | 606 | while (1) { |
| 590 | pr_debug("qp#%d state = %s\n", qp_num(qp), | 607 | rxe_dbg_qp(qp, "state = %s\n", comp_state_name[state]); |
| 591 | comp_state_name[state]); | ||
| 592 | switch (state) { | 608 | switch (state) { |
| 593 | case COMPST_GET_ACK: | 609 | case COMPST_GET_ACK: |
| 594 | skb = skb_dequeue(&qp->resp_pkts); | 610 | skb = skb_dequeue(&qp->resp_pkts); |
| @@ -646,7 +662,7 @@ int rxe_completer(void *arg) · 51 unmodified lines | |||
| 646 | 662 | ||
| 647 | if (qp->req.wait_psn) { | 663 | if (qp->req.wait_psn) { |
| 648 | qp->req.wait_psn = 0; | 664 | qp->req.wait_psn = 0; |
| 649 | rxe_run_task(&qp->req.task, 1); | 665 | rxe_sched_task(&qp->req.task); |
| 650 | } | 666 | } |
| 651 | 667 | ||
| 652 | state = COMPST_DONE; | 668 | state = COMPST_DONE; |
| @@ -714,7 +730,7 @@ int rxe_completer(void *arg) · 61 unmodified lines | |||
| 714 | RXE_CNT_COMP_RETRY); | 730 | RXE_CNT_COMP_RETRY); |
| 715 | qp->req.need_retry = 1; | 731 | qp->req.need_retry = 1; |
| 716 | qp->comp.started_retry = 1; | 732 | qp->comp.started_retry = 1; |
| 717 | rxe_run_task(&qp->req.task, 0); | 733 | rxe_run_task(&qp->req.task); |
| 718 | } | 734 | } |
| 719 | goto done; | 735 | goto done; |
| 720 | 736 | ||
| @@ -735,8 +751,7 @@ int rxe_completer(void *arg) · 14 unmodified lines | |||
| 735 | * rnr timer has fired | 751 | * rnr timer has fired |
| 736 | */ | 752 | */ |
| 737 | qp->req.wait_for_rnr_timer = 1; | 753 | qp->req.wait_for_rnr_timer = 1; |
| 738 | pr_debug("qp#%d set rnr nak timer\n", | 754 | rxe_dbg_qp(qp, "set rnr nak timer\n"); |
| 739 | qp_num(qp)); | ||
| 740 | mod_timer(&qp->rnr_nak_timer, | 755 | mod_timer(&qp->rnr_nak_timer, |
| 741 | jiffies + rnrnak_jiffies(aeth_syn(pkt) | 756 | jiffies + rnrnak_jiffies(aeth_syn(pkt) |
| 742 | & ~AETH_TYPE_MASK)); | 757 | & ~AETH_TYPE_MASK)); |
| @@ -14,12 +14,12 @@ int rxe_cq_chk_attr(struct rxe_dev *rxe, struct rxe_cq *cq, · 13 unmodified lines | |||
| 14 | int count; | 14 | int count; |
| 15 | 15 | ||
| 16 | if (cqe <= 0) { | 16 | if (cqe <= 0) { |
| 17 | pr_warn("cqe(%d) <= 0\n", cqe); | 17 | rxe_dbg(rxe, "cqe(%d) <= 0\n", cqe); |
| 18 | goto err1; | 18 | goto err1; |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | if (cqe > rxe->attr.max_cqe) { | 21 | if (cqe > rxe->attr.max_cqe) { |
| 22 | pr_debug("cqe(%d) > max_cqe(%d)\n", | 22 | rxe_dbg(rxe, "cqe(%d) > max_cqe(%d)\n", |
| 23 | cqe, rxe->attr.max_cqe); | 23 | cqe, rxe->attr.max_cqe); |
| 24 | goto err1; | 24 | goto err1; |
| 25 | } | 25 | } |
| @@ -27,7 +27,7 @@ int rxe_cq_chk_attr(struct rxe_dev *rxe, struct rxe_cq *cq, · 1 unmodified line | |||
| 27 | if (cq) { | 27 | if (cq) { |
| 28 | count = queue_count(cq->queue, QUEUE_TYPE_TO_CLIENT); | 28 | count = queue_count(cq->queue, QUEUE_TYPE_TO_CLIENT); |
| 29 | if (cqe < count) { | 29 | if (cqe < count) { |
| 30 | pr_debug("cqe(%d) < current # elements in queue (%d)", | 30 | rxe_dbg_cq(cq, "cqe(%d) < current # elements in queue (%d)", |
| 31 | cqe, count); | 31 | cqe, count); |
| 32 | goto err1; | 32 | goto err1; |
| 33 | } | 33 | } |
| @@ -65,7 +65,7 @@ int rxe_cq_from_init(struct rxe_dev *rxe, struct rxe_cq *cq, int cqe, · 31 unmodified lines | |||
| 65 | cq->queue = rxe_queue_init(rxe, &cqe, | 65 | cq->queue = rxe_queue_init(rxe, &cqe, |
| 66 | sizeof(struct rxe_cqe), type); | 66 | sizeof(struct rxe_cqe), type); |
| 67 | if (!cq->queue) { | 67 | if (!cq->queue) { |
| 68 | pr_warn("unable to create cq\n"); | 68 | rxe_dbg(rxe, "unable to create cq\n"); |
| 69 | return -ENOMEM; | 69 | return -ENOMEM; |
| 70 | } | 70 | } |
| 71 | 71 | ||
| @@ -607,6 +607,52 @@ static inline void reth_set_len(struct rxe_pkt_info *pkt, u32 len) · 606 unmodified lines | |||
| 607 | rxe_opcode[pkt->opcode].offset[RXE_RETH], len); | 607 | rxe_opcode[pkt->opcode].offset[RXE_RETH], len); |
| 608 | } | 608 | } |
| 609 | 609 | ||
| 610 | /****************************************************************************** | ||
| 611 | * FLUSH Extended Transport Header | ||
| 612 | ******************************************************************************/ | ||
| 613 | |||
| 614 | struct rxe_feth { | ||
| 615 | __be32 bits; | ||
| 616 | }; | ||
| 617 | |||
| 618 | #define FETH_PLT_MASK (0x0000000f) /* bits 3-0 */ | ||
| 619 | #define FETH_SEL_MASK (0x00000030) /* bits 5-4 */ | ||
| 620 | #define FETH_SEL_SHIFT (4U) | ||
| 621 | |||
| 622 | static inline u32 __feth_plt(void *arg) | ||
| 623 | { | ||
| 624 | struct rxe_feth *feth = arg; | ||
| 625 | |||
| 626 | return be32_to_cpu(feth->bits) & FETH_PLT_MASK; | ||
| 627 | } | ||
| 628 | |||
| 629 | static inline u32 __feth_sel(void *arg) | ||
| 630 | { | ||
| 631 | struct rxe_feth *feth = arg; | ||
| 632 | |||
| 633 | return (be32_to_cpu(feth->bits) & FETH_SEL_MASK) >> FETH_SEL_SHIFT; | ||
| 634 | } | ||
| 635 | |||
| 636 | static inline u32 feth_plt(struct rxe_pkt_info *pkt) | ||
| 637 | { | ||
| 638 | return __feth_plt(pkt->hdr + rxe_opcode[pkt->opcode].offset[RXE_FETH]); | ||
| 639 | } | ||
| 640 | |||
| 641 | static inline u32 feth_sel(struct rxe_pkt_info *pkt) | ||
| 642 | { | ||
| 643 | return __feth_sel(pkt->hdr + rxe_opcode[pkt->opcode].offset[RXE_FETH]); | ||
| 644 | } | ||
| 645 | |||
| 646 | static inline void feth_init(struct rxe_pkt_info *pkt, u8 type, u8 level) | ||
| 647 | { | ||
| 648 | struct rxe_feth *feth = (struct rxe_feth *) | ||
| 649 | (pkt->hdr + rxe_opcode[pkt->opcode].offset[RXE_FETH]); | ||
| 650 | u32 bits = ((level << FETH_SEL_SHIFT) & FETH_SEL_MASK) | | ||
| 651 | (type & FETH_PLT_MASK); | ||
| 652 | |||
| 653 | feth->bits = cpu_to_be32(bits); | ||
| 654 | } | ||
| 655 | |||
| 610 | /****************************************************************************** | 656 | /****************************************************************************** |
| 611 | * Atomic Extended Transport Header | 657 | * Atomic Extended Transport Header |
| 612 | ******************************************************************************/ | 658 | ******************************************************************************/ |
| @@ -742,7 +788,6 @@ enum aeth_syndrome { · 129 unmodified lines | |||
| 742 | AETH_NAK_INVALID_REQ = 0x61, | 788 | AETH_NAK_INVALID_REQ = 0x61, |
| 743 | AETH_NAK_REM_ACC_ERR = 0x62, | 789 | AETH_NAK_REM_ACC_ERR = 0x62, |
| 744 | AETH_NAK_REM_OP_ERR = 0x63, | 790 | AETH_NAK_REM_OP_ERR = 0x63, |
| 745 | AETH_NAK_INV_RD_REQ = 0x64, | ||
| 746 | }; | 791 | }; |
| 747 | 792 | ||
| 748 | static inline u8 __aeth_syn(void *arg) | 793 | static inline u8 __aeth_syn(void *arg) |
| @@ -910,6 +955,7 @@ enum rxe_hdr_length { · 161 unmodified lines | |||
| 910 | RXE_ATMETH_BYTES = sizeof(struct rxe_atmeth), | 955 | RXE_ATMETH_BYTES = sizeof(struct rxe_atmeth), |
| 911 | RXE_IETH_BYTES = sizeof(struct rxe_ieth), | 956 | RXE_IETH_BYTES = sizeof(struct rxe_ieth), |
| 912 | RXE_RDETH_BYTES = sizeof(struct rxe_rdeth), | 957 | RXE_RDETH_BYTES = sizeof(struct rxe_rdeth), |
| 958 | RXE_FETH_BYTES = sizeof(struct rxe_feth), | ||
| 913 | }; | 959 | }; |
| 914 | 960 | ||
| 915 | static inline size_t header_size(struct rxe_pkt_info *pkt) | 961 | static inline size_t header_size(struct rxe_pkt_info *pkt) |
| @@ -21,7 +21,7 @@ int rxe_icrc_init(struct rxe_dev *rxe) · 20 unmodified lines | |||
| 21 | 21 | ||
| 22 | tfm = crypto_alloc_shash("crc32", 0, 0); | 22 | tfm = crypto_alloc_shash("crc32", 0, 0); |
| 23 | if (IS_ERR(tfm)) { | 23 | if (IS_ERR(tfm)) { |
| 24 | pr_warn("failed to init crc32 algorithm err:%ld\n", | 24 | rxe_dbg(rxe, "failed to init crc32 algorithm err: %ld\n", |
| 25 | PTR_ERR(tfm)); | 25 | PTR_ERR(tfm)); |
| 26 | return PTR_ERR(tfm); | 26 | return PTR_ERR(tfm); |
| 27 | } | 27 | } |
| @@ -51,7 +51,7 @@ static __be32 rxe_crc32(struct rxe_dev *rxe, __be32 crc, void *next, size_t len) · 23 unmodified lines | |||
| 51 | *(__be32 *)shash_desc_ctx(shash) = crc; | 51 | *(__be32 *)shash_desc_ctx(shash) = crc; |
| 52 | err = crypto_shash_update(shash, next, len); | 52 | err = crypto_shash_update(shash, next, len); |
| 53 | if (unlikely(err)) { | 53 | if (unlikely(err)) { |
| 54 | pr_warn_ratelimited("failed crc calculation, err: %d\n", err); | 54 | rxe_dbg(rxe, "failed crc calculation, err: %d\n", err); |
| 55 | return (__force __be32)crc32_le((__force u32)crc, next, len); | 55 | return (__force __be32)crc32_le((__force u32)crc, next, len); |
| 56 | } | 56 | } |
| 57 | 57 | ||
| @@ -9,16 +9,12 @@ · 8 unmodified lines | |||
| 9 | 9 | ||
| 10 | /* rxe_av.c */ | 10 | /* rxe_av.c */ |
| 11 | void rxe_init_av(struct rdma_ah_attr *attr, struct rxe_av *av); | 11 | void rxe_init_av(struct rdma_ah_attr *attr, struct rxe_av *av); |
| 12 | 12 | int rxe_av_chk_attr(struct rxe_qp *qp, struct rdma_ah_attr *attr); | |
| 13 | int rxe_av_chk_attr(struct rxe_dev *rxe, struct rdma_ah_attr *attr); | 13 | int rxe_ah_chk_attr(struct rxe_ah *ah, struct rdma_ah_attr *attr); |
| 14 | |||
| 15 | void rxe_av_from_attr(u8 port_num, struct rxe_av *av, | 14 | void rxe_av_from_attr(u8 port_num, struct rxe_av *av, |
| 16 | struct rdma_ah_attr *attr); | 15 | struct rdma_ah_attr *attr); |
| 17 | |||
| 18 | void rxe_av_to_attr(struct rxe_av *av, struct rdma_ah_attr *attr); | 16 | void rxe_av_to_attr(struct rxe_av *av, struct rdma_ah_attr *attr); |
| 19 | |||
| 20 | void rxe_av_fill_ip_info(struct rxe_av *av, struct rdma_ah_attr *attr); | 17 | void rxe_av_fill_ip_info(struct rxe_av *av, struct rdma_ah_attr *attr); |
| 21 | |||
| 22 | struct rxe_av *rxe_get_av(struct rxe_pkt_info *pkt, struct rxe_ah **ahp); | 18 | struct rxe_av *rxe_get_av(struct rxe_pkt_info *pkt, struct rxe_ah **ahp); |
| 23 | 19 | ||
| 24 | /* rxe_cq.c */ | 20 | /* rxe_cq.c */ |
| @@ -68,6 +64,7 @@ void rxe_mr_init_dma(int access, struct rxe_mr *mr); · 43 unmodified lines | |||
| 68 | int rxe_mr_init_user(struct rxe_dev *rxe, u64 start, u64 length, u64 iova, | 64 | int rxe_mr_init_user(struct rxe_dev *rxe, u64 start, u64 length, u64 iova, |
| 69 | int access, struct rxe_mr *mr); | 65 | int access, struct rxe_mr *mr); |
| 70 | int rxe_mr_init_fast(int max_pages, struct rxe_mr *mr); | 66 | int rxe_mr_init_fast(int max_pages, struct rxe_mr *mr); |
| 67 | int rxe_flush_pmem_iova(struct rxe_mr *mr, u64 iova, int length); | ||
| 71 | int rxe_mr_copy(struct rxe_mr *mr, u64 iova, void *addr, int length, | 68 | int rxe_mr_copy(struct rxe_mr *mr, u64 iova, void *addr, int length, |
| 72 | enum rxe_mr_copy_dir dir); | 69 | enum rxe_mr_copy_dir dir); |
| 73 | int copy_data(struct rxe_pd *pd, int access, struct rxe_dma_info *dma, | 70 | int copy_data(struct rxe_pd *pd, int access, struct rxe_dma_info *dma, |
| @@ -79,7 +79,7 @@ int rxe_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) · 78 unmodified lines | |||
| 79 | 79 | ||
| 80 | /* Don't allow a mmap larger than the object. */ | 80 | /* Don't allow a mmap larger than the object. */ |
| 81 | if (size > ip->info.size) { | 81 | if (size > ip->info.size) { |
| 82 | pr_err("mmap region is larger than the object!\n"); | 82 | rxe_dbg(rxe, "mmap region is larger than the object!\n"); |
| 83 | spin_unlock_bh(&rxe->pending_lock); | 83 | spin_unlock_bh(&rxe->pending_lock); |
| 84 | ret = -EINVAL; | 84 | ret = -EINVAL; |
| 85 | goto done; | 85 | goto done; |
| @@ -87,7 +87,7 @@ int rxe_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) · 1 unmodified line | |||
| 87 | 87 | ||
| 88 | goto found_it; | 88 | goto found_it; |
| 89 | } | 89 | } |
| 90 | pr_warn("unable to find pending mmap info\n"); | 90 | rxe_dbg(rxe, "unable to find pending mmap info\n"); |
| 91 | spin_unlock_bh(&rxe->pending_lock); | 91 | spin_unlock_bh(&rxe->pending_lock); |
| 92 | ret = -EINVAL; | 92 | ret = -EINVAL; |
| 93 | goto done; | 93 | goto done; |
| @@ -98,7 +98,7 @@ found_it: · 4 unmodified lines | |||
| 98 | 98 | ||
| 99 | ret = remap_vmalloc_range(vma, ip->obj, 0); | 99 | ret = remap_vmalloc_range(vma, ip->obj, 0); |
| 100 | if (ret) { | 100 | if (ret) { |
| 101 | pr_err("err %d from remap_vmalloc_range\n", ret); | 101 | rxe_dbg(rxe, "err %d from remap_vmalloc_range\n", ret); |
| 102 | goto done; | 102 | goto done; |
| 103 | } | 103 | } |
| 104 | 104 | ||
| @@ -4,6 +4,8 @@ · 3 unmodified lines | |||
| 4 | * Copyright (c) 2015 System Fabric Works, Inc. All rights reserved. | 4 | * Copyright (c) 2015 System Fabric Works, Inc. All rights reserved. |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | #include <linux/libnvdimm.h> | ||
| 8 | |||
| 7 | #include "rxe.h" | 9 | #include "rxe.h" |
| 8 | #include "rxe_loc.h" | 10 | #include "rxe_loc.h" |
| 9 | 11 | ||
| @@ -26,7 +28,7 @@ int mr_check_range(struct rxe_mr *mr, u64 iova, size_t length) · 16 unmodified lines | |||
| 26 | { | 28 | { |
| 27 | 29 | ||
| 28 | 30 | ||
| 29 | switch (mr->type) { | 31 | switch (mr->ibmr.type) { |
| 30 | case IB_MR_TYPE_DMA: | 32 | case IB_MR_TYPE_DMA: |
| 31 | return 0; | 33 | return 0; |
| 32 | 34 | ||
| @@ -38,8 +40,7 @@ int mr_check_range(struct rxe_mr *mr, u64 iova, size_t length) · 5 unmodified lines | |||
| 38 | return 0; | 40 | return 0; |
| 39 | 41 | ||
| 40 | default: | 42 | default: |
| 41 | pr_warn("%s: mr type (%d) not supported\n", | 43 | rxe_dbg_mr(mr, "type (%d) not supported\n", mr->ibmr.type); |
| 42 | __func__, mr->type); | ||
| 43 | return -EFAULT; | 44 | return -EFAULT; |
| 44 | } | 45 | } |
| 45 | } | 46 | } |
| @@ -62,7 +63,6 @@ static void rxe_mr_init(int access, struct rxe_mr *mr) · 16 unmodified lines | |||
| 62 | mr->rkey = mr->ibmr.rkey = rkey; | 63 | mr->rkey = mr->ibmr.rkey = rkey; |
| 63 | 64 | ||
| 64 | mr->state = RXE_MR_STATE_INVALID; | 65 | mr->state = RXE_MR_STATE_INVALID; |
| 65 | mr->map_shift = ilog2(RXE_BUF_PER_MAP); | ||
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | static int rxe_mr_alloc(struct rxe_mr *mr, int num_buf) | 68 | static int rxe_mr_alloc(struct rxe_mr *mr, int num_buf) |
| @@ -99,6 +99,7 @@ err2: · 30 unmodified lines | |||
| 99 | kfree(mr->map[i]); | 99 | kfree(mr->map[i]); |
| 100 | 100 | ||
| 101 | kfree(mr->map); | 101 | kfree(mr->map); |
| 102 | mr->map = NULL; | ||
| 102 | err1: | 103 | err1: |
| 103 | return -ENOMEM; | 104 | return -ENOMEM; |
| 104 | } | 105 | } |
| @@ -109,7 +110,16 @@ void rxe_mr_init_dma(int access, struct rxe_mr *mr) · 4 unmodified lines | |||
| 109 | 110 | ||
| 110 | mr->access = access; | 111 | mr->access = access; |
| 111 | mr->state = RXE_MR_STATE_VALID; | 112 | mr->state = RXE_MR_STATE_VALID; |
| 112 | mr->type = IB_MR_TYPE_DMA; | 113 | mr->ibmr.type = IB_MR_TYPE_DMA; |
| 114 | } | ||
| 115 | |||
| 116 | static bool is_pmem_page(struct page *pg) | ||
| 117 | { | ||
| 118 | unsigned long paddr = page_to_phys(pg); | ||
| 119 | |||
| 120 | return REGION_INTERSECTS == | ||
| 121 | region_intersects(paddr, PAGE_SIZE, IORESOURCE_MEM, | ||
| 122 | IORES_DESC_PERSISTENT_MEMORY); | ||
| 113 | } | 123 | } |
| 114 | 124 | ||
| 115 | int rxe_mr_init_user(struct rxe_dev *rxe, u64 start, u64 length, u64 iova, | 125 | int rxe_mr_init_user(struct rxe_dev *rxe, u64 start, u64 length, u64 iova, |
| @@ -122,12 +132,11 @@ int rxe_mr_init_user(struct rxe_dev *rxe, u64 start, u64 length, u64 iova, · 6 unmodified lines | |||
| 122 | int num_buf; | 132 | int num_buf; |
| 123 | void *vaddr; | 133 | void *vaddr; |
| 124 | int err; | 134 | int err; |
| 125 | int i; | ||
| 126 | 135 | ||
| 127 | umem = ib_umem_get(&rxe->ib_dev, start, length, access); | 136 | umem = ib_umem_get(&rxe->ib_dev, start, length, access); |
| 128 | if (IS_ERR(umem)) { | 137 | if (IS_ERR(umem)) { |
| 129 | pr_warn("%s: Unable to pin memory region err = %d\n", | 138 | rxe_dbg_mr(mr, "Unable to pin memory region err = %d\n", |
| 130 | __func__, (int)PTR_ERR(umem)); | 139 | (int)PTR_ERR(umem)); |
| 131 | err = PTR_ERR(umem); | 140 | err = PTR_ERR(umem); |
| 132 | goto err_out; | 141 | goto err_out; |
| 133 | } | 142 | } |
| @@ -138,8 +147,7 @@ int rxe_mr_init_user(struct rxe_dev *rxe, u64 start, u64 length, u64 iova, · 4 unmodified lines | |||
| 138 | 147 | ||
| 139 | err = rxe_mr_alloc(mr, num_buf); | 148 | err = rxe_mr_alloc(mr, num_buf); |
| 140 | if (err) { | 149 | if (err) { |
| 141 | pr_warn("%s: Unable to allocate memory for map\n", | 150 | rxe_dbg_mr(mr, "Unable to allocate memory for map\n"); |
| 142 | __func__); | ||
| 143 | goto err_release_umem; | 151 | goto err_release_umem; |
| 144 | } | 152 | } |
| 145 | 153 | ||
| @@ -149,23 +157,30 @@ int rxe_mr_init_user(struct rxe_dev *rxe, u64 start, u64 length, u64 iova, · 3 unmodified lines | |||
| 149 | num_buf = 0; | 157 | num_buf = 0; |
| 150 | map = mr->map; | 158 | map = mr->map; |
| 151 | if (length > 0) { | 159 | if (length > 0) { |
| 152 | buf = map[0]->buf; | 160 | bool persistent_access = access & IB_ACCESS_FLUSH_PERSISTENT; |
| 153 | 161 | ||
| 162 | buf = map[0]->buf; | ||
| 154 | for_each_sgtable_page (&umem->sgt_append.sgt, &sg_iter, 0) { | 163 | for_each_sgtable_page (&umem->sgt_append.sgt, &sg_iter, 0) { |
| 164 | struct page *pg = sg_page_iter_page(&sg_iter); | ||
| 165 | |||
| 166 | if (persistent_access && !is_pmem_page(pg)) { | ||
| 167 | rxe_dbg_mr(mr, "Unable to register persistent access to non-pmem device\n"); | ||
| 168 | err = -EINVAL; | ||
| 169 | goto err_release_umem; | ||
| 170 | } | ||
| 171 | |||
| 155 | if (num_buf >= RXE_BUF_PER_MAP) { | 172 | if (num_buf >= RXE_BUF_PER_MAP) { |
| 156 | map++; | 173 | map++; |
| 157 | buf = map[0]->buf; | 174 | buf = map[0]->buf; |
| 158 | num_buf = 0; | 175 | num_buf = 0; |
| 159 | } | 176 | } |
| 160 | 177 | ||
| 161 | vaddr = page_address(sg_page_iter_page(&sg_iter)); | 178 | vaddr = page_address(pg); |
| 162 | if (!vaddr) { | 179 | if (!vaddr) { |
| 163 | pr_warn("%s: Unable to get virtual address\n", | 180 | rxe_dbg_mr(mr, "Unable to get virtual address\n"); |
| 164 | __func__); | ||
| 165 | err = -ENOMEM; | 181 | err = -ENOMEM; |
| 166 | goto err_cleanup_map; | 182 | goto err_release_umem; |
| 167 | } | 183 | } |
| 168 | |||
| 169 | buf->addr = (uintptr_t)vaddr; | 184 | buf->addr = (uintptr_t)vaddr; |
| 170 | buf->size = PAGE_SIZE; | 185 | buf->size = PAGE_SIZE; |
| 171 | num_buf++; | 186 | num_buf++; |
| @@ -178,14 +193,11 @@ int rxe_mr_init_user(struct rxe_dev *rxe, u64 start, u64 length, u64 iova, · 6 unmodified lines | |||
| 178 | mr->access = access; | 193 | mr->access = access; |
| 179 | mr->offset = ib_umem_offset(umem); | 194 | mr->offset = ib_umem_offset(umem); |
| 180 | mr->state = RXE_MR_STATE_VALID; | 195 | mr->state = RXE_MR_STATE_VALID; |
| 181 | mr->type = IB_MR_TYPE_USER; | 196 | mr->ibmr.type = IB_MR_TYPE_USER; |
| 197 | mr->ibmr.page_size = PAGE_SIZE; | ||
| 182 | 198 | ||
| 183 | return 0; | 199 | return 0; |
| 184 | 200 | ||
| 185 | err_cleanup_map: | ||
| 186 | for (i = 0; i < mr->num_map; i++) | ||
| 187 | kfree(mr->map[i]); | ||
| 188 | kfree(mr->map); | ||
| 189 | err_release_umem: | 201 | err_release_umem: |
| 190 | ib_umem_release(umem); | 202 | ib_umem_release(umem); |
| 191 | err_out: | 203 | err_out: |
| @@ -205,7 +217,7 @@ int rxe_mr_init_fast(int max_pages, struct rxe_mr *mr) · 13 unmodified lines | |||
| 205 | 217 | ||
| 206 | mr->max_buf = max_pages; | 218 | mr->max_buf = max_pages; |
| 207 | mr->state = RXE_MR_STATE_FREE; | 219 | mr->state = RXE_MR_STATE_FREE; |
| 208 | mr->type = IB_MR_TYPE_MEM_REG; | 220 | mr->ibmr.type = IB_MR_TYPE_MEM_REG; |
| 209 | 221 | ||
| 210 | return 0; | 222 | return 0; |
| 211 | 223 | ||
| @@ -256,7 +268,7 @@ void *iova_to_vaddr(struct rxe_mr *mr, u64 iova, int length) · 44 unmodified lines | |||
| 256 | void *addr; | 268 | void *addr; |
| 257 | 269 | ||
| 258 | if (mr->state != RXE_MR_STATE_VALID) { | 270 | if (mr->state != RXE_MR_STATE_VALID) { |
| 259 | pr_warn("mr not in valid state\n"); | 271 | rxe_dbg_mr(mr, "Not in valid state\n"); |
| 260 | addr = NULL; | 272 | addr = NULL; |
| 261 | goto out; | 273 | goto out; |
| 262 | } | 274 | } |
| @@ -267,7 +279,7 @@ void *iova_to_vaddr(struct rxe_mr *mr, u64 iova, int length) · 4 unmodified lines | |||
| 267 | } | 279 | } |
| 268 | 280 | ||
| 269 | if (mr_check_range(mr, iova, length)) { | 281 | if (mr_check_range(mr, iova, length)) { |
| 270 | pr_warn("range violation\n"); | 282 | rxe_dbg_mr(mr, "Range violation\n"); |
| 271 | addr = NULL; | 283 | addr = NULL; |
| 272 | goto out; | 284 | goto out; |
| 273 | } | 285 | } |
| @@ -275,7 +287,7 @@ void *iova_to_vaddr(struct rxe_mr *mr, u64 iova, int length) · 1 unmodified line | |||
| 275 | lookup_iova(mr, iova, &m, &n, &offset); | 287 | lookup_iova(mr, iova, &m, &n, &offset); |
| 276 | 288 | ||
| 277 | if (offset + length > mr->map[m]->buf[n].size) { | 289 | if (offset + length > mr->map[m]->buf[n].size) { |
| 278 | pr_warn("crosses page boundary\n"); | 290 | rxe_dbg_mr(mr, "Crosses page boundary\n"); |
| 279 | addr = NULL; | 291 | addr = NULL; |
| 280 | goto out; | 292 | goto out; |
| 281 | } | 293 | } |
| @@ -286,6 +298,39 @@ out: · 4 unmodified lines | |||
| 286 | return addr; | 298 | return addr; |
| 287 | } | 299 | } |
| 288 | 300 | ||
| 301 | int rxe_flush_pmem_iova(struct rxe_mr *mr, u64 iova, int length) | ||
| 302 | { | ||
| 303 | size_t offset; | ||
| 304 | |||
| 305 | if (length == 0) | ||
| 306 | return 0; | ||
| 307 | |||
| 308 | if (mr->ibmr.type == IB_MR_TYPE_DMA) | ||
| 309 | return -EFAULT; | ||
| 310 | |||
| 311 | offset = (iova - mr->ibmr.iova + mr->offset) & mr->page_mask; | ||
| 312 | while (length > 0) { | ||
| 313 | u8 *va; | ||
| 314 | int bytes; | ||
| 315 | |||
| 316 | bytes = mr->ibmr.page_size - offset; | ||
| 317 | if (bytes > length) | ||
| 318 | bytes = length; | ||
| 319 | |||
| 320 | va = iova_to_vaddr(mr, iova, length); | ||
| 321 | if (!va) | ||
| 322 | return -EFAULT; | ||
| 323 | |||
| 324 | arch_wb_cache_pmem(va, bytes); | ||
| 325 | |||
| 326 | length -= bytes; | ||
| 327 | iova += bytes; | ||
| 328 | offset = 0; | ||
| 329 | } | ||
| 330 | |||
| 331 | return 0; | ||
| 332 | } | ||
| 333 | |||
| 289 | /* copy data from a range (vaddr, vaddr+length-1) to or from | 334 | /* copy data from a range (vaddr, vaddr+length-1) to or from |
| 290 | * a mr object starting at iova. | 335 | * a mr object starting at iova. |
| 291 | */ | 336 | */ |
| @@ -304,7 +349,7 @@ int rxe_mr_copy(struct rxe_mr *mr, u64 iova, void *addr, int length, · 12 unmodified lines | |||
| 304 | if (length == 0) | 349 | if (length == 0) |
| 305 | return 0; | 350 | return 0; |
| 306 | 351 | ||
| 307 | if (mr->type == IB_MR_TYPE_DMA) { | 352 | if (mr->ibmr.type == IB_MR_TYPE_DMA) { |
| 308 | u8 *src, *dest; | 353 | u8 *src, *dest; |
| 309 | 354 | ||
| 310 | src = (dir == RXE_TO_MR_OBJ) ? addr : ((void *)(uintptr_t)iova); | 355 | src = (dir == RXE_TO_MR_OBJ) ? addr : ((void *)(uintptr_t)iova); |
| @@ -511,7 +556,7 @@ struct rxe_mr *lookup_mr(struct rxe_pd *pd, int access, u32 key, · 200 unmodified lines | |||
| 511 | 556 | ||
| 512 | if (unlikely((type == RXE_LOOKUP_LOCAL && mr->lkey != key) || | 557 | if (unlikely((type == RXE_LOOKUP_LOCAL && mr->lkey != key) || |
| 513 | (type == RXE_LOOKUP_REMOTE && mr->rkey != key) || | 558 | (type == RXE_LOOKUP_REMOTE && mr->rkey != key) || |
| 514 | mr_pd(mr) != pd || (access && !(access & mr->access)) || | 559 | mr_pd(mr) != pd || ((access & mr->access) != access) || |
| 515 | mr->state != RXE_MR_STATE_VALID)) { | 560 | mr->state != RXE_MR_STATE_VALID)) { |
| 516 | rxe_put(mr); | 561 | rxe_put(mr); |
| 517 | mr = NULL; | 562 | mr = NULL; |
| @@ -528,27 +573,26 @@ int rxe_invalidate_mr(struct rxe_qp *qp, u32 key) · 10 unmodified lines | |||
| 528 | 573 | ||
| 529 | mr = rxe_pool_get_index(&rxe->mr_pool, key >> 8); | 574 | mr = rxe_pool_get_index(&rxe->mr_pool, key >> 8); |
| 530 | if (!mr) { | 575 | if (!mr) { |
| 531 | pr_err("%s: No MR for key %#x\n", __func__, key); | 576 | rxe_dbg_qp(qp, "No MR for key %#x\n", key); |
| 532 | ret = -EINVAL; | 577 | ret = -EINVAL; |
| 533 | goto err; | 578 | goto err; |
| 534 | } | 579 | } |
| 535 | 580 | ||
| 536 | if (mr->rkey ? (key != mr->rkey) : (key != mr->lkey)) { | 581 | if (mr->rkey ? (key != mr->rkey) : (key != mr->lkey)) { |
| 537 | pr_err("%s: wr key (%#x) doesn't match mr key (%#x)\n", | 582 | rxe_dbg_mr(mr, "wr key (%#x) doesn't match mr key (%#x)\n", |
| 538 | __func__, key, (mr->rkey ? mr->rkey : mr->lkey)); | 583 | key, (mr->rkey ? mr->rkey : mr->lkey)); |
| 539 | ret = -EINVAL; | 584 | ret = -EINVAL; |
| 540 | goto err_drop_ref; | 585 | goto err_drop_ref; |
| 541 | } | 586 | } |
| 542 | 587 | ||
| 543 | if (atomic_read(&mr->num_mw) > 0) { | 588 | if (atomic_read(&mr->num_mw) > 0) { |
| 544 | pr_warn("%s: Attempt to invalidate an MR while bound to MWs\n", | 589 | rxe_dbg_mr(mr, "Attempt to invalidate an MR while bound to MWs\n"); |
| 545 | __func__); | ||
| 546 | ret = -EINVAL; | 590 | ret = -EINVAL; |
| 547 | goto err_drop_ref; | 591 | goto err_drop_ref; |
| 548 | } | 592 | } |
| 549 | 593 | ||
| 550 | if (unlikely(mr->type != IB_MR_TYPE_MEM_REG)) { | 594 | if (unlikely(mr->ibmr.type != IB_MR_TYPE_MEM_REG)) { |
| 551 | pr_warn("%s: mr->type (%d) is wrong type\n", __func__, mr->type); | 595 | rxe_dbg_mr(mr, "Type (%d) is wrong\n", mr->ibmr.type); |
| 552 | ret = -EINVAL; | 596 | ret = -EINVAL; |
| 553 | goto err_drop_ref; | 597 | goto err_drop_ref; |
| 554 | } | 598 | } |
| @@ -577,22 +621,20 @@ int rxe_reg_fast_mr(struct rxe_qp *qp, struct rxe_send_wqe *wqe) · 22 unmodified lines | |||
| 577 | 621 | ||
| 578 | /* user can only register MR in free state */ | 622 | /* user can only register MR in free state */ |
| 579 | if (unlikely(mr->state != RXE_MR_STATE_FREE)) { | 623 | if (unlikely(mr->state != RXE_MR_STATE_FREE)) { |
| 580 | pr_warn("%s: mr->lkey = 0x%x not free\n", | 624 | rxe_dbg_mr(mr, "mr->lkey = 0x%x not free\n", mr->lkey); |
| 581 | __func__, mr->lkey); | ||
| 582 | return -EINVAL; | 625 | return -EINVAL; |
| 583 | } | 626 | } |
| 584 | 627 | ||
| 585 | /* user can only register mr with qp in same protection domain */ | 628 | /* user can only register mr with qp in same protection domain */ |
| 586 | if (unlikely(qp->ibqp.pd != mr->ibmr.pd)) { | 629 | if (unlikely(qp->ibqp.pd != mr->ibmr.pd)) { |
| 587 | pr_warn("%s: qp->pd and mr->pd don't match\n", | 630 | rxe_dbg_mr(mr, "qp->pd and mr->pd don't match\n"); |
| 588 | __func__); | ||
| 589 | return -EINVAL; | 631 | return -EINVAL; |
| 590 | } | 632 | } |
| 591 | 633 | ||
| 592 | /* user is only allowed to change key portion of l/rkey */ | 634 | /* user is only allowed to change key portion of l/rkey */ |
| 593 | if (unlikely((mr->lkey & ~0xff) != (key & ~0xff))) { | 635 | if (unlikely((mr->lkey & ~0xff) != (key & ~0xff))) { |
| 594 | pr_warn("%s: key = 0x%x has wrong index mr->lkey = 0x%x\n", | 636 | rxe_dbg_mr(mr, "key = 0x%x has wrong index mr->lkey = 0x%x\n", |
| 595 | __func__, key, mr->lkey); | 637 | key, mr->lkey); |
| 596 | return -EINVAL; | 638 | return -EINVAL; |
| 597 | } | 639 | } |
| 598 | 640 | ||
| @@ -52,14 +52,14 @@ static int rxe_check_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe, · 51 unmodified lines | |||
| 52 | { | 52 | { |
| 53 | if (mw->ibmw.type == IB_MW_TYPE_1) { | 53 | if (mw->ibmw.type == IB_MW_TYPE_1) { |
| 54 | if (unlikely(mw->state != RXE_MW_STATE_VALID)) { | 54 | if (unlikely(mw->state != RXE_MW_STATE_VALID)) { |
| 55 | pr_err_once( | 55 | rxe_dbg_mw(mw, |
| 56 | "attempt to bind a type 1 MW not in the valid state\n"); | 56 | "attempt to bind a type 1 MW not in the valid state\n"); |
| 57 | return -EINVAL; | 57 | return -EINVAL; |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | /* o10-36.2.2 */ | 60 | /* o10-36.2.2 */ |
| 61 | if (unlikely((mw->access & IB_ZERO_BASED))) { | 61 | if (unlikely((mw->access & IB_ZERO_BASED))) { |
| 62 | pr_err_once("attempt to bind a zero based type 1 MW\n"); | 62 | rxe_dbg_mw(mw, "attempt to bind a zero based type 1 MW\n"); |
| 63 | return -EINVAL; | 63 | return -EINVAL; |
| 64 | } | 64 | } |
| 65 | } | 65 | } |
| @@ -67,21 +67,21 @@ static int rxe_check_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe, · 1 unmodified line | |||
| 67 | if (mw->ibmw.type == IB_MW_TYPE_2) { | 67 | if (mw->ibmw.type == IB_MW_TYPE_2) { |
| 68 | /* o10-37.2.30 */ | 68 | /* o10-37.2.30 */ |
| 69 | if (unlikely(mw->state != RXE_MW_STATE_FREE)) { | 69 | if (unlikely(mw->state != RXE_MW_STATE_FREE)) { |
| 70 | pr_err_once( | 70 | rxe_dbg_mw(mw, |
| 71 | "attempt to bind a type 2 MW not in the free state\n"); | 71 | "attempt to bind a type 2 MW not in the free state\n"); |
| 72 | return -EINVAL; | 72 | return -EINVAL; |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | /* C10-72 */ | 75 | /* C10-72 */ |
| 76 | if (unlikely(qp->pd != to_rpd(mw->ibmw.pd))) { | 76 | if (unlikely(qp->pd != to_rpd(mw->ibmw.pd))) { |
| 77 | pr_err_once( | 77 | rxe_dbg_mw(mw, |
| 78 | "attempt to bind type 2 MW with qp with different PD\n"); | 78 | "attempt to bind type 2 MW with qp with different PD\n"); |
| 79 | return -EINVAL; | 79 | return -EINVAL; |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | /* o10-37.2.40 */ | 82 | /* o10-37.2.40 */ |
| 83 | if (unlikely(!mr || wqe->wr.wr.mw.length == 0)) { | 83 | if (unlikely(!mr || wqe->wr.wr.mw.length == 0)) { |
| 84 | pr_err_once( | 84 | rxe_dbg_mw(mw, |
| 85 | "attempt to invalidate type 2 MW by binding with NULL or zero length MR\n"); | 85 | "attempt to invalidate type 2 MW by binding with NULL or zero length MR\n"); |
| 86 | return -EINVAL; | 86 | return -EINVAL; |
| 87 | } | 87 | } |
| @@ -92,13 +92,13 @@ static int rxe_check_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe, · 4 unmodified lines | |||
| 92 | return 0; | 92 | return 0; |
| 93 | 93 | ||
| 94 | if (unlikely(mr->access & IB_ZERO_BASED)) { | 94 | if (unlikely(mr->access & IB_ZERO_BASED)) { |
| 95 | pr_err_once("attempt to bind MW to zero based MR\n"); | 95 | rxe_dbg_mw(mw, "attempt to bind MW to zero based MR\n"); |
| 96 | return -EINVAL; | 96 | return -EINVAL; |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | /* C10-73 */ | 99 | /* C10-73 */ |
| 100 | if (unlikely(!(mr->access & IB_ACCESS_MW_BIND))) { | 100 | if (unlikely(!(mr->access & IB_ACCESS_MW_BIND))) { |
| 101 | pr_err_once( | 101 | rxe_dbg_mw(mw, |
| 102 | "attempt to bind an MW to an MR without bind access\n"); | 102 | "attempt to bind an MW to an MR without bind access\n"); |
| 103 | return -EINVAL; | 103 | return -EINVAL; |
| 104 | } | 104 | } |
| @@ -107,7 +107,7 @@ static int rxe_check_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe, · 2 unmodified lines | |||
| 107 | if (unlikely((mw->access & | 107 | if (unlikely((mw->access & |
| 108 | (IB_ACCESS_REMOTE_WRITE | IB_ACCESS_REMOTE_ATOMIC)) && | 108 | (IB_ACCESS_REMOTE_WRITE | IB_ACCESS_REMOTE_ATOMIC)) && |
| 109 | !(mr->access & IB_ACCESS_LOCAL_WRITE))) { | 109 | !(mr->access & IB_ACCESS_LOCAL_WRITE))) { |
| 110 | pr_err_once( | 110 | rxe_dbg_mw(mw, |
| 111 | "attempt to bind an Writable MW to an MR without local write access\n"); | 111 | "attempt to bind an Writable MW to an MR without local write access\n"); |
| 112 | return -EINVAL; | 112 | return -EINVAL; |
| 113 | } | 113 | } |
| @@ -115,7 +115,7 @@ static int rxe_check_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe, · 1 unmodified line | |||
| 115 | /* C10-75 */ | 115 | /* C10-75 */ |
| 116 | if (mw->access & IB_ZERO_BASED) { | 116 | if (mw->access & IB_ZERO_BASED) { |
| 117 | if (unlikely(wqe->wr.wr.mw.length > mr->ibmr.length)) { | 117 | if (unlikely(wqe->wr.wr.mw.length > mr->ibmr.length)) { |
| 118 | pr_err_once( | 118 | rxe_dbg_mw(mw, |
| 119 | "attempt to bind a ZB MW outside of the MR\n"); | 119 | "attempt to bind a ZB MW outside of the MR\n"); |
| 120 | return -EINVAL; | 120 | return -EINVAL; |
| 121 | } | 121 | } |
| @@ -123,7 +123,7 @@ static int rxe_check_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe, · 1 unmodified line | |||
| 123 | if (unlikely((wqe->wr.wr.mw.addr < mr->ibmr.iova) || | 123 | if (unlikely((wqe->wr.wr.mw.addr < mr->ibmr.iova) || |
| 124 | ((wqe->wr.wr.mw.addr + wqe->wr.wr.mw.length) > | 124 | ((wqe->wr.wr.mw.addr + wqe->wr.wr.mw.length) > |
| 125 | (mr->ibmr.iova + mr->ibmr.length)))) { | 125 | (mr->ibmr.iova + mr->ibmr.length)))) { |
| 126 | pr_err_once( | 126 | rxe_dbg_mw(mw, |
| 127 | "attempt to bind a VA MW outside of the MR\n"); | 127 | "attempt to bind a VA MW outside of the MR\n"); |
| 128 | return -EINVAL; | 128 | return -EINVAL; |
| 129 | } | 129 | } |
| @@ -293,8 +293,7 @@ struct rxe_mw *rxe_lookup_mw(struct rxe_qp *qp, int access, u32 rkey) · 163 unmodified lines | |||
| 293 | 293 | ||
| 294 | if (unlikely((mw->rkey != rkey) || rxe_mw_pd(mw) != pd || | 294 | if (unlikely((mw->rkey != rkey) || rxe_mw_pd(mw) != pd || |
| 295 | (mw->ibmw.type == IB_MW_TYPE_2 && mw->qp != qp) || | 295 | (mw->ibmw.type == IB_MW_TYPE_2 && mw->qp != qp) || |
| 296 | (mw->length == 0) || | 296 | (mw->length == 0) || ((access & mw->access) != access) || |
| 297 | (access && !(access & mw->access)) || | ||
| 298 | mw->state != RXE_MW_STATE_VALID)) { | 297 | mw->state != RXE_MW_STATE_VALID)) { |
| 299 | rxe_put(mw); | 298 | rxe_put(mw); |
| 300 | return NULL; | 299 | return NULL; |
| @@ -20,9 +20,10 @@ · 19 unmodified lines | |||
| 20 | 20 | ||
| 21 | static struct rxe_recv_sockets recv_sockets; | 21 | static struct rxe_recv_sockets recv_sockets; |
| 22 | 22 | ||
| 23 | static struct dst_entry *rxe_find_route4(struct net_device *ndev, | 23 | static struct dst_entry *rxe_find_route4(struct rxe_qp *qp, |
| 24 | struct in_addr *saddr, | 24 | struct net_device *ndev, |
| 25 | struct in_addr *daddr) | 25 | struct in_addr *saddr, |
| 26 | struct in_addr *daddr) | ||
| 26 | { | 27 | { |
| 27 | struct rtable *rt; | 28 | struct rtable *rt; |
| 28 | struct flowi4 fl = { { 0 } }; | 29 | struct flowi4 fl = { { 0 } }; |
| @@ -35,7 +36,7 @@ static struct dst_entry *rxe_find_route4(struct net_device *ndev, · 6 unmodified lines | |||
| 35 | 36 | ||
| 36 | rt = ip_route_output_key(&init_net, &fl); | 37 | rt = ip_route_output_key(&init_net, &fl); |
| 37 | if (IS_ERR(rt)) { | 38 | if (IS_ERR(rt)) { |
| 38 | pr_err_ratelimited("no route to %pI4\n", &daddr->s_addr); | 39 | rxe_dbg_qp(qp, "no route to %pI4\n", &daddr->s_addr); |
| 39 | return NULL; | 40 | return NULL; |
| 40 | } | 41 | } |
| 41 | 42 | ||
| @@ -43,7 +44,8 @@ static struct dst_entry *rxe_find_route4(struct net_device *ndev, · 1 unmodified line | |||
| 43 | } | 44 | } |
| 44 | 45 | ||
| 45 | #if IS_ENABLED(CONFIG_IPV6) | 46 | #if IS_ENABLED(CONFIG_IPV6) |
| 46 | static struct dst_entry *rxe_find_route6(struct net_device *ndev, | 47 | static struct dst_entry *rxe_find_route6(struct rxe_qp *qp, |
| 48 | struct net_device *ndev, | ||
| 47 | struct in6_addr *saddr, | 49 | struct in6_addr *saddr, |
| 48 | struct in6_addr *daddr) | 50 | struct in6_addr *daddr) |
| 49 | { | 51 | { |
| @@ -60,12 +62,12 @@ static struct dst_entry *rxe_find_route6(struct net_device *ndev, · 10 unmodified lines | |||
| 60 | recv_sockets.sk6->sk, &fl6, | 62 | recv_sockets.sk6->sk, &fl6, |
| 61 | NULL); | 63 | NULL); |
| 62 | if (IS_ERR(ndst)) { | 64 | if (IS_ERR(ndst)) { |
| 63 | pr_err_ratelimited("no route to %pI6\n", daddr); | 65 | rxe_dbg_qp(qp, "no route to %pI6\n", daddr); |
| 64 | return NULL; | 66 | return NULL; |
| 65 | } | 67 | } |
| 66 | 68 | ||
| 67 | if (unlikely(ndst->error)) { | 69 | if (unlikely(ndst->error)) { |
| 68 | pr_err("no route to %pI6\n", daddr); | 70 | rxe_dbg_qp(qp, "no route to %pI6\n", daddr); |
| 69 | goto put; | 71 | goto put; |
| 70 | } | 72 | } |
| 71 | 73 | ||
| @@ -77,7 +79,8 @@ put: · 5 unmodified lines | |||
| 77 | 79 | ||
| 78 | #else | 80 | #else |
| 79 | 81 | ||
| 80 | static struct dst_entry *rxe_find_route6(struct net_device *ndev, | 82 | static struct dst_entry *rxe_find_route6(struct rxe_qp *qp, |
| 83 | struct net_device *ndev, | ||
| 81 | struct in6_addr *saddr, | 84 | struct in6_addr *saddr, |
| 82 | struct in6_addr *daddr) | 85 | struct in6_addr *daddr) |
| 83 | { | 86 | { |
| @@ -105,14 +108,14 @@ static struct dst_entry *rxe_find_route(struct net_device *ndev, · 21 unmodified lines | |||
| 105 | 108 | ||
| 106 | saddr = &av->sgid_addr._sockaddr_in.sin_addr; | 109 | saddr = &av->sgid_addr._sockaddr_in.sin_addr; |
| 107 | daddr = &av->dgid_addr._sockaddr_in.sin_addr; | 110 | daddr = &av->dgid_addr._sockaddr_in.sin_addr; |
| 108 | dst = rxe_find_route4(ndev, saddr, daddr); | 111 | dst = rxe_find_route4(qp, ndev, saddr, daddr); |
| 109 | } else if (av->network_type == RXE_NETWORK_TYPE_IPV6) { | 112 | } else if (av->network_type == RXE_NETWORK_TYPE_IPV6) { |
| 110 | struct in6_addr *saddr6; | 113 | struct in6_addr *saddr6; |
| 111 | struct in6_addr *daddr6; | 114 | struct in6_addr *daddr6; |
| 112 | 115 | ||
| 113 | saddr6 = &av->sgid_addr._sockaddr_in6.sin6_addr; | 116 | saddr6 = &av->sgid_addr._sockaddr_in6.sin6_addr; |
| 114 | daddr6 = &av->dgid_addr._sockaddr_in6.sin6_addr; | 117 | daddr6 = &av->dgid_addr._sockaddr_in6.sin6_addr; |
| 115 | dst = rxe_find_route6(ndev, saddr6, daddr6); | 118 | dst = rxe_find_route6(qp, ndev, saddr6, daddr6); |
| 116 | #if IS_ENABLED(CONFIG_IPV6) | 119 | #if IS_ENABLED(CONFIG_IPV6) |
| 117 | if (dst) | 120 | if (dst) |
| 118 | qp->dst_cookie = | 121 | qp->dst_cookie = |
| @@ -282,7 +285,7 @@ static int prepare4(struct rxe_av *av, struct rxe_pkt_info *pkt, · 163 unmodified lines | |||
| 282 | 285 | ||
| 283 | dst = rxe_find_route(skb->dev, qp, av); | 286 | dst = rxe_find_route(skb->dev, qp, av); |
| 284 | if (!dst) { | 287 | if (!dst) { |
| 285 | pr_err("Host not reachable\n"); | 288 | rxe_dbg_qp(qp, "Host not reachable\n"); |
| 286 | return -EHOSTUNREACH; | 289 | return -EHOSTUNREACH; |
| 287 | } | 290 | } |
| 288 | 291 | ||
| @@ -306,7 +309,7 @@ static int prepare6(struct rxe_av *av, struct rxe_pkt_info *pkt, · 17 unmodified lines | |||
| 306 | 309 | ||
| 307 | dst = rxe_find_route(skb->dev, qp, av); | 310 | dst = rxe_find_route(skb->dev, qp, av); |
| 308 | if (!dst) { | 311 | if (!dst) { |
| 309 | pr_err("Host not reachable\n"); | 312 | rxe_dbg_qp(qp, "Host not reachable\n"); |
| 310 | return -EHOSTUNREACH; | 313 | return -EHOSTUNREACH; |
| 311 | } | 314 | } |
| 312 | 315 | ||
| @@ -345,7 +348,7 @@ static void rxe_skb_tx_dtor(struct sk_buff *skb) · 32 unmodified lines | |||
| 345 | 348 | ||
| 346 | if (unlikely(qp->need_req_skb && | 349 | if (unlikely(qp->need_req_skb && |
| 347 | skb_out < RXE_INFLIGHT_SKBS_PER_QP_LOW)) | 350 | skb_out < RXE_INFLIGHT_SKBS_PER_QP_LOW)) |
| 348 | rxe_run_task(&qp->req.task, 1); | 351 | rxe_sched_task(&qp->req.task); |
| 349 | 352 | ||
| 350 | rxe_put(qp); | 353 | rxe_put(qp); |
| 351 | } | 354 | } |
| @@ -365,7 +368,8 @@ static int rxe_send(struct sk_buff *skb, struct rxe_pkt_info *pkt) · 13 unmodified lines | |||
| 365 | } else if (skb->protocol == htons(ETH_P_IPV6)) { | 368 | } else if (skb->protocol == htons(ETH_P_IPV6)) { |
| 366 | err = ip6_local_out(dev_net(skb_dst(skb)->dev), skb->sk, skb); | 369 | err = ip6_local_out(dev_net(skb_dst(skb)->dev), skb->sk, skb); |
| 367 | } else { | 370 | } else { |
| 368 | pr_err("Unknown layer 3 protocol: %d\n", skb->protocol); | 371 | rxe_dbg_qp(pkt->qp, "Unknown layer 3 protocol: %d\n", |
| 372 | skb->protocol); | ||
| 369 | atomic_dec(&pkt->qp->skb_out); | 373 | atomic_dec(&pkt->qp->skb_out); |
| 370 | rxe_put(pkt->qp); | 374 | rxe_put(pkt->qp); |
| 371 | kfree_skb(skb); | 375 | kfree_skb(skb); |
| @@ -373,7 +377,7 @@ static int rxe_send(struct sk_buff *skb, struct rxe_pkt_info *pkt) · 1 unmodified line | |||
| 373 | } | 377 | } |
| 374 | 378 | ||
| 375 | if (unlikely(net_xmit_eval(err))) { | 379 | if (unlikely(net_xmit_eval(err))) { |
| 376 | pr_debug("error sending packet: %d\n", err); | 380 | rxe_dbg_qp(pkt->qp, "error sending packet: %d\n", err); |
| 377 | return -EAGAIN; | 381 | return -EAGAIN; |
| 378 | } | 382 | } |
| 379 | 383 | ||
| @@ -411,7 +415,7 @@ int rxe_xmit_packet(struct rxe_qp *qp, struct rxe_pkt_info *pkt, · 31 unmodified lines | |||
| 411 | 415 | ||
| 412 | if ((is_request && (qp->req.state != QP_STATE_READY)) || | 416 | if ((is_request && (qp->req.state != QP_STATE_READY)) || |
| 413 | (!is_request && (qp->resp.state != QP_STATE_READY))) { | 417 | (!is_request && (qp->resp.state != QP_STATE_READY))) { |
| 414 | pr_info("Packet dropped. QP is not in ready state\n"); | 418 | rxe_dbg_qp(qp, "Packet dropped. QP is not in ready state\n"); |
| 415 | goto drop; | 419 | goto drop; |
| 416 | } | 420 | } |
| 417 | 421 | ||
| @@ -429,7 +433,7 @@ int rxe_xmit_packet(struct rxe_qp *qp, struct rxe_pkt_info *pkt, · 11 unmodified lines | |||
| 429 | if ((qp_type(qp) != IB_QPT_RC) && | 433 | if ((qp_type(qp) != IB_QPT_RC) && |
| 430 | (pkt->mask & RXE_END_MASK)) { | 434 | (pkt->mask & RXE_END_MASK)) { |
| 431 | pkt->wqe->state = wqe_state_done; | 435 | pkt->wqe->state = wqe_state_done; |
| 432 | rxe_run_task(&qp->comp.task, 1); | 436 | rxe_sched_task(&qp->comp.task); |
| 433 | } | 437 | } |
| 434 | 438 | ||
| 435 | rxe_counter_inc(rxe, RXE_CNT_SENT_PKTS); | 439 | rxe_counter_inc(rxe, RXE_CNT_SENT_PKTS); |
| @@ -592,7 +596,7 @@ static int rxe_notify(struct notifier_block *not_blk, · 156 unmodified lines | |||
| 592 | rxe_port_down(rxe); | 596 | rxe_port_down(rxe); |
| 593 | break; | 597 | break; |
| 594 | case NETDEV_CHANGEMTU: | 598 | case NETDEV_CHANGEMTU: |
| 595 | pr_info("%s changed mtu to %d\n", ndev->name, ndev->mtu); | 599 | rxe_dbg(rxe, "%s changed mtu to %d\n", ndev->name, ndev->mtu); |
| 596 | rxe_set_mtu(rxe, ndev->mtu); | 600 | rxe_set_mtu(rxe, ndev->mtu); |
| 597 | break; | 601 | break; |
| 598 | case NETDEV_CHANGE: | 602 | case NETDEV_CHANGE: |
| @@ -604,7 +608,7 @@ static int rxe_notify(struct notifier_block *not_blk, · 5 unmodified lines | |||
| 604 | case NETDEV_CHANGENAME: | 608 | case NETDEV_CHANGENAME: |
| 605 | case NETDEV_FEAT_CHANGE: | 609 | case NETDEV_FEAT_CHANGE: |
| 606 | default: | 610 | default: |
| 607 | pr_info("ignoring netdev event = %ld for %s\n", | 611 | rxe_dbg(rxe, "ignoring netdev event = %ld for %s\n", |
| 608 | event, ndev->name); | 612 | event, ndev->name); |
| 609 | break; | 613 | break; |
| 610 | } | 614 | } |
| @@ -101,6 +101,18 @@ struct rxe_wr_opcode_info rxe_wr_opcode_info[] = { · 100 unmodified lines | |||
| 101 | [IB_QPT_UC] = WR_LOCAL_OP_MASK, | 101 | [IB_QPT_UC] = WR_LOCAL_OP_MASK, |
| 102 | }, | 102 | }, |
| 103 | }, | 103 | }, |
| 104 | [IB_WR_FLUSH] = { | ||
| 105 | .name = "IB_WR_FLUSH", | ||
| 106 | .mask = { | ||
| 107 | [IB_QPT_RC] = WR_FLUSH_MASK, | ||
| 108 | }, | ||
| 109 | }, | ||
| 110 | [IB_WR_ATOMIC_WRITE] = { | ||
| 111 | .name = "IB_WR_ATOMIC_WRITE", | ||
| 112 | .mask = { | ||
| 113 | [IB_QPT_RC] = WR_ATOMIC_WRITE_MASK, | ||
| 114 | }, | ||
| 115 | }, | ||
| 104 | }; | 116 | }; |
| 105 | 117 | ||
| 106 | struct rxe_opcode_info rxe_opcode[RXE_NUM_OPCODE] = { | 118 | struct rxe_opcode_info rxe_opcode[RXE_NUM_OPCODE] = { |
| @@ -378,6 +390,29 @@ struct rxe_opcode_info rxe_opcode[RXE_NUM_OPCODE] = { · 271 unmodified lines | |||
| 378 | RXE_IETH_BYTES, | 390 | RXE_IETH_BYTES, |
| 379 | } | 391 | } |
| 380 | }, | 392 | }, |
| 393 | [IB_OPCODE_RC_FLUSH] = { | ||
| 394 | .name = "IB_OPCODE_RC_FLUSH", | ||
| 395 | .mask = RXE_FETH_MASK | RXE_RETH_MASK | RXE_FLUSH_MASK | | ||
| 396 | RXE_START_MASK | RXE_END_MASK | RXE_REQ_MASK, | ||
| 397 | .length = RXE_BTH_BYTES + RXE_FETH_BYTES + RXE_RETH_BYTES, | ||
| 398 | .offset = { | ||
| 399 | [RXE_BTH] = 0, | ||
| 400 | [RXE_FETH] = RXE_BTH_BYTES, | ||
| 401 | [RXE_RETH] = RXE_BTH_BYTES + RXE_FETH_BYTES, | ||
| 402 | } | ||
| 403 | }, | ||
| 404 | [IB_OPCODE_RC_ATOMIC_WRITE] = { | ||
| 405 | .name = "IB_OPCODE_RC_ATOMIC_WRITE", | ||
| 406 | .mask = RXE_RETH_MASK | RXE_PAYLOAD_MASK | RXE_REQ_MASK | | ||
| 407 | RXE_ATOMIC_WRITE_MASK | RXE_START_MASK | | ||
| 408 | RXE_END_MASK, | ||
| 409 | .length = RXE_BTH_BYTES + RXE_RETH_BYTES, | ||
| 410 | .offset = { | ||
| 411 | [RXE_BTH] = 0, | ||
| 412 | [RXE_RETH] = RXE_BTH_BYTES, | ||
| 413 | [RXE_PAYLOAD] = RXE_BTH_BYTES + RXE_RETH_BYTES, | ||
| 414 | } | ||
| 415 | }, | ||
| 381 | 416 | ||
| 382 | /* UC */ | 417 | /* UC */ |
| 383 | [IB_OPCODE_UC_SEND_FIRST] = { | 418 | [IB_OPCODE_UC_SEND_FIRST] = { |
| @@ -20,6 +20,8 @@ enum rxe_wr_mask { · 19 unmodified lines | |||
| 20 | WR_READ_MASK = BIT(3), | 20 | WR_READ_MASK = BIT(3), |
| 21 | WR_WRITE_MASK = BIT(4), | 21 | WR_WRITE_MASK = BIT(4), |
| 22 | WR_LOCAL_OP_MASK = BIT(5), | 22 | WR_LOCAL_OP_MASK = BIT(5), |
| 23 | WR_FLUSH_MASK = BIT(6), | ||
| 24 | WR_ATOMIC_WRITE_MASK = BIT(7), | ||
| 23 | 25 | ||
| 24 | WR_READ_OR_WRITE_MASK = WR_READ_MASK | WR_WRITE_MASK, | 26 | WR_READ_OR_WRITE_MASK = WR_READ_MASK | WR_WRITE_MASK, |
| 25 | WR_WRITE_OR_SEND_MASK = WR_WRITE_MASK | WR_SEND_MASK, | 27 | WR_WRITE_OR_SEND_MASK = WR_WRITE_MASK | WR_SEND_MASK, |
| @@ -47,6 +49,7 @@ enum rxe_hdr_type { · 21 unmodified lines | |||
| 47 | RXE_RDETH, | 49 | RXE_RDETH, |
| 48 | RXE_DETH, | 50 | RXE_DETH, |
| 49 | RXE_IMMDT, | 51 | RXE_IMMDT, |
| 52 | RXE_FETH, | ||
| 50 | RXE_PAYLOAD, | 53 | RXE_PAYLOAD, |
| 51 | NUM_HDR_TYPES | 54 | NUM_HDR_TYPES |
| 52 | }; | 55 | }; |
| @@ -63,6 +66,7 @@ enum rxe_hdr_mask { · 10 unmodified lines | |||
| 63 | RXE_IETH_MASK = BIT(RXE_IETH), | 66 | RXE_IETH_MASK = BIT(RXE_IETH), |
| 64 | RXE_RDETH_MASK = BIT(RXE_RDETH), | 67 | RXE_RDETH_MASK = BIT(RXE_RDETH), |
| 65 | RXE_DETH_MASK = BIT(RXE_DETH), | 68 | RXE_DETH_MASK = BIT(RXE_DETH), |
| 69 | RXE_FETH_MASK = BIT(RXE_FETH), | ||
| 66 | RXE_PAYLOAD_MASK = BIT(RXE_PAYLOAD), | 70 | RXE_PAYLOAD_MASK = BIT(RXE_PAYLOAD), |
| 67 | 71 | ||
| 68 | RXE_REQ_MASK = BIT(NUM_HDR_TYPES + 0), | 72 | RXE_REQ_MASK = BIT(NUM_HDR_TYPES + 0), |
| @@ -71,16 +75,19 @@ enum rxe_hdr_mask { · 2 unmodified lines | |||
| 71 | RXE_WRITE_MASK = BIT(NUM_HDR_TYPES + 3), | 75 | RXE_WRITE_MASK = BIT(NUM_HDR_TYPES + 3), |
| 72 | RXE_READ_MASK = BIT(NUM_HDR_TYPES + 4), | 76 | RXE_READ_MASK = BIT(NUM_HDR_TYPES + 4), |
| 73 | RXE_ATOMIC_MASK = BIT(NUM_HDR_TYPES + 5), | 77 | RXE_ATOMIC_MASK = BIT(NUM_HDR_TYPES + 5), |
| 78 | RXE_FLUSH_MASK = BIT(NUM_HDR_TYPES + 6), | ||
| 74 | 79 | ||
| 75 | RXE_RWR_MASK = BIT(NUM_HDR_TYPES + 6), | 80 | RXE_RWR_MASK = BIT(NUM_HDR_TYPES + 7), |
| 76 | RXE_COMP_MASK = BIT(NUM_HDR_TYPES + 7), | 81 | RXE_COMP_MASK = BIT(NUM_HDR_TYPES + 8), |
| 77 | 82 | ||
| 78 | RXE_START_MASK = BIT(NUM_HDR_TYPES + 8), | 83 | RXE_START_MASK = BIT(NUM_HDR_TYPES + 9), |
| 79 | RXE_MIDDLE_MASK = BIT(NUM_HDR_TYPES + 9), | 84 | RXE_MIDDLE_MASK = BIT(NUM_HDR_TYPES + 10), |
| 80 | RXE_END_MASK = BIT(NUM_HDR_TYPES + 10), | 85 | RXE_END_MASK = BIT(NUM_HDR_TYPES + 11), |
| 81 | 86 | ||
| 82 | RXE_LOOPBACK_MASK = BIT(NUM_HDR_TYPES + 12), | 87 | RXE_LOOPBACK_MASK = BIT(NUM_HDR_TYPES + 12), |
| 83 | 88 | ||
| 89 | RXE_ATOMIC_WRITE_MASK = BIT(NUM_HDR_TYPES + 14), | ||
| 90 | |||
| 84 | RXE_READ_OR_ATOMIC_MASK = (RXE_READ_MASK | RXE_ATOMIC_MASK), | 91 | RXE_READ_OR_ATOMIC_MASK = (RXE_READ_MASK | RXE_ATOMIC_MASK), |
| 85 | RXE_WRITE_OR_SEND_MASK = (RXE_WRITE_MASK | RXE_SEND_MASK), | 92 | RXE_WRITE_OR_SEND_MASK = (RXE_WRITE_MASK | RXE_SEND_MASK), |
| 86 | RXE_READ_OR_WRITE_MASK = (RXE_READ_MASK | RXE_WRITE_MASK), | 93 | RXE_READ_OR_WRITE_MASK = (RXE_READ_MASK | RXE_WRITE_MASK), |
| @@ -51,7 +51,14 @@ enum rxe_device_param { · 50 unmodified lines | |||
| 51 | | IB_DEVICE_SRQ_RESIZE | 51 | | IB_DEVICE_SRQ_RESIZE |
| 52 | | IB_DEVICE_MEM_MGT_EXTENSIONS | 52 | | IB_DEVICE_MEM_MGT_EXTENSIONS |
| 53 | | IB_DEVICE_MEM_WINDOW | 53 | | IB_DEVICE_MEM_WINDOW |
| 54 | | IB_DEVICE_FLUSH_GLOBAL | ||
| 55 | | IB_DEVICE_FLUSH_PERSISTENT | ||
| 56 | #ifdef CONFIG_64BIT | ||
| 57 | | IB_DEVICE_MEM_WINDOW_TYPE_2B | ||
| 58 | | IB_DEVICE_ATOMIC_WRITE, | ||
| 59 | #else | ||
| 54 | | IB_DEVICE_MEM_WINDOW_TYPE_2B, | 60 | | IB_DEVICE_MEM_WINDOW_TYPE_2B, |
| 61 | #endif /* CONFIG_64BIT */ | ||
| 55 | RXE_MAX_SGE = 32, | 62 | RXE_MAX_SGE = 32, |
| 56 | RXE_MAX_WQE_SIZE = sizeof(struct rxe_send_wqe) + | 63 | RXE_MAX_WQE_SIZE = sizeof(struct rxe_send_wqe) + |
| 57 | sizeof(struct ib_sge) * RXE_MAX_SGE, | 64 | sizeof(struct ib_sge) * RXE_MAX_SGE, |
| @@ -19,33 +19,33 @@ static int rxe_qp_chk_cap(struct rxe_dev *rxe, struct ib_qp_cap *cap, · 18 unmodified lines | |||
| 19 | int has_srq) | 19 | int has_srq) |
| 20 | { | 20 | { |
| 21 | if (cap->max_send_wr > rxe->attr.max_qp_wr) { | 21 | if (cap->max_send_wr > rxe->attr.max_qp_wr) { |
| 22 | pr_debug("invalid send wr = %u > %d\n", | 22 | rxe_dbg(rxe, "invalid send wr = %u > %d\n", |
| 23 | cap->max_send_wr, rxe->attr.max_qp_wr); | 23 | cap->max_send_wr, rxe->attr.max_qp_wr); |
| 24 | goto err1; | 24 | goto err1; |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | if (cap->max_send_sge > rxe->attr.max_send_sge) { | 27 | if (cap->max_send_sge > rxe->attr.max_send_sge) { |
| 28 | pr_debug("invalid send sge = %u > %d\n", | 28 | rxe_dbg(rxe, "invalid send sge = %u > %d\n", |
| 29 | cap->max_send_sge, rxe->attr.max_send_sge); | 29 | cap->max_send_sge, rxe->attr.max_send_sge); |
| 30 | goto err1; | 30 | goto err1; |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | if (!has_srq) { | 33 | if (!has_srq) { |
| 34 | if (cap->max_recv_wr > rxe->attr.max_qp_wr) { | 34 | if (cap->max_recv_wr > rxe->attr.max_qp_wr) { |
| 35 | pr_debug("invalid recv wr = %u > %d\n", | 35 | rxe_dbg(rxe, "invalid recv wr = %u > %d\n", |
| 36 | cap->max_recv_wr, rxe->attr.max_qp_wr); | 36 | cap->max_recv_wr, rxe->attr.max_qp_wr); |
| 37 | goto err1; | 37 | goto err1; |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | if (cap->max_recv_sge > rxe->attr.max_recv_sge) { | 40 | if (cap->max_recv_sge > rxe->attr.max_recv_sge) { |
| 41 | pr_debug("invalid recv sge = %u > %d\n", | 41 | rxe_dbg(rxe, "invalid recv sge = %u > %d\n", |
| 42 | cap->max_recv_sge, rxe->attr.max_recv_sge); | 42 | cap->max_recv_sge, rxe->attr.max_recv_sge); |
| 43 | goto err1; | 43 | goto err1; |
| 44 | } | 44 | } |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | if (cap->max_inline_data > rxe->max_inline_data) { | 47 | if (cap->max_inline_data > rxe->max_inline_data) { |
| 48 | pr_debug("invalid max inline data = %u > %d\n", | 48 | rxe_dbg(rxe, "invalid max inline data = %u > %d\n", |
| 49 | cap->max_inline_data, rxe->max_inline_data); | 49 | cap->max_inline_data, rxe->max_inline_data); |
| 50 | goto err1; | 50 | goto err1; |
| 51 | } | 51 | } |
| @@ -73,7 +73,7 @@ int rxe_qp_chk_init(struct rxe_dev *rxe, struct ib_qp_init_attr *init) · 21 unmodified lines | |||
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | if (!init->recv_cq || !init->send_cq) { | 75 | if (!init->recv_cq || !init->send_cq) { |
| 76 | pr_debug("missing cq\n"); | 76 | rxe_dbg(rxe, "missing cq\n"); |
| 77 | goto err1; | 77 | goto err1; |
| 78 | } | 78 | } |
| 79 | 79 | ||
| @@ -82,14 +82,14 @@ int rxe_qp_chk_init(struct rxe_dev *rxe, struct ib_qp_init_attr *init) · 2 unmodified lines | |||
| 82 | 82 | ||
| 83 | if (init->qp_type == IB_QPT_GSI) { | 83 | if (init->qp_type == IB_QPT_GSI) { |
| 84 | if (!rdma_is_port_valid(&rxe->ib_dev, port_num)) { | 84 | if (!rdma_is_port_valid(&rxe->ib_dev, port_num)) { |
| 85 | pr_debug("invalid port = %d\n", port_num); | 85 | rxe_dbg(rxe, "invalid port = %d\n", port_num); |
| 86 | goto err1; | 86 | goto err1; |
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | port = &rxe->port; | 89 | port = &rxe->port; |
| 90 | 90 | ||
| 91 | if (init->qp_type == IB_QPT_GSI && port->qp_gsi_index) { | 91 | if (init->qp_type == IB_QPT_GSI && port->qp_gsi_index) { |
| 92 | pr_debug("GSI QP exists for port %d\n", port_num); | 92 | rxe_dbg(rxe, "GSI QP exists for port %d\n", port_num); |
| 93 | goto err1; | 93 | goto err1; |
| 94 | } | 94 | } |
| 95 | } | 95 | } |
| @@ -172,10 +172,6 @@ static void rxe_qp_init_misc(struct rxe_dev *rxe, struct rxe_qp *qp, · 76 unmodified lines | |||
| 172 | 172 | ||
| 173 | spin_lock_init(&qp->state_lock); | 173 | spin_lock_init(&qp->state_lock); |
| 174 | 174 | ||
| 175 | spin_lock_init(&qp->req.task.state_lock); | ||
| 176 | spin_lock_init(&qp->resp.task.state_lock); | ||
| 177 | spin_lock_init(&qp->comp.task.state_lock); | ||
| 178 | |||
| 179 | spin_lock_init(&qp->sq.sq_lock); | 175 | spin_lock_init(&qp->sq.sq_lock); |
| 180 | spin_lock_init(&qp->rq.producer_lock); | 176 | spin_lock_init(&qp->rq.producer_lock); |
| 181 | spin_lock_init(&qp->rq.consumer_lock); | 177 | spin_lock_init(&qp->rq.consumer_lock); |
| @@ -242,10 +238,8 @@ static int rxe_qp_init_req(struct rxe_dev *rxe, struct rxe_qp *qp, · 60 unmodified lines | |||
| 242 | 238 | ||
| 243 | skb_queue_head_init(&qp->req_pkts); | 239 | skb_queue_head_init(&qp->req_pkts); |
| 244 | 240 | ||
| 245 | rxe_init_task(&qp->req.task, qp, | 241 | rxe_init_task(&qp->req.task, qp, rxe_requester); |
| 246 | rxe_requester, "req"); | 242 | rxe_init_task(&qp->comp.task, qp, rxe_completer); |
| 247 | rxe_init_task(&qp->comp.task, qp, | ||
| 248 | rxe_completer, "comp"); | ||
| 249 | 243 | ||
| 250 | qp->qp_timeout_jiffies = 0; /* Can't be set for UD/UC in modify_qp */ | 244 | qp->qp_timeout_jiffies = 0; /* Can't be set for UD/UC in modify_qp */ |
| 251 | if (init->qp_type == IB_QPT_RC) { | 245 | if (init->qp_type == IB_QPT_RC) { |
| @@ -270,9 +264,6 @@ static int rxe_qp_init_resp(struct rxe_dev *rxe, struct rxe_qp *qp, · 18 unmodified lines | |||
| 270 | 264 | ||
| 271 | wqe_size = rcv_wqe_size(qp->rq.max_sge); | 265 | wqe_size = rcv_wqe_size(qp->rq.max_sge); |
| 272 | 266 | ||
| 273 | pr_debug("qp#%d max_wr = %d, max_sge = %d, wqe_size = %d\n", | ||
| 274 | qp_num(qp), qp->rq.max_wr, qp->rq.max_sge, wqe_size); | ||
| 275 | |||
| 276 | type = QUEUE_TYPE_FROM_CLIENT; | 267 | type = QUEUE_TYPE_FROM_CLIENT; |
| 277 | qp->rq.queue = rxe_queue_init(rxe, &qp->rq.max_wr, | 268 | qp->rq.queue = rxe_queue_init(rxe, &qp->rq.max_wr, |
| 278 | wqe_size, type); | 269 | wqe_size, type); |
| @@ -292,8 +283,7 @@ static int rxe_qp_init_resp(struct rxe_dev *rxe, struct rxe_qp *qp, · 13 unmodified lines | |||
| 292 | 283 | ||
| 293 | skb_queue_head_init(&qp->resp_pkts); | 284 | skb_queue_head_init(&qp->resp_pkts); |
| 294 | 285 | ||
| 295 | rxe_init_task(&qp->resp.task, qp, | 286 | rxe_init_task(&qp->resp.task, qp, rxe_responder); |
| 296 | rxe_responder, "resp"); | ||
| 297 | 287 | ||
| 298 | qp->resp.opcode = OPCODE_NONE; | 288 | qp->resp.opcode = OPCODE_NONE; |
| 299 | qp->resp.msn = 0; | 289 | qp->resp.msn = 0; |
| @@ -402,7 +392,7 @@ int rxe_qp_chk_attr(struct rxe_dev *rxe, struct rxe_qp *qp, · 102 unmodified lines | |||
| 402 | attr->qp_state : cur_state; | 392 | attr->qp_state : cur_state; |
| 403 | 393 | ||
| 404 | if (!ib_modify_qp_is_ok(cur_state, new_state, qp_type(qp), mask)) { | 394 | if (!ib_modify_qp_is_ok(cur_state, new_state, qp_type(qp), mask)) { |
| 405 | pr_debug("invalid mask or state for qp\n"); | 395 | rxe_dbg_qp(qp, "invalid mask or state\n"); |
| 406 | goto err1; | 396 | goto err1; |
| 407 | } | 397 | } |
| 408 | 398 | ||
| @@ -416,7 +406,7 @@ int rxe_qp_chk_attr(struct rxe_dev *rxe, struct rxe_qp *qp, · 7 unmodified lines | |||
| 416 | 406 | ||
| 417 | if (mask & IB_QP_PORT) { | 407 | if (mask & IB_QP_PORT) { |
| 418 | if (!rdma_is_port_valid(&rxe->ib_dev, attr->port_num)) { | 408 | if (!rdma_is_port_valid(&rxe->ib_dev, attr->port_num)) { |
| 419 | pr_debug("invalid port %d\n", attr->port_num); | 409 | rxe_dbg_qp(qp, "invalid port %d\n", attr->port_num); |
| 420 | goto err1; | 410 | goto err1; |
| 421 | } | 411 | } |
| 422 | } | 412 | } |
| @@ -424,18 +414,18 @@ int rxe_qp_chk_attr(struct rxe_dev *rxe, struct rxe_qp *qp, · 1 unmodified line | |||
| 424 | if (mask & IB_QP_CAP && rxe_qp_chk_cap(rxe, &attr->cap, !!qp->srq)) | 414 | if (mask & IB_QP_CAP && rxe_qp_chk_cap(rxe, &attr->cap, !!qp->srq)) |
| 425 | goto err1; | 415 | goto err1; |
| 426 | 416 | ||
| 427 | if (mask & IB_QP_AV && rxe_av_chk_attr(rxe, &attr->ah_attr)) | 417 | if (mask & IB_QP_AV && rxe_av_chk_attr(qp, &attr->ah_attr)) |
| 428 | goto err1; | 418 | goto err1; |
| 429 | 419 | ||
| 430 | if (mask & IB_QP_ALT_PATH) { | 420 | if (mask & IB_QP_ALT_PATH) { |
| 431 | if (rxe_av_chk_attr(rxe, &attr->alt_ah_attr)) | 421 | if (rxe_av_chk_attr(qp, &attr->alt_ah_attr)) |
| 432 | goto err1; | 422 | goto err1; |
| 433 | if (!rdma_is_port_valid(&rxe->ib_dev, attr->alt_port_num)) { | 423 | if (!rdma_is_port_valid(&rxe->ib_dev, attr->alt_port_num)) { |
| 434 | pr_debug("invalid alt port %d\n", attr->alt_port_num); | 424 | rxe_dbg_qp(qp, "invalid alt port %d\n", attr->alt_port_num); |
| 435 | goto err1; | 425 | goto err1; |
| 436 | } | 426 | } |
| 437 | if (attr->alt_timeout > 31) { | 427 | if (attr->alt_timeout > 31) { |
| 438 | pr_debug("invalid QP alt timeout %d > 31\n", | 428 | rxe_dbg_qp(qp, "invalid alt timeout %d > 31\n", |
| 439 | attr->alt_timeout); | 429 | attr->alt_timeout); |
| 440 | goto err1; | 430 | goto err1; |
| 441 | } | 431 | } |
| @@ -448,7 +438,7 @@ int rxe_qp_chk_attr(struct rxe_dev *rxe, struct rxe_qp *qp, · 6 unmodified lines | |||
| 448 | enum ib_mtu mtu = attr->path_mtu; | 438 | enum ib_mtu mtu = attr->path_mtu; |
| 449 | 439 | ||
| 450 | if (mtu > max_mtu) { | 440 | if (mtu > max_mtu) { |
| 451 | pr_debug("invalid mtu (%d) > (%d)\n", | 441 | rxe_dbg_qp(qp, "invalid mtu (%d) > (%d)\n", |
| 452 | ib_mtu_enum_to_int(mtu), | 442 | ib_mtu_enum_to_int(mtu), |
| 453 | ib_mtu_enum_to_int(max_mtu)); | 443 | ib_mtu_enum_to_int(max_mtu)); |
| 454 | goto err1; | 444 | goto err1; |
| @@ -457,7 +447,7 @@ int rxe_qp_chk_attr(struct rxe_dev *rxe, struct rxe_qp *qp, · 2 unmodified lines | |||
| 457 | 447 | ||
| 458 | if (mask & IB_QP_MAX_QP_RD_ATOMIC) { | 448 | if (mask & IB_QP_MAX_QP_RD_ATOMIC) { |
| 459 | if (attr->max_rd_atomic > rxe->attr.max_qp_rd_atom) { | 449 | if (attr->max_rd_atomic > rxe->attr.max_qp_rd_atom) { |
| 460 | pr_debug("invalid max_rd_atomic %d > %d\n", | 450 | rxe_dbg_qp(qp, "invalid max_rd_atomic %d > %d\n", |
| 461 | attr->max_rd_atomic, | 451 | attr->max_rd_atomic, |
| 462 | rxe->attr.max_qp_rd_atom); | 452 | rxe->attr.max_qp_rd_atom); |
| 463 | goto err1; | 453 | goto err1; |
| @@ -466,7 +456,8 @@ int rxe_qp_chk_attr(struct rxe_dev *rxe, struct rxe_qp *qp, · 2 unmodified lines | |||
| 466 | 456 | ||
| 467 | if (mask & IB_QP_TIMEOUT) { | 457 | if (mask & IB_QP_TIMEOUT) { |
| 468 | if (attr->timeout > 31) { | 458 | if (attr->timeout > 31) { |
| 469 | pr_debug("invalid QP timeout %d > 31\n", attr->timeout); | 459 | rxe_dbg_qp(qp, "invalid timeout %d > 31\n", |
| 460 | attr->timeout); | ||
| 470 | goto err1; | 461 | goto err1; |
| 471 | } | 462 | } |
| 472 | } | 463 | } |
| @@ -543,10 +534,10 @@ static void rxe_qp_drain(struct rxe_qp *qp) · 70 unmodified lines | |||
| 543 | if (qp->req.state != QP_STATE_DRAINED) { | 534 | if (qp->req.state != QP_STATE_DRAINED) { |
| 544 | qp->req.state = QP_STATE_DRAIN; | 535 | qp->req.state = QP_STATE_DRAIN; |
| 545 | if (qp_type(qp) == IB_QPT_RC) | 536 | if (qp_type(qp) == IB_QPT_RC) |
| 546 | rxe_run_task(&qp->comp.task, 1); | 537 | rxe_sched_task(&qp->comp.task); |
| 547 | else | 538 | else |
| 548 | __rxe_do_task(&qp->comp.task); | 539 | __rxe_do_task(&qp->comp.task); |
| 549 | rxe_run_task(&qp->req.task, 1); | 540 | rxe_sched_task(&qp->req.task); |
| 550 | } | 541 | } |
| 551 | } | 542 | } |
| 552 | } | 543 | } |
| @@ -560,13 +551,13 @@ void rxe_qp_error(struct rxe_qp *qp) · 7 unmodified lines | |||
| 560 | qp->attr.qp_state = IB_QPS_ERR; | 551 | qp->attr.qp_state = IB_QPS_ERR; |
| 561 | 552 | ||
| 562 | /* drain work and packet queues */ | 553 | /* drain work and packet queues */ |
| 563 | rxe_run_task(&qp->resp.task, 1); | 554 | rxe_sched_task(&qp->resp.task); |
| 564 | 555 | ||
| 565 | if (qp_type(qp) == IB_QPT_RC) | 556 | if (qp_type(qp) == IB_QPT_RC) |
| 566 | rxe_run_task(&qp->comp.task, 1); | 557 | rxe_sched_task(&qp->comp.task); |
| 567 | else | 558 | else |
| 568 | __rxe_do_task(&qp->comp.task); | 559 | __rxe_do_task(&qp->comp.task); |
| 569 | rxe_run_task(&qp->req.task, 1); | 560 | rxe_sched_task(&qp->req.task); |
| 570 | } | 561 | } |
| 571 | 562 | ||
| 572 | /* called by the modify qp verb */ | 563 | /* called by the modify qp verb */ |
| @@ -644,27 +635,24 @@ int rxe_qp_from_attr(struct rxe_qp *qp, struct ib_qp_attr *attr, int mask, · 71 unmodified lines | |||
| 644 | if (mask & IB_QP_RETRY_CNT) { | 635 | if (mask & IB_QP_RETRY_CNT) { |
| 645 | qp->attr.retry_cnt = attr->retry_cnt; | 636 | qp->attr.retry_cnt = attr->retry_cnt; |
| 646 | qp->comp.retry_cnt = attr->retry_cnt; | 637 | qp->comp.retry_cnt = attr->retry_cnt; |
| 647 | pr_debug("qp#%d set retry count = %d\n", qp_num(qp), | 638 | rxe_dbg_qp(qp, "set retry count = %d\n", attr->retry_cnt); |
| 648 | attr->retry_cnt); | ||
| 649 | } | 639 | } |
| 650 | 640 | ||
| 651 | if (mask & IB_QP_RNR_RETRY) { | 641 | if (mask & IB_QP_RNR_RETRY) { |
| 652 | qp->attr.rnr_retry = attr->rnr_retry; | 642 | qp->attr.rnr_retry = attr->rnr_retry; |
| 653 | qp->comp.rnr_retry = attr->rnr_retry; | 643 | qp->comp.rnr_retry = attr->rnr_retry; |
| 654 | pr_debug("qp#%d set rnr retry count = %d\n", qp_num(qp), | 644 | rxe_dbg_qp(qp, "set rnr retry count = %d\n", attr->rnr_retry); |
| 655 | attr->rnr_retry); | ||
| 656 | } | 645 | } |
| 657 | 646 | ||
| 658 | if (mask & IB_QP_RQ_PSN) { | 647 | if (mask & IB_QP_RQ_PSN) { |
| 659 | qp->attr.rq_psn = (attr->rq_psn & BTH_PSN_MASK); | 648 | qp->attr.rq_psn = (attr->rq_psn & BTH_PSN_MASK); |
| 660 | qp->resp.psn = qp->attr.rq_psn; | 649 | qp->resp.psn = qp->attr.rq_psn; |
| 661 | pr_debug("qp#%d set resp psn = 0x%x\n", qp_num(qp), | 650 | rxe_dbg_qp(qp, "set resp psn = 0x%x\n", qp->resp.psn); |
| 662 | qp->resp.psn); | ||
| 663 | } | 651 | } |
| 664 | 652 | ||
| 665 | if (mask & IB_QP_MIN_RNR_TIMER) { | 653 | if (mask & IB_QP_MIN_RNR_TIMER) { |
| 666 | qp->attr.min_rnr_timer = attr->min_rnr_timer; | 654 | qp->attr.min_rnr_timer = attr->min_rnr_timer; |
| 667 | pr_debug("qp#%d set min rnr timer = 0x%x\n", qp_num(qp), | 655 | rxe_dbg_qp(qp, "set min rnr timer = 0x%x\n", |
| 668 | attr->min_rnr_timer); | 656 | attr->min_rnr_timer); |
| 669 | } | 657 | } |
| 670 | 658 | ||
| @@ -672,7 +660,7 @@ int rxe_qp_from_attr(struct rxe_qp *qp, struct ib_qp_attr *attr, int mask, · 1 unmodified line | |||
| 672 | qp->attr.sq_psn = (attr->sq_psn & BTH_PSN_MASK); | 660 | qp->attr.sq_psn = (attr->sq_psn & BTH_PSN_MASK); |
| 673 | qp->req.psn = qp->attr.sq_psn; | 661 | qp->req.psn = qp->attr.sq_psn; |
| 674 | qp->comp.psn = qp->attr.sq_psn; | 662 | qp->comp.psn = qp->attr.sq_psn; |
| 675 | pr_debug("qp#%d set req psn = 0x%x\n", qp_num(qp), qp->req.psn); | 663 | rxe_dbg_qp(qp, "set req psn = 0x%x\n", qp->req.psn); |
| 676 | } | 664 | } |
| 677 | 665 | ||
| 678 | if (mask & IB_QP_PATH_MIG_STATE) | 666 | if (mask & IB_QP_PATH_MIG_STATE) |
| @@ -686,40 +674,40 @@ int rxe_qp_from_attr(struct rxe_qp *qp, struct ib_qp_attr *attr, int mask, · 7 unmodified lines | |||
| 686 | 674 | ||
| 687 | switch (attr->qp_state) { | 675 | switch (attr->qp_state) { |
| 688 | case IB_QPS_RESET: | 676 | case IB_QPS_RESET: |
| 689 | pr_debug("qp#%d state -> RESET\n", qp_num(qp)); | 677 | rxe_dbg_qp(qp, "state -> RESET\n"); |
| 690 | rxe_qp_reset(qp); | 678 | rxe_qp_reset(qp); |
| 691 | break; | 679 | break; |
| 692 | 680 | ||
| 693 | case IB_QPS_INIT: | 681 | case IB_QPS_INIT: |
| 694 | pr_debug("qp#%d state -> INIT\n", qp_num(qp)); | 682 | rxe_dbg_qp(qp, "state -> INIT\n"); |
| 695 | qp->req.state = QP_STATE_INIT; | 683 | qp->req.state = QP_STATE_INIT; |
| 696 | qp->resp.state = QP_STATE_INIT; | 684 | qp->resp.state = QP_STATE_INIT; |
| 697 | qp->comp.state = QP_STATE_INIT; | 685 | qp->comp.state = QP_STATE_INIT; |
| 698 | break; | 686 | break; |
| 699 | 687 | ||
| 700 | case IB_QPS_RTR: | 688 | case IB_QPS_RTR: |
| 701 | pr_debug("qp#%d state -> RTR\n", qp_num(qp)); | 689 | rxe_dbg_qp(qp, "state -> RTR\n"); |
| 702 | qp->resp.state = QP_STATE_READY; | 690 | qp->resp.state = QP_STATE_READY; |
| 703 | break; | 691 | break; |
| 704 | 692 | ||
| 705 | case IB_QPS_RTS: | 693 | case IB_QPS_RTS: |
| 706 | pr_debug("qp#%d state -> RTS\n", qp_num(qp)); | 694 | rxe_dbg_qp(qp, "state -> RTS\n"); |
| 707 | qp->req.state = QP_STATE_READY; | 695 | qp->req.state = QP_STATE_READY; |
| 708 | qp->comp.state = QP_STATE_READY; | 696 | qp->comp.state = QP_STATE_READY; |
| 709 | break; | 697 | break; |
| 710 | 698 | ||
| 711 | case IB_QPS_SQD: | 699 | case IB_QPS_SQD: |
| 712 | pr_debug("qp#%d state -> SQD\n", qp_num(qp)); | 700 | rxe_dbg_qp(qp, "state -> SQD\n"); |
| 713 | rxe_qp_drain(qp); | 701 | rxe_qp_drain(qp); |
| 714 | break; | 702 | break; |
| 715 | 703 | ||
| 716 | case IB_QPS_SQE: | 704 | case IB_QPS_SQE: |
| 717 | pr_warn("qp#%d state -> SQE !!?\n", qp_num(qp)); | 705 | rxe_dbg_qp(qp, "state -> SQE !!?\n"); |
| 718 | /* Not possible from modify_qp. */ | 706 | /* Not possible from modify_qp. */ |
| 719 | break; | 707 | break; |
| 720 | 708 | ||
| 721 | case IB_QPS_ERR: | 709 | case IB_QPS_ERR: |
| 722 | pr_debug("qp#%d state -> ERR\n", qp_num(qp)); | 710 | rxe_dbg_qp(qp, "state -> ERR\n"); |
| 723 | rxe_qp_error(qp); | 711 | rxe_qp_error(qp); |
| 724 | break; | 712 | break; |
| 725 | } | 713 | } |
| @@ -759,7 +747,7 @@ int rxe_qp_to_attr(struct rxe_qp *qp, struct ib_qp_attr *attr, int mask) · 33 unmodified lines | |||
| 759 | attr->sq_draining = 0; | 747 | attr->sq_draining = 0; |
| 760 | } | 748 | } |
| 761 | 749 | ||
| 762 | pr_debug("attr->sq_draining = %d\n", attr->sq_draining); | 750 | rxe_dbg_qp(qp, "attr->sq_draining = %d\n", attr->sq_draining); |
| 763 | 751 | ||
| 764 | return 0; | 752 | return 0; |
| 765 | } | 753 | } |
| @@ -771,7 +759,7 @@ int rxe_qp_chk_destroy(struct rxe_qp *qp) · 5 unmodified lines | |||
| 771 | * will fail immediately. | 759 | * will fail immediately. |
| 772 | */ | 760 | */ |
| 773 | if (atomic_read(&qp->mcg_num)) { | 761 | if (atomic_read(&qp->mcg_num)) { |
| 774 | pr_debug("Attempt to destroy QP while attached to multicast group\n"); | 762 | rxe_dbg_qp(qp, "Attempt to destroy while attached to multicast group\n"); |
| 775 | return -EBUSY; | 763 | return -EBUSY; |
| 776 | } | 764 | } |
| 777 | 765 | ||
| @@ -829,12 +817,12 @@ static void rxe_qp_do_cleanup(struct work_struct *work) · 51 unmodified lines | |||
| 829 | if (qp->resp.mr) | 817 | if (qp->resp.mr) |
| 830 | rxe_put(qp->resp.mr); | 818 | rxe_put(qp->resp.mr); |
| 831 | 819 | ||
| 832 | if (qp_type(qp) == IB_QPT_RC) | ||
| 833 | sk_dst_reset(qp->sk->sk); | ||
| 834 | |||
| 835 | free_rd_atomic_resources(qp); | 820 | free_rd_atomic_resources(qp); |
| 836 | 821 | ||
| 837 | if (qp->sk) { | 822 | if (qp->sk) { |
| 823 | if (qp_type(qp) == IB_QPT_RC) | ||
| 824 | sk_dst_reset(qp->sk->sk); | ||
| 825 | |||
| 838 | kernel_sock_shutdown(qp->sk, SHUT_RDWR); | 826 | kernel_sock_shutdown(qp->sk, SHUT_RDWR); |
| 839 | sock_release(qp->sk); | 827 | sock_release(qp->sk); |
| 840 | } | 828 | } |
| @@ -100,12 +100,12 @@ void rnr_nak_timer(struct timer_list *t) · 99 unmodified lines | |||
| 100 | { | 100 | { |
| 101 | struct rxe_qp *qp = from_timer(qp, t, rnr_nak_timer); | 101 | struct rxe_qp *qp = from_timer(qp, t, rnr_nak_timer); |
| 102 | 102 | ||
| 103 | pr_debug("%s: fired for qp#%d\n", __func__, qp_num(qp)); | 103 | rxe_dbg_qp(qp, "nak timer fired\n"); |
| 104 | 104 | ||
| 105 | /* request a send queue retry */ | 105 | /* request a send queue retry */ |
| 106 | qp->req.need_retry = 1; | 106 | qp->req.need_retry = 1; |
| 107 | qp->req.wait_for_rnr_timer = 0; | 107 | qp->req.wait_for_rnr_timer = 0; |
| 108 | rxe_run_task(&qp->req.task, 1); | 108 | rxe_sched_task(&qp->req.task); |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | static struct rxe_send_wqe *req_next_wqe(struct rxe_qp *qp) | 111 | static struct rxe_send_wqe *req_next_wqe(struct rxe_qp *qp) |
| @@ -241,6 +241,9 @@ static int next_opcode_rc(struct rxe_qp *qp, u32 opcode, int fits) · 129 unmodified lines | |||
| 241 | IB_OPCODE_RC_SEND_ONLY_WITH_IMMEDIATE : | 241 | IB_OPCODE_RC_SEND_ONLY_WITH_IMMEDIATE : |
| 242 | IB_OPCODE_RC_SEND_FIRST; | 242 | IB_OPCODE_RC_SEND_FIRST; |
| 243 | 243 | ||
| 244 | case IB_WR_FLUSH: | ||
| 245 | return IB_OPCODE_RC_FLUSH; | ||
| 246 | |||
| 244 | case IB_WR_RDMA_READ: | 247 | case IB_WR_RDMA_READ: |
| 245 | return IB_OPCODE_RC_RDMA_READ_REQUEST; | 248 | return IB_OPCODE_RC_RDMA_READ_REQUEST; |
| 246 | 249 | ||
| @@ -258,6 +261,10 @@ static int next_opcode_rc(struct rxe_qp *qp, u32 opcode, int fits) · 11 unmodified lines | |||
| 258 | else | 261 | else |
| 259 | return fits ? IB_OPCODE_RC_SEND_ONLY_WITH_INVALIDATE : | 262 | return fits ? IB_OPCODE_RC_SEND_ONLY_WITH_INVALIDATE : |
| 260 | IB_OPCODE_RC_SEND_FIRST; | 263 | IB_OPCODE_RC_SEND_FIRST; |
| 264 | |||
| 265 | case IB_WR_ATOMIC_WRITE: | ||
| 266 | return IB_OPCODE_RC_ATOMIC_WRITE; | ||
| 267 | |||
| 261 | case IB_WR_REG_MR: | 268 | case IB_WR_REG_MR: |
| 262 | case IB_WR_LOCAL_INV: | 269 | case IB_WR_LOCAL_INV: |
| 263 | return opcode; | 270 | return opcode; |
| @@ -421,11 +428,18 @@ static struct sk_buff *init_req_packet(struct rxe_qp *qp, · 157 unmodified lines | |||
| 421 | 428 | ||
| 422 | /* init optional headers */ | 429 | /* init optional headers */ |
| 423 | if (pkt->mask & RXE_RETH_MASK) { | 430 | if (pkt->mask & RXE_RETH_MASK) { |
| 424 | reth_set_rkey(pkt, ibwr->wr.rdma.rkey); | 431 | if (pkt->mask & RXE_FETH_MASK) |
| 432 | reth_set_rkey(pkt, ibwr->wr.flush.rkey); | ||
| 433 | else | ||
| 434 | reth_set_rkey(pkt, ibwr->wr.rdma.rkey); | ||
| 425 | reth_set_va(pkt, wqe->iova); | 435 | reth_set_va(pkt, wqe->iova); |
| 426 | reth_set_len(pkt, wqe->dma.resid); | 436 | reth_set_len(pkt, wqe->dma.resid); |
| 427 | } | 437 | } |
| 428 | 438 | ||
| 439 | /* Fill Flush Extension Transport Header */ | ||
| 440 | if (pkt->mask & RXE_FETH_MASK) | ||
| 441 | feth_init(pkt, ibwr->wr.flush.type, ibwr->wr.flush.level); | ||
| 442 | |||
| 429 | if (pkt->mask & RXE_IMMDT_MASK) | 443 | if (pkt->mask & RXE_IMMDT_MASK) |
| 430 | immdt_set_imm(pkt, ibwr->ex.imm_data); | 444 | immdt_set_imm(pkt, ibwr->ex.imm_data); |
| 431 | 445 | ||
| @@ -484,6 +498,14 @@ static int finish_packet(struct rxe_qp *qp, struct rxe_av *av, · 52 unmodified lines | |||
| 484 | 498 | ||
| 485 | memset(pad, 0, bth_pad(pkt)); | 499 | memset(pad, 0, bth_pad(pkt)); |
| 486 | } | 500 | } |
| 501 | } else if (pkt->mask & RXE_FLUSH_MASK) { | ||
| 502 | /* oA19-2: shall have no payload. */ | ||
| 503 | wqe->dma.resid = 0; | ||
| 504 | } | ||
| 505 | |||
| 506 | if (pkt->mask & RXE_ATOMIC_WRITE_MASK) { | ||
| 507 | memcpy(payload_addr(pkt), wqe->dma.atomic_wr, payload); | ||
| 508 | wqe->dma.resid -= payload; | ||
| 487 | } | 509 | } |
| 488 | 510 | ||
| 489 | return 0; | 511 | return 0; |
| @@ -595,7 +617,7 @@ static int rxe_do_local_ops(struct rxe_qp *qp, struct rxe_send_wqe *wqe) · 105 unmodified lines | |||
| 595 | } | 617 | } |
| 596 | break; | 618 | break; |
| 597 | default: | 619 | default: |
| 598 | pr_err("Unexpected send wqe opcode %d\n", opcode); | 620 | rxe_dbg_qp(qp, "Unexpected send wqe opcode %d\n", opcode); |
| 599 | wqe->status = IB_WC_LOC_QP_OP_ERR; | 621 | wqe->status = IB_WC_LOC_QP_OP_ERR; |
| 600 | return -EINVAL; | 622 | return -EINVAL; |
| 601 | } | 623 | } |
| @@ -608,7 +630,7 @@ static int rxe_do_local_ops(struct rxe_qp *qp, struct rxe_send_wqe *wqe) · 6 unmodified lines | |||
| 608 | * which can lead to a deadlock. So go ahead and complete | 630 | * which can lead to a deadlock. So go ahead and complete |
| 609 | * it now. | 631 | * it now. |
| 610 | */ | 632 | */ |
| 611 | rxe_run_task(&qp->comp.task, 1); | 633 | rxe_sched_task(&qp->comp.task); |
| 612 | 634 | ||
| 613 | return 0; | 635 | return 0; |
| 614 | } | 636 | } |
| @@ -709,13 +731,15 @@ int rxe_requester(void *arg) · 94 unmodified lines | |||
| 709 | } | 731 | } |
| 710 | 732 | ||
| 711 | mask = rxe_opcode[opcode].mask; | 733 | mask = rxe_opcode[opcode].mask; |
| 712 | if (unlikely(mask & RXE_READ_OR_ATOMIC_MASK)) { | 734 | if (unlikely(mask & (RXE_READ_OR_ATOMIC_MASK | |
| 735 | RXE_ATOMIC_WRITE_MASK))) { | ||
| 713 | if (check_init_depth(qp, wqe)) | 736 | if (check_init_depth(qp, wqe)) |
| 714 | goto exit; | 737 | goto exit; |
| 715 | } | 738 | } |
| 716 | 739 | ||
| 717 | mtu = get_mtu(qp); | 740 | mtu = get_mtu(qp); |
| 718 | payload = (mask & RXE_WRITE_OR_SEND_MASK) ? wqe->dma.resid : 0; | 741 | payload = (mask & (RXE_WRITE_OR_SEND_MASK | RXE_ATOMIC_WRITE_MASK)) ? |
| 742 | wqe->dma.resid : 0; | ||
| 719 | if (payload > mtu) { | 743 | if (payload > mtu) { |
| 720 | if (qp_type(qp) == IB_QPT_UD) { | 744 | if (qp_type(qp) == IB_QPT_UD) { |
| 721 | /* C10-93.1.1: If the total sum of all the buffer lengths specified for a | 745 | /* C10-93.1.1: If the total sum of all the buffer lengths specified for a |
| @@ -733,7 +757,7 @@ int rxe_requester(void *arg) · 11 unmodified lines | |||
| 733 | qp->req.wqe_index); | 757 | qp->req.wqe_index); |
| 734 | wqe->state = wqe_state_done; | 758 | wqe->state = wqe_state_done; |
| 735 | wqe->status = IB_WC_SUCCESS; | 759 | wqe->status = IB_WC_SUCCESS; |
| 736 | rxe_run_task(&qp->comp.task, 0); | 760 | rxe_run_task(&qp->comp.task); |
| 737 | goto done; | 761 | goto done; |
| 738 | } | 762 | } |
| 739 | payload = mtu; | 763 | payload = mtu; |
| @@ -748,14 +772,14 @@ int rxe_requester(void *arg) · 8 unmodified lines | |||
| 748 | 772 | ||
| 749 | av = rxe_get_av(&pkt, &ah); | 773 | av = rxe_get_av(&pkt, &ah); |
| 750 | if (unlikely(!av)) { | 774 | if (unlikely(!av)) { |
| 751 | pr_err("qp#%d Failed no address vector\n", qp_num(qp)); | 775 | rxe_dbg_qp(qp, "Failed no address vector\n"); |
| 752 | wqe->status = IB_WC_LOC_QP_OP_ERR; | 776 | wqe->status = IB_WC_LOC_QP_OP_ERR; |
| 753 | goto err; | 777 | goto err; |
| 754 | } | 778 | } |
| 755 | 779 | ||
| 756 | skb = init_req_packet(qp, av, wqe, opcode, payload, &pkt); | 780 | skb = init_req_packet(qp, av, wqe, opcode, payload, &pkt); |
| 757 | if (unlikely(!skb)) { | 781 | if (unlikely(!skb)) { |
| 758 | pr_err("qp#%d Failed allocating skb\n", qp_num(qp)); | 782 | rxe_dbg_qp(qp, "Failed allocating skb\n"); |
| 759 | wqe->status = IB_WC_LOC_QP_OP_ERR; | 783 | wqe->status = IB_WC_LOC_QP_OP_ERR; |
| 760 | if (ah) | 784 | if (ah) |
| 761 | rxe_put(ah); | 785 | rxe_put(ah); |
| @@ -764,7 +788,7 @@ int rxe_requester(void *arg) · 2 unmodified lines | |||
| 764 | 788 | ||
| 765 | err = finish_packet(qp, av, wqe, &pkt, skb, payload); | 789 | err = finish_packet(qp, av, wqe, &pkt, skb, payload); |
| 766 | if (unlikely(err)) { | 790 | if (unlikely(err)) { |
| 767 | pr_debug("qp#%d Error during finish packet\n", qp_num(qp)); | 791 | rxe_dbg_qp(qp, "Error during finish packet\n"); |
| 768 | if (err == -EFAULT) | 792 | if (err == -EFAULT) |
| 769 | wqe->status = IB_WC_LOC_PROT_ERR; | 793 | wqe->status = IB_WC_LOC_PROT_ERR; |
| 770 | else | 794 | else |
| @@ -795,7 +819,7 @@ int rxe_requester(void *arg) · 24 unmodified lines | |||
| 795 | rollback_state(wqe, qp, &rollback_wqe, rollback_psn); | 819 | rollback_state(wqe, qp, &rollback_wqe, rollback_psn); |
| 796 | 820 | ||
| 797 | if (err == -EAGAIN) { | 821 | if (err == -EAGAIN) { |
| 798 | rxe_run_task(&qp->req.task, 1); | 822 | rxe_sched_task(&qp->req.task); |
| 799 | goto exit; | 823 | goto exit; |
| 800 | } | 824 | } |
| 801 | 825 | ||
| @@ -817,7 +841,7 @@ err: · 15 unmodified lines | |||
| 817 | qp->req.wqe_index = queue_next_index(qp->sq.queue, qp->req.wqe_index); | 841 | qp->req.wqe_index = queue_next_index(qp->sq.queue, qp->req.wqe_index); |
| 818 | wqe->state = wqe_state_error; | 842 | wqe->state = wqe_state_error; |
| 819 | qp->req.state = QP_STATE_ERROR; | 843 | qp->req.state = QP_STATE_ERROR; |
| 820 | rxe_run_task(&qp->comp.task, 0); | 844 | rxe_run_task(&qp->comp.task); |
| 821 | exit: | 845 | exit: |
| 822 | ret = -EAGAIN; | 846 | ret = -EAGAIN; |
| 823 | out: | 847 | out: |
| @@ -22,6 +22,8 @@ enum resp_states { · 21 unmodified lines | |||
| 22 | RESPST_EXECUTE, | 22 | RESPST_EXECUTE, |
| 23 | RESPST_READ_REPLY, | 23 | RESPST_READ_REPLY, |
| 24 | RESPST_ATOMIC_REPLY, | 24 | RESPST_ATOMIC_REPLY, |
| 25 | RESPST_ATOMIC_WRITE_REPLY, | ||
| 26 | RESPST_PROCESS_FLUSH, | ||
| 25 | RESPST_COMPLETE, | 27 | RESPST_COMPLETE, |
| 26 | RESPST_ACKNOWLEDGE, | 28 | RESPST_ACKNOWLEDGE, |
| 27 | RESPST_CLEANUP, | 29 | RESPST_CLEANUP, |
| @@ -57,6 +59,8 @@ static char *resp_state_name[] = { · 29 unmodified lines | |||
| 57 | [RESPST_EXECUTE] = "EXECUTE", | 59 | [RESPST_EXECUTE] = "EXECUTE", |
| 58 | [RESPST_READ_REPLY] = "READ_REPLY", | 60 | [RESPST_READ_REPLY] = "READ_REPLY", |
| 59 | [RESPST_ATOMIC_REPLY] = "ATOMIC_REPLY", | 61 | [RESPST_ATOMIC_REPLY] = "ATOMIC_REPLY", |
| 62 | [RESPST_ATOMIC_WRITE_REPLY] = "ATOMIC_WRITE_REPLY", | ||
| 63 | [RESPST_PROCESS_FLUSH] = "PROCESS_FLUSH", | ||
| 60 | [RESPST_COMPLETE] = "COMPLETE", | 64 | [RESPST_COMPLETE] = "COMPLETE", |
| 61 | [RESPST_ACKNOWLEDGE] = "ACKNOWLEDGE", | 65 | [RESPST_ACKNOWLEDGE] = "ACKNOWLEDGE", |
| 62 | [RESPST_CLEANUP] = "CLEANUP", | 66 | [RESPST_CLEANUP] = "CLEANUP", |
| @@ -91,7 +95,10 @@ void rxe_resp_queue_pkt(struct rxe_qp *qp, struct sk_buff *skb) · 28 unmodified lines | |||
| 91 | must_sched = (pkt->opcode == IB_OPCODE_RC_RDMA_READ_REQUEST) || | 95 | must_sched = (pkt->opcode == IB_OPCODE_RC_RDMA_READ_REQUEST) || |
| 92 | (skb_queue_len(&qp->req_pkts) > 1); | 96 | (skb_queue_len(&qp->req_pkts) > 1); |
| 93 | 97 | ||
| 94 | rxe_run_task(&qp->resp.task, must_sched); | 98 | if (must_sched) |
| 99 | rxe_sched_task(&qp->resp.task); | ||
| 100 | else | ||
| 101 | rxe_run_task(&qp->resp.task); | ||
| 95 | } | 102 | } |
| 96 | 103 | ||
| 97 | static inline enum resp_states get_req(struct rxe_qp *qp, | 104 | static inline enum resp_states get_req(struct rxe_qp *qp, |
| @@ -253,19 +260,37 @@ static enum resp_states check_op_seq(struct rxe_qp *qp, · 155 unmodified lines | |||
| 253 | } | 260 | } |
| 254 | } | 261 | } |
| 255 | 262 | ||
| 263 | static bool check_qp_attr_access(struct rxe_qp *qp, | ||
| 264 | struct rxe_pkt_info *pkt) | ||
| 265 | { | ||
| 266 | if (((pkt->mask & RXE_READ_MASK) && | ||
| 267 | !(qp->attr.qp_access_flags & IB_ACCESS_REMOTE_READ)) || | ||
| 268 | ((pkt->mask & (RXE_WRITE_MASK | RXE_ATOMIC_WRITE_MASK)) && | ||
| 269 | !(qp->attr.qp_access_flags & IB_ACCESS_REMOTE_WRITE)) || | ||
| 270 | ((pkt->mask & RXE_ATOMIC_MASK) && | ||
| 271 | !(qp->attr.qp_access_flags & IB_ACCESS_REMOTE_ATOMIC))) | ||
| 272 | return false; | ||
| 273 | |||
| 274 | if (pkt->mask & RXE_FLUSH_MASK) { | ||
| 275 | u32 flush_type = feth_plt(pkt); | ||
| 276 | |||
| 277 | if ((flush_type & IB_FLUSH_GLOBAL && | ||
| 278 | !(qp->attr.qp_access_flags & IB_ACCESS_FLUSH_GLOBAL)) || | ||
| 279 | (flush_type & IB_FLUSH_PERSISTENT && | ||
| 280 | !(qp->attr.qp_access_flags & IB_ACCESS_FLUSH_PERSISTENT))) | ||
| 281 | return false; | ||
| 282 | } | ||
| 283 | |||
| 284 | return true; | ||
| 285 | } | ||
| 286 | |||
| 256 | static enum resp_states check_op_valid(struct rxe_qp *qp, | 287 | static enum resp_states check_op_valid(struct rxe_qp *qp, |
| 257 | struct rxe_pkt_info *pkt) | 288 | struct rxe_pkt_info *pkt) |
| 258 | { | 289 | { |
| 259 | switch (qp_type(qp)) { | 290 | switch (qp_type(qp)) { |
| 260 | case IB_QPT_RC: | 291 | case IB_QPT_RC: |
| 261 | if (((pkt->mask & RXE_READ_MASK) && | 292 | if (!check_qp_attr_access(qp, pkt)) |
| 262 | !(qp->attr.qp_access_flags & IB_ACCESS_REMOTE_READ)) || | ||
| 263 | ((pkt->mask & RXE_WRITE_MASK) && | ||
| 264 | !(qp->attr.qp_access_flags & IB_ACCESS_REMOTE_WRITE)) || | ||
| 265 | ((pkt->mask & RXE_ATOMIC_MASK) && | ||
| 266 | !(qp->attr.qp_access_flags & IB_ACCESS_REMOTE_ATOMIC))) { | ||
| 267 | return RESPST_ERR_UNSUPPORTED_OPCODE; | 293 | return RESPST_ERR_UNSUPPORTED_OPCODE; |
| 268 | } | ||
| 269 | 294 | ||
| 270 | break; | 295 | break; |
| 271 | 296 | ||
| @@ -314,7 +339,7 @@ static enum resp_states get_srq_wqe(struct rxe_qp *qp) · 42 unmodified lines | |||
| 314 | /* don't trust user space data */ | 339 | /* don't trust user space data */ |
| 315 | if (unlikely(wqe->dma.num_sge > srq->rq.max_sge)) { | 340 | if (unlikely(wqe->dma.num_sge > srq->rq.max_sge)) { |
| 316 | spin_unlock_irqrestore(&srq->rq.consumer_lock, flags); | 341 | spin_unlock_irqrestore(&srq->rq.consumer_lock, flags); |
| 317 | pr_warn("%s: invalid num_sge in SRQ entry\n", __func__); | 342 | rxe_dbg_qp(qp, "invalid num_sge in SRQ entry\n"); |
| 318 | return RESPST_ERR_MALFORMED_WQE; | 343 | return RESPST_ERR_MALFORMED_WQE; |
| 319 | } | 344 | } |
| 320 | size = sizeof(*wqe) + wqe->dma.num_sge*sizeof(struct rxe_sge); | 345 | size = sizeof(*wqe) + wqe->dma.num_sge*sizeof(struct rxe_sge); |
| @@ -364,7 +389,7 @@ static enum resp_states check_resource(struct rxe_qp *qp, · 43 unmodified lines | |||
| 364 | } | 389 | } |
| 365 | } | 390 | } |
| 366 | 391 | ||
| 367 | if (pkt->mask & RXE_READ_OR_ATOMIC_MASK) { | 392 | if (pkt->mask & (RXE_READ_OR_ATOMIC_MASK | RXE_ATOMIC_WRITE_MASK)) { |
| 368 | /* it is the requesters job to not send | 393 | /* it is the requesters job to not send |
| 369 | * too many read/atomic ops, we just | 394 | * too many read/atomic ops, we just |
| 370 | * recycle the responder resource queue | 395 | * recycle the responder resource queue |
| @@ -387,19 +412,66 @@ static enum resp_states check_resource(struct rxe_qp *qp, · 16 unmodified lines | |||
| 387 | return RESPST_CHK_LENGTH; | 412 | return RESPST_CHK_LENGTH; |
| 388 | } | 413 | } |
| 389 | 414 | ||
| 390 | static enum resp_states check_length(struct rxe_qp *qp, | 415 | static enum resp_states rxe_resp_check_length(struct rxe_qp *qp, |
| 391 | struct rxe_pkt_info *pkt) | 416 | struct rxe_pkt_info *pkt) |
| 392 | { | 417 | { |
| 393 | switch (qp_type(qp)) { | 418 | /* |
| 394 | case IB_QPT_RC: | 419 | * See IBA C9-92 |
| 395 | return RESPST_CHK_RKEY; | 420 | * For UD QPs we only check if the packet will fit in the |
| 396 | 421 | * receive buffer later. For rmda operations additional | |
| 397 | case IB_QPT_UC: | 422 | * length checks are performed in check_rkey. |
| 398 | return RESPST_CHK_RKEY; | 423 | */ |
| 424 | if (pkt->mask & RXE_PAYLOAD_MASK && ((qp_type(qp) == IB_QPT_RC) || | ||
| 425 | (qp_type(qp) == IB_QPT_UC))) { | ||
| 426 | unsigned int mtu = qp->mtu; | ||
| 427 | unsigned int payload = payload_size(pkt); | ||
| 428 | |||
| 429 | if ((pkt->mask & RXE_START_MASK) && | ||
| 430 | (pkt->mask & RXE_END_MASK)) { | ||
| 431 | if (unlikely(payload > mtu)) { | ||
| 432 | rxe_dbg_qp(qp, "only packet too long"); | ||
| 433 | return RESPST_ERR_LENGTH; | ||
| 434 | } | ||
| 435 | } else if ((pkt->mask & RXE_START_MASK) || | ||
| 436 | (pkt->mask & RXE_MIDDLE_MASK)) { | ||
| 437 | if (unlikely(payload != mtu)) { | ||
| 438 | rxe_dbg_qp(qp, "first or middle packet not mtu"); | ||
| 439 | return RESPST_ERR_LENGTH; | ||
| 440 | } | ||
| 441 | } else if (pkt->mask & RXE_END_MASK) { | ||
| 442 | if (unlikely((payload == 0) || (payload > mtu))) { | ||
| 443 | rxe_dbg_qp(qp, "last packet zero or too long"); | ||
| 444 | return RESPST_ERR_LENGTH; | ||
| 445 | } | ||
| 446 | } | ||
| 447 | } | ||
| 399 | 448 | ||
| 400 | default: | 449 | /* See IBA C9-94 */ |
| 401 | return RESPST_CHK_RKEY; | 450 | if (pkt->mask & RXE_RETH_MASK) { |
| 451 | if (reth_len(pkt) > (1U << 31)) { | ||
| 452 | rxe_dbg_qp(qp, "dma length too long"); | ||
| 453 | return RESPST_ERR_LENGTH; | ||
| 454 | } | ||
| 402 | } | 455 | } |
| 456 | |||
| 457 | return RESPST_CHK_RKEY; | ||
| 458 | } | ||
| 459 | |||
| 460 | static void qp_resp_from_reth(struct rxe_qp *qp, struct rxe_pkt_info *pkt) | ||
| 461 | { | ||
| 462 | qp->resp.va = reth_va(pkt); | ||
| 463 | qp->resp.offset = 0; | ||
| 464 | qp->resp.rkey = reth_rkey(pkt); | ||
| 465 | qp->resp.resid = reth_len(pkt); | ||
| 466 | qp->resp.length = reth_len(pkt); | ||
| 467 | } | ||
| 468 | |||
| 469 | static void qp_resp_from_atmeth(struct rxe_qp *qp, struct rxe_pkt_info *pkt) | ||
| 470 | { | ||
| 471 | qp->resp.va = atmeth_va(pkt); | ||
| 472 | qp->resp.offset = 0; | ||
| 473 | qp->resp.rkey = atmeth_rkey(pkt); | ||
| 474 | qp->resp.resid = sizeof(u64); | ||
| 403 | } | 475 | } |
| 404 | 476 | ||
| 405 | static enum resp_states check_rkey(struct rxe_qp *qp, | 477 | static enum resp_states check_rkey(struct rxe_qp *qp, |
| @@ -413,29 +485,32 @@ static enum resp_states check_rkey(struct rxe_qp *qp, · 7 unmodified lines | |||
| 413 | u32 pktlen; | 485 | u32 pktlen; |
| 414 | int mtu = qp->mtu; | 486 | int mtu = qp->mtu; |
| 415 | enum resp_states state; | 487 | enum resp_states state; |
| 416 | int access; | 488 | int access = 0; |
| 417 | 489 | ||
| 418 | if (pkt->mask & RXE_READ_OR_WRITE_MASK) { | 490 | if (pkt->mask & (RXE_READ_OR_WRITE_MASK | RXE_ATOMIC_WRITE_MASK)) { |
| 419 | if (pkt->mask & RXE_RETH_MASK) { | 491 | if (pkt->mask & RXE_RETH_MASK) |
| 420 | qp->resp.va = reth_va(pkt); | 492 | qp_resp_from_reth(qp, pkt); |
| 421 | qp->resp.offset = 0; | 493 | |
| 422 | qp->resp.rkey = reth_rkey(pkt); | ||
| 423 | qp->resp.resid = reth_len(pkt); | ||
| 424 | qp->resp.length = reth_len(pkt); | ||
| 425 | } | ||
| 426 | access = (pkt->mask & RXE_READ_MASK) ? IB_ACCESS_REMOTE_READ | 494 | access = (pkt->mask & RXE_READ_MASK) ? IB_ACCESS_REMOTE_READ |
| 427 | : IB_ACCESS_REMOTE_WRITE; | 495 | : IB_ACCESS_REMOTE_WRITE; |
| 496 | } else if (pkt->mask & RXE_FLUSH_MASK) { | ||
| 497 | u32 flush_type = feth_plt(pkt); | ||
| 498 | |||
| 499 | if (pkt->mask & RXE_RETH_MASK) | ||
| 500 | qp_resp_from_reth(qp, pkt); | ||
| 501 | |||
| 502 | if (flush_type & IB_FLUSH_GLOBAL) | ||
| 503 | access |= IB_ACCESS_FLUSH_GLOBAL; | ||
| 504 | if (flush_type & IB_FLUSH_PERSISTENT) | ||
| 505 | access |= IB_ACCESS_FLUSH_PERSISTENT; | ||
| 428 | } else if (pkt->mask & RXE_ATOMIC_MASK) { | 506 | } else if (pkt->mask & RXE_ATOMIC_MASK) { |
| 429 | qp->resp.va = atmeth_va(pkt); | 507 | qp_resp_from_atmeth(qp, pkt); |
| 430 | qp->resp.offset = 0; | ||
| 431 | qp->resp.rkey = atmeth_rkey(pkt); | ||
| 432 | qp->resp.resid = sizeof(u64); | ||
| 433 | access = IB_ACCESS_REMOTE_ATOMIC; | 508 | access = IB_ACCESS_REMOTE_ATOMIC; |
| 434 | } else { | 509 | } else { |
| 435 | return RESPST_EXECUTE; | 510 | return RESPST_EXECUTE; |
| 436 | } | 511 | } |
| 437 | 512 | ||
| 438 | /* A zero-byte op is not required to set an addr or rkey. */ | 513 | /* A zero-byte op is not required to set an addr or rkey. See C9-88 */ |
| 439 | if ((pkt->mask & RXE_READ_OR_WRITE_MASK) && | 514 | if ((pkt->mask & RXE_READ_OR_WRITE_MASK) && |
| 440 | (pkt->mask & RXE_RETH_MASK) && | 515 | (pkt->mask & RXE_RETH_MASK) && |
| 441 | reth_len(pkt) == 0) { | 516 | reth_len(pkt) == 0) { |
| @@ -450,15 +525,14 @@ static enum resp_states check_rkey(struct rxe_qp *qp, · 8 unmodified lines | |||
| 450 | if (rkey_is_mw(rkey)) { | 525 | if (rkey_is_mw(rkey)) { |
| 451 | mw = rxe_lookup_mw(qp, access, rkey); | 526 | mw = rxe_lookup_mw(qp, access, rkey); |
| 452 | if (!mw) { | 527 | if (!mw) { |
| 453 | pr_debug("%s: no MW matches rkey %#x\n", | 528 | rxe_dbg_qp(qp, "no MW matches rkey %#x\n", rkey); |
| 454 | __func__, rkey); | ||
| 455 | state = RESPST_ERR_RKEY_VIOLATION; | 529 | state = RESPST_ERR_RKEY_VIOLATION; |
| 456 | goto err; | 530 | goto err; |
| 457 | } | 531 | } |
| 458 | 532 | ||
| 459 | mr = mw->mr; | 533 | mr = mw->mr; |
| 460 | if (!mr) { | 534 | if (!mr) { |
| 461 | pr_err("%s: MW doesn't have an MR\n", __func__); | 535 | rxe_dbg_qp(qp, "MW doesn't have an MR\n"); |
| 462 | state = RESPST_ERR_RKEY_VIOLATION; | 536 | state = RESPST_ERR_RKEY_VIOLATION; |
| 463 | goto err; | 537 | goto err; |
| 464 | } | 538 | } |
| @@ -471,19 +545,27 @@ static enum resp_states check_rkey(struct rxe_qp *qp, · 6 unmodified lines | |||
| 471 | } else { | 545 | } else { |
| 472 | mr = lookup_mr(qp->pd, access, rkey, RXE_LOOKUP_REMOTE); | 546 | mr = lookup_mr(qp->pd, access, rkey, RXE_LOOKUP_REMOTE); |
| 473 | if (!mr) { | 547 | if (!mr) { |
| 474 | pr_debug("%s: no MR matches rkey %#x\n", | 548 | rxe_dbg_qp(qp, "no MR matches rkey %#x\n", rkey); |
| 475 | __func__, rkey); | ||
| 476 | state = RESPST_ERR_RKEY_VIOLATION; | 549 | state = RESPST_ERR_RKEY_VIOLATION; |
| 477 | goto err; | 550 | goto err; |
| 478 | } | 551 | } |
| 479 | } | 552 | } |
| 480 | 553 | ||
| 554 | if (pkt->mask & RXE_FLUSH_MASK) { | ||
| 555 | /* FLUSH MR may not set va or resid | ||
| 556 | * no need to check range since we will flush whole mr | ||
| 557 | */ | ||
| 558 | if (feth_sel(pkt) == IB_FLUSH_MR) | ||
| 559 | goto skip_check_range; | ||
| 560 | } | ||
| 561 | |||
| 481 | if (mr_check_range(mr, va + qp->resp.offset, resid)) { | 562 | if (mr_check_range(mr, va + qp->resp.offset, resid)) { |
| 482 | state = RESPST_ERR_RKEY_VIOLATION; | 563 | state = RESPST_ERR_RKEY_VIOLATION; |
| 483 | goto err; | 564 | goto err; |
| 484 | } | 565 | } |
| 485 | 566 | ||
| 486 | if (pkt->mask & RXE_WRITE_MASK) { | 567 | skip_check_range: |
| 568 | if (pkt->mask & (RXE_WRITE_MASK | RXE_ATOMIC_WRITE_MASK)) { | ||
| 487 | if (resid > mtu) { | 569 | if (resid > mtu) { |
| 488 | if (pktlen != mtu || bth_pad(pkt)) { | 570 | if (pktlen != mtu || bth_pad(pkt)) { |
| 489 | state = RESPST_ERR_LENGTH; | 571 | state = RESPST_ERR_LENGTH; |
| @@ -583,15 +665,66 @@ static struct resp_res *rxe_prepare_res(struct rxe_qp *qp, · 93 unmodified lines | |||
| 583 | res->state = rdatm_res_state_new; | 665 | res->state = rdatm_res_state_new; |
| 584 | break; | 666 | break; |
| 585 | case RXE_ATOMIC_MASK: | 667 | case RXE_ATOMIC_MASK: |
| 668 | case RXE_ATOMIC_WRITE_MASK: | ||
| 586 | res->first_psn = pkt->psn; | 669 | res->first_psn = pkt->psn; |
| 587 | res->last_psn = pkt->psn; | 670 | res->last_psn = pkt->psn; |
| 588 | res->cur_psn = pkt->psn; | 671 | res->cur_psn = pkt->psn; |
| 589 | break; | 672 | break; |
| 673 | case RXE_FLUSH_MASK: | ||
| 674 | res->flush.va = qp->resp.va + qp->resp.offset; | ||
| 675 | res->flush.length = qp->resp.length; | ||
| 676 | res->flush.type = feth_plt(pkt); | ||
| 677 | res->flush.level = feth_sel(pkt); | ||
| 590 | } | 678 | } |
| 591 | 679 | ||
| 592 | return res; | 680 | return res; |
| 593 | } | 681 | } |
| 594 | 682 | ||
| 683 | static enum resp_states process_flush(struct rxe_qp *qp, | ||
| 684 | struct rxe_pkt_info *pkt) | ||
| 685 | { | ||
| 686 | u64 length, start; | ||
| 687 | struct rxe_mr *mr = qp->resp.mr; | ||
| 688 | struct resp_res *res = qp->resp.res; | ||
| 689 | |||
| 690 | /* oA19-14, oA19-15 */ | ||
| 691 | if (res && res->replay) | ||
| 692 | return RESPST_ACKNOWLEDGE; | ||
| 693 | else if (!res) { | ||
| 694 | res = rxe_prepare_res(qp, pkt, RXE_FLUSH_MASK); | ||
| 695 | qp->resp.res = res; | ||
| 696 | } | ||
| 697 | |||
| 698 | if (res->flush.level == IB_FLUSH_RANGE) { | ||
| 699 | start = res->flush.va; | ||
| 700 | length = res->flush.length; | ||
| 701 | } else { /* level == IB_FLUSH_MR */ | ||
| 702 | start = mr->ibmr.iova; | ||
| 703 | length = mr->ibmr.length; | ||
| 704 | } | ||
| 705 | |||
| 706 | if (res->flush.type & IB_FLUSH_PERSISTENT) { | ||
| 707 | if (rxe_flush_pmem_iova(mr, start, length)) | ||
| 708 | return RESPST_ERR_RKEY_VIOLATION; | ||
| 709 | /* Make data persistent. */ | ||
| 710 | wmb(); | ||
| 711 | } else if (res->flush.type & IB_FLUSH_GLOBAL) { | ||
| 712 | /* Make data global visibility. */ | ||
| 713 | wmb(); | ||
| 714 | } | ||
| 715 | |||
| 716 | qp->resp.msn++; | ||
| 717 | |||
| 718 | /* next expected psn, read handles this separately */ | ||
| 719 | qp->resp.psn = (pkt->psn + 1) & BTH_PSN_MASK; | ||
| 720 | qp->resp.ack_psn = qp->resp.psn; | ||
| 721 | |||
| 722 | qp->resp.opcode = pkt->opcode; | ||
| 723 | qp->resp.status = IB_WC_SUCCESS; | ||
| 724 | |||
| 725 | return RESPST_ACKNOWLEDGE; | ||
| 726 | } | ||
| 727 | |||
| 595 | /* Guarantee atomicity of atomic operations at the machine level. */ | 728 | /* Guarantee atomicity of atomic operations at the machine level. */ |
| 596 | static DEFINE_SPINLOCK(atomic_ops_lock); | 729 | static DEFINE_SPINLOCK(atomic_ops_lock); |
| 597 | 730 | ||
| @@ -652,6 +785,55 @@ out: · 54 unmodified lines | |||
| 652 | return ret; | 785 | return ret; |
| 653 | } | 786 | } |
| 654 | 787 | ||
| 788 | static enum resp_states atomic_write_reply(struct rxe_qp *qp, | ||
| 789 | struct rxe_pkt_info *pkt) | ||
| 790 | { | ||
| 791 | u64 src, *dst; | ||
| 792 | struct resp_res *res = qp->resp.res; | ||
| 793 | struct rxe_mr *mr = qp->resp.mr; | ||
| 794 | int payload = payload_size(pkt); | ||
| 795 | |||
| 796 | if (!res) { | ||
| 797 | res = rxe_prepare_res(qp, pkt, RXE_ATOMIC_WRITE_MASK); | ||
| 798 | qp->resp.res = res; | ||
| 799 | } | ||
| 800 | |||
| 801 | if (!res->replay) { | ||
| 802 | #ifdef CONFIG_64BIT | ||
| 803 | if (mr->state != RXE_MR_STATE_VALID) | ||
| 804 | return RESPST_ERR_RKEY_VIOLATION; | ||
| 805 | |||
| 806 | memcpy(&src, payload_addr(pkt), payload); | ||
| 807 | |||
| 808 | dst = iova_to_vaddr(mr, qp->resp.va + qp->resp.offset, payload); | ||
| 809 | /* check vaddr is 8 bytes aligned. */ | ||
| 810 | if (!dst || (uintptr_t)dst & 7) | ||
| 811 | return RESPST_ERR_MISALIGNED_ATOMIC; | ||
| 812 | |||
| 813 | /* Do atomic write after all prior operations have completed */ | ||
| 814 | smp_store_release(dst, src); | ||
| 815 | |||
| 816 | /* decrease resp.resid to zero */ | ||
| 817 | qp->resp.resid -= sizeof(payload); | ||
| 818 | |||
| 819 | qp->resp.msn++; | ||
| 820 | |||
| 821 | /* next expected psn, read handles this separately */ | ||
| 822 | qp->resp.psn = (pkt->psn + 1) & BTH_PSN_MASK; | ||
| 823 | qp->resp.ack_psn = qp->resp.psn; | ||
| 824 | |||
| 825 | qp->resp.opcode = pkt->opcode; | ||
| 826 | qp->resp.status = IB_WC_SUCCESS; | ||
| 827 | |||
| 828 | return RESPST_ACKNOWLEDGE; | ||
| 829 | #else | ||
| 830 | return RESPST_ERR_UNSUPPORTED_OPCODE; | ||
| 831 | #endif /* CONFIG_64BIT */ | ||
| 832 | } | ||
| 833 | |||
| 834 | return RESPST_ACKNOWLEDGE; | ||
| 835 | } | ||
| 836 | |||
| 655 | static struct sk_buff *prepare_ack_packet(struct rxe_qp *qp, | 837 | static struct sk_buff *prepare_ack_packet(struct rxe_qp *qp, |
| 656 | struct rxe_pkt_info *ack, | 838 | struct rxe_pkt_info *ack, |
| 657 | int opcode, | 839 | int opcode, |
| @@ -807,14 +989,19 @@ static enum resp_states read_reply(struct rxe_qp *qp, · 149 unmodified lines | |||
| 807 | skb = prepare_ack_packet(qp, &ack_pkt, opcode, payload, | 989 | skb = prepare_ack_packet(qp, &ack_pkt, opcode, payload, |
| 808 | res->cur_psn, AETH_ACK_UNLIMITED); | 990 | res->cur_psn, AETH_ACK_UNLIMITED); |
| 809 | if (!skb) { | 991 | if (!skb) { |
| 810 | rxe_put(mr); | 992 | if (mr) |
| 993 | rxe_put(mr); | ||
| 811 | return RESPST_ERR_RNR; | 994 | return RESPST_ERR_RNR; |
| 812 | } | 995 | } |
| 813 | 996 | ||
| 814 | rxe_mr_copy(mr, res->read.va, payload_addr(&ack_pkt), | 997 | err = rxe_mr_copy(mr, res->read.va, payload_addr(&ack_pkt), |
| 815 | payload, RXE_FROM_MR_OBJ); | 998 | payload, RXE_FROM_MR_OBJ); |
| 816 | if (mr) | 999 | if (mr) |
| 817 | rxe_put(mr); | 1000 | rxe_put(mr); |
| 1001 | if (err) { | ||
| 1002 | kfree_skb(skb); | ||
| 1003 | return RESPST_ERR_RKEY_VIOLATION; | ||
| 1004 | } | ||
| 818 | 1005 | ||
| 819 | if (bth_pad(&ack_pkt)) { | 1006 | if (bth_pad(&ack_pkt)) { |
| 820 | u8 *pad = payload_addr(&ack_pkt) + payload; | 1007 | u8 *pad = payload_addr(&ack_pkt) + payload; |
| @@ -890,6 +1077,10 @@ static enum resp_states execute(struct rxe_qp *qp, struct rxe_pkt_info *pkt) · 69 unmodified lines | |||
| 890 | return RESPST_READ_REPLY; | 1077 | return RESPST_READ_REPLY; |
| 891 | } else if (pkt->mask & RXE_ATOMIC_MASK) { | 1078 | } else if (pkt->mask & RXE_ATOMIC_MASK) { |
| 892 | return RESPST_ATOMIC_REPLY; | 1079 | return RESPST_ATOMIC_REPLY; |
| 1080 | } else if (pkt->mask & RXE_ATOMIC_WRITE_MASK) { | ||
| 1081 | return RESPST_ATOMIC_WRITE_REPLY; | ||
| 1082 | } else if (pkt->mask & RXE_FLUSH_MASK) { | ||
| 1083 | return RESPST_PROCESS_FLUSH; | ||
| 893 | } else { | 1084 | } else { |
| 894 | /* Unreachable */ | 1085 | /* Unreachable */ |
| 895 | WARN_ON_ONCE(1); | 1086 | WARN_ON_ONCE(1); |
| @@ -1040,7 +1231,7 @@ static int send_common_ack(struct rxe_qp *qp, u8 syndrome, u32 psn, · 144 unmodified lines | |||
| 1040 | 1231 | ||
| 1041 | err = rxe_xmit_packet(qp, &ack_pkt, skb); | 1232 | err = rxe_xmit_packet(qp, &ack_pkt, skb); |
| 1042 | if (err) | 1233 | if (err) |
| 1043 | pr_err_ratelimited("Failed sending %s\n", msg); | 1234 | rxe_dbg_qp(qp, "Failed sending %s\n", msg); |
| 1044 | 1235 | ||
| 1045 | return err; | 1236 | return err; |
| 1046 | } | 1237 | } |
| @@ -1063,6 +1254,19 @@ static int send_atomic_ack(struct rxe_qp *qp, u8 syndrome, u32 psn) · 16 unmodified lines | |||
| 1063 | return ret; | 1254 | return ret; |
| 1064 | } | 1255 | } |
| 1065 | 1256 | ||
| 1257 | static int send_read_response_ack(struct rxe_qp *qp, u8 syndrome, u32 psn) | ||
| 1258 | { | ||
| 1259 | int ret = send_common_ack(qp, syndrome, psn, | ||
| 1260 | IB_OPCODE_RC_RDMA_READ_RESPONSE_ONLY, | ||
| 1261 | "RDMA READ response of length zero ACK"); | ||
| 1262 | |||
| 1263 | /* have to clear this since it is used to trigger | ||
| 1264 | * long read replies | ||
| 1265 | */ | ||
| 1266 | qp->resp.res = NULL; | ||
| 1267 | return ret; | ||
| 1268 | } | ||
| 1269 | |||
| 1066 | static enum resp_states acknowledge(struct rxe_qp *qp, | 1270 | static enum resp_states acknowledge(struct rxe_qp *qp, |
| 1067 | struct rxe_pkt_info *pkt) | 1271 | struct rxe_pkt_info *pkt) |
| 1068 | { | 1272 | { |
| @@ -1073,6 +1277,8 @@ static enum resp_states acknowledge(struct rxe_qp *qp, · 4 unmodified lines | |||
| 1073 | send_ack(qp, qp->resp.aeth_syndrome, pkt->psn); | 1277 | send_ack(qp, qp->resp.aeth_syndrome, pkt->psn); |
| 1074 | else if (pkt->mask & RXE_ATOMIC_MASK) | 1278 | else if (pkt->mask & RXE_ATOMIC_MASK) |
| 1075 | send_atomic_ack(qp, AETH_ACK_UNLIMITED, pkt->psn); | 1279 | send_atomic_ack(qp, AETH_ACK_UNLIMITED, pkt->psn); |
| 1280 | else if (pkt->mask & (RXE_FLUSH_MASK | RXE_ATOMIC_WRITE_MASK)) | ||
| 1281 | send_read_response_ack(qp, AETH_ACK_UNLIMITED, pkt->psn); | ||
| 1076 | else if (bth_ack(pkt)) | 1282 | else if (bth_ack(pkt)) |
| 1077 | send_ack(qp, AETH_ACK_UNLIMITED, pkt->psn); | 1283 | send_ack(qp, AETH_ACK_UNLIMITED, pkt->psn); |
| 1078 | 1284 | ||
| @@ -1129,6 +1335,22 @@ static enum resp_states duplicate_request(struct rxe_qp *qp, · 50 unmodified lines | |||
| 1129 | /* SEND. Ack again and cleanup. C9-105. */ | 1335 | /* SEND. Ack again and cleanup. C9-105. */ |
| 1130 | send_ack(qp, AETH_ACK_UNLIMITED, prev_psn); | 1336 | send_ack(qp, AETH_ACK_UNLIMITED, prev_psn); |
| 1131 | return RESPST_CLEANUP; | 1337 | return RESPST_CLEANUP; |
| 1338 | } else if (pkt->mask & RXE_FLUSH_MASK) { | ||
| 1339 | struct resp_res *res; | ||
| 1340 | |||
| 1341 | /* Find the operation in our list of responder resources. */ | ||
| 1342 | res = find_resource(qp, pkt->psn); | ||
| 1343 | if (res) { | ||
| 1344 | res->replay = 1; | ||
| 1345 | res->cur_psn = pkt->psn; | ||
| 1346 | qp->resp.res = res; | ||
| 1347 | rc = RESPST_PROCESS_FLUSH; | ||
| 1348 | goto out; | ||
| 1349 | } | ||
| 1350 | |||
| 1351 | /* Resource not found. Class D error. Drop the request. */ | ||
| 1352 | rc = RESPST_CLEANUP; | ||
| 1353 | goto out; | ||
| 1132 | } else if (pkt->mask & RXE_READ_MASK) { | 1354 | } else if (pkt->mask & RXE_READ_MASK) { |
| 1133 | struct resp_res *res; | 1355 | struct resp_res *res; |
| 1134 | 1356 | ||
| @@ -1184,7 +1406,9 @@ static enum resp_states duplicate_request(struct rxe_qp *qp, · 49 unmodified lines | |||
| 1184 | res->replay = 1; | 1406 | res->replay = 1; |
| 1185 | res->cur_psn = pkt->psn; | 1407 | res->cur_psn = pkt->psn; |
| 1186 | qp->resp.res = res; | 1408 | qp->resp.res = res; |
| 1187 | rc = RESPST_ATOMIC_REPLY; | 1409 | rc = pkt->mask & RXE_ATOMIC_MASK ? |
| 1410 | RESPST_ATOMIC_REPLY : | ||
| 1411 | RESPST_ATOMIC_WRITE_REPLY; | ||
| 1188 | goto out; | 1412 | goto out; |
| 1189 | } | 1413 | } |
| 1190 | 1414 | ||
| @@ -1286,8 +1510,7 @@ int rxe_responder(void *arg) · 95 unmodified lines | |||
| 1286 | } | 1510 | } |
| 1287 | 1511 | ||
| 1288 | while (1) { | 1512 | while (1) { |
| 1289 | pr_debug("qp#%d state = %s\n", qp_num(qp), | 1513 | rxe_dbg_qp(qp, "state = %s\n", resp_state_name[state]); |
| 1290 | resp_state_name[state]); | ||
| 1291 | switch (state) { | 1514 | switch (state) { |
| 1292 | case RESPST_GET_REQ: | 1515 | case RESPST_GET_REQ: |
| 1293 | state = get_req(qp, &pkt); | 1516 | state = get_req(qp, &pkt); |
| @@ -1305,7 +1528,7 @@ int rxe_responder(void *arg) · 11 unmodified lines | |||
| 1305 | state = check_resource(qp, pkt); | 1528 | state = check_resource(qp, pkt); |
| 1306 | break; | 1529 | break; |
| 1307 | case RESPST_CHK_LENGTH: | 1530 | case RESPST_CHK_LENGTH: |
| 1308 | state = check_length(qp, pkt); | 1531 | state = rxe_resp_check_length(qp, pkt); |
| 1309 | break; | 1532 | break; |
| 1310 | case RESPST_CHK_RKEY: | 1533 | case RESPST_CHK_RKEY: |
| 1311 | state = check_rkey(qp, pkt); | 1534 | state = check_rkey(qp, pkt); |
| @@ -1322,6 +1545,12 @@ int rxe_responder(void *arg) · 10 unmodified lines | |||
| 1322 | case RESPST_ATOMIC_REPLY: | 1545 | case RESPST_ATOMIC_REPLY: |
| 1323 | state = atomic_reply(qp, pkt); | 1546 | state = atomic_reply(qp, pkt); |
| 1324 | break; | 1547 | break; |
| 1548 | case RESPST_ATOMIC_WRITE_REPLY: | ||
| 1549 | state = atomic_write_reply(qp, pkt); | ||
| 1550 | break; | ||
| 1551 | case RESPST_PROCESS_FLUSH: | ||
| 1552 | state = process_flush(qp, pkt); | ||
| 1553 | break; | ||
| 1325 | case RESPST_ACKNOWLEDGE: | 1554 | case RESPST_ACKNOWLEDGE: |
| 1326 | state = acknowledge(qp, pkt); | 1555 | state = acknowledge(qp, pkt); |
| 1327 | break; | 1556 | break; |
| @@ -1444,7 +1673,7 @@ int rxe_responder(void *arg) · 116 unmodified lines | |||
| 1444 | 1673 | ||
| 1445 | case RESPST_ERROR: | 1674 | case RESPST_ERROR: |
| 1446 | qp->resp.goto_error = 0; | 1675 | qp->resp.goto_error = 0; |
| 1447 | pr_debug("qp#%d moved to error state\n", qp_num(qp)); | 1676 | rxe_dbg_qp(qp, "moved to error state\n"); |
| 1448 | rxe_qp_error(qp); | 1677 | rxe_qp_error(qp); |
| 1449 | goto exit; | 1678 | goto exit; |
| 1450 | 1679 | ||
| @@ -13,13 +13,13 @@ int rxe_srq_chk_init(struct rxe_dev *rxe, struct ib_srq_init_attr *init) · 12 unmodified lines | |||
| 13 | struct ib_srq_attr *attr = &init->attr; | 13 | struct ib_srq_attr *attr = &init->attr; |
| 14 | 14 | ||
| 15 | if (attr->max_wr > rxe->attr.max_srq_wr) { | 15 | if (attr->max_wr > rxe->attr.max_srq_wr) { |
| 16 | pr_warn("max_wr(%d) > max_srq_wr(%d)\n", | 16 | rxe_dbg(rxe, "max_wr(%d) > max_srq_wr(%d)\n", |
| 17 | attr->max_wr, rxe->attr.max_srq_wr); | 17 | attr->max_wr, rxe->attr.max_srq_wr); |
| 18 | goto err1; | 18 | goto err1; |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | if (attr->max_wr <= 0) { | 21 | if (attr->max_wr <= 0) { |
| 22 | pr_warn("max_wr(%d) <= 0\n", attr->max_wr); | 22 | rxe_dbg(rxe, "max_wr(%d) <= 0\n", attr->max_wr); |
| 23 | goto err1; | 23 | goto err1; |
| 24 | } | 24 | } |
| 25 | 25 | ||
| @@ -27,7 +27,7 @@ int rxe_srq_chk_init(struct rxe_dev *rxe, struct ib_srq_init_attr *init) · 1 unmodified line | |||
| 27 | attr->max_wr = RXE_MIN_SRQ_WR; | 27 | attr->max_wr = RXE_MIN_SRQ_WR; |
| 28 | 28 | ||
| 29 | if (attr->max_sge > rxe->attr.max_srq_sge) { | 29 | if (attr->max_sge > rxe->attr.max_srq_sge) { |
| 30 | pr_warn("max_sge(%d) > max_srq_sge(%d)\n", | 30 | rxe_dbg(rxe, "max_sge(%d) > max_srq_sge(%d)\n", |
| 31 | attr->max_sge, rxe->attr.max_srq_sge); | 31 | attr->max_sge, rxe->attr.max_srq_sge); |
| 32 | goto err1; | 32 | goto err1; |
| 33 | } | 33 | } |
| @@ -65,7 +65,7 @@ int rxe_srq_from_init(struct rxe_dev *rxe, struct rxe_srq *srq, · 31 unmodified lines | |||
| 65 | type = QUEUE_TYPE_FROM_CLIENT; | 65 | type = QUEUE_TYPE_FROM_CLIENT; |
| 66 | q = rxe_queue_init(rxe, &srq->rq.max_wr, srq_wqe_size, type); | 66 | q = rxe_queue_init(rxe, &srq->rq.max_wr, srq_wqe_size, type); |
| 67 | if (!q) { | 67 | if (!q) { |
| 68 | pr_warn("unable to allocate queue for srq\n"); | 68 | rxe_dbg_srq(srq, "Unable to allocate queue\n"); |
| 69 | return -ENOMEM; | 69 | return -ENOMEM; |
| 70 | } | 70 | } |
| 71 | 71 | ||
| @@ -94,24 +94,24 @@ int rxe_srq_chk_attr(struct rxe_dev *rxe, struct rxe_srq *srq, · 22 unmodified lines | |||
| 94 | struct ib_srq_attr *attr, enum ib_srq_attr_mask mask) | 94 | struct ib_srq_attr *attr, enum ib_srq_attr_mask mask) |
| 95 | { | 95 | { |
| 96 | if (srq->error) { | 96 | if (srq->error) { |
| 97 | pr_warn("srq in error state\n"); | 97 | rxe_dbg_srq(srq, "in error state\n"); |
| 98 | goto err1; | 98 | goto err1; |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | if (mask & IB_SRQ_MAX_WR) { | 101 | if (mask & IB_SRQ_MAX_WR) { |
| 102 | if (attr->max_wr > rxe->attr.max_srq_wr) { | 102 | if (attr->max_wr > rxe->attr.max_srq_wr) { |
| 103 | pr_warn("max_wr(%d) > max_srq_wr(%d)\n", | 103 | rxe_dbg_srq(srq, "max_wr(%d) > max_srq_wr(%d)\n", |
| 104 | attr->max_wr, rxe->attr.max_srq_wr); | 104 | attr->max_wr, rxe->attr.max_srq_wr); |
| 105 | goto err1; | 105 | goto err1; |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | if (attr->max_wr <= 0) { | 108 | if (attr->max_wr <= 0) { |
| 109 | pr_warn("max_wr(%d) <= 0\n", attr->max_wr); | 109 | rxe_dbg_srq(srq, "max_wr(%d) <= 0\n", attr->max_wr); |
| 110 | goto err1; | 110 | goto err1; |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | if (srq->limit && (attr->max_wr < srq->limit)) { | 113 | if (srq->limit && (attr->max_wr < srq->limit)) { |
| 114 | pr_warn("max_wr (%d) < srq->limit (%d)\n", | 114 | rxe_dbg_srq(srq, "max_wr (%d) < srq->limit (%d)\n", |
| 115 | attr->max_wr, srq->limit); | 115 | attr->max_wr, srq->limit); |
| 116 | goto err1; | 116 | goto err1; |
| 117 | } | 117 | } |
| @@ -122,13 +122,13 @@ int rxe_srq_chk_attr(struct rxe_dev *rxe, struct rxe_srq *srq, · 4 unmodified lines | |||
| 122 | 122 | ||
| 123 | if (mask & IB_SRQ_LIMIT) { | 123 | if (mask & IB_SRQ_LIMIT) { |
| 124 | if (attr->srq_limit > rxe->attr.max_srq_wr) { | 124 | if (attr->srq_limit > rxe->attr.max_srq_wr) { |
| 125 | pr_warn("srq_limit(%d) > max_srq_wr(%d)\n", | 125 | rxe_dbg_srq(srq, "srq_limit(%d) > max_srq_wr(%d)\n", |
| 126 | attr->srq_limit, rxe->attr.max_srq_wr); | 126 | attr->srq_limit, rxe->attr.max_srq_wr); |
| 127 | goto err1; | 127 | goto err1; |
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | if (attr->srq_limit > srq->rq.queue->buf->index_mask) { | 130 | if (attr->srq_limit > srq->rq.queue->buf->index_mask) { |
| 131 | pr_warn("srq_limit (%d) > cur limit(%d)\n", | 131 | rxe_dbg_srq(srq, "srq_limit (%d) > cur limit(%d)\n", |
| 132 | attr->srq_limit, | 132 | attr->srq_limit, |
| 133 | srq->rq.queue->buf->index_mask); | 133 | srq->rq.queue->buf->index_mask); |
| 134 | goto err1; | 134 | goto err1; |
| @@ -4,10 +4,6 @@ · 3 unmodified lines | |||
| 4 | * Copyright (c) 2015 System Fabric Works, Inc. All rights reserved. | 4 | * Copyright (c) 2015 System Fabric Works, Inc. All rights reserved. |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | #include <linux/kernel.h> | ||
| 8 | #include <linux/interrupt.h> | ||
| 9 | #include <linux/hardirq.h> | ||
| 10 | |||
| 11 | #include "rxe.h" | 7 | #include "rxe.h" |
| 12 | 8 | ||
| 13 | int __rxe_do_task(struct rxe_task *task) | 9 | int __rxe_do_task(struct rxe_task *task) |
| @@ -28,30 +24,31 @@ int __rxe_do_task(struct rxe_task *task) · 14 unmodified lines | |||
| 28 | * a second caller finds the task already running | 24 | * a second caller finds the task already running |
| 29 | * but looks just after the last call to func | 25 | * but looks just after the last call to func |
| 30 | */ | 26 | */ |
| 31 | void rxe_do_task(struct tasklet_struct *t) | 27 | static void do_task(struct tasklet_struct *t) |
| 32 | { | 28 | { |
| 33 | int cont; | 29 | int cont; |
| 34 | int ret; | 30 | int ret; |
| 35 | struct rxe_task *task = from_tasklet(task, t, tasklet); | 31 | struct rxe_task *task = from_tasklet(task, t, tasklet); |
| 32 | struct rxe_qp *qp = (struct rxe_qp *)task->arg; | ||
| 36 | unsigned int iterations = RXE_MAX_ITERATIONS; | 33 | unsigned int iterations = RXE_MAX_ITERATIONS; |
| 37 | 34 | ||
| 38 | spin_lock_bh(&task->state_lock); | 35 | spin_lock_bh(&task->lock); |
| 39 | switch (task->state) { | 36 | switch (task->state) { |
| 40 | case TASK_STATE_START: | 37 | case TASK_STATE_START: |
| 41 | task->state = TASK_STATE_BUSY; | 38 | task->state = TASK_STATE_BUSY; |
| 42 | spin_unlock_bh(&task->state_lock); | 39 | spin_unlock_bh(&task->lock); |
| 43 | break; | 40 | break; |
| 44 | 41 | ||
| 45 | case TASK_STATE_BUSY: | 42 | case TASK_STATE_BUSY: |
| 46 | task->state = TASK_STATE_ARMED; | 43 | task->state = TASK_STATE_ARMED; |
| 47 | fallthrough; | 44 | fallthrough; |
| 48 | case TASK_STATE_ARMED: | 45 | case TASK_STATE_ARMED: |
| 49 | spin_unlock_bh(&task->state_lock); | 46 | spin_unlock_bh(&task->lock); |
| 50 | return; | 47 | return; |
| 51 | 48 | ||
| 52 | default: | 49 | default: |
| 53 | spin_unlock_bh(&task->state_lock); | 50 | spin_unlock_bh(&task->lock); |
| 54 | pr_warn("%s failed with bad state %d\n", __func__, task->state); | 51 | rxe_dbg_qp(qp, "failed with bad state %d\n", task->state); |
| 55 | return; | 52 | return; |
| 56 | } | 53 | } |
| 57 | 54 | ||
| @@ -59,7 +56,7 @@ void rxe_do_task(struct tasklet_struct *t) · 1 unmodified line | |||
| 59 | cont = 0; | 56 | cont = 0; |
| 60 | ret = task->func(task->arg); | 57 | ret = task->func(task->arg); |
| 61 | 58 | ||
| 62 | spin_lock_bh(&task->state_lock); | 59 | spin_lock_bh(&task->lock); |
| 63 | switch (task->state) { | 60 | switch (task->state) { |
| 64 | case TASK_STATE_BUSY: | 61 | case TASK_STATE_BUSY: |
| 65 | if (ret) { | 62 | if (ret) { |
| @@ -85,27 +82,25 @@ void rxe_do_task(struct tasklet_struct *t) · 19 unmodified lines | |||
| 85 | break; | 82 | break; |
| 86 | 83 | ||
| 87 | default: | 84 | default: |
| 88 | pr_warn("%s failed with bad state %d\n", __func__, | 85 | rxe_dbg_qp(qp, "failed with bad state %d\n", |
| 89 | task->state); | 86 | task->state); |
| 90 | } | 87 | } |
| 91 | spin_unlock_bh(&task->state_lock); | 88 | spin_unlock_bh(&task->lock); |
| 92 | } while (cont); | 89 | } while (cont); |
| 93 | 90 | ||
| 94 | task->ret = ret; | 91 | task->ret = ret; |
| 95 | } | 92 | } |
| 96 | 93 | ||
| 97 | int rxe_init_task(struct rxe_task *task, | 94 | int rxe_init_task(struct rxe_task *task, void *arg, int (*func)(void *)) |
| 98 | void *arg, int (*func)(void *), char *name) | ||
| 99 | { | 95 | { |
| 100 | task->arg = arg; | 96 | task->arg = arg; |
| 101 | task->func = func; | 97 | task->func = func; |
| 102 | snprintf(task->name, sizeof(task->name), "%s", name); | ||
| 103 | task->destroyed = false; | 98 | task->destroyed = false; |
| 104 | 99 | ||
| 105 | tasklet_setup(&task->tasklet, rxe_do_task); | 100 | tasklet_setup(&task->tasklet, do_task); |
| 106 | 101 | ||
| 107 | task->state = TASK_STATE_START; | 102 | task->state = TASK_STATE_START; |
| 108 | spin_lock_init(&task->state_lock); | 103 | spin_lock_init(&task->lock); |
| 109 | 104 | ||
| 110 | return 0; | 105 | return 0; |
| 111 | } | 106 | } |
| @@ -121,23 +116,28 @@ void rxe_cleanup_task(struct rxe_task *task) · 9 unmodified lines | |||
| 121 | task->destroyed = true; | 116 | task->destroyed = true; |
| 122 | 117 | ||
| 123 | do { | 118 | do { |
| 124 | spin_lock_bh(&task->state_lock); | 119 | spin_lock_bh(&task->lock); |
| 125 | idle = (task->state == TASK_STATE_START); | 120 | idle = (task->state == TASK_STATE_START); |
| 126 | spin_unlock_bh(&task->state_lock); | 121 | spin_unlock_bh(&task->lock); |
| 127 | } while (!idle); | 122 | } while (!idle); |
| 128 | 123 | ||
| 129 | tasklet_kill(&task->tasklet); | 124 | tasklet_kill(&task->tasklet); |
| 130 | } | 125 | } |
| 131 | 126 | ||
| 132 | void rxe_run_task(struct rxe_task *task, int sched) | 127 | void rxe_run_task(struct rxe_task *task) |
| 128 | { | ||
| 129 | if (task->destroyed) | ||
| 130 | return; | ||
| 131 | |||
| 132 | do_task(&task->tasklet); | ||
| 133 | } | ||
| 134 | |||
| 135 | void rxe_sched_task(struct rxe_task *task) | ||
| 133 | { | 136 | { |
| 134 | if (task->destroyed) | 137 | if (task->destroyed) |
| 135 | return; | 138 | return; |
| 136 | 139 | ||
| 137 | if (sched) | 140 | tasklet_schedule(&task->tasklet); |
| 138 | tasklet_schedule(&task->tasklet); | ||
| 139 | else | ||
| 140 | rxe_do_task(&task->tasklet); | ||
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | void rxe_disable_task(struct rxe_task *task) | 143 | void rxe_disable_task(struct rxe_task *task) |
| @@ -21,11 +21,10 @@ enum { · 20 unmodified lines | |||
| 21 | struct rxe_task { | 21 | struct rxe_task { |
| 22 | struct tasklet_struct tasklet; | 22 | struct tasklet_struct tasklet; |
| 23 | int state; | 23 | int state; |
| 24 | spinlock_t state_lock; /* spinlock for task state */ | 24 | spinlock_t lock; |
| 25 | void *arg; | 25 | void *arg; |
| 26 | int (*func)(void *arg); | 26 | int (*func)(void *arg); |
| 27 | int ret; | 27 | int ret; |
| 28 | char name[16]; | ||
| 29 | bool destroyed; | 28 | bool destroyed; |
| 30 | }; | 29 | }; |
| 31 | 30 | ||
| @@ -34,8 +33,7 @@ struct rxe_task { · 2 unmodified lines | |||
| 34 | * arg => parameter to pass to fcn | 33 | * arg => parameter to pass to fcn |
| 35 | * func => function to call until it returns != 0 | 34 | * func => function to call until it returns != 0 |
| 36 | */ | 35 | */ |
| 37 | int rxe_init_task(struct rxe_task *task, | 36 | int rxe_init_task(struct rxe_task *task, void *arg, int (*func)(void *)); |
| 38 | void *arg, int (*func)(void *), char *name); | ||
| 39 | 37 | ||
| 40 | /* cleanup task */ | 38 | /* cleanup task */ |
| 41 | void rxe_cleanup_task(struct rxe_task *task); | 39 | void rxe_cleanup_task(struct rxe_task *task); |
| @@ -46,18 +44,9 @@ void rxe_cleanup_task(struct rxe_task *task); · 4 unmodified lines | |||
| 46 | */ | 44 | */ |
| 47 | int __rxe_do_task(struct rxe_task *task); | 45 | int __rxe_do_task(struct rxe_task *task); |
| 48 | 46 | ||
| 49 | /* | 47 | void rxe_run_task(struct rxe_task *task); |
| 50 | * common function called by any of the main tasklets | ||
| 51 | * If there is any chance that there is additional | ||
| 52 | * work to do someone must reschedule the task before | ||
| 53 | * leaving | ||
| 54 | */ | ||
| 55 | void rxe_do_task(struct tasklet_struct *t); | ||
| 56 | 48 | ||
| 57 | /* run a task, else schedule it to run as a tasklet, The decision | 49 | void rxe_sched_task(struct rxe_task *task); |
| 58 | * to run or schedule tasklet is based on the parameter sched. | ||
| 59 | */ | ||
| 60 | void rxe_run_task(struct rxe_task *task, int sched); | ||
| 61 | 50 | ||
| 62 | /* keep a task from scheduling */ | 51 | /* keep a task from scheduling */ |
| 63 | void rxe_disable_task(struct rxe_task *task); | 52 | void rxe_disable_task(struct rxe_task *task); |
| @@ -172,10 +172,6 @@ static int rxe_create_ah(struct ib_ah *ibah, · 171 unmodified lines | |||
| 172 | ah->is_user = false; | 172 | ah->is_user = false; |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | err = rxe_av_chk_attr(rxe, init_attr->ah_attr); | ||
| 176 | if (err) | ||
| 177 | return err; | ||
| 178 | |||
| 179 | err = rxe_add_to_pool_ah(&rxe->ah_pool, ah, | 175 | err = rxe_add_to_pool_ah(&rxe->ah_pool, ah, |
| 180 | init_attr->flags & RDMA_CREATE_AH_SLEEPABLE); | 176 | init_attr->flags & RDMA_CREATE_AH_SLEEPABLE); |
| 181 | if (err) | 177 | if (err) |
| @@ -184,6 +180,12 @@ static int rxe_create_ah(struct ib_ah *ibah, · 2 unmodified lines | |||
| 184 | /* create index > 0 */ | 180 | /* create index > 0 */ |
| 185 | ah->ah_num = ah->elem.index; | 181 | ah->ah_num = ah->elem.index; |
| 186 | 182 | ||
| 183 | err = rxe_ah_chk_attr(ah, init_attr->ah_attr); | ||
| 184 | if (err) { | ||
| 185 | rxe_cleanup(ah); | ||
| 186 | return err; | ||
| 187 | } | ||
| 188 | |||
| 187 | if (uresp) { | 189 | if (uresp) { |
| 188 | /* only if new user provider */ | 190 | /* only if new user provider */ |
| 189 | err = copy_to_user(&uresp->ah_num, &ah->ah_num, | 191 | err = copy_to_user(&uresp->ah_num, &ah->ah_num, |
| @@ -206,10 +208,9 @@ static int rxe_create_ah(struct ib_ah *ibah, · 16 unmodified lines | |||
| 206 | static int rxe_modify_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr) | 208 | static int rxe_modify_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr) |
| 207 | { | 209 | { |
| 208 | int err; | 210 | int err; |
| 209 | struct rxe_dev *rxe = to_rdev(ibah->device); | ||
| 210 | struct rxe_ah *ah = to_rah(ibah); | 211 | struct rxe_ah *ah = to_rah(ibah); |
| 211 | 212 | ||
| 212 | err = rxe_av_chk_attr(rxe, attr); | 213 | err = rxe_ah_chk_attr(ah, attr); |
| 213 | if (err) | 214 | if (err) |
| 214 | return err; | 215 | return err; |
| 215 | 216 | ||
| @@ -238,7 +239,6 @@ static int rxe_destroy_ah(struct ib_ah *ibah, u32 flags) · 22 unmodified lines | |||
| 238 | 239 | ||
| 239 | static int post_one_recv(struct rxe_rq *rq, const struct ib_recv_wr *ibwr) | 240 | static int post_one_recv(struct rxe_rq *rq, const struct ib_recv_wr *ibwr) |
| 240 | { | 241 | { |
| 241 | int err; | ||
| 242 | int i; | 242 | int i; |
| 243 | u32 length; | 243 | u32 length; |
| 244 | struct rxe_recv_wqe *recv_wqe; | 244 | struct rxe_recv_wqe *recv_wqe; |
| @@ -246,15 +246,11 @@ static int post_one_recv(struct rxe_rq *rq, const struct ib_recv_wr *ibwr) · 1 unmodified line | |||
| 246 | int full; | 246 | int full; |
| 247 | 247 | ||
| 248 | full = queue_full(rq->queue, QUEUE_TYPE_TO_DRIVER); | 248 | full = queue_full(rq->queue, QUEUE_TYPE_TO_DRIVER); |
| 249 | if (unlikely(full)) { | 249 | if (unlikely(full)) |
| 250 | err = -ENOMEM; | 250 | return -ENOMEM; |
| 251 | goto err1; | ||
| 252 | } | ||
| 253 | 251 | ||
| 254 | if (unlikely(num_sge > rq->max_sge)) { | 252 | if (unlikely(num_sge > rq->max_sge)) |
| 255 | err = -EINVAL; | 253 | return -EINVAL; |
| 256 | goto err1; | ||
| 257 | } | ||
| 258 | 254 | ||
| 259 | length = 0; | 255 | length = 0; |
| 260 | for (i = 0; i < num_sge; i++) | 256 | for (i = 0; i < num_sge; i++) |
| @@ -275,9 +271,6 @@ static int post_one_recv(struct rxe_rq *rq, const struct ib_recv_wr *ibwr) · 14 unmodified lines | |||
| 275 | queue_advance_producer(rq->queue, QUEUE_TYPE_TO_DRIVER); | 271 | queue_advance_producer(rq->queue, QUEUE_TYPE_TO_DRIVER); |
| 276 | 272 | ||
| 277 | return 0; | 273 | return 0; |
| 278 | |||
| 279 | err1: | ||
| 280 | return err; | ||
| 281 | } | 274 | } |
| 282 | 275 | ||
| 283 | static int rxe_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *init, | 276 | static int rxe_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *init, |
| @@ -343,10 +336,7 @@ static int rxe_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, · 59 unmodified lines | |||
| 343 | if (err) | 336 | if (err) |
| 344 | return err; | 337 | return err; |
| 345 | 338 | ||
| 346 | err = rxe_srq_from_attr(rxe, srq, attr, mask, &ucmd, udata); | 339 | return rxe_srq_from_attr(rxe, srq, attr, mask, &ucmd, udata); |
| 347 | if (err) | ||
| 348 | return err; | ||
| 349 | return 0; | ||
| 350 | } | 340 | } |
| 351 | 341 | ||
| 352 | static int rxe_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr) | 342 | static int rxe_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr) |
| @@ -453,11 +443,11 @@ static int rxe_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, · 100 unmodified lines | |||
| 453 | 443 | ||
| 454 | err = rxe_qp_chk_attr(rxe, qp, attr, mask); | 444 | err = rxe_qp_chk_attr(rxe, qp, attr, mask); |
| 455 | if (err) | 445 | if (err) |
| 456 | goto err1; | 446 | return err; |
| 457 | 447 | ||
| 458 | err = rxe_qp_from_attr(qp, attr, mask, udata); | 448 | err = rxe_qp_from_attr(qp, attr, mask, udata); |
| 459 | if (err) | 449 | if (err) |
| 460 | goto err1; | 450 | return err; |
| 461 | 451 | ||
| 462 | if ((mask & IB_QP_AV) && (attr->ah_attr.ah_flags & IB_AH_GRH)) | 452 | if ((mask & IB_QP_AV) && (attr->ah_attr.ah_flags & IB_AH_GRH)) |
| 463 | qp->src_port = rdma_get_udp_sport(attr->ah_attr.grh.flow_label, | 453 | qp->src_port = rdma_get_udp_sport(attr->ah_attr.grh.flow_label, |
| @@ -465,9 +455,6 @@ static int rxe_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, · 1 unmodified line | |||
| 465 | qp->attr.dest_qp_num); | 455 | qp->attr.dest_qp_num); |
| 466 | 456 | ||
| 467 | return 0; | 457 | return 0; |
| 468 | |||
| 469 | err1: | ||
| 470 | return err; | ||
| 471 | } | 458 | } |
| 472 | 459 | ||
| 473 | static int rxe_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, | 460 | static int rxe_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, |
| @@ -501,24 +488,21 @@ static int validate_send_wr(struct rxe_qp *qp, const struct ib_send_wr *ibwr, · 27 unmodified lines | |||
| 501 | struct rxe_sq *sq = &qp->sq; | 488 | struct rxe_sq *sq = &qp->sq; |
| 502 | 489 | ||
| 503 | if (unlikely(num_sge > sq->max_sge)) | 490 | if (unlikely(num_sge > sq->max_sge)) |
| 504 | goto err1; | 491 | return -EINVAL; |
| 505 | 492 | ||
| 506 | if (unlikely(mask & WR_ATOMIC_MASK)) { | 493 | if (unlikely(mask & WR_ATOMIC_MASK)) { |
| 507 | if (length < 8) | 494 | if (length < 8) |
| 508 | goto err1; | 495 | return -EINVAL; |
| 509 | 496 | ||
| 510 | if (atomic_wr(ibwr)->remote_addr & 0x7) | 497 | if (atomic_wr(ibwr)->remote_addr & 0x7) |
| 511 | goto err1; | 498 | return -EINVAL; |
| 512 | } | 499 | } |
| 513 | 500 | ||
| 514 | if (unlikely((ibwr->send_flags & IB_SEND_INLINE) && | 501 | if (unlikely((ibwr->send_flags & IB_SEND_INLINE) && |
| 515 | (length > sq->max_inline))) | 502 | (length > sq->max_inline))) |
| 516 | goto err1; | 503 | return -EINVAL; |
| 517 | 504 | ||
| 518 | return 0; | 505 | return 0; |
| 519 | |||
| 520 | err1: | ||
| 521 | return -EINVAL; | ||
| 522 | } | 506 | } |
| 523 | 507 | ||
| 524 | static void init_send_wr(struct rxe_qp *qp, struct rxe_send_wr *wr, | 508 | static void init_send_wr(struct rxe_qp *qp, struct rxe_send_wr *wr, |
| @@ -695,9 +679,9 @@ static int rxe_post_send_kernel(struct rxe_qp *qp, const struct ib_send_wr *wr, · 170 unmodified lines | |||
| 695 | wr = next; | 679 | wr = next; |
| 696 | } | 680 | } |
| 697 | 681 | ||
| 698 | rxe_run_task(&qp->req.task, 1); | 682 | rxe_sched_task(&qp->req.task); |
| 699 | if (unlikely(qp->req.state == QP_STATE_ERROR)) | 683 | if (unlikely(qp->req.state == QP_STATE_ERROR)) |
| 700 | rxe_run_task(&qp->comp.task, 1); | 684 | rxe_sched_task(&qp->comp.task); |
| 701 | 685 | ||
| 702 | return err; | 686 | return err; |
| 703 | } | 687 | } |
| @@ -719,7 +703,7 @@ static int rxe_post_send(struct ib_qp *ibqp, const struct ib_send_wr *wr, · 15 unmodified lines | |||
| 719 | 703 | ||
| 720 | if (qp->is_user) { | 704 | if (qp->is_user) { |
| 721 | /* Utilize process context to do protocol processing */ | 705 | /* Utilize process context to do protocol processing */ |
| 722 | rxe_run_task(&qp->req.task, 0); | 706 | rxe_run_task(&qp->req.task); |
| 723 | return 0; | 707 | return 0; |
| 724 | } else | 708 | } else |
| 725 | return rxe_post_send_kernel(qp, wr, bad_wr); | 709 | return rxe_post_send_kernel(qp, wr, bad_wr); |
| @@ -735,14 +719,12 @@ static int rxe_post_recv(struct ib_qp *ibqp, const struct ib_recv_wr *wr, · 9 unmodified lines | |||
| 735 | 719 | ||
| 736 | if (unlikely((qp_state(qp) < IB_QPS_INIT) || !qp->valid)) { | 720 | if (unlikely((qp_state(qp) < IB_QPS_INIT) || !qp->valid)) { |
| 737 | *bad_wr = wr; | 721 | *bad_wr = wr; |
| 738 | err = -EINVAL; | 722 | return -EINVAL; |
| 739 | goto err1; | ||
| 740 | } | 723 | } |
| 741 | 724 | ||
| 742 | if (unlikely(qp->srq)) { | 725 | if (unlikely(qp->srq)) { |
| 743 | *bad_wr = wr; | 726 | *bad_wr = wr; |
| 744 | err = -EINVAL; | 727 | return -EINVAL; |
| 745 | goto err1; | ||
| 746 | } | 728 | } |
| 747 | 729 | ||
| 748 | spin_lock_irqsave(&rq->producer_lock, flags); | 730 | spin_lock_irqsave(&rq->producer_lock, flags); |
| @@ -759,9 +741,8 @@ static int rxe_post_recv(struct ib_qp *ibqp, const struct ib_recv_wr *wr, · 10 unmodified lines | |||
| 759 | spin_unlock_irqrestore(&rq->producer_lock, flags); | 741 | spin_unlock_irqrestore(&rq->producer_lock, flags); |
| 760 | 742 | ||
| 761 | if (qp->resp.state == QP_STATE_ERROR) | 743 | if (qp->resp.state == QP_STATE_ERROR) |
| 762 | rxe_run_task(&qp->resp.task, 1); | 744 | rxe_sched_task(&qp->resp.task); |
| 763 | 745 | ||
| 764 | err1: | ||
| 765 | return err; | 746 | return err; |
| 766 | } | 747 | } |
| 767 | 748 | ||
| @@ -826,16 +807,9 @@ static int rxe_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata) · 58 unmodified lines | |||
| 826 | 807 | ||
| 827 | err = rxe_cq_chk_attr(rxe, cq, cqe, 0); | 808 | err = rxe_cq_chk_attr(rxe, cq, cqe, 0); |
| 828 | if (err) | 809 | if (err) |
| 829 | goto err1; | 810 | return err; |
| 830 | |||
| 831 | err = rxe_cq_resize_queue(cq, cqe, uresp, udata); | ||
| 832 | if (err) | ||
| 833 | goto err1; | ||
| 834 | |||
| 835 | return 0; | ||
| 836 | 811 | ||
| 837 | err1: | 812 | return rxe_cq_resize_queue(cq, cqe, uresp, udata); |
| 838 | return err; | ||
| 839 | } | 813 | } |
| 840 | 814 | ||
| 841 | static int rxe_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc) | 815 | static int rxe_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc) |
| @@ -902,6 +876,7 @@ static struct ib_mr *rxe_get_dma_mr(struct ib_pd *ibpd, int access) · 60 unmodified lines | |||
| 902 | 876 | ||
| 903 | rxe_get(pd); | 877 | rxe_get(pd); |
| 904 | mr->ibmr.pd = ibpd; | 878 | mr->ibmr.pd = ibpd; |
| 879 | mr->ibmr.device = ibpd->device; | ||
| 905 | 880 | ||
| 906 | rxe_mr_init_dma(access, mr); | 881 | rxe_mr_init_dma(access, mr); |
| 907 | rxe_finalize(mr); | 882 | rxe_finalize(mr); |
| @@ -921,26 +896,23 @@ static struct ib_mr *rxe_reg_user_mr(struct ib_pd *ibpd, · 13 unmodified lines | |||
| 921 | struct rxe_mr *mr; | 896 | struct rxe_mr *mr; |
| 922 | 897 | ||
| 923 | mr = rxe_alloc(&rxe->mr_pool); | 898 | mr = rxe_alloc(&rxe->mr_pool); |
| 924 | if (!mr) { | 899 | if (!mr) |
| 925 | err = -ENOMEM; | 900 | return ERR_PTR(-ENOMEM); |
| 926 | goto err2; | ||
| 927 | } | ||
| 928 | |||
| 929 | 901 | ||
| 930 | rxe_get(pd); | 902 | rxe_get(pd); |
| 931 | mr->ibmr.pd = ibpd; | 903 | mr->ibmr.pd = ibpd; |
| 904 | mr->ibmr.device = ibpd->device; | ||
| 932 | 905 | ||
| 933 | err = rxe_mr_init_user(rxe, start, length, iova, access, mr); | 906 | err = rxe_mr_init_user(rxe, start, length, iova, access, mr); |
| 934 | if (err) | 907 | if (err) |
| 935 | goto err3; | 908 | goto err1; |
| 936 | 909 | ||
| 937 | rxe_finalize(mr); | 910 | rxe_finalize(mr); |
| 938 | 911 | ||
| 939 | return &mr->ibmr; | 912 | return &mr->ibmr; |
| 940 | 913 | ||
| 941 | err3: | 914 | err1: |
| 942 | rxe_cleanup(mr); | 915 | rxe_cleanup(mr); |
| 943 | err2: | ||
| 944 | return ERR_PTR(err); | 916 | return ERR_PTR(err); |
| 945 | } | 917 | } |
| 946 | 918 | ||
| @@ -956,25 +928,23 @@ static struct ib_mr *rxe_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type mr_type, · 9 unmodified lines | |||
| 956 | return ERR_PTR(-EINVAL); | 928 | return ERR_PTR(-EINVAL); |
| 957 | 929 | ||
| 958 | mr = rxe_alloc(&rxe->mr_pool); | 930 | mr = rxe_alloc(&rxe->mr_pool); |
| 959 | if (!mr) { | 931 | if (!mr) |
| 960 | err = -ENOMEM; | 932 | return ERR_PTR(-ENOMEM); |
| 961 | goto err1; | ||
| 962 | } | ||
| 963 | 933 | ||
| 964 | rxe_get(pd); | 934 | rxe_get(pd); |
| 965 | mr->ibmr.pd = ibpd; | 935 | mr->ibmr.pd = ibpd; |
| 936 | mr->ibmr.device = ibpd->device; | ||
| 966 | 937 | ||
| 967 | err = rxe_mr_init_fast(max_num_sg, mr); | 938 | err = rxe_mr_init_fast(max_num_sg, mr); |
| 968 | if (err) | 939 | if (err) |
| 969 | goto err2; | 940 | goto err1; |
| 970 | 941 | ||
| 971 | rxe_finalize(mr); | 942 | rxe_finalize(mr); |
| 972 | 943 | ||
| 973 | return &mr->ibmr; | 944 | return &mr->ibmr; |
| 974 | 945 | ||
| 975 | err2: | ||
| 976 | rxe_cleanup(mr); | ||
| 977 | err1: | 946 | err1: |
| 947 | rxe_cleanup(mr); | ||
| 978 | return ERR_PTR(err); | 948 | return ERR_PTR(err); |
| 979 | } | 949 | } |
| 980 | 950 | ||
| @@ -1134,7 +1104,7 @@ int rxe_register_device(struct rxe_dev *rxe, const char *ibdev_name) · 153 unmodified lines | |||
| 1134 | 1104 | ||
| 1135 | err = ib_register_device(dev, ibdev_name, NULL); | 1105 | err = ib_register_device(dev, ibdev_name, NULL); |
| 1136 | if (err) | 1106 | if (err) |
| 1137 | pr_warn("%s failed with error %d\n", __func__, err); | 1107 | rxe_dbg(rxe, "failed with error %d\n", err); |
| 1138 | 1108 | ||
| 1139 | /* | 1109 | /* |
| 1140 | * Note that rxe may be invalid at this point if another thread | 1110 | * Note that rxe may be invalid at this point if another thread |
| @@ -165,6 +165,12 @@ struct resp_res { · 164 unmodified lines | |||
| 165 | u64 va; | 165 | u64 va; |
| 166 | u32 resid; | 166 | u32 resid; |
| 167 | } read; | 167 | } read; |
| 168 | struct { | ||
| 169 | u32 length; | ||
| 170 | u64 va; | ||
| 171 | u8 type; | ||
| 172 | u8 level; | ||
| 173 | } flush; | ||
| 168 | }; | 174 | }; |
| 169 | }; | 175 | }; |
| 170 | 176 | ||
| @@ -304,7 +310,6 @@ struct rxe_mr { · 133 unmodified lines | |||
| 304 | u32 lkey; | 310 | u32 lkey; |
| 305 | u32 rkey; | 311 | u32 rkey; |
| 306 | enum rxe_mr_state state; | 312 | enum rxe_mr_state state; |
| 307 | enum ib_mr_type type; | ||
| 308 | u32 offset; | 313 | u32 offset; |
| 309 | int access; | 314 | int access; |
| 310 | 315 | ||
| @@ -56,8 +56,6 @@ int siw_reap_cqe(struct siw_cq *cq, struct ib_wc *wc) · 55 unmodified lines | |||
| 56 | if (READ_ONCE(cqe->flags) & SIW_WQE_VALID) { | 56 | if (READ_ONCE(cqe->flags) & SIW_WQE_VALID) { |
| 57 | memset(wc, 0, sizeof(*wc)); | 57 | memset(wc, 0, sizeof(*wc)); |
| 58 | wc->wr_id = cqe->id; | 58 | wc->wr_id = cqe->id; |
| 59 | wc->status = map_cqe_status[cqe->status].ib; | ||
| 60 | wc->opcode = map_wc_opcode[cqe->opcode]; | ||
| 61 | wc->byte_len = cqe->bytes; | 59 | wc->byte_len = cqe->bytes; |
| 62 | 60 | ||
| 63 | /* | 61 | /* |
| @@ -71,10 +69,32 @@ int siw_reap_cqe(struct siw_cq *cq, struct ib_wc *wc) · 7 unmodified lines | |||
| 71 | wc->wc_flags = IB_WC_WITH_INVALIDATE; | 69 | wc->wc_flags = IB_WC_WITH_INVALIDATE; |
| 72 | } | 70 | } |
| 73 | wc->qp = cqe->base_qp; | 71 | wc->qp = cqe->base_qp; |
| 72 | wc->opcode = map_wc_opcode[cqe->opcode]; | ||
| 73 | wc->status = map_cqe_status[cqe->status].ib; | ||
| 74 | siw_dbg_cq(cq, | 74 | siw_dbg_cq(cq, |
| 75 | "idx %u, type %d, flags %2x, id 0x%pK\n", | 75 | "idx %u, type %d, flags %2x, id 0x%pK\n", |
| 76 | cq->cq_get % cq->num_cqe, cqe->opcode, | 76 | cq->cq_get % cq->num_cqe, cqe->opcode, |
| 77 | cqe->flags, (void *)(uintptr_t)cqe->id); | 77 | cqe->flags, (void *)(uintptr_t)cqe->id); |
| 78 | } else { | ||
| 79 | /* | ||
| 80 | * A malicious user may set invalid opcode or | ||
| 81 | * status in the user mmapped CQE array. | ||
| 82 | * Sanity check and correct values in that case | ||
| 83 | * to avoid out-of-bounds access to global arrays | ||
| 84 | * for opcode and status mapping. | ||
| 85 | */ | ||
| 86 | u8 opcode = cqe->opcode; | ||
| 87 | u16 status = cqe->status; | ||
| 88 | |||
| 89 | if (opcode >= SIW_NUM_OPCODES) { | ||
| 90 | opcode = 0; | ||
| 91 | status = SIW_WC_GENERAL_ERR; | ||
| 92 | } else if (status >= SIW_NUM_WC_STATUS) { | ||
| 93 | status = SIW_WC_GENERAL_ERR; | ||
| 94 | } | ||
| 95 | wc->opcode = map_wc_opcode[opcode]; | ||
| 96 | wc->status = map_cqe_status[status].ib; | ||
| 97 | |||
| 78 | } | 98 | } |
| 79 | WRITE_ONCE(cqe->flags, 0); | 99 | WRITE_ONCE(cqe->flags, 0); |
| 80 | cq->cq_get++; | 100 | cq->cq_get++; |
| @@ -676,13 +676,45 @@ static int siw_copy_inline_sgl(const struct ib_send_wr *core_wr, · 675 unmodified lines | |||
| 676 | static int siw_sq_flush_wr(struct siw_qp *qp, const struct ib_send_wr *wr, | 676 | static int siw_sq_flush_wr(struct siw_qp *qp, const struct ib_send_wr *wr, |
| 677 | const struct ib_send_wr **bad_wr) | 677 | const struct ib_send_wr **bad_wr) |
| 678 | { | 678 | { |
| 679 | struct siw_sqe sqe = {}; | ||
| 680 | int rv = 0; | 679 | int rv = 0; |
| 681 | 680 | ||
| 682 | while (wr) { | 681 | while (wr) { |
| 683 | sqe.id = wr->wr_id; | 682 | struct siw_sqe sqe = {}; |
| 684 | sqe.opcode = wr->opcode; | 683 | |
| 685 | rv = siw_sqe_complete(qp, &sqe, 0, SIW_WC_WR_FLUSH_ERR); | 684 | switch (wr->opcode) { |
| 685 | case IB_WR_RDMA_WRITE: | ||
| 686 | sqe.opcode = SIW_OP_WRITE; | ||
| 687 | break; | ||
| 688 | case IB_WR_RDMA_READ: | ||
| 689 | sqe.opcode = SIW_OP_READ; | ||
| 690 | break; | ||
| 691 | case IB_WR_RDMA_READ_WITH_INV: | ||
| 692 | sqe.opcode = SIW_OP_READ_LOCAL_INV; | ||
| 693 | break; | ||
| 694 | case IB_WR_SEND: | ||
| 695 | sqe.opcode = SIW_OP_SEND; | ||
| 696 | break; | ||
| 697 | case IB_WR_SEND_WITH_IMM: | ||
| 698 | sqe.opcode = SIW_OP_SEND_WITH_IMM; | ||
| 699 | break; | ||
| 700 | case IB_WR_SEND_WITH_INV: | ||
| 701 | sqe.opcode = SIW_OP_SEND_REMOTE_INV; | ||
| 702 | break; | ||
| 703 | case IB_WR_LOCAL_INV: | ||
| 704 | sqe.opcode = SIW_OP_INVAL_STAG; | ||
| 705 | break; | ||
| 706 | case IB_WR_REG_MR: | ||
| 707 | sqe.opcode = SIW_OP_REG_MR; | ||
| 708 | break; | ||
| 709 | default: | ||
| 710 | rv = -EINVAL; | ||
| 711 | break; | ||
| 712 | } | ||
| 713 | if (!rv) { | ||
| 714 | sqe.id = wr->wr_id; | ||
| 715 | rv = siw_sqe_complete(qp, &sqe, 0, | ||
| 716 | SIW_WC_WR_FLUSH_ERR); | ||
| 717 | } | ||
| 686 | if (rv) { | 718 | if (rv) { |
| 687 | if (bad_wr) | 719 | if (bad_wr) |
| 688 | *bad_wr = wr; | 720 | *bad_wr = wr; |
| @@ -41,6 +41,11 @@ static const struct nla_policy ipoib_policy[IFLA_IPOIB_MAX + 1] = { · 40 unmodified lines | |||
| 41 | [IFLA_IPOIB_UMCAST] = { .type = NLA_U16 }, | 41 | [IFLA_IPOIB_UMCAST] = { .type = NLA_U16 }, |
| 42 | }; | 42 | }; |
| 43 | 43 | ||
| 44 | static unsigned int ipoib_get_max_num_queues(void) | ||
| 45 | { | ||
| 46 | return min_t(unsigned int, num_possible_cpus(), 128); | ||
| 47 | } | ||
| 48 | |||
| 44 | static int ipoib_fill_info(struct sk_buff *skb, const struct net_device *dev) | 49 | static int ipoib_fill_info(struct sk_buff *skb, const struct net_device *dev) |
| 45 | { | 50 | { |
| 46 | struct ipoib_dev_priv *priv = ipoib_priv(dev); | 51 | struct ipoib_dev_priv *priv = ipoib_priv(dev); |
| @@ -172,6 +177,8 @@ static struct rtnl_link_ops ipoib_link_ops __read_mostly = { · 125 unmodified lines | |||
| 172 | .changelink = ipoib_changelink, | 177 | .changelink = ipoib_changelink, |
| 173 | .get_size = ipoib_get_size, | 178 | .get_size = ipoib_get_size, |
| 174 | .fill_info = ipoib_fill_info, | 179 | .fill_info = ipoib_fill_info, |
| 180 | .get_num_rx_queues = ipoib_get_max_num_queues, | ||
| 181 | .get_num_tx_queues = ipoib_get_max_num_queues, | ||
| 175 | }; | 182 | }; |
| 176 | 183 | ||
| 177 | struct rtnl_link_ops *ipoib_get_link_ops(void) | 184 | struct rtnl_link_ops *ipoib_get_link_ops(void) |
| @@ -347,22 +347,6 @@ static void iser_device_try_release(struct iser_device *device) · 346 unmodified lines | |||
| 347 | mutex_unlock(&ig.device_list_mutex); | 347 | mutex_unlock(&ig.device_list_mutex); |
| 348 | } | 348 | } |
| 349 | 349 | ||
| 350 | /* | ||
| 351 | * Called with state mutex held | ||
| 352 | */ | ||
| 353 | static int iser_conn_state_comp_exch(struct iser_conn *iser_conn, | ||
| 354 | enum iser_conn_state comp, | ||
| 355 | enum iser_conn_state exch) | ||
| 356 | { | ||
| 357 | int ret; | ||
| 358 | |||
| 359 | ret = (iser_conn->state == comp); | ||
| 360 | if (ret) | ||
| 361 | iser_conn->state = exch; | ||
| 362 | |||
| 363 | return ret; | ||
| 364 | } | ||
| 365 | |||
| 366 | void iser_release_work(struct work_struct *work) | 350 | void iser_release_work(struct work_struct *work) |
| 367 | { | 351 | { |
| 368 | struct iser_conn *iser_conn; | 352 | struct iser_conn *iser_conn; |
| @@ -464,11 +448,13 @@ int iser_conn_terminate(struct iser_conn *iser_conn) · 95 unmodified lines | |||
| 464 | struct ib_conn *ib_conn = &iser_conn->ib_conn; | 448 | struct ib_conn *ib_conn = &iser_conn->ib_conn; |
| 465 | int err = 0; | 449 | int err = 0; |
| 466 | 450 | ||
| 451 | lockdep_assert_held(&iser_conn->state_mutex); | ||
| 452 | |||
| 467 | /* terminate the iser conn only if the conn state is UP */ | 453 | /* terminate the iser conn only if the conn state is UP */ |
| 468 | if (!iser_conn_state_comp_exch(iser_conn, ISER_CONN_UP, | 454 | if (iser_conn->state != ISER_CONN_UP) |
| 469 | ISER_CONN_TERMINATING)) | ||
| 470 | return 0; | 455 | return 0; |
| 471 | 456 | ||
| 457 | iser_conn->state = ISER_CONN_TERMINATING; | ||
| 472 | iser_info("iser_conn %p state %d\n", iser_conn, iser_conn->state); | 458 | iser_info("iser_conn %p state %d\n", iser_conn, iser_conn->state); |
| 473 | 459 | ||
| 474 | /* suspend queuing of new iscsi commands */ | 460 | /* suspend queuing of new iscsi commands */ |
| @@ -498,9 +484,10 @@ int iser_conn_terminate(struct iser_conn *iser_conn) · 23 unmodified lines | |||
| 498 | */ | 484 | */ |
| 499 | static void iser_connect_error(struct rdma_cm_id *cma_id) | 485 | static void iser_connect_error(struct rdma_cm_id *cma_id) |
| 500 | { | 486 | { |
| 501 | struct iser_conn *iser_conn; | 487 | struct iser_conn *iser_conn = cma_id->context; |
| 488 | |||
| 489 | lockdep_assert_held(&iser_conn->state_mutex); | ||
| 502 | 490 | ||
| 503 | iser_conn = cma_id->context; | ||
| 504 | iser_conn->state = ISER_CONN_TERMINATING; | 491 | iser_conn->state = ISER_CONN_TERMINATING; |
| 505 | } | 492 | } |
| 506 | 493 | ||
| @@ -542,12 +529,13 @@ static void iser_calc_scsi_params(struct iser_conn *iser_conn, · 35 unmodified lines | |||
| 542 | */ | 529 | */ |
| 543 | static void iser_addr_handler(struct rdma_cm_id *cma_id) | 530 | static void iser_addr_handler(struct rdma_cm_id *cma_id) |
| 544 | { | 531 | { |
| 532 | struct iser_conn *iser_conn = cma_id->context; | ||
| 545 | struct iser_device *device; | 533 | struct iser_device *device; |
| 546 | struct iser_conn *iser_conn; | ||
| 547 | struct ib_conn *ib_conn; | 534 | struct ib_conn *ib_conn; |
| 548 | int ret; | 535 | int ret; |
| 549 | 536 | ||
| 550 | iser_conn = cma_id->context; | 537 | lockdep_assert_held(&iser_conn->state_mutex); |
| 538 | |||
| 551 | if (iser_conn->state != ISER_CONN_PENDING) | 539 | if (iser_conn->state != ISER_CONN_PENDING) |
| 552 | /* bailout */ | 540 | /* bailout */ |
| 553 | return; | 541 | return; |
| @@ -597,6 +585,8 @@ static void iser_route_handler(struct rdma_cm_id *cma_id) · 43 unmodified lines | |||
| 597 | struct ib_conn *ib_conn = &iser_conn->ib_conn; | 585 | struct ib_conn *ib_conn = &iser_conn->ib_conn; |
| 598 | struct ib_device *ib_dev = ib_conn->device->ib_device; | 586 | struct ib_device *ib_dev = ib_conn->device->ib_device; |
| 599 | 587 | ||
| 588 | lockdep_assert_held(&iser_conn->state_mutex); | ||
| 589 | |||
| 600 | if (iser_conn->state != ISER_CONN_PENDING) | 590 | if (iser_conn->state != ISER_CONN_PENDING) |
| 601 | /* bailout */ | 591 | /* bailout */ |
| 602 | return; | 592 | return; |
| @@ -629,14 +619,18 @@ failure: · 26 unmodified lines | |||
| 629 | iser_connect_error(cma_id); | 619 | iser_connect_error(cma_id); |
| 630 | } | 620 | } |
| 631 | 621 | ||
| 622 | /* | ||
| 623 | * Called with state mutex held | ||
| 624 | */ | ||
| 632 | static void iser_connected_handler(struct rdma_cm_id *cma_id, | 625 | static void iser_connected_handler(struct rdma_cm_id *cma_id, |
| 633 | const void *private_data) | 626 | const void *private_data) |
| 634 | { | 627 | { |
| 635 | struct iser_conn *iser_conn; | 628 | struct iser_conn *iser_conn = cma_id->context; |
| 636 | struct ib_qp_attr attr; | 629 | struct ib_qp_attr attr; |
| 637 | struct ib_qp_init_attr init_attr; | 630 | struct ib_qp_init_attr init_attr; |
| 638 | 631 | ||
| 639 | iser_conn = cma_id->context; | 632 | lockdep_assert_held(&iser_conn->state_mutex); |
| 633 | |||
| 640 | if (iser_conn->state != ISER_CONN_PENDING) | 634 | if (iser_conn->state != ISER_CONN_PENDING) |
| 641 | /* bailout */ | 635 | /* bailout */ |
| 642 | return; | 636 | return; |
| @@ -657,30 +651,27 @@ static void iser_connected_handler(struct rdma_cm_id *cma_id, · 14 unmodified lines | |||
| 657 | complete(&iser_conn->up_completion); | 651 | complete(&iser_conn->up_completion); |
| 658 | } | 652 | } |
| 659 | 653 | ||
| 660 | static void iser_disconnected_handler(struct rdma_cm_id *cma_id) | 654 | /* |
| 661 | { | 655 | * Called with state mutex held |
| 662 | struct iser_conn *iser_conn = cma_id->context; | 656 | */ |
| 663 | |||
| 664 | if (iser_conn_terminate(iser_conn)) { | ||
| 665 | if (iser_conn->iscsi_conn) | ||
| 666 | iscsi_conn_failure(iser_conn->iscsi_conn, | ||
| 667 | ISCSI_ERR_CONN_FAILED); | ||
| 668 | else | ||
| 669 | iser_err("iscsi_iser connection isn't bound\n"); | ||
| 670 | } | ||
| 671 | } | ||
| 672 | |||
| 673 | static void iser_cleanup_handler(struct rdma_cm_id *cma_id, | 657 | static void iser_cleanup_handler(struct rdma_cm_id *cma_id, |
| 674 | bool destroy) | 658 | bool destroy) |
| 675 | { | 659 | { |
| 676 | struct iser_conn *iser_conn = cma_id->context; | 660 | struct iser_conn *iser_conn = cma_id->context; |
| 677 | 661 | ||
| 662 | lockdep_assert_held(&iser_conn->state_mutex); | ||
| 678 | /* | 663 | /* |
| 679 | * We are not guaranteed that we visited disconnected_handler | 664 | * We are not guaranteed that we visited disconnected_handler |
| 680 | * by now, call it here to be safe that we handle CM drep | 665 | * by now, call it here to be safe that we handle CM drep |
| 681 | * and flush errors. | 666 | * and flush errors. |
| 682 | */ | 667 | */ |
| 683 | iser_disconnected_handler(cma_id); | 668 | if (iser_conn_terminate(iser_conn)) { |
| 669 | if (iser_conn->iscsi_conn) | ||
| 670 | iscsi_conn_failure(iser_conn->iscsi_conn, | ||
| 671 | ISCSI_ERR_CONN_FAILED); | ||
| 672 | else | ||
| 673 | iser_err("iscsi_iser connection isn't bound\n"); | ||
| 674 | } | ||
| 684 | iser_free_ib_conn_res(iser_conn, destroy); | 675 | iser_free_ib_conn_res(iser_conn, destroy); |
| 685 | complete(&iser_conn->ib_completion); | 676 | complete(&iser_conn->ib_completion); |
| 686 | } | 677 | } |
| @@ -993,9 +993,8 @@ isert_rx_login_req(struct isert_conn *isert_conn) · 992 unmodified lines | |||
| 993 | * login request PDU. | 993 | * login request PDU. |
| 994 | */ | 994 | */ |
| 995 | login->leading_connection = (!login_req->tsih) ? 1 : 0; | 995 | login->leading_connection = (!login_req->tsih) ? 1 : 0; |
| 996 | login->current_stage = | 996 | login->current_stage = ISCSI_LOGIN_CURRENT_STAGE( |
| 997 | (login_req->flags & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK) | 997 | login_req->flags); |
| 998 | >> 2; | ||
| 999 | login->version_min = login_req->min_version; | 998 | login->version_min = login_req->min_version; |
| 1000 | login->version_max = login_req->max_version; | 999 | login->version_max = login_req->max_version; |
| 1001 | memcpy(login->isid, login_req->isid, 6); | 1000 | memcpy(login->isid, login_req->isid, 6); |
| @@ -1064,10 +1064,8 @@ static int rtrs_map_sg_fr(struct rtrs_clt_io_req *req, size_t count) · 1063 unmodified lines | |||
| 1064 | 1064 | ||
| 1065 | /* Align the MR to a 4K page size to match the block virt boundary */ | 1065 | /* Align the MR to a 4K page size to match the block virt boundary */ |
| 1066 | nr = ib_map_mr_sg(req->mr, req->sglist, count, NULL, SZ_4K); | 1066 | nr = ib_map_mr_sg(req->mr, req->sglist, count, NULL, SZ_4K); |
| 1067 | if (nr < 0) | 1067 | if (nr != count) |
| 1068 | return nr; | 1068 | return nr < 0 ? nr : -EINVAL; |
| 1069 | if (nr < req->sg_cnt) | ||
| 1070 | return -EINVAL; | ||
| 1071 | ib_update_fast_reg_key(req->mr, ib_inc_rkey(req->mr->rkey)); | 1069 | ib_update_fast_reg_key(req->mr, ib_inc_rkey(req->mr->rkey)); |
| 1072 | 1070 | ||
| 1073 | return nr; | 1071 | return nr; |
| @@ -68,10 +68,7 @@ enum { · 67 unmodified lines | |||
| 68 | struct rtrs_ib_dev; | 68 | struct rtrs_ib_dev; |
| 69 | 69 | ||
| 70 | struct rtrs_rdma_dev_pd_ops { | 70 | struct rtrs_rdma_dev_pd_ops { |
| 71 | struct rtrs_ib_dev *(*alloc)(void); | ||
| 72 | void (*free)(struct rtrs_ib_dev *dev); | ||
| 73 | int (*init)(struct rtrs_ib_dev *dev); | 71 | int (*init)(struct rtrs_ib_dev *dev); |
| 74 | void (*deinit)(struct rtrs_ib_dev *dev); | ||
| 75 | }; | 72 | }; |
| 76 | 73 | ||
| 77 | struct rtrs_rdma_dev_pd { | 74 | struct rtrs_rdma_dev_pd { |
| @@ -203,7 +203,6 @@ rtrs_srv_destroy_once_sysfs_root_folders(struct rtrs_srv_path *srv_path) · 202 unmodified lines | |||
| 203 | 203 | ||
| 204 | mutex_lock(&srv->paths_mutex); | 204 | mutex_lock(&srv->paths_mutex); |
| 205 | if (!--srv->dev_ref) { | 205 | if (!--srv->dev_ref) { |
| 206 | kobject_del(srv->kobj_paths); | ||
| 207 | kobject_put(srv->kobj_paths); | 206 | kobject_put(srv->kobj_paths); |
| 208 | mutex_unlock(&srv->paths_mutex); | 207 | mutex_unlock(&srv->paths_mutex); |
| 209 | device_del(&srv->dev); | 208 | device_del(&srv->dev); |
| @@ -304,12 +303,18 @@ destroy_root: · 94 unmodified lines | |||
| 304 | 303 | ||
| 305 | void rtrs_srv_destroy_path_files(struct rtrs_srv_path *srv_path) | 304 | void rtrs_srv_destroy_path_files(struct rtrs_srv_path *srv_path) |
| 306 | { | 305 | { |
| 307 | if (srv_path->kobj.state_in_sysfs) { | 306 | if (srv_path->stats->kobj_stats.state_in_sysfs) { |
| 307 | sysfs_remove_group(&srv_path->stats->kobj_stats, | ||
| 308 | &rtrs_srv_stats_attr_group); | ||
| 308 | kobject_del(&srv_path->stats->kobj_stats); | 309 | kobject_del(&srv_path->stats->kobj_stats); |
| 309 | kobject_put(&srv_path->stats->kobj_stats); | 310 | kobject_put(&srv_path->stats->kobj_stats); |
| 311 | } | ||
| 312 | |||
| 313 | if (srv_path->kobj.state_in_sysfs) { | ||
| 310 | sysfs_remove_group(&srv_path->kobj, &rtrs_srv_path_attr_group); | 314 | sysfs_remove_group(&srv_path->kobj, &rtrs_srv_path_attr_group); |
| 315 | kobject_del(&srv_path->kobj); | ||
| 311 | kobject_put(&srv_path->kobj); | 316 | kobject_put(&srv_path->kobj); |
| 312 | |||
| 313 | rtrs_srv_destroy_once_sysfs_root_folders(srv_path); | ||
| 314 | } | 317 | } |
| 318 | |||
| 319 | rtrs_srv_destroy_once_sysfs_root_folders(srv_path); | ||
| 315 | } | 320 | } |
| @@ -561,9 +561,11 @@ static int map_cont_bufs(struct rtrs_srv_path *srv_path) · 560 unmodified lines | |||
| 561 | { | 561 | { |
| 562 | struct rtrs_srv_sess *srv = srv_path->srv; | 562 | struct rtrs_srv_sess *srv = srv_path->srv; |
| 563 | struct rtrs_path *ss = &srv_path->s; | 563 | struct rtrs_path *ss = &srv_path->s; |
| 564 | int i, mri, err, mrs_num; | 564 | int i, err, mrs_num; |
| 565 | unsigned int chunk_bits; | 565 | unsigned int chunk_bits; |
| 566 | int chunks_per_mr = 1; | 566 | int chunks_per_mr = 1; |
| 567 | struct ib_mr *mr; | ||
| 568 | struct sg_table *sgt; | ||
| 567 | 569 | ||
| 568 | /* | 570 | /* |
| 569 | * Here we map queue_depth chunks to MR. Firstly we have to | 571 | * Here we map queue_depth chunks to MR. Firstly we have to |
| @@ -586,16 +588,14 @@ static int map_cont_bufs(struct rtrs_srv_path *srv_path) · 16 unmodified lines | |||
| 586 | if (!srv_path->mrs) | 588 | if (!srv_path->mrs) |
| 587 | return -ENOMEM; | 589 | return -ENOMEM; |
| 588 | 590 | ||
| 589 | srv_path->mrs_num = mrs_num; | 591 | for (srv_path->mrs_num = 0; srv_path->mrs_num < mrs_num; |
| 590 | 592 | srv_path->mrs_num++) { | |
| 591 | for (mri = 0; mri < mrs_num; mri++) { | 593 | struct rtrs_srv_mr *srv_mr = &srv_path->mrs[srv_path->mrs_num]; |
| 592 | struct rtrs_srv_mr *srv_mr = &srv_path->mrs[mri]; | ||
| 593 | struct sg_table *sgt = &srv_mr->sgt; | ||
| 594 | struct scatterlist *s; | 594 | struct scatterlist *s; |
| 595 | struct ib_mr *mr; | ||
| 596 | int nr, nr_sgt, chunks; | 595 | int nr, nr_sgt, chunks; |
| 597 | 596 | ||
| 598 | chunks = chunks_per_mr * mri; | 597 | sgt = &srv_mr->sgt; |
| 598 | chunks = chunks_per_mr * srv_path->mrs_num; | ||
| 599 | if (!always_invalidate) | 599 | if (!always_invalidate) |
| 600 | chunks_per_mr = min_t(int, chunks_per_mr, | 600 | chunks_per_mr = min_t(int, chunks_per_mr, |
| 601 | srv->queue_depth - chunks); | 601 | srv->queue_depth - chunks); |
| @@ -622,7 +622,7 @@ static int map_cont_bufs(struct rtrs_srv_path *srv_path) · 20 unmodified lines | |||
| 622 | } | 622 | } |
| 623 | nr = ib_map_mr_sg(mr, sgt->sgl, nr_sgt, | 623 | nr = ib_map_mr_sg(mr, sgt->sgl, nr_sgt, |
| 624 | NULL, max_chunk_size); | 624 | NULL, max_chunk_size); |
| 625 | if (nr < 0 || nr < sgt->nents) { | 625 | if (nr != nr_sgt) { |
| 626 | err = nr < 0 ? nr : -EINVAL; | 626 | err = nr < 0 ? nr : -EINVAL; |
| 627 | goto dereg_mr; | 627 | goto dereg_mr; |
| 628 | } | 628 | } |
| @@ -644,31 +644,24 @@ static int map_cont_bufs(struct rtrs_srv_path *srv_path) · 15 unmodified lines | |||
| 644 | 644 | ||
| 645 | ib_update_fast_reg_key(mr, ib_inc_rkey(mr->rkey)); | 645 | ib_update_fast_reg_key(mr, ib_inc_rkey(mr->rkey)); |
| 646 | srv_mr->mr = mr; | 646 | srv_mr->mr = mr; |
| 647 | |||
| 648 | continue; | ||
| 649 | err: | ||
| 650 | while (mri--) { | ||
| 651 | srv_mr = &srv_path->mrs[mri]; | ||
| 652 | sgt = &srv_mr->sgt; | ||
| 653 | mr = srv_mr->mr; | ||
| 654 | rtrs_iu_free(srv_mr->iu, srv_path->s.dev->ib_dev, 1); | ||
| 655 | dereg_mr: | ||
| 656 | ib_dereg_mr(mr); | ||
| 657 | unmap_sg: | ||
| 658 | ib_dma_unmap_sg(srv_path->s.dev->ib_dev, sgt->sgl, | ||
| 659 | sgt->nents, DMA_BIDIRECTIONAL); | ||
| 660 | free_sg: | ||
| 661 | sg_free_table(sgt); | ||
| 662 | } | ||
| 663 | kfree(srv_path->mrs); | ||
| 664 | |||
| 665 | return err; | ||
| 666 | } | 647 | } |
| 667 | 648 | ||
| 668 | chunk_bits = ilog2(srv->queue_depth - 1) + 1; | 649 | chunk_bits = ilog2(srv->queue_depth - 1) + 1; |
| 669 | srv_path->mem_bits = (MAX_IMM_PAYL_BITS - chunk_bits); | 650 | srv_path->mem_bits = (MAX_IMM_PAYL_BITS - chunk_bits); |
| 670 | 651 | ||
| 671 | return 0; | 652 | return 0; |
| 653 | |||
| 654 | dereg_mr: | ||
| 655 | ib_dereg_mr(mr); | ||
| 656 | unmap_sg: | ||
| 657 | ib_dma_unmap_sg(srv_path->s.dev->ib_dev, sgt->sgl, | ||
| 658 | sgt->nents, DMA_BIDIRECTIONAL); | ||
| 659 | free_sg: | ||
| 660 | sg_free_table(sgt); | ||
| 661 | err: | ||
| 662 | unmap_cont_bufs(srv_path); | ||
| 663 | |||
| 664 | return err; | ||
| 672 | } | 665 | } |
| 673 | 666 | ||
| 674 | static void rtrs_srv_hb_err_handler(struct rtrs_con *c) | 667 | static void rtrs_srv_hb_err_handler(struct rtrs_con *c) |
| @@ -1678,12 +1671,6 @@ static int create_con(struct rtrs_srv_path *srv_path, · 1003 unmodified lines | |||
| 1678 | srv->queue_depth * (1 + 2) + 1); | 1671 | srv->queue_depth * (1 + 2) + 1); |
| 1679 | 1672 | ||
| 1680 | max_recv_wr = srv->queue_depth + 1; | 1673 | max_recv_wr = srv->queue_depth + 1; |
| 1681 | /* | ||
| 1682 | * If we have all receive requests posted and | ||
| 1683 | * all write requests posted and each read request | ||
| 1684 | * requires an invalidate request + drain | ||
| 1685 | * and qp gets into error state. | ||
| 1686 | */ | ||
| 1687 | } | 1674 | } |
| 1688 | cq_num = max_send_wr + max_recv_wr; | 1675 | cq_num = max_send_wr + max_recv_wr; |
| 1689 | atomic_set(&con->c.sq_wr_avail, max_send_wr); | 1676 | atomic_set(&con->c.sq_wr_avail, max_send_wr); |
| @@ -1950,22 +1937,21 @@ static int rtrs_srv_rdma_cm_handler(struct rdma_cm_id *cm_id, · 260 unmodified lines | |||
| 1950 | { | 1937 | { |
| 1951 | struct rtrs_srv_path *srv_path = NULL; | 1938 | struct rtrs_srv_path *srv_path = NULL; |
| 1952 | struct rtrs_path *s = NULL; | 1939 | struct rtrs_path *s = NULL; |
| 1940 | struct rtrs_con *c = NULL; | ||
| 1953 | 1941 | ||
| 1954 | if (ev->event != RDMA_CM_EVENT_CONNECT_REQUEST) { | 1942 | if (ev->event == RDMA_CM_EVENT_CONNECT_REQUEST) |
| 1955 | struct rtrs_con *c = cm_id->context; | ||
| 1956 | |||
| 1957 | s = c->path; | ||
| 1958 | srv_path = to_srv_path(s); | ||
| 1959 | } | ||
| 1960 | |||
| 1961 | switch (ev->event) { | ||
| 1962 | case RDMA_CM_EVENT_CONNECT_REQUEST: | ||
| 1963 | /* | 1943 | /* |
| 1964 | * In case of error cma.c will destroy cm_id, | 1944 | * In case of error cma.c will destroy cm_id, |
| 1965 | * see cma_process_remove() | 1945 | * see cma_process_remove() |
| 1966 | */ | 1946 | */ |
| 1967 | return rtrs_rdma_connect(cm_id, ev->param.conn.private_data, | 1947 | return rtrs_rdma_connect(cm_id, ev->param.conn.private_data, |
| 1968 | ev->param.conn.private_data_len); | 1948 | ev->param.conn.private_data_len); |
| 1949 | |||
| 1950 | c = cm_id->context; | ||
| 1951 | s = c->path; | ||
| 1952 | srv_path = to_srv_path(s); | ||
| 1953 | |||
| 1954 | switch (ev->event) { | ||
| 1969 | case RDMA_CM_EVENT_ESTABLISHED: | 1955 | case RDMA_CM_EVENT_ESTABLISHED: |
| 1970 | /* Nothing here */ | 1956 | /* Nothing here */ |
| 1971 | break; | 1957 | break; |
| @@ -557,7 +557,6 @@ EXPORT_SYMBOL(rtrs_addr_to_sockaddr); · 556 unmodified lines | |||
| 557 | void rtrs_rdma_dev_pd_init(enum ib_pd_flags pd_flags, | 557 | void rtrs_rdma_dev_pd_init(enum ib_pd_flags pd_flags, |
| 558 | struct rtrs_rdma_dev_pd *pool) | 558 | struct rtrs_rdma_dev_pd *pool) |
| 559 | { | 559 | { |
| 560 | WARN_ON(pool->ops && (!pool->ops->alloc ^ !pool->ops->free)); | ||
| 561 | INIT_LIST_HEAD(&pool->list); | 560 | INIT_LIST_HEAD(&pool->list); |
| 562 | mutex_init(&pool->mutex); | 561 | mutex_init(&pool->mutex); |
| 563 | pool->pd_flags = pd_flags; | 562 | pool->pd_flags = pd_flags; |
| @@ -583,15 +582,8 @@ static void dev_free(struct kref *ref) · 19 unmodified lines | |||
| 583 | list_del(&dev->entry); | 582 | list_del(&dev->entry); |
| 584 | mutex_unlock(&pool->mutex); | 583 | mutex_unlock(&pool->mutex); |
| 585 | 584 | ||
| 586 | if (pool->ops && pool->ops->deinit) | ||
| 587 | pool->ops->deinit(dev); | ||
| 588 | |||
| 589 | ib_dealloc_pd(dev->ib_pd); | 585 | ib_dealloc_pd(dev->ib_pd); |
| 590 | 586 | kfree(dev); | |
| 591 | if (pool->ops && pool->ops->free) | ||
| 592 | pool->ops->free(dev); | ||
| 593 | else | ||
| 594 | kfree(dev); | ||
| 595 | } | 587 | } |
| 596 | 588 | ||
| 597 | int rtrs_ib_dev_put(struct rtrs_ib_dev *dev) | 589 | int rtrs_ib_dev_put(struct rtrs_ib_dev *dev) |
| @@ -618,11 +610,8 @@ rtrs_ib_dev_find_or_add(struct ib_device *ib_dev, · 20 unmodified lines | |||
| 618 | goto out_unlock; | 610 | goto out_unlock; |
| 619 | } | 611 | } |
| 620 | mutex_unlock(&pool->mutex); | 612 | mutex_unlock(&pool->mutex); |
| 621 | if (pool->ops && pool->ops->alloc) | 613 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
| 622 | dev = pool->ops->alloc(); | 614 | if (!dev) |
| 623 | else | ||
| 624 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
| 625 | if (IS_ERR_OR_NULL(dev)) | ||
| 626 | goto out_err; | 615 | goto out_err; |
| 627 | 616 | ||
| 628 | kref_init(&dev->ref); | 617 | kref_init(&dev->ref); |
| @@ -644,10 +633,7 @@ out_unlock: · 15 unmodified lines | |||
| 644 | out_free_pd: | 633 | out_free_pd: |
| 645 | ib_dealloc_pd(dev->ib_pd); | 634 | ib_dealloc_pd(dev->ib_pd); |
| 646 | out_free_dev: | 635 | out_free_dev: |
| 647 | if (pool->ops && pool->ops->free) | 636 | kfree(dev); |
| 648 | pool->ops->free(dev); | ||
| 649 | else | ||
| 650 | kfree(dev); | ||
| 651 | out_err: | 637 | out_err: |
| 652 | return NULL; | 638 | return NULL; |
| 653 | } | 639 | } |
| @@ -3410,7 +3410,8 @@ static int srp_parse_options(struct net *net, const char *buf, · 3409 unmodified lines | |||
| 3410 | break; | 3410 | break; |
| 3411 | 3411 | ||
| 3412 | case SRP_OPT_PKEY: | 3412 | case SRP_OPT_PKEY: |
| 3413 | if (match_hex(args, &token)) { | 3413 | ret = match_hex(args, &token); |
| 3414 | if (ret) { | ||
| 3414 | pr_warn("bad P_Key parameter '%s'\n", p); | 3415 | pr_warn("bad P_Key parameter '%s'\n", p); |
| 3415 | goto out; | 3416 | goto out; |
| 3416 | } | 3417 | } |
| @@ -3470,7 +3471,8 @@ static int srp_parse_options(struct net *net, const char *buf, · 53 unmodified lines | |||
| 3470 | break; | 3471 | break; |
| 3471 | 3472 | ||
| 3472 | case SRP_OPT_MAX_SECT: | 3473 | case SRP_OPT_MAX_SECT: |
| 3473 | if (match_int(args, &token)) { | 3474 | ret = match_int(args, &token); |
| 3475 | if (ret) { | ||
| 3474 | pr_warn("bad max sect parameter '%s'\n", p); | 3476 | pr_warn("bad max sect parameter '%s'\n", p); |
| 3475 | goto out; | 3477 | goto out; |
| 3476 | } | 3478 | } |
| @@ -3478,8 +3480,15 @@ static int srp_parse_options(struct net *net, const char *buf, · 1 unmodified line | |||
| 3478 | break; | 3480 | break; |
| 3479 | 3481 | ||
| 3480 | case SRP_OPT_QUEUE_SIZE: | 3482 | case SRP_OPT_QUEUE_SIZE: |
| 3481 | if (match_int(args, &token) || token < 1) { | 3483 | ret = match_int(args, &token); |
| 3484 | if (ret) { | ||
| 3485 | pr_warn("match_int() failed for queue_size parameter '%s', Error %d\n", | ||
| 3486 | p, ret); | ||
| 3487 | goto out; | ||
| 3488 | } | ||
| 3489 | if (token < 1) { | ||
| 3482 | pr_warn("bad queue_size parameter '%s'\n", p); | 3490 | pr_warn("bad queue_size parameter '%s'\n", p); |
| 3491 | ret = -EINVAL; | ||
| 3483 | goto out; | 3492 | goto out; |
| 3484 | } | 3493 | } |
| 3485 | target->scsi_host->can_queue = token; | 3494 | target->scsi_host->can_queue = token; |
| @@ -3490,25 +3499,40 @@ static int srp_parse_options(struct net *net, const char *buf, · 4 unmodified lines | |||
| 3490 | break; | 3499 | break; |
| 3491 | 3500 | ||
| 3492 | case SRP_OPT_MAX_CMD_PER_LUN: | 3501 | case SRP_OPT_MAX_CMD_PER_LUN: |
| 3493 | if (match_int(args, &token) || token < 1) { | 3502 | ret = match_int(args, &token); |
| 3503 | if (ret) { | ||
| 3504 | pr_warn("match_int() failed for max cmd_per_lun parameter '%s', Error %d\n", | ||
| 3505 | p, ret); | ||
| 3506 | goto out; | ||
| 3507 | } | ||
| 3508 | if (token < 1) { | ||
| 3494 | pr_warn("bad max cmd_per_lun parameter '%s'\n", | 3509 | pr_warn("bad max cmd_per_lun parameter '%s'\n", |
| 3495 | p); | 3510 | p); |
| 3511 | ret = -EINVAL; | ||
| 3496 | goto out; | 3512 | goto out; |
| 3497 | } | 3513 | } |
| 3498 | target->scsi_host->cmd_per_lun = token; | 3514 | target->scsi_host->cmd_per_lun = token; |
| 3499 | break; | 3515 | break; |
| 3500 | 3516 | ||
| 3501 | case SRP_OPT_TARGET_CAN_QUEUE: | 3517 | case SRP_OPT_TARGET_CAN_QUEUE: |
| 3502 | if (match_int(args, &token) || token < 1) { | 3518 | ret = match_int(args, &token); |
| 3519 | if (ret) { | ||
| 3520 | pr_warn("match_int() failed for max target_can_queue parameter '%s', Error %d\n", | ||
| 3521 | p, ret); | ||
| 3522 | goto out; | ||
| 3523 | } | ||
| 3524 | if (token < 1) { | ||
| 3503 | pr_warn("bad max target_can_queue parameter '%s'\n", | 3525 | pr_warn("bad max target_can_queue parameter '%s'\n", |
| 3504 | p); | 3526 | p); |
| 3527 | ret = -EINVAL; | ||
| 3505 | goto out; | 3528 | goto out; |
| 3506 | } | 3529 | } |
| 3507 | target->target_can_queue = token; | 3530 | target->target_can_queue = token; |
| 3508 | break; | 3531 | break; |
| 3509 | 3532 | ||
| 3510 | case SRP_OPT_IO_CLASS: | 3533 | case SRP_OPT_IO_CLASS: |
| 3511 | if (match_hex(args, &token)) { | 3534 | ret = match_hex(args, &token); |
| 3535 | if (ret) { | ||
| 3512 | pr_warn("bad IO class parameter '%s'\n", p); | 3536 | pr_warn("bad IO class parameter '%s'\n", p); |
| 3513 | goto out; | 3537 | goto out; |
| 3514 | } | 3538 | } |
| @@ -3517,6 +3541,7 @@ static int srp_parse_options(struct net *net, const char *buf, · 2 unmodified lines | |||
| 3517 | pr_warn("unknown IO class parameter value %x specified (use %x or %x).\n", | 3541 | pr_warn("unknown IO class parameter value %x specified (use %x or %x).\n", |
| 3518 | token, SRP_REV10_IB_IO_CLASS, | 3542 | token, SRP_REV10_IB_IO_CLASS, |
| 3519 | SRP_REV16A_IB_IO_CLASS); | 3543 | SRP_REV16A_IB_IO_CLASS); |
| 3544 | ret = -EINVAL; | ||
| 3520 | goto out; | 3545 | goto out; |
| 3521 | } | 3546 | } |
| 3522 | target->io_class = token; | 3547 | target->io_class = token; |
| @@ -3539,16 +3564,24 @@ static int srp_parse_options(struct net *net, const char *buf, · 16 unmodified lines | |||
| 3539 | break; | 3564 | break; |
| 3540 | 3565 | ||
| 3541 | case SRP_OPT_CMD_SG_ENTRIES: | 3566 | case SRP_OPT_CMD_SG_ENTRIES: |
| 3542 | if (match_int(args, &token) || token < 1 || token > 255) { | 3567 | ret = match_int(args, &token); |
| 3568 | if (ret) { | ||
| 3569 | pr_warn("match_int() failed for max cmd_sg_entries parameter '%s', Error %d\n", | ||
| 3570 | p, ret); | ||
| 3571 | goto out; | ||
| 3572 | } | ||
| 3573 | if (token < 1 || token > 255) { | ||
| 3543 | pr_warn("bad max cmd_sg_entries parameter '%s'\n", | 3574 | pr_warn("bad max cmd_sg_entries parameter '%s'\n", |
| 3544 | p); | 3575 | p); |
| 3576 | ret = -EINVAL; | ||
| 3545 | goto out; | 3577 | goto out; |
| 3546 | } | 3578 | } |
| 3547 | target->cmd_sg_cnt = token; | 3579 | target->cmd_sg_cnt = token; |
| 3548 | break; | 3580 | break; |
| 3549 | 3581 | ||
| 3550 | case SRP_OPT_ALLOW_EXT_SG: | 3582 | case SRP_OPT_ALLOW_EXT_SG: |
| 3551 | if (match_int(args, &token)) { | 3583 | ret = match_int(args, &token); |
| 3584 | if (ret) { | ||
| 3552 | pr_warn("bad allow_ext_sg parameter '%s'\n", p); | 3585 | pr_warn("bad allow_ext_sg parameter '%s'\n", p); |
| 3553 | goto out; | 3586 | goto out; |
| 3554 | } | 3587 | } |
| @@ -3556,43 +3589,77 @@ static int srp_parse_options(struct net *net, const char *buf, · 1 unmodified line | |||
| 3556 | break; | 3589 | break; |
| 3557 | 3590 | ||
| 3558 | case SRP_OPT_SG_TABLESIZE: | 3591 | case SRP_OPT_SG_TABLESIZE: |
| 3559 | if (match_int(args, &token) || token < 1 || | 3592 | ret = match_int(args, &token); |
| 3560 | token > SG_MAX_SEGMENTS) { | 3593 | if (ret) { |
| 3594 | pr_warn("match_int() failed for max sg_tablesize parameter '%s', Error %d\n", | ||
| 3595 | p, ret); | ||
| 3596 | goto out; | ||
| 3597 | } | ||
| 3598 | if (token < 1 || token > SG_MAX_SEGMENTS) { | ||
| 3561 | pr_warn("bad max sg_tablesize parameter '%s'\n", | 3599 | pr_warn("bad max sg_tablesize parameter '%s'\n", |
| 3562 | p); | 3600 | p); |
| 3601 | ret = -EINVAL; | ||
| 3563 | goto out; | 3602 | goto out; |
| 3564 | } | 3603 | } |
| 3565 | target->sg_tablesize = token; | 3604 | target->sg_tablesize = token; |
| 3566 | break; | 3605 | break; |
| 3567 | 3606 | ||
| 3568 | case SRP_OPT_COMP_VECTOR: | 3607 | case SRP_OPT_COMP_VECTOR: |
| 3569 | if (match_int(args, &token) || token < 0) { | 3608 | ret = match_int(args, &token); |
| 3609 | if (ret) { | ||
| 3610 | pr_warn("match_int() failed for comp_vector parameter '%s', Error %d\n", | ||
| 3611 | p, ret); | ||
| 3612 | goto out; | ||
| 3613 | } | ||
| 3614 | if (token < 0) { | ||
| 3570 | pr_warn("bad comp_vector parameter '%s'\n", p); | 3615 | pr_warn("bad comp_vector parameter '%s'\n", p); |
| 3616 | ret = -EINVAL; | ||
| 3571 | goto out; | 3617 | goto out; |
| 3572 | } | 3618 | } |
| 3573 | target->comp_vector = token; | 3619 | target->comp_vector = token; |
| 3574 | break; | 3620 | break; |
| 3575 | 3621 | ||
| 3576 | case SRP_OPT_TL_RETRY_COUNT: | 3622 | case SRP_OPT_TL_RETRY_COUNT: |
| 3577 | if (match_int(args, &token) || token < 2 || token > 7) { | 3623 | ret = match_int(args, &token); |
| 3624 | if (ret) { | ||
| 3625 | pr_warn("match_int() failed for tl_retry_count parameter '%s', Error %d\n", | ||
| 3626 | p, ret); | ||
| 3627 | goto out; | ||
| 3628 | } | ||
| 3629 | if (token < 2 || token > 7) { | ||
| 3578 | pr_warn("bad tl_retry_count parameter '%s' (must be a number between 2 and 7)\n", | 3630 | pr_warn("bad tl_retry_count parameter '%s' (must be a number between 2 and 7)\n", |
| 3579 | p); | 3631 | p); |
| 3632 | ret = -EINVAL; | ||
| 3580 | goto out; | 3633 | goto out; |
| 3581 | } | 3634 | } |
| 3582 | target->tl_retry_count = token; | 3635 | target->tl_retry_count = token; |
| 3583 | break; | 3636 | break; |
| 3584 | 3637 | ||
| 3585 | case SRP_OPT_MAX_IT_IU_SIZE: | 3638 | case SRP_OPT_MAX_IT_IU_SIZE: |
| 3586 | if (match_int(args, &token) || token < 0) { | 3639 | ret = match_int(args, &token); |
| 3640 | if (ret) { | ||
| 3641 | pr_warn("match_int() failed for max it_iu_size parameter '%s', Error %d\n", | ||
| 3642 | p, ret); | ||
| 3643 | goto out; | ||
| 3644 | } | ||
| 3645 | if (token < 0) { | ||
| 3587 | pr_warn("bad maximum initiator to target IU size '%s'\n", p); | 3646 | pr_warn("bad maximum initiator to target IU size '%s'\n", p); |
| 3647 | ret = -EINVAL; | ||
| 3588 | goto out; | 3648 | goto out; |
| 3589 | } | 3649 | } |
| 3590 | target->max_it_iu_size = token; | 3650 | target->max_it_iu_size = token; |
| 3591 | break; | 3651 | break; |
| 3592 | 3652 | ||
| 3593 | case SRP_OPT_CH_COUNT: | 3653 | case SRP_OPT_CH_COUNT: |
| 3594 | if (match_int(args, &token) || token < 1) { | 3654 | ret = match_int(args, &token); |
| 3655 | if (ret) { | ||
| 3656 | pr_warn("match_int() failed for channel count parameter '%s', Error %d\n", | ||
| 3657 | p, ret); | ||
| 3658 | goto out; | ||
| 3659 | } | ||
| 3660 | if (token < 1) { | ||
| 3595 | pr_warn("bad channel count %s\n", p); | 3661 | pr_warn("bad channel count %s\n", p); |
| 3662 | ret = -EINVAL; | ||
| 3596 | goto out; | 3663 | goto out; |
| 3597 | } | 3664 | } |
| 3598 | target->ch_count = token; | 3665 | target->ch_count = token; |
| @@ -3601,6 +3668,7 @@ static int srp_parse_options(struct net *net, const char *buf, · 2 unmodified lines | |||
| 3601 | default: | 3668 | default: |
| 3602 | pr_warn("unknown parameter or missing value '%s' in target creation request\n", | 3669 | pr_warn("unknown parameter or missing value '%s' in target creation request\n", |
| 3603 | p); | 3670 | p); |
| 3671 | ret = -EINVAL; | ||
| 3604 | goto out; | 3672 | goto out; |
| 3605 | } | 3673 | } |
| 3606 | } | 3674 | } |
| @@ -671,8 +671,7 @@ free_q: · 670 unmodified lines | |||
| 671 | return err; | 671 | return err; |
| 672 | } | 672 | } |
| 673 | 673 | ||
| 674 | int mana_gd_destroy_dma_region(struct gdma_context *gc, | 674 | int mana_gd_destroy_dma_region(struct gdma_context *gc, u64 dma_region_handle) |
| 675 | gdma_obj_handle_t dma_region_handle) | ||
| 676 | { | 675 | { |
| 677 | struct gdma_destroy_dma_region_req req = {}; | 676 | struct gdma_destroy_dma_region_req req = {}; |
| 678 | struct gdma_general_resp resp = {}; | 677 | struct gdma_general_resp resp = {}; |
| @@ -65,8 +65,6 @@ enum { · 64 unmodified lines | |||
| 65 | GDMA_DEVICE_MANA = 2, | 65 | GDMA_DEVICE_MANA = 2, |
| 66 | }; | 66 | }; |
| 67 | 67 | ||
| 68 | typedef u64 gdma_obj_handle_t; | ||
| 69 | |||
| 70 | struct gdma_resource { | 68 | struct gdma_resource { |
| 71 | /* Protect the bitmap */ | 69 | /* Protect the bitmap */ |
| 72 | spinlock_t lock; | 70 | spinlock_t lock; |
| @@ -200,7 +198,7 @@ struct gdma_mem_info { · 127 unmodified lines | |||
| 200 | u64 length; | 198 | u64 length; |
| 201 | 199 | ||
| 202 | /* Allocated by the PF driver */ | 200 | /* Allocated by the PF driver */ |
| 203 | gdma_obj_handle_t dma_region_handle; | 201 | u64 dma_region_handle; |
| 204 | }; | 202 | }; |
| 205 | 203 | ||
| 206 | #define REGISTER_ATB_MST_MKEY_LOWER_SIZE 8 | 204 | #define REGISTER_ATB_MST_MKEY_LOWER_SIZE 8 |
| @@ -632,7 +630,7 @@ struct gdma_create_queue_req { · 425 unmodified lines | |||
| 632 | u32 reserved1; | 630 | u32 reserved1; |
| 633 | u32 pdid; | 631 | u32 pdid; |
| 634 | u32 doolbell_id; | 632 | u32 doolbell_id; |
| 635 | gdma_obj_handle_t gdma_region; | 633 | u64 gdma_region; |
| 636 | u32 reserved2; | 634 | u32 reserved2; |
| 637 | u32 queue_size; | 635 | u32 queue_size; |
| 638 | u32 log2_throttle_limit; | 636 | u32 log2_throttle_limit; |
| @@ -707,14 +705,14 @@ struct gdma_create_dma_region_req { · 68 unmodified lines | |||
| 707 | 705 | ||
| 708 | struct gdma_create_dma_region_resp { | 706 | struct gdma_create_dma_region_resp { |
| 709 | struct gdma_resp_hdr hdr; | 707 | struct gdma_resp_hdr hdr; |
| 710 | gdma_obj_handle_t dma_region_handle; | 708 | u64 dma_region_handle; |
| 711 | }; /* HW DATA */ | 709 | }; /* HW DATA */ |
| 712 | 710 | ||
| 713 | /* GDMA_DMA_REGION_ADD_PAGES */ | 711 | /* GDMA_DMA_REGION_ADD_PAGES */ |
| 714 | struct gdma_dma_region_add_pages_req { | 712 | struct gdma_dma_region_add_pages_req { |
| 715 | struct gdma_req_hdr hdr; | 713 | struct gdma_req_hdr hdr; |
| 716 | 714 | ||
| 717 | gdma_obj_handle_t dma_region_handle; | 715 | u64 dma_region_handle; |
| 718 | 716 | ||
| 719 | u32 page_addr_list_len; | 717 | u32 page_addr_list_len; |
| 720 | u32 reserved3; | 718 | u32 reserved3; |
| @@ -726,7 +724,7 @@ struct gdma_dma_region_add_pages_req { · 5 unmodified lines | |||
| 726 | struct gdma_destroy_dma_region_req { | 724 | struct gdma_destroy_dma_region_req { |
| 727 | struct gdma_req_hdr hdr; | 725 | struct gdma_req_hdr hdr; |
| 728 | 726 | ||
| 729 | gdma_obj_handle_t dma_region_handle; | 727 | u64 dma_region_handle; |
| 730 | }; /* HW DATA */ | 728 | }; /* HW DATA */ |
| 731 | 729 | ||
| 732 | enum gdma_pd_flags { | 730 | enum gdma_pd_flags { |
| @@ -741,14 +739,14 @@ struct gdma_create_pd_req { · 8 unmodified lines | |||
| 741 | 739 | ||
| 742 | struct gdma_create_pd_resp { | 740 | struct gdma_create_pd_resp { |
| 743 | struct gdma_resp_hdr hdr; | 741 | struct gdma_resp_hdr hdr; |
| 744 | gdma_obj_handle_t pd_handle; | 742 | u64 pd_handle; |
| 745 | u32 pd_id; | 743 | u32 pd_id; |
| 746 | u32 reserved; | 744 | u32 reserved; |
| 747 | };/* HW DATA */ | 745 | };/* HW DATA */ |
| 748 | 746 | ||
| 749 | struct gdma_destroy_pd_req { | 747 | struct gdma_destroy_pd_req { |
| 750 | struct gdma_req_hdr hdr; | 748 | struct gdma_req_hdr hdr; |
| 751 | gdma_obj_handle_t pd_handle; | 749 | u64 pd_handle; |
| 752 | };/* HW DATA */ | 750 | };/* HW DATA */ |
| 753 | 751 | ||
| 754 | struct gdma_destory_pd_resp { | 752 | struct gdma_destory_pd_resp { |
| @@ -764,11 +762,11 @@ enum gdma_mr_type { · 9 unmodified lines | |||
| 764 | }; | 762 | }; |
| 765 | 763 | ||
| 766 | struct gdma_create_mr_params { | 764 | struct gdma_create_mr_params { |
| 767 | gdma_obj_handle_t pd_handle; | 765 | u64 pd_handle; |
| 768 | enum gdma_mr_type mr_type; | 766 | enum gdma_mr_type mr_type; |
| 769 | union { | 767 | union { |
| 770 | struct { | 768 | struct { |
| 771 | gdma_obj_handle_t dma_region_handle; | 769 | u64 dma_region_handle; |
| 772 | u64 virtual_address; | 770 | u64 virtual_address; |
| 773 | enum gdma_mr_access_flags access_flags; | 771 | enum gdma_mr_access_flags access_flags; |
| 774 | } gva; | 772 | } gva; |
| @@ -777,13 +775,13 @@ struct gdma_create_mr_params { · 2 unmodified lines | |||
| 777 | 775 | ||
| 778 | struct gdma_create_mr_request { | 776 | struct gdma_create_mr_request { |
| 779 | struct gdma_req_hdr hdr; | 777 | struct gdma_req_hdr hdr; |
| 780 | gdma_obj_handle_t pd_handle; | 778 | u64 pd_handle; |
| 781 | enum gdma_mr_type mr_type; | 779 | enum gdma_mr_type mr_type; |
| 782 | u32 reserved_1; | 780 | u32 reserved_1; |
| 783 | 781 | ||
| 784 | union { | 782 | union { |
| 785 | struct { | 783 | struct { |
| 786 | gdma_obj_handle_t dma_region_handle; | 784 | u64 dma_region_handle; |
| 787 | u64 virtual_address; | 785 | u64 virtual_address; |
| 788 | enum gdma_mr_access_flags access_flags; | 786 | enum gdma_mr_access_flags access_flags; |
| 789 | } gva; | 787 | } gva; |
| @@ -794,14 +792,14 @@ struct gdma_create_mr_request { · 4 unmodified lines | |||
| 794 | 792 | ||
| 795 | struct gdma_create_mr_response { | 793 | struct gdma_create_mr_response { |
| 796 | struct gdma_resp_hdr hdr; | 794 | struct gdma_resp_hdr hdr; |
| 797 | gdma_obj_handle_t mr_handle; | 795 | u64 mr_handle; |
| 798 | u32 lkey; | 796 | u32 lkey; |
| 799 | u32 rkey; | 797 | u32 rkey; |
| 800 | };/* HW DATA */ | 798 | };/* HW DATA */ |
| 801 | 799 | ||
| 802 | struct gdma_destroy_mr_request { | 800 | struct gdma_destroy_mr_request { |
| 803 | struct gdma_req_hdr hdr; | 801 | struct gdma_req_hdr hdr; |
| 804 | gdma_obj_handle_t mr_handle; | 802 | u64 mr_handle; |
| 805 | };/* HW DATA */ | 803 | };/* HW DATA */ |
| 806 | 804 | ||
| 807 | struct gdma_destroy_mr_response { | 805 | struct gdma_destroy_mr_response { |
| @@ -835,7 +833,6 @@ void mana_gd_free_memory(struct gdma_mem_info *gmi); · 27 unmodified lines | |||
| 835 | int mana_gd_send_request(struct gdma_context *gc, u32 req_len, const void *req, | 833 | int mana_gd_send_request(struct gdma_context *gc, u32 req_len, const void *req, |
| 836 | u32 resp_len, void *resp); | 834 | u32 resp_len, void *resp); |
| 837 | 835 | ||
| 838 | int mana_gd_destroy_dma_region(struct gdma_context *gc, | 836 | int mana_gd_destroy_dma_region(struct gdma_context *gc, u64 dma_region_handle); |
| 839 | gdma_obj_handle_t dma_region_handle); | ||
| 840 | 837 | ||
| 841 | #endif /* _GDMA_H */ | 838 | #endif /* _GDMA_H */ |
| @@ -412,6 +412,9 @@ int mana_bpf(struct net_device *ndev, struct netdev_bpf *bpf); · 411 unmodified lines | |||
| 412 | 412 | ||
| 413 | extern const struct ethtool_ops mana_ethtool_ops; | 413 | extern const struct ethtool_ops mana_ethtool_ops; |
| 414 | 414 | ||
| 415 | /* A CQ can be created not associated with any EQ */ | ||
| 416 | #define GDMA_CQ_NO_EQ 0xffff | ||
| 417 | |||
| 415 | struct mana_obj_spec { | 418 | struct mana_obj_spec { |
| 416 | u32 queue_index; | 419 | u32 queue_index; |
| 417 | u64 gdma_region; | 420 | u64 gdma_region; |
| @@ -84,6 +84,8 @@ enum { · 83 unmodified lines | |||
| 84 | /* opcode 0x15 is reserved */ | 84 | /* opcode 0x15 is reserved */ |
| 85 | IB_OPCODE_SEND_LAST_WITH_INVALIDATE = 0x16, | 85 | IB_OPCODE_SEND_LAST_WITH_INVALIDATE = 0x16, |
| 86 | IB_OPCODE_SEND_ONLY_WITH_INVALIDATE = 0x17, | 86 | IB_OPCODE_SEND_ONLY_WITH_INVALIDATE = 0x17, |
| 87 | IB_OPCODE_FLUSH = 0x1C, | ||
| 88 | IB_OPCODE_ATOMIC_WRITE = 0x1D, | ||
| 87 | 89 | ||
| 88 | /* real constants follow -- see comment about above IB_OPCODE() | 90 | /* real constants follow -- see comment about above IB_OPCODE() |
| 89 | macro for more details */ | 91 | macro for more details */ |
| @@ -112,6 +114,8 @@ enum { · 22 unmodified lines | |||
| 112 | IB_OPCODE(RC, FETCH_ADD), | 114 | IB_OPCODE(RC, FETCH_ADD), |
| 113 | IB_OPCODE(RC, SEND_LAST_WITH_INVALIDATE), | 115 | IB_OPCODE(RC, SEND_LAST_WITH_INVALIDATE), |
| 114 | IB_OPCODE(RC, SEND_ONLY_WITH_INVALIDATE), | 116 | IB_OPCODE(RC, SEND_ONLY_WITH_INVALIDATE), |
| 117 | IB_OPCODE(RC, FLUSH), | ||
| 118 | IB_OPCODE(RC, ATOMIC_WRITE), | ||
| 115 | 119 | ||
| 116 | /* UC */ | 120 | /* UC */ |
| 117 | IB_OPCODE(UC, SEND_FIRST), | 121 | IB_OPCODE(UC, SEND_FIRST), |
| @@ -149,6 +153,7 @@ enum { · 31 unmodified lines | |||
| 149 | IB_OPCODE(RD, ATOMIC_ACKNOWLEDGE), | 153 | IB_OPCODE(RD, ATOMIC_ACKNOWLEDGE), |
| 150 | IB_OPCODE(RD, COMPARE_SWAP), | 154 | IB_OPCODE(RD, COMPARE_SWAP), |
| 151 | IB_OPCODE(RD, FETCH_ADD), | 155 | IB_OPCODE(RD, FETCH_ADD), |
| 156 | IB_OPCODE(RD, FLUSH), | ||
| 152 | 157 | ||
| 153 | /* UD */ | 158 | /* UD */ |
| 154 | IB_OPCODE(UD, SEND_ONLY), | 159 | IB_OPCODE(UD, SEND_ONLY), |
| @@ -270,6 +270,10 @@ enum ib_device_cap_flags { · 269 unmodified lines | |||
| 270 | /* The device supports padding incoming writes to cacheline. */ | 270 | /* The device supports padding incoming writes to cacheline. */ |
| 271 | IB_DEVICE_PCI_WRITE_END_PADDING = | 271 | IB_DEVICE_PCI_WRITE_END_PADDING = |
| 272 | IB_UVERBS_DEVICE_PCI_WRITE_END_PADDING, | 272 | IB_UVERBS_DEVICE_PCI_WRITE_END_PADDING, |
| 273 | /* Placement type attributes */ | ||
| 274 | IB_DEVICE_FLUSH_GLOBAL = IB_UVERBS_DEVICE_FLUSH_GLOBAL, | ||
| 275 | IB_DEVICE_FLUSH_PERSISTENT = IB_UVERBS_DEVICE_FLUSH_PERSISTENT, | ||
| 276 | IB_DEVICE_ATOMIC_WRITE = IB_UVERBS_DEVICE_ATOMIC_WRITE, | ||
| 273 | }; | 277 | }; |
| 274 | 278 | ||
| 275 | enum ib_kernel_cap_flags { | 279 | enum ib_kernel_cap_flags { |
| @@ -982,9 +986,11 @@ enum ib_wc_opcode { · 706 unmodified lines | |||
| 982 | IB_WC_BIND_MW = IB_UVERBS_WC_BIND_MW, | 986 | IB_WC_BIND_MW = IB_UVERBS_WC_BIND_MW, |
| 983 | IB_WC_LOCAL_INV = IB_UVERBS_WC_LOCAL_INV, | 987 | IB_WC_LOCAL_INV = IB_UVERBS_WC_LOCAL_INV, |
| 984 | IB_WC_LSO = IB_UVERBS_WC_TSO, | 988 | IB_WC_LSO = IB_UVERBS_WC_TSO, |
| 989 | IB_WC_ATOMIC_WRITE = IB_UVERBS_WC_ATOMIC_WRITE, | ||
| 985 | IB_WC_REG_MR, | 990 | IB_WC_REG_MR, |
| 986 | IB_WC_MASKED_COMP_SWAP, | 991 | IB_WC_MASKED_COMP_SWAP, |
| 987 | IB_WC_MASKED_FETCH_ADD, | 992 | IB_WC_MASKED_FETCH_ADD, |
| 993 | IB_WC_FLUSH = IB_UVERBS_WC_FLUSH, | ||
| 988 | /* | 994 | /* |
| 989 | * Set value of IB_WC_RECV so consumers can test if a completion is a | 995 | * Set value of IB_WC_RECV so consumers can test if a completion is a |
| 990 | * receive by testing (opcode & IB_WC_RECV). | 996 | * receive by testing (opcode & IB_WC_RECV). |
| @@ -1325,6 +1331,8 @@ enum ib_wr_opcode { · 334 unmodified lines | |||
| 1325 | IB_UVERBS_WR_MASKED_ATOMIC_CMP_AND_SWP, | 1331 | IB_UVERBS_WR_MASKED_ATOMIC_CMP_AND_SWP, |
| 1326 | IB_WR_MASKED_ATOMIC_FETCH_AND_ADD = | 1332 | IB_WR_MASKED_ATOMIC_FETCH_AND_ADD = |
| 1327 | IB_UVERBS_WR_MASKED_ATOMIC_FETCH_AND_ADD, | 1333 | IB_UVERBS_WR_MASKED_ATOMIC_FETCH_AND_ADD, |
| 1334 | IB_WR_FLUSH = IB_UVERBS_WR_FLUSH, | ||
| 1335 | IB_WR_ATOMIC_WRITE = IB_UVERBS_WR_ATOMIC_WRITE, | ||
| 1328 | 1336 | ||
| 1329 | /* These are kernel only and can not be issued by userspace */ | 1337 | /* These are kernel only and can not be issued by userspace */ |
| 1330 | IB_WR_REG_MR = 0x20, | 1338 | IB_WR_REG_MR = 0x20, |
| @@ -1458,10 +1466,12 @@ enum ib_access_flags { · 127 unmodified lines | |||
| 1458 | IB_ACCESS_ON_DEMAND = IB_UVERBS_ACCESS_ON_DEMAND, | 1466 | IB_ACCESS_ON_DEMAND = IB_UVERBS_ACCESS_ON_DEMAND, |
| 1459 | IB_ACCESS_HUGETLB = IB_UVERBS_ACCESS_HUGETLB, | 1467 | IB_ACCESS_HUGETLB = IB_UVERBS_ACCESS_HUGETLB, |
| 1460 | IB_ACCESS_RELAXED_ORDERING = IB_UVERBS_ACCESS_RELAXED_ORDERING, | 1468 | IB_ACCESS_RELAXED_ORDERING = IB_UVERBS_ACCESS_RELAXED_ORDERING, |
| 1469 | IB_ACCESS_FLUSH_GLOBAL = IB_UVERBS_ACCESS_FLUSH_GLOBAL, | ||
| 1470 | IB_ACCESS_FLUSH_PERSISTENT = IB_UVERBS_ACCESS_FLUSH_PERSISTENT, | ||
| 1461 | 1471 | ||
| 1462 | IB_ACCESS_OPTIONAL = IB_UVERBS_ACCESS_OPTIONAL_RANGE, | 1472 | IB_ACCESS_OPTIONAL = IB_UVERBS_ACCESS_OPTIONAL_RANGE, |
| 1463 | IB_ACCESS_SUPPORTED = | 1473 | IB_ACCESS_SUPPORTED = |
| 1464 | ((IB_ACCESS_HUGETLB << 1) - 1) | IB_ACCESS_OPTIONAL, | 1474 | ((IB_ACCESS_FLUSH_PERSISTENT << 1) - 1) | IB_ACCESS_OPTIONAL, |
| 1465 | }; | 1475 | }; |
| 1466 | 1476 | ||
| 1467 | /* | 1477 | /* |
| @@ -2203,6 +2213,7 @@ struct ib_port_data { · 735 unmodified lines | |||
| 2203 | struct ib_port_cache cache; | 2213 | struct ib_port_cache cache; |
| 2204 | 2214 | ||
| 2205 | struct net_device __rcu *netdev; | 2215 | struct net_device __rcu *netdev; |
| 2216 | netdevice_tracker netdev_tracker; | ||
| 2206 | struct hlist_node ndev_hash_link; | 2217 | struct hlist_node ndev_hash_link; |
| 2207 | struct rdma_port_counter port_counter; | 2218 | struct rdma_port_counter port_counter; |
| 2208 | struct ib_port *sysfs; | 2219 | struct ib_port *sysfs; |
| @@ -4321,6 +4332,8 @@ int ib_dealloc_xrcd_user(struct ib_xrcd *xrcd, struct ib_udata *udata); · 2112 unmodified lines | |||
| 4321 | static inline int ib_check_mr_access(struct ib_device *ib_dev, | 4332 | static inline int ib_check_mr_access(struct ib_device *ib_dev, |
| 4322 | unsigned int flags) | 4333 | unsigned int flags) |
| 4323 | { | 4334 | { |
| 4335 | u64 device_cap = ib_dev->attrs.device_cap_flags; | ||
| 4336 | |||
| 4324 | /* | 4337 | /* |
| 4325 | * Local write permission is required if remote write or | 4338 | * Local write permission is required if remote write or |
| 4326 | * remote atomic permission is also requested. | 4339 | * remote atomic permission is also requested. |
| @@ -4334,7 +4347,14 @@ static inline int ib_check_mr_access(struct ib_device *ib_dev, · 7 unmodified lines | |||
| 4334 | 4347 | ||
| 4335 | if (flags & IB_ACCESS_ON_DEMAND && | 4348 | if (flags & IB_ACCESS_ON_DEMAND && |
| 4336 | !(ib_dev->attrs.kernel_cap_flags & IBK_ON_DEMAND_PAGING)) | 4349 | !(ib_dev->attrs.kernel_cap_flags & IBK_ON_DEMAND_PAGING)) |
| 4337 | return -EINVAL; | 4350 | return -EOPNOTSUPP; |
| 4351 | |||
| 4352 | if ((flags & IB_ACCESS_FLUSH_GLOBAL && | ||
| 4353 | !(device_cap & IB_DEVICE_FLUSH_GLOBAL)) || | ||
| 4354 | (flags & IB_ACCESS_FLUSH_PERSISTENT && | ||
| 4355 | !(device_cap & IB_DEVICE_FLUSH_PERSISTENT))) | ||
| 4356 | return -EOPNOTSUPP; | ||
| 4357 | |||
| 4338 | return 0; | 4358 | return 0; |
| 4339 | } | 4359 | } |
| 4340 | 4360 | ||
| @@ -51,7 +51,7 @@ static inline void *opa_vnic_dev_priv(const struct net_device *dev) · 50 unmodified lines | |||
| 51 | return oparn->dev_priv; | 51 | return oparn->dev_priv; |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | /* opa_vnic skb meta data structrue */ | 54 | /* opa_vnic skb meta data structure */ |
| 55 | struct opa_vnic_skb_mdata { | 55 | struct opa_vnic_skb_mdata { |
| 56 | u8 vl; | 56 | u8 vl; |
| 57 | u8 entropy; | 57 | u8 entropy; |
| @@ -49,7 +49,6 @@ DECLARE_EVENT_CLASS(ib_mad_send_template, · 48 unmodified lines | |||
| 49 | __field(int, retries_left) | 49 | __field(int, retries_left) |
| 50 | __field(int, max_retries) | 50 | __field(int, max_retries) |
| 51 | __field(int, retry) | 51 | __field(int, retry) |
| 52 | __field(u16, pkey) | ||
| 53 | ), | 52 | ), |
| 54 | 53 | ||
| 55 | TP_fast_assign( | 54 | TP_fast_assign( |
| @@ -89,7 +88,7 @@ DECLARE_EVENT_CLASS(ib_mad_send_template, · 33 unmodified lines | |||
| 89 | "hdr : base_ver 0x%x class 0x%x class_ver 0x%x " \ | 88 | "hdr : base_ver 0x%x class 0x%x class_ver 0x%x " \ |
| 90 | "method 0x%x status 0x%x class_specific 0x%x tid 0x%llx " \ | 89 | "method 0x%x status 0x%x class_specific 0x%x tid 0x%llx " \ |
| 91 | "attr_id 0x%x attr_mod 0x%x => dlid 0x%08x sl %d "\ | 90 | "attr_id 0x%x attr_mod 0x%x => dlid 0x%08x sl %d "\ |
| 92 | "pkey 0x%x rpqn 0x%x rqpkey 0x%x", | 91 | "rpqn 0x%x rqpkey 0x%x", |
| 93 | __entry->dev_index, __entry->port_num, __entry->qp_num, | 92 | __entry->dev_index, __entry->port_num, __entry->qp_num, |
| 94 | __entry->agent_priv, be64_to_cpu(__entry->wrtid), | 93 | __entry->agent_priv, be64_to_cpu(__entry->wrtid), |
| 95 | __entry->retries_left, __entry->max_retries, | 94 | __entry->retries_left, __entry->max_retries, |
| @@ -100,7 +99,7 @@ DECLARE_EVENT_CLASS(ib_mad_send_template, · 4 unmodified lines | |||
| 100 | be16_to_cpu(__entry->class_specific), | 99 | be16_to_cpu(__entry->class_specific), |
| 101 | be64_to_cpu(__entry->tid), be16_to_cpu(__entry->attr_id), | 100 | be64_to_cpu(__entry->tid), be16_to_cpu(__entry->attr_id), |
| 102 | be32_to_cpu(__entry->attr_mod), | 101 | be32_to_cpu(__entry->attr_mod), |
| 103 | be32_to_cpu(__entry->dlid), __entry->sl, __entry->pkey, | 102 | be32_to_cpu(__entry->dlid), __entry->sl, |
| 104 | __entry->rqpn, __entry->rqkey | 103 | __entry->rqpn, __entry->rqkey |
| 105 | ) | 104 | ) |
| 106 | ); | 105 | ); |
| @@ -204,7 +203,6 @@ TRACE_EVENT(ib_mad_recv_done_handler, · 97 unmodified lines | |||
| 204 | __field(u16, wc_status) | 203 | __field(u16, wc_status) |
| 205 | __field(u32, slid) | 204 | __field(u32, slid) |
| 206 | __field(u32, dev_index) | 205 | __field(u32, dev_index) |
| 207 | __field(u16, pkey) | ||
| 208 | ), | 206 | ), |
| 209 | 207 | ||
| 210 | TP_fast_assign( | 208 | TP_fast_assign( |
| @@ -224,9 +222,6 @@ TRACE_EVENT(ib_mad_recv_done_handler, · 13 unmodified lines | |||
| 224 | __entry->slid = wc->slid; | 222 | __entry->slid = wc->slid; |
| 225 | __entry->src_qp = wc->src_qp; | 223 | __entry->src_qp = wc->src_qp; |
| 226 | __entry->sl = wc->sl; | 224 | __entry->sl = wc->sl; |
| 227 | ib_query_pkey(qp_info->port_priv->device, | ||
| 228 | qp_info->port_priv->port_num, | ||
| 229 | wc->pkey_index, &__entry->pkey); | ||
| 230 | __entry->wc_status = wc->status; | 225 | __entry->wc_status = wc->status; |
| 231 | ), | 226 | ), |
| 232 | 227 | ||
| @@ -234,7 +229,7 @@ TRACE_EVENT(ib_mad_recv_done_handler, · 1 unmodified line | |||
| 234 | "base_ver 0x%02x class 0x%02x class_ver 0x%02x " \ | 229 | "base_ver 0x%02x class 0x%02x class_ver 0x%02x " \ |
| 235 | "method 0x%02x status 0x%04x class_specific 0x%04x " \ | 230 | "method 0x%02x status 0x%04x class_specific 0x%04x " \ |
| 236 | "tid 0x%016llx attr_id 0x%04x attr_mod 0x%08x " \ | 231 | "tid 0x%016llx attr_id 0x%04x attr_mod 0x%08x " \ |
| 237 | "slid 0x%08x src QP%d, sl %d pkey 0x%04x", | 232 | "slid 0x%08x src QP%d, sl %d", |
| 238 | __entry->dev_index, __entry->port_num, __entry->qp_num, | 233 | __entry->dev_index, __entry->port_num, __entry->qp_num, |
| 239 | __entry->wc_status, | 234 | __entry->wc_status, |
| 240 | __entry->length, | 235 | __entry->length, |
| @@ -244,7 +239,7 @@ TRACE_EVENT(ib_mad_recv_done_handler, · 3 unmodified lines | |||
| 244 | be16_to_cpu(__entry->class_specific), | 239 | be16_to_cpu(__entry->class_specific), |
| 245 | be64_to_cpu(__entry->tid), be16_to_cpu(__entry->attr_id), | 240 | be64_to_cpu(__entry->tid), be16_to_cpu(__entry->attr_id), |
| 246 | be32_to_cpu(__entry->attr_mod), | 241 | be32_to_cpu(__entry->attr_mod), |
| 247 | __entry->slid, __entry->src_qp, __entry->sl, __entry->pkey | 242 | __entry->slid, __entry->src_qp, __entry->sl |
| 248 | ) | 243 | ) |
| 249 | ); | 244 | ); |
| 250 | 245 | ||
| @@ -85,11 +85,26 @@ struct hns_roce_ib_create_qp_resp { · 84 unmodified lines | |||
| 85 | __aligned_u64 dwqe_mmap_key; | 85 | __aligned_u64 dwqe_mmap_key; |
| 86 | }; | 86 | }; |
| 87 | 87 | ||
| 88 | enum { | ||
| 89 | HNS_ROCE_EXSGE_FLAGS = 1 << 0, | ||
| 90 | }; | ||
| 91 | |||
| 92 | enum { | ||
| 93 | HNS_ROCE_RSP_EXSGE_FLAGS = 1 << 0, | ||
| 94 | }; | ||
| 95 | |||
| 88 | struct hns_roce_ib_alloc_ucontext_resp { | 96 | struct hns_roce_ib_alloc_ucontext_resp { |
| 89 | __u32 qp_tab_size; | 97 | __u32 qp_tab_size; |
| 90 | __u32 cqe_size; | 98 | __u32 cqe_size; |
| 91 | __u32 srq_tab_size; | 99 | __u32 srq_tab_size; |
| 92 | __u32 reserved; | 100 | __u32 reserved; |
| 101 | __u32 config; | ||
| 102 | __u32 max_inline_data; | ||
| 103 | }; | ||
| 104 | |||
| 105 | struct hns_roce_ib_alloc_ucontext { | ||
| 106 | __u32 config; | ||
| 107 | __u32 reserved; | ||
| 93 | }; | 108 | }; |
| 94 | 109 | ||
| 95 | struct hns_roce_ib_alloc_pd_resp { | 110 | struct hns_roce_ib_alloc_pd_resp { |
| @@ -57,6 +57,8 @@ enum ib_uverbs_access_flags { · 56 unmodified lines | |||
| 57 | IB_UVERBS_ACCESS_ZERO_BASED = 1 << 5, | 57 | IB_UVERBS_ACCESS_ZERO_BASED = 1 << 5, |
| 58 | IB_UVERBS_ACCESS_ON_DEMAND = 1 << 6, | 58 | IB_UVERBS_ACCESS_ON_DEMAND = 1 << 6, |
| 59 | IB_UVERBS_ACCESS_HUGETLB = 1 << 7, | 59 | IB_UVERBS_ACCESS_HUGETLB = 1 << 7, |
| 60 | IB_UVERBS_ACCESS_FLUSH_GLOBAL = 1 << 8, | ||
| 61 | IB_UVERBS_ACCESS_FLUSH_PERSISTENT = 1 << 9, | ||
| 60 | 62 | ||
| 61 | IB_UVERBS_ACCESS_RELAXED_ORDERING = IB_UVERBS_ACCESS_OPTIONAL_FIRST, | 63 | IB_UVERBS_ACCESS_RELAXED_ORDERING = IB_UVERBS_ACCESS_OPTIONAL_FIRST, |
| 62 | IB_UVERBS_ACCESS_OPTIONAL_RANGE = | 64 | IB_UVERBS_ACCESS_OPTIONAL_RANGE = |
| @@ -251,6 +253,7 @@ enum rdma_driver_id { · 188 unmodified lines | |||
| 251 | RDMA_DRIVER_EFA, | 253 | RDMA_DRIVER_EFA, |
| 252 | RDMA_DRIVER_SIW, | 254 | RDMA_DRIVER_SIW, |
| 253 | RDMA_DRIVER_ERDMA, | 255 | RDMA_DRIVER_ERDMA, |
| 256 | RDMA_DRIVER_MANA, | ||
| 254 | }; | 257 | }; |
| 255 | 258 | ||
| 256 | enum ib_uverbs_gid_type { | 259 | enum ib_uverbs_gid_type { |
| @@ -105,6 +105,18 @@ enum { · 104 unmodified lines | |||
| 105 | IB_USER_VERBS_EX_CMD_MODIFY_CQ | 105 | IB_USER_VERBS_EX_CMD_MODIFY_CQ |
| 106 | }; | 106 | }; |
| 107 | 107 | ||
| 108 | /* see IBA A19.4.1.1 Placement Types */ | ||
| 109 | enum ib_placement_type { | ||
| 110 | IB_FLUSH_GLOBAL = 1U << 0, | ||
| 111 | IB_FLUSH_PERSISTENT = 1U << 1, | ||
| 112 | }; | ||
| 113 | |||
| 114 | /* see IBA A19.4.1.2 Selectivity Level */ | ||
| 115 | enum ib_selectivity_level { | ||
| 116 | IB_FLUSH_RANGE = 0, | ||
| 117 | IB_FLUSH_MR, | ||
| 118 | }; | ||
| 119 | |||
| 108 | /* | 120 | /* |
| 109 | * Make sure that all structs defined in this file remain laid out so | 121 | * Make sure that all structs defined in this file remain laid out so |
| 110 | * that they pack the same way on 32-bit and 64-bit architectures (to | 122 | * that they pack the same way on 32-bit and 64-bit architectures (to |
| @@ -466,6 +478,8 @@ enum ib_uverbs_wc_opcode { · 355 unmodified lines | |||
| 466 | IB_UVERBS_WC_BIND_MW = 5, | 478 | IB_UVERBS_WC_BIND_MW = 5, |
| 467 | IB_UVERBS_WC_LOCAL_INV = 6, | 479 | IB_UVERBS_WC_LOCAL_INV = 6, |
| 468 | IB_UVERBS_WC_TSO = 7, | 480 | IB_UVERBS_WC_TSO = 7, |
| 481 | IB_UVERBS_WC_FLUSH = 8, | ||
| 482 | IB_UVERBS_WC_ATOMIC_WRITE = 9, | ||
| 469 | }; | 483 | }; |
| 470 | 484 | ||
| 471 | struct ib_uverbs_wc { | 485 | struct ib_uverbs_wc { |
| @@ -784,6 +798,8 @@ enum ib_uverbs_wr_opcode { · 312 unmodified lines | |||
| 784 | IB_UVERBS_WR_RDMA_READ_WITH_INV = 11, | 798 | IB_UVERBS_WR_RDMA_READ_WITH_INV = 11, |
| 785 | IB_UVERBS_WR_MASKED_ATOMIC_CMP_AND_SWP = 12, | 799 | IB_UVERBS_WR_MASKED_ATOMIC_CMP_AND_SWP = 12, |
| 786 | IB_UVERBS_WR_MASKED_ATOMIC_FETCH_AND_ADD = 13, | 800 | IB_UVERBS_WR_MASKED_ATOMIC_FETCH_AND_ADD = 13, |
| 801 | IB_UVERBS_WR_FLUSH = 14, | ||
| 802 | IB_UVERBS_WR_ATOMIC_WRITE = 15, | ||
| 787 | /* Review enum ib_wr_opcode before modifying this */ | 803 | /* Review enum ib_wr_opcode before modifying this */ |
| 788 | }; | 804 | }; |
| 789 | 805 | ||
| @@ -1331,6 +1347,11 @@ enum ib_uverbs_device_cap_flags { · 541 unmodified lines | |||
| 1331 | /* Deprecated. Please use IB_UVERBS_RAW_PACKET_CAP_SCATTER_FCS. */ | 1347 | /* Deprecated. Please use IB_UVERBS_RAW_PACKET_CAP_SCATTER_FCS. */ |
| 1332 | IB_UVERBS_DEVICE_RAW_SCATTER_FCS = 1ULL << 34, | 1348 | IB_UVERBS_DEVICE_RAW_SCATTER_FCS = 1ULL << 34, |
| 1333 | IB_UVERBS_DEVICE_PCI_WRITE_END_PADDING = 1ULL << 36, | 1349 | IB_UVERBS_DEVICE_PCI_WRITE_END_PADDING = 1ULL << 36, |
| 1350 | /* Flush placement types */ | ||
| 1351 | IB_UVERBS_DEVICE_FLUSH_GLOBAL = 1ULL << 38, | ||
| 1352 | IB_UVERBS_DEVICE_FLUSH_PERSISTENT = 1ULL << 39, | ||
| 1353 | /* Atomic write attributes */ | ||
| 1354 | IB_UVERBS_DEVICE_ATOMIC_WRITE = 1ULL << 40, | ||
| 1334 | }; | 1355 | }; |
| 1335 | 1356 | ||
| 1336 | enum ib_uverbs_raw_packet_caps { | 1357 | enum ib_uverbs_raw_packet_caps { |
| @@ -0,0 +1,66 @@ | |||
| 1 | /* SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) */ | ||
| 2 | /* | ||
| 3 | * Copyright (c) 2022, Microsoft Corporation. All rights reserved. | ||
| 4 | */ | ||
| 5 | |||
| 6 | #ifndef MANA_ABI_USER_H | ||
| 7 | #define MANA_ABI_USER_H | ||
| 8 | |||
| 9 | #include <linux/types.h> | ||
| 10 | #include <rdma/ib_user_ioctl_verbs.h> | ||
| 11 | |||
| 12 | /* | ||
| 13 | * Increment this value if any changes that break userspace ABI | ||
| 14 | * compatibility are made. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #define MANA_IB_UVERBS_ABI_VERSION 1 | ||
| 18 | |||
| 19 | struct mana_ib_create_cq { | ||
| 20 | __aligned_u64 buf_addr; | ||
| 21 | }; | ||
| 22 | |||
| 23 | struct mana_ib_create_qp { | ||
| 24 | __aligned_u64 sq_buf_addr; | ||
| 25 | __u32 sq_buf_size; | ||
| 26 | __u32 port; | ||
| 27 | }; | ||
| 28 | |||
| 29 | struct mana_ib_create_qp_resp { | ||
| 30 | __u32 sqid; | ||
| 31 | __u32 cqid; | ||
| 32 | __u32 tx_vp_offset; | ||
| 33 | __u32 reserved; | ||
| 34 | }; | ||
| 35 | |||
| 36 | struct mana_ib_create_wq { | ||
| 37 | __aligned_u64 wq_buf_addr; | ||
| 38 | __u32 wq_buf_size; | ||
| 39 | __u32 reserved; | ||
| 40 | }; | ||
| 41 | |||
| 42 | /* RX Hash function flags */ | ||
| 43 | enum mana_ib_rx_hash_function_flags { | ||
| 44 | MANA_IB_RX_HASH_FUNC_TOEPLITZ = 1 << 0, | ||
| 45 | }; | ||
| 46 | |||
| 47 | struct mana_ib_create_qp_rss { | ||
| 48 | __aligned_u64 rx_hash_fields_mask; | ||
| 49 | __u8 rx_hash_function; | ||
| 50 | __u8 reserved[7]; | ||
| 51 | __u32 rx_hash_key_len; | ||
| 52 | __u8 rx_hash_key[40]; | ||
| 53 | __u32 port; | ||
| 54 | }; | ||
| 55 | |||
| 56 | struct rss_resp_entry { | ||
| 57 | __u32 cqid; | ||
| 58 | __u32 wqid; | ||
| 59 | }; | ||
| 60 | |||
| 61 | struct mana_ib_create_qp_rss_resp { | ||
| 62 | __aligned_u64 num_entries; | ||
| 63 | struct rss_resp_entry entries[64]; | ||
| 64 | }; | ||
| 65 | |||
| 66 | #endif | ||
| @@ -82,6 +82,13 @@ struct rxe_send_wr { · 81 unmodified lines | |||
| 82 | __u32 invalidate_rkey; | 82 | __u32 invalidate_rkey; |
| 83 | } ex; | 83 | } ex; |
| 84 | union { | 84 | union { |
| 85 | struct { | ||
| 86 | __aligned_u64 remote_addr; | ||
| 87 | __u32 length; | ||
| 88 | __u32 rkey; | ||
| 89 | __u8 type; | ||
| 90 | __u8 level; | ||
| 91 | } flush; | ||
| 85 | struct { | 92 | struct { |
| 86 | __aligned_u64 remote_addr; | 93 | __aligned_u64 remote_addr; |
| 87 | __u32 rkey; | 94 | __u32 rkey; |
| @@ -146,6 +153,7 @@ struct rxe_dma_info { · 58 unmodified lines | |||
| 146 | __u32 reserved; | 153 | __u32 reserved; |
| 147 | union { | 154 | union { |
| 148 | __DECLARE_FLEX_ARRAY(__u8, inline_data); | 155 | __DECLARE_FLEX_ARRAY(__u8, inline_data); |
| 156 | __DECLARE_FLEX_ARRAY(__u8, atomic_wr); | ||
| 149 | __DECLARE_FLEX_ARRAY(struct rxe_sge, sge); | 157 | __DECLARE_FLEX_ARRAY(struct rxe_sge, sge); |
| 150 | }; | 158 | }; |
| 151 | }; | 159 | }; |