diff options
Diffstat (limited to 'drivers/infiniband/hw')
-rw-r--r-- | drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 8 | ||||
-rw-r--r-- | drivers/infiniband/hw/bnxt_re/qplib_rcfw.h | 11 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/fault.c | 12 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/tid_rdma.c | 76 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx4/mad.c | 4 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx5/main.c | 6 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx5/mem.c | 5 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx5/mlx5_ib.h | 14 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx5/mr.c | 7 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx5/odp.c | 17 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx5/qp.c | 24 |
11 files changed, 103 insertions, 81 deletions
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c index 48b04d2f175f..60c8f76aab33 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | |||
@@ -136,6 +136,13 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw, struct cmdq_base *req, | |||
136 | spin_unlock_irqrestore(&cmdq->lock, flags); | 136 | spin_unlock_irqrestore(&cmdq->lock, flags); |
137 | return -EBUSY; | 137 | return -EBUSY; |
138 | } | 138 | } |
139 | |||
140 | size = req->cmd_size; | ||
141 | /* change the cmd_size to the number of 16byte cmdq unit. | ||
142 | * req->cmd_size is modified here | ||
143 | */ | ||
144 | bnxt_qplib_set_cmd_slots(req); | ||
145 | |||
139 | memset(resp, 0, sizeof(*resp)); | 146 | memset(resp, 0, sizeof(*resp)); |
140 | crsqe->resp = (struct creq_qp_event *)resp; | 147 | crsqe->resp = (struct creq_qp_event *)resp; |
141 | crsqe->resp->cookie = req->cookie; | 148 | crsqe->resp->cookie = req->cookie; |
@@ -150,7 +157,6 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw, struct cmdq_base *req, | |||
150 | 157 | ||
151 | cmdq_ptr = (struct bnxt_qplib_cmdqe **)cmdq->pbl_ptr; | 158 | cmdq_ptr = (struct bnxt_qplib_cmdqe **)cmdq->pbl_ptr; |
152 | preq = (u8 *)req; | 159 | preq = (u8 *)req; |
153 | size = req->cmd_size * BNXT_QPLIB_CMDQE_UNITS; | ||
154 | do { | 160 | do { |
155 | /* Locate the next cmdq slot */ | 161 | /* Locate the next cmdq slot */ |
156 | sw_prod = HWQ_CMP(cmdq->prod, cmdq); | 162 | sw_prod = HWQ_CMP(cmdq->prod, cmdq); |
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h index 2138533bb642..dfeadc192e17 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h +++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h | |||
@@ -55,9 +55,7 @@ | |||
55 | do { \ | 55 | do { \ |
56 | memset(&(req), 0, sizeof((req))); \ | 56 | memset(&(req), 0, sizeof((req))); \ |
57 | (req).opcode = CMDQ_BASE_OPCODE_##CMD; \ | 57 | (req).opcode = CMDQ_BASE_OPCODE_##CMD; \ |
58 | (req).cmd_size = (sizeof((req)) + \ | 58 | (req).cmd_size = sizeof((req)); \ |
59 | BNXT_QPLIB_CMDQE_UNITS - 1) / \ | ||
60 | BNXT_QPLIB_CMDQE_UNITS; \ | ||
61 | (req).flags = cpu_to_le16(cmd_flags); \ | 59 | (req).flags = cpu_to_le16(cmd_flags); \ |
62 | } while (0) | 60 | } while (0) |
63 | 61 | ||
@@ -95,6 +93,13 @@ static inline u32 bnxt_qplib_cmdqe_cnt_per_pg(u32 depth) | |||
95 | BNXT_QPLIB_CMDQE_UNITS); | 93 | BNXT_QPLIB_CMDQE_UNITS); |
96 | } | 94 | } |
97 | 95 | ||
96 | /* Set the cmd_size to a factor of CMDQE unit */ | ||
97 | static inline void bnxt_qplib_set_cmd_slots(struct cmdq_base *req) | ||
98 | { | ||
99 | req->cmd_size = (req->cmd_size + BNXT_QPLIB_CMDQE_UNITS - 1) / | ||
100 | BNXT_QPLIB_CMDQE_UNITS; | ||
101 | } | ||
102 | |||
98 | #define MAX_CMDQ_IDX(depth) ((depth) - 1) | 103 | #define MAX_CMDQ_IDX(depth) ((depth) - 1) |
99 | 104 | ||
100 | static inline u32 bnxt_qplib_max_cmdq_idx_per_pg(u32 depth) | 105 | static inline u32 bnxt_qplib_max_cmdq_idx_per_pg(u32 depth) |
diff --git a/drivers/infiniband/hw/hfi1/fault.c b/drivers/infiniband/hw/hfi1/fault.c index 93613e5def9b..986c12153e62 100644 --- a/drivers/infiniband/hw/hfi1/fault.c +++ b/drivers/infiniband/hw/hfi1/fault.c | |||
@@ -141,12 +141,14 @@ static ssize_t fault_opcodes_write(struct file *file, const char __user *buf, | |||
141 | if (!data) | 141 | if (!data) |
142 | return -ENOMEM; | 142 | return -ENOMEM; |
143 | copy = min(len, datalen - 1); | 143 | copy = min(len, datalen - 1); |
144 | if (copy_from_user(data, buf, copy)) | 144 | if (copy_from_user(data, buf, copy)) { |
145 | return -EFAULT; | 145 | ret = -EFAULT; |
146 | goto free_data; | ||
147 | } | ||
146 | 148 | ||
147 | ret = debugfs_file_get(file->f_path.dentry); | 149 | ret = debugfs_file_get(file->f_path.dentry); |
148 | if (unlikely(ret)) | 150 | if (unlikely(ret)) |
149 | return ret; | 151 | goto free_data; |
150 | ptr = data; | 152 | ptr = data; |
151 | token = ptr; | 153 | token = ptr; |
152 | for (ptr = data; *ptr; ptr = end + 1, token = ptr) { | 154 | for (ptr = data; *ptr; ptr = end + 1, token = ptr) { |
@@ -195,6 +197,7 @@ static ssize_t fault_opcodes_write(struct file *file, const char __user *buf, | |||
195 | ret = len; | 197 | ret = len; |
196 | 198 | ||
197 | debugfs_file_put(file->f_path.dentry); | 199 | debugfs_file_put(file->f_path.dentry); |
200 | free_data: | ||
198 | kfree(data); | 201 | kfree(data); |
199 | return ret; | 202 | return ret; |
200 | } | 203 | } |
@@ -214,7 +217,7 @@ static ssize_t fault_opcodes_read(struct file *file, char __user *buf, | |||
214 | return -ENOMEM; | 217 | return -ENOMEM; |
215 | ret = debugfs_file_get(file->f_path.dentry); | 218 | ret = debugfs_file_get(file->f_path.dentry); |
216 | if (unlikely(ret)) | 219 | if (unlikely(ret)) |
217 | return ret; | 220 | goto free_data; |
218 | bit = find_first_bit(fault->opcodes, bitsize); | 221 | bit = find_first_bit(fault->opcodes, bitsize); |
219 | while (bit < bitsize) { | 222 | while (bit < bitsize) { |
220 | zero = find_next_zero_bit(fault->opcodes, bitsize, bit); | 223 | zero = find_next_zero_bit(fault->opcodes, bitsize, bit); |
@@ -232,6 +235,7 @@ static ssize_t fault_opcodes_read(struct file *file, char __user *buf, | |||
232 | data[size - 1] = '\n'; | 235 | data[size - 1] = '\n'; |
233 | data[size] = '\0'; | 236 | data[size] = '\0'; |
234 | ret = simple_read_from_buffer(buf, len, pos, data, size); | 237 | ret = simple_read_from_buffer(buf, len, pos, data, size); |
238 | free_data: | ||
235 | kfree(data); | 239 | kfree(data); |
236 | return ret; | 240 | return ret; |
237 | } | 241 | } |
diff --git a/drivers/infiniband/hw/hfi1/tid_rdma.c b/drivers/infiniband/hw/hfi1/tid_rdma.c index 996fc298207e..6141f4edc6bf 100644 --- a/drivers/infiniband/hw/hfi1/tid_rdma.c +++ b/drivers/infiniband/hw/hfi1/tid_rdma.c | |||
@@ -2574,18 +2574,9 @@ void hfi1_kern_read_tid_flow_free(struct rvt_qp *qp) | |||
2574 | hfi1_kern_clear_hw_flow(priv->rcd, qp); | 2574 | hfi1_kern_clear_hw_flow(priv->rcd, qp); |
2575 | } | 2575 | } |
2576 | 2576 | ||
2577 | static bool tid_rdma_tid_err(struct hfi1_ctxtdata *rcd, | 2577 | static bool tid_rdma_tid_err(struct hfi1_packet *packet, u8 rcv_type) |
2578 | struct hfi1_packet *packet, u8 rcv_type, | ||
2579 | u8 opcode) | ||
2580 | { | 2578 | { |
2581 | struct rvt_qp *qp = packet->qp; | 2579 | struct rvt_qp *qp = packet->qp; |
2582 | struct hfi1_qp_priv *qpriv = qp->priv; | ||
2583 | u32 ipsn; | ||
2584 | struct ib_other_headers *ohdr = packet->ohdr; | ||
2585 | struct rvt_ack_entry *e; | ||
2586 | struct tid_rdma_request *req; | ||
2587 | struct rvt_dev_info *rdi = ib_to_rvt(qp->ibqp.device); | ||
2588 | u32 i; | ||
2589 | 2580 | ||
2590 | if (rcv_type >= RHF_RCV_TYPE_IB) | 2581 | if (rcv_type >= RHF_RCV_TYPE_IB) |
2591 | goto done; | 2582 | goto done; |
@@ -2602,41 +2593,9 @@ static bool tid_rdma_tid_err(struct hfi1_ctxtdata *rcd, | |||
2602 | if (rcv_type == RHF_RCV_TYPE_EAGER) { | 2593 | if (rcv_type == RHF_RCV_TYPE_EAGER) { |
2603 | hfi1_restart_rc(qp, qp->s_last_psn + 1, 1); | 2594 | hfi1_restart_rc(qp, qp->s_last_psn + 1, 1); |
2604 | hfi1_schedule_send(qp); | 2595 | hfi1_schedule_send(qp); |
2605 | goto done_unlock; | ||
2606 | } | ||
2607 | |||
2608 | /* | ||
2609 | * For TID READ response, error out QP after freeing the tid | ||
2610 | * resources. | ||
2611 | */ | ||
2612 | if (opcode == TID_OP(READ_RESP)) { | ||
2613 | ipsn = mask_psn(be32_to_cpu(ohdr->u.tid_rdma.r_rsp.verbs_psn)); | ||
2614 | if (cmp_psn(ipsn, qp->s_last_psn) > 0 && | ||
2615 | cmp_psn(ipsn, qp->s_psn) < 0) { | ||
2616 | hfi1_kern_read_tid_flow_free(qp); | ||
2617 | spin_unlock(&qp->s_lock); | ||
2618 | rvt_rc_error(qp, IB_WC_LOC_QP_OP_ERR); | ||
2619 | goto done; | ||
2620 | } | ||
2621 | goto done_unlock; | ||
2622 | } | ||
2623 | |||
2624 | /* | ||
2625 | * Error out the qp for TID RDMA WRITE | ||
2626 | */ | ||
2627 | hfi1_kern_clear_hw_flow(qpriv->rcd, qp); | ||
2628 | for (i = 0; i < rvt_max_atomic(rdi); i++) { | ||
2629 | e = &qp->s_ack_queue[i]; | ||
2630 | if (e->opcode == TID_OP(WRITE_REQ)) { | ||
2631 | req = ack_to_tid_req(e); | ||
2632 | hfi1_kern_exp_rcv_clear_all(req); | ||
2633 | } | ||
2634 | } | 2596 | } |
2635 | spin_unlock(&qp->s_lock); | ||
2636 | rvt_rc_error(qp, IB_WC_LOC_LEN_ERR); | ||
2637 | goto done; | ||
2638 | 2597 | ||
2639 | done_unlock: | 2598 | /* Since no payload is delivered, just drop the packet */ |
2640 | spin_unlock(&qp->s_lock); | 2599 | spin_unlock(&qp->s_lock); |
2641 | done: | 2600 | done: |
2642 | return true; | 2601 | return true; |
@@ -2687,12 +2646,12 @@ static bool handle_read_kdeth_eflags(struct hfi1_ctxtdata *rcd, | |||
2687 | u32 fpsn; | 2646 | u32 fpsn; |
2688 | 2647 | ||
2689 | lockdep_assert_held(&qp->r_lock); | 2648 | lockdep_assert_held(&qp->r_lock); |
2649 | spin_lock(&qp->s_lock); | ||
2690 | /* If the psn is out of valid range, drop the packet */ | 2650 | /* If the psn is out of valid range, drop the packet */ |
2691 | if (cmp_psn(ibpsn, qp->s_last_psn) < 0 || | 2651 | if (cmp_psn(ibpsn, qp->s_last_psn) < 0 || |
2692 | cmp_psn(ibpsn, qp->s_psn) > 0) | 2652 | cmp_psn(ibpsn, qp->s_psn) > 0) |
2693 | return ret; | 2653 | goto s_unlock; |
2694 | 2654 | ||
2695 | spin_lock(&qp->s_lock); | ||
2696 | /* | 2655 | /* |
2697 | * Note that NAKs implicitly ACK outstanding SEND and RDMA write | 2656 | * Note that NAKs implicitly ACK outstanding SEND and RDMA write |
2698 | * requests and implicitly NAK RDMA read and atomic requests issued | 2657 | * requests and implicitly NAK RDMA read and atomic requests issued |
@@ -2740,9 +2699,12 @@ static bool handle_read_kdeth_eflags(struct hfi1_ctxtdata *rcd, | |||
2740 | 2699 | ||
2741 | wqe = do_rc_completion(qp, wqe, ibp); | 2700 | wqe = do_rc_completion(qp, wqe, ibp); |
2742 | if (qp->s_acked == qp->s_tail) | 2701 | if (qp->s_acked == qp->s_tail) |
2743 | break; | 2702 | goto s_unlock; |
2744 | } | 2703 | } |
2745 | 2704 | ||
2705 | if (qp->s_acked == qp->s_tail) | ||
2706 | goto s_unlock; | ||
2707 | |||
2746 | /* Handle the eflags for the request */ | 2708 | /* Handle the eflags for the request */ |
2747 | if (wqe->wr.opcode != IB_WR_TID_RDMA_READ) | 2709 | if (wqe->wr.opcode != IB_WR_TID_RDMA_READ) |
2748 | goto s_unlock; | 2710 | goto s_unlock; |
@@ -2922,7 +2884,7 @@ bool hfi1_handle_kdeth_eflags(struct hfi1_ctxtdata *rcd, | |||
2922 | if (lnh == HFI1_LRH_GRH) | 2884 | if (lnh == HFI1_LRH_GRH) |
2923 | goto r_unlock; | 2885 | goto r_unlock; |
2924 | 2886 | ||
2925 | if (tid_rdma_tid_err(rcd, packet, rcv_type, opcode)) | 2887 | if (tid_rdma_tid_err(packet, rcv_type)) |
2926 | goto r_unlock; | 2888 | goto r_unlock; |
2927 | } | 2889 | } |
2928 | 2890 | ||
@@ -2942,8 +2904,15 @@ bool hfi1_handle_kdeth_eflags(struct hfi1_ctxtdata *rcd, | |||
2942 | */ | 2904 | */ |
2943 | spin_lock(&qp->s_lock); | 2905 | spin_lock(&qp->s_lock); |
2944 | qpriv = qp->priv; | 2906 | qpriv = qp->priv; |
2907 | if (qpriv->r_tid_tail == HFI1_QP_WQE_INVALID || | ||
2908 | qpriv->r_tid_tail == qpriv->r_tid_head) | ||
2909 | goto unlock; | ||
2945 | e = &qp->s_ack_queue[qpriv->r_tid_tail]; | 2910 | e = &qp->s_ack_queue[qpriv->r_tid_tail]; |
2911 | if (e->opcode != TID_OP(WRITE_REQ)) | ||
2912 | goto unlock; | ||
2946 | req = ack_to_tid_req(e); | 2913 | req = ack_to_tid_req(e); |
2914 | if (req->comp_seg == req->cur_seg) | ||
2915 | goto unlock; | ||
2947 | flow = &req->flows[req->clear_tail]; | 2916 | flow = &req->flows[req->clear_tail]; |
2948 | trace_hfi1_eflags_err_write(qp, rcv_type, rte, psn); | 2917 | trace_hfi1_eflags_err_write(qp, rcv_type, rte, psn); |
2949 | trace_hfi1_rsp_handle_kdeth_eflags(qp, psn); | 2918 | trace_hfi1_rsp_handle_kdeth_eflags(qp, psn); |
@@ -4509,7 +4478,7 @@ void hfi1_rc_rcv_tid_rdma_ack(struct hfi1_packet *packet) | |||
4509 | struct rvt_swqe *wqe; | 4478 | struct rvt_swqe *wqe; |
4510 | struct tid_rdma_request *req; | 4479 | struct tid_rdma_request *req; |
4511 | struct tid_rdma_flow *flow; | 4480 | struct tid_rdma_flow *flow; |
4512 | u32 aeth, psn, req_psn, ack_psn, resync_psn, ack_kpsn; | 4481 | u32 aeth, psn, req_psn, ack_psn, flpsn, resync_psn, ack_kpsn; |
4513 | unsigned long flags; | 4482 | unsigned long flags; |
4514 | u16 fidx; | 4483 | u16 fidx; |
4515 | 4484 | ||
@@ -4538,6 +4507,9 @@ void hfi1_rc_rcv_tid_rdma_ack(struct hfi1_packet *packet) | |||
4538 | ack_kpsn--; | 4507 | ack_kpsn--; |
4539 | } | 4508 | } |
4540 | 4509 | ||
4510 | if (unlikely(qp->s_acked == qp->s_tail)) | ||
4511 | goto ack_op_err; | ||
4512 | |||
4541 | wqe = rvt_get_swqe_ptr(qp, qp->s_acked); | 4513 | wqe = rvt_get_swqe_ptr(qp, qp->s_acked); |
4542 | 4514 | ||
4543 | if (wqe->wr.opcode != IB_WR_TID_RDMA_WRITE) | 4515 | if (wqe->wr.opcode != IB_WR_TID_RDMA_WRITE) |
@@ -4550,7 +4522,8 @@ void hfi1_rc_rcv_tid_rdma_ack(struct hfi1_packet *packet) | |||
4550 | trace_hfi1_tid_flow_rcv_tid_ack(qp, req->acked_tail, flow); | 4522 | trace_hfi1_tid_flow_rcv_tid_ack(qp, req->acked_tail, flow); |
4551 | 4523 | ||
4552 | /* Drop stale ACK/NAK */ | 4524 | /* Drop stale ACK/NAK */ |
4553 | if (cmp_psn(psn, full_flow_psn(flow, flow->flow_state.spsn)) < 0) | 4525 | if (cmp_psn(psn, full_flow_psn(flow, flow->flow_state.spsn)) < 0 || |
4526 | cmp_psn(req_psn, flow->flow_state.resp_ib_psn) < 0) | ||
4554 | goto ack_op_err; | 4527 | goto ack_op_err; |
4555 | 4528 | ||
4556 | while (cmp_psn(ack_kpsn, | 4529 | while (cmp_psn(ack_kpsn, |
@@ -4712,7 +4685,12 @@ done: | |||
4712 | switch ((aeth >> IB_AETH_CREDIT_SHIFT) & | 4685 | switch ((aeth >> IB_AETH_CREDIT_SHIFT) & |
4713 | IB_AETH_CREDIT_MASK) { | 4686 | IB_AETH_CREDIT_MASK) { |
4714 | case 0: /* PSN sequence error */ | 4687 | case 0: /* PSN sequence error */ |
4688 | if (!req->flows) | ||
4689 | break; | ||
4715 | flow = &req->flows[req->acked_tail]; | 4690 | flow = &req->flows[req->acked_tail]; |
4691 | flpsn = full_flow_psn(flow, flow->flow_state.lpsn); | ||
4692 | if (cmp_psn(psn, flpsn) > 0) | ||
4693 | break; | ||
4716 | trace_hfi1_tid_flow_rcv_tid_ack(qp, req->acked_tail, | 4694 | trace_hfi1_tid_flow_rcv_tid_ack(qp, req->acked_tail, |
4717 | flow); | 4695 | flow); |
4718 | req->r_ack_psn = mask_psn(be32_to_cpu(ohdr->bth[2])); | 4696 | req->r_ack_psn = mask_psn(be32_to_cpu(ohdr->bth[2])); |
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c index 68c951491a08..57079110af9b 100644 --- a/drivers/infiniband/hw/mlx4/mad.c +++ b/drivers/infiniband/hw/mlx4/mad.c | |||
@@ -1677,8 +1677,6 @@ tx_err: | |||
1677 | tx_buf_size, DMA_TO_DEVICE); | 1677 | tx_buf_size, DMA_TO_DEVICE); |
1678 | kfree(tun_qp->tx_ring[i].buf.addr); | 1678 | kfree(tun_qp->tx_ring[i].buf.addr); |
1679 | } | 1679 | } |
1680 | kfree(tun_qp->tx_ring); | ||
1681 | tun_qp->tx_ring = NULL; | ||
1682 | i = MLX4_NUM_TUNNEL_BUFS; | 1680 | i = MLX4_NUM_TUNNEL_BUFS; |
1683 | err: | 1681 | err: |
1684 | while (i > 0) { | 1682 | while (i > 0) { |
@@ -1687,6 +1685,8 @@ err: | |||
1687 | rx_buf_size, DMA_FROM_DEVICE); | 1685 | rx_buf_size, DMA_FROM_DEVICE); |
1688 | kfree(tun_qp->ring[i].addr); | 1686 | kfree(tun_qp->ring[i].addr); |
1689 | } | 1687 | } |
1688 | kfree(tun_qp->tx_ring); | ||
1689 | tun_qp->tx_ring = NULL; | ||
1690 | kfree(tun_qp->ring); | 1690 | kfree(tun_qp->ring); |
1691 | tun_qp->ring = NULL; | 1691 | tun_qp->ring = NULL; |
1692 | return -ENOMEM; | 1692 | return -ENOMEM; |
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index e12a4404096b..0569bcab02d4 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c | |||
@@ -1023,7 +1023,7 @@ static int mlx5_ib_query_device(struct ib_device *ibdev, | |||
1023 | props->timestamp_mask = 0x7FFFFFFFFFFFFFFFULL; | 1023 | props->timestamp_mask = 0x7FFFFFFFFFFFFFFFULL; |
1024 | 1024 | ||
1025 | if (IS_ENABLED(CONFIG_INFINIBAND_ON_DEMAND_PAGING)) { | 1025 | if (IS_ENABLED(CONFIG_INFINIBAND_ON_DEMAND_PAGING)) { |
1026 | if (MLX5_CAP_GEN(mdev, pg)) | 1026 | if (dev->odp_caps.general_caps & IB_ODP_SUPPORT) |
1027 | props->device_cap_flags |= IB_DEVICE_ON_DEMAND_PAGING; | 1027 | props->device_cap_flags |= IB_DEVICE_ON_DEMAND_PAGING; |
1028 | props->odp_caps = dev->odp_caps; | 1028 | props->odp_caps = dev->odp_caps; |
1029 | } | 1029 | } |
@@ -6139,6 +6139,8 @@ static int mlx5_ib_stage_init_init(struct mlx5_ib_dev *dev) | |||
6139 | dev->port[i].roce.last_port_state = IB_PORT_DOWN; | 6139 | dev->port[i].roce.last_port_state = IB_PORT_DOWN; |
6140 | } | 6140 | } |
6141 | 6141 | ||
6142 | mlx5_ib_internal_fill_odp_caps(dev); | ||
6143 | |||
6142 | err = mlx5_ib_init_multiport_master(dev); | 6144 | err = mlx5_ib_init_multiport_master(dev); |
6143 | if (err) | 6145 | if (err) |
6144 | return err; | 6146 | return err; |
@@ -6563,8 +6565,6 @@ static void mlx5_ib_stage_dev_res_cleanup(struct mlx5_ib_dev *dev) | |||
6563 | 6565 | ||
6564 | static int mlx5_ib_stage_odp_init(struct mlx5_ib_dev *dev) | 6566 | static int mlx5_ib_stage_odp_init(struct mlx5_ib_dev *dev) |
6565 | { | 6567 | { |
6566 | mlx5_ib_internal_fill_odp_caps(dev); | ||
6567 | |||
6568 | return mlx5_ib_odp_init_one(dev); | 6568 | return mlx5_ib_odp_init_one(dev); |
6569 | } | 6569 | } |
6570 | 6570 | ||
diff --git a/drivers/infiniband/hw/mlx5/mem.c b/drivers/infiniband/hw/mlx5/mem.c index fe1a76d8531c..a40e0abf2338 100644 --- a/drivers/infiniband/hw/mlx5/mem.c +++ b/drivers/infiniband/hw/mlx5/mem.c | |||
@@ -57,9 +57,10 @@ void mlx5_ib_cont_pages(struct ib_umem *umem, u64 addr, | |||
57 | int entry; | 57 | int entry; |
58 | 58 | ||
59 | if (umem->is_odp) { | 59 | if (umem->is_odp) { |
60 | unsigned int page_shift = to_ib_umem_odp(umem)->page_shift; | 60 | struct ib_umem_odp *odp = to_ib_umem_odp(umem); |
61 | unsigned int page_shift = odp->page_shift; | ||
61 | 62 | ||
62 | *ncont = ib_umem_page_count(umem); | 63 | *ncont = ib_umem_odp_num_pages(odp); |
63 | *count = *ncont << (page_shift - PAGE_SHIFT); | 64 | *count = *ncont << (page_shift - PAGE_SHIFT); |
64 | *shift = page_shift; | 65 | *shift = page_shift; |
65 | if (order) | 66 | if (order) |
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h index f6a53455bf8b..9ae587b74b12 100644 --- a/drivers/infiniband/hw/mlx5/mlx5_ib.h +++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h | |||
@@ -1475,4 +1475,18 @@ int bfregn_to_uar_index(struct mlx5_ib_dev *dev, | |||
1475 | bool dyn_bfreg); | 1475 | bool dyn_bfreg); |
1476 | 1476 | ||
1477 | int mlx5_ib_qp_set_counter(struct ib_qp *qp, struct rdma_counter *counter); | 1477 | int mlx5_ib_qp_set_counter(struct ib_qp *qp, struct rdma_counter *counter); |
1478 | |||
1479 | static inline bool mlx5_ib_can_use_umr(struct mlx5_ib_dev *dev, | ||
1480 | bool do_modify_atomic) | ||
1481 | { | ||
1482 | if (MLX5_CAP_GEN(dev->mdev, umr_modify_entity_size_disabled)) | ||
1483 | return false; | ||
1484 | |||
1485 | if (do_modify_atomic && | ||
1486 | MLX5_CAP_GEN(dev->mdev, atomic) && | ||
1487 | MLX5_CAP_GEN(dev->mdev, umr_modify_atomic_disabled)) | ||
1488 | return false; | ||
1489 | |||
1490 | return true; | ||
1491 | } | ||
1478 | #endif /* MLX5_IB_H */ | 1492 | #endif /* MLX5_IB_H */ |
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c index b74fad08412f..3401f5f6792e 100644 --- a/drivers/infiniband/hw/mlx5/mr.c +++ b/drivers/infiniband/hw/mlx5/mr.c | |||
@@ -1293,9 +1293,7 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, | |||
1293 | if (err < 0) | 1293 | if (err < 0) |
1294 | return ERR_PTR(err); | 1294 | return ERR_PTR(err); |
1295 | 1295 | ||
1296 | use_umr = !MLX5_CAP_GEN(dev->mdev, umr_modify_entity_size_disabled) && | 1296 | use_umr = mlx5_ib_can_use_umr(dev, true); |
1297 | (!MLX5_CAP_GEN(dev->mdev, umr_modify_atomic_disabled) || | ||
1298 | !MLX5_CAP_GEN(dev->mdev, atomic)); | ||
1299 | 1297 | ||
1300 | if (order <= mr_cache_max_order(dev) && use_umr) { | 1298 | if (order <= mr_cache_max_order(dev) && use_umr) { |
1301 | mr = alloc_mr_from_cache(pd, umem, virt_addr, length, ncont, | 1299 | mr = alloc_mr_from_cache(pd, umem, virt_addr, length, ncont, |
@@ -1448,7 +1446,8 @@ int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start, | |||
1448 | goto err; | 1446 | goto err; |
1449 | } | 1447 | } |
1450 | 1448 | ||
1451 | if (flags & IB_MR_REREG_TRANS && !use_umr_mtt_update(mr, addr, len)) { | 1449 | if (!mlx5_ib_can_use_umr(dev, true) || |
1450 | (flags & IB_MR_REREG_TRANS && !use_umr_mtt_update(mr, addr, len))) { | ||
1452 | /* | 1451 | /* |
1453 | * UMR can't be used - MKey needs to be replaced. | 1452 | * UMR can't be used - MKey needs to be replaced. |
1454 | */ | 1453 | */ |
diff --git a/drivers/infiniband/hw/mlx5/odp.c b/drivers/infiniband/hw/mlx5/odp.c index 1d257d1b3b0d..0a59912a4cef 100644 --- a/drivers/infiniband/hw/mlx5/odp.c +++ b/drivers/infiniband/hw/mlx5/odp.c | |||
@@ -301,7 +301,8 @@ void mlx5_ib_internal_fill_odp_caps(struct mlx5_ib_dev *dev) | |||
301 | 301 | ||
302 | memset(caps, 0, sizeof(*caps)); | 302 | memset(caps, 0, sizeof(*caps)); |
303 | 303 | ||
304 | if (!MLX5_CAP_GEN(dev->mdev, pg)) | 304 | if (!MLX5_CAP_GEN(dev->mdev, pg) || |
305 | !mlx5_ib_can_use_umr(dev, true)) | ||
305 | return; | 306 | return; |
306 | 307 | ||
307 | caps->general_caps = IB_ODP_SUPPORT; | 308 | caps->general_caps = IB_ODP_SUPPORT; |
@@ -355,7 +356,8 @@ void mlx5_ib_internal_fill_odp_caps(struct mlx5_ib_dev *dev) | |||
355 | 356 | ||
356 | if (MLX5_CAP_GEN(dev->mdev, fixed_buffer_size) && | 357 | if (MLX5_CAP_GEN(dev->mdev, fixed_buffer_size) && |
357 | MLX5_CAP_GEN(dev->mdev, null_mkey) && | 358 | MLX5_CAP_GEN(dev->mdev, null_mkey) && |
358 | MLX5_CAP_GEN(dev->mdev, umr_extended_translation_offset)) | 359 | MLX5_CAP_GEN(dev->mdev, umr_extended_translation_offset) && |
360 | !MLX5_CAP_GEN(dev->mdev, umr_indirect_mkey_disabled)) | ||
359 | caps->general_caps |= IB_ODP_SUPPORT_IMPLICIT; | 361 | caps->general_caps |= IB_ODP_SUPPORT_IMPLICIT; |
360 | 362 | ||
361 | return; | 363 | return; |
@@ -1622,8 +1624,10 @@ int mlx5_ib_odp_init_one(struct mlx5_ib_dev *dev) | |||
1622 | { | 1624 | { |
1623 | int ret = 0; | 1625 | int ret = 0; |
1624 | 1626 | ||
1625 | if (dev->odp_caps.general_caps & IB_ODP_SUPPORT) | 1627 | if (!(dev->odp_caps.general_caps & IB_ODP_SUPPORT)) |
1626 | ib_set_device_ops(&dev->ib_dev, &mlx5_ib_dev_odp_ops); | 1628 | return ret; |
1629 | |||
1630 | ib_set_device_ops(&dev->ib_dev, &mlx5_ib_dev_odp_ops); | ||
1627 | 1631 | ||
1628 | if (dev->odp_caps.general_caps & IB_ODP_SUPPORT_IMPLICIT) { | 1632 | if (dev->odp_caps.general_caps & IB_ODP_SUPPORT_IMPLICIT) { |
1629 | ret = mlx5_cmd_null_mkey(dev->mdev, &dev->null_mkey); | 1633 | ret = mlx5_cmd_null_mkey(dev->mdev, &dev->null_mkey); |
@@ -1633,9 +1637,6 @@ int mlx5_ib_odp_init_one(struct mlx5_ib_dev *dev) | |||
1633 | } | 1637 | } |
1634 | } | 1638 | } |
1635 | 1639 | ||
1636 | if (!MLX5_CAP_GEN(dev->mdev, pg)) | ||
1637 | return ret; | ||
1638 | |||
1639 | ret = mlx5_ib_create_pf_eq(dev, &dev->odp_pf_eq); | 1640 | ret = mlx5_ib_create_pf_eq(dev, &dev->odp_pf_eq); |
1640 | 1641 | ||
1641 | return ret; | 1642 | return ret; |
@@ -1643,7 +1644,7 @@ int mlx5_ib_odp_init_one(struct mlx5_ib_dev *dev) | |||
1643 | 1644 | ||
1644 | void mlx5_ib_odp_cleanup_one(struct mlx5_ib_dev *dev) | 1645 | void mlx5_ib_odp_cleanup_one(struct mlx5_ib_dev *dev) |
1645 | { | 1646 | { |
1646 | if (!MLX5_CAP_GEN(dev->mdev, pg)) | 1647 | if (!(dev->odp_caps.general_caps & IB_ODP_SUPPORT)) |
1647 | return; | 1648 | return; |
1648 | 1649 | ||
1649 | mlx5_ib_destroy_pf_eq(dev, &dev->odp_pf_eq); | 1650 | mlx5_ib_destroy_pf_eq(dev, &dev->odp_pf_eq); |
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index 379328b2598f..72869ff4a334 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c | |||
@@ -4162,7 +4162,7 @@ static u64 get_xlt_octo(u64 bytes) | |||
4162 | MLX5_IB_UMR_OCTOWORD; | 4162 | MLX5_IB_UMR_OCTOWORD; |
4163 | } | 4163 | } |
4164 | 4164 | ||
4165 | static __be64 frwr_mkey_mask(void) | 4165 | static __be64 frwr_mkey_mask(bool atomic) |
4166 | { | 4166 | { |
4167 | u64 result; | 4167 | u64 result; |
4168 | 4168 | ||
@@ -4175,10 +4175,12 @@ static __be64 frwr_mkey_mask(void) | |||
4175 | MLX5_MKEY_MASK_LW | | 4175 | MLX5_MKEY_MASK_LW | |
4176 | MLX5_MKEY_MASK_RR | | 4176 | MLX5_MKEY_MASK_RR | |
4177 | MLX5_MKEY_MASK_RW | | 4177 | MLX5_MKEY_MASK_RW | |
4178 | MLX5_MKEY_MASK_A | | ||
4179 | MLX5_MKEY_MASK_SMALL_FENCE | | 4178 | MLX5_MKEY_MASK_SMALL_FENCE | |
4180 | MLX5_MKEY_MASK_FREE; | 4179 | MLX5_MKEY_MASK_FREE; |
4181 | 4180 | ||
4181 | if (atomic) | ||
4182 | result |= MLX5_MKEY_MASK_A; | ||
4183 | |||
4182 | return cpu_to_be64(result); | 4184 | return cpu_to_be64(result); |
4183 | } | 4185 | } |
4184 | 4186 | ||
@@ -4204,7 +4206,7 @@ static __be64 sig_mkey_mask(void) | |||
4204 | } | 4206 | } |
4205 | 4207 | ||
4206 | static void set_reg_umr_seg(struct mlx5_wqe_umr_ctrl_seg *umr, | 4208 | static void set_reg_umr_seg(struct mlx5_wqe_umr_ctrl_seg *umr, |
4207 | struct mlx5_ib_mr *mr, u8 flags) | 4209 | struct mlx5_ib_mr *mr, u8 flags, bool atomic) |
4208 | { | 4210 | { |
4209 | int size = (mr->ndescs + mr->meta_ndescs) * mr->desc_size; | 4211 | int size = (mr->ndescs + mr->meta_ndescs) * mr->desc_size; |
4210 | 4212 | ||
@@ -4212,7 +4214,7 @@ static void set_reg_umr_seg(struct mlx5_wqe_umr_ctrl_seg *umr, | |||
4212 | 4214 | ||
4213 | umr->flags = flags; | 4215 | umr->flags = flags; |
4214 | umr->xlt_octowords = cpu_to_be16(get_xlt_octo(size)); | 4216 | umr->xlt_octowords = cpu_to_be16(get_xlt_octo(size)); |
4215 | umr->mkey_mask = frwr_mkey_mask(); | 4217 | umr->mkey_mask = frwr_mkey_mask(atomic); |
4216 | } | 4218 | } |
4217 | 4219 | ||
4218 | static void set_linv_umr_seg(struct mlx5_wqe_umr_ctrl_seg *umr) | 4220 | static void set_linv_umr_seg(struct mlx5_wqe_umr_ctrl_seg *umr) |
@@ -4811,10 +4813,22 @@ static int set_reg_wr(struct mlx5_ib_qp *qp, | |||
4811 | { | 4813 | { |
4812 | struct mlx5_ib_mr *mr = to_mmr(wr->mr); | 4814 | struct mlx5_ib_mr *mr = to_mmr(wr->mr); |
4813 | struct mlx5_ib_pd *pd = to_mpd(qp->ibqp.pd); | 4815 | struct mlx5_ib_pd *pd = to_mpd(qp->ibqp.pd); |
4816 | struct mlx5_ib_dev *dev = to_mdev(pd->ibpd.device); | ||
4814 | int mr_list_size = (mr->ndescs + mr->meta_ndescs) * mr->desc_size; | 4817 | int mr_list_size = (mr->ndescs + mr->meta_ndescs) * mr->desc_size; |
4815 | bool umr_inline = mr_list_size <= MLX5_IB_SQ_UMR_INLINE_THRESHOLD; | 4818 | bool umr_inline = mr_list_size <= MLX5_IB_SQ_UMR_INLINE_THRESHOLD; |
4819 | bool atomic = wr->access & IB_ACCESS_REMOTE_ATOMIC; | ||
4816 | u8 flags = 0; | 4820 | u8 flags = 0; |
4817 | 4821 | ||
4822 | if (!mlx5_ib_can_use_umr(dev, atomic)) { | ||
4823 | mlx5_ib_warn(to_mdev(qp->ibqp.device), | ||
4824 | "Fast update of %s for MR is disabled\n", | ||
4825 | (MLX5_CAP_GEN(dev->mdev, | ||
4826 | umr_modify_entity_size_disabled)) ? | ||
4827 | "entity size" : | ||
4828 | "atomic access"); | ||
4829 | return -EINVAL; | ||
4830 | } | ||
4831 | |||
4818 | if (unlikely(wr->wr.send_flags & IB_SEND_INLINE)) { | 4832 | if (unlikely(wr->wr.send_flags & IB_SEND_INLINE)) { |
4819 | mlx5_ib_warn(to_mdev(qp->ibqp.device), | 4833 | mlx5_ib_warn(to_mdev(qp->ibqp.device), |
4820 | "Invalid IB_SEND_INLINE send flag\n"); | 4834 | "Invalid IB_SEND_INLINE send flag\n"); |
@@ -4826,7 +4840,7 @@ static int set_reg_wr(struct mlx5_ib_qp *qp, | |||
4826 | if (umr_inline) | 4840 | if (umr_inline) |
4827 | flags |= MLX5_UMR_INLINE; | 4841 | flags |= MLX5_UMR_INLINE; |
4828 | 4842 | ||
4829 | set_reg_umr_seg(*seg, mr, flags); | 4843 | set_reg_umr_seg(*seg, mr, flags, atomic); |
4830 | *seg += sizeof(struct mlx5_wqe_umr_ctrl_seg); | 4844 | *seg += sizeof(struct mlx5_wqe_umr_ctrl_seg); |
4831 | *size += sizeof(struct mlx5_wqe_umr_ctrl_seg) / 16; | 4845 | *size += sizeof(struct mlx5_wqe_umr_ctrl_seg) / 16; |
4832 | handle_post_send_edge(&qp->sq, seg, *size, cur_edge); | 4846 | handle_post_send_edge(&qp->sq, seg, *size, cur_edge); |