From 30e1b3441a82e164003904cf1e2724e3484213be Mon Sep 17 00:00:00 2001 From: Tatyana Nikolova Date: Mon, 9 Oct 2017 10:11:21 -0700 Subject: [PATCH] Fixes for i40iw which have been included in kernels 4.12 and 4.13 Signed-off-by: Tatyana Nikolova --- ...Fix-device-initialization-error-path.patch | 75 ++++++ ...RDMA-i40iw-Remove-MSS-change-support.patch | 168 ++++++++++++ ...uplicated-code-for-different-branche.patch | 36 +++ ...e-deprecated-create_singlethread_wor.patch | 37 +++ ...-i40iw-Fix-order-of-cleanup-in-close.patch | 51 ++++ ...o-not-poll-CCQ-after-it-is-destroyed.patch | 32 +++ ...wdev-reset-during-PCI-function-reset.patch | 213 ++++++++++++++++ ...ease-cm_id-ref-on-PCI-function-reset.patch | 45 ++++ ...-resources-on-CQP-destroy-QP-failure.patch | 39 +++ ...168-i40iw-Add-missing-memory-barrier.patch | 31 +++ .../0169-i40iw-Update-list-correctly.patch | 33 +++ ...d-memory-leak-of-CQP-request-objects.patch | 126 +++++++++ ...ee-QP-PBLEs-when-the-QP-is-destroyed.patch | 95 +++++++ ...iw-Fix-error-code-in-i40iw_create_cq.patch | 36 +++ ...-parsing-of-query-commit-FPM-buffers.patch | 218 ++++++++++++++++ .../0174-i40iw-Correct-variable-names.patch | 63 +++++ ...75-i40iw-Fix-typecast-of-tcp_seq_num.patch | 31 +++ ...Use-correct-alignment-for-CQ0-memory.patch | 31 +++ ...potential-fcn_id_array-out-of-bounds.patch | 31 +++ .../0178-i40iw-Simplify-code.patch | 45 ++++ ...iw-Fixes-for-static-checker-warnings.patch | 58 +++++ ...pelling-mistake-allloc_buf-alloc_buf.patch | 42 +++ ...0181-i40iw-Improve-CQP-timeout-logic.patch | 138 ++++++++++ ...82-RDMA-i40iw-Remove-unused-argument.patch | 84 ++++++ ...MA-i40iw-use-designated-initializers.patch | 240 ++++++++++++++++++ ...184-i40iw-make-some-structures-const.patch | 47 ++++ 26 files changed, 2045 insertions(+) create mode 100644 linux-next-cherry-picks/0159-RDMA-i40iw-Fix-device-initialization-error-path.patch create mode 100644 linux-next-cherry-picks/0160-RDMA-i40iw-Remove-MSS-change-support.patch create mode 100644 linux-next-cherry-picks/0161-RDMA-i40iw-fix-duplicated-code-for-different-branche.patch create mode 100644 linux-next-cherry-picks/0162-i40iw_main-Remove-deprecated-create_singlethread_wor.patch create mode 100644 linux-next-cherry-picks/0163-i40iw-Fix-order-of-cleanup-in-close.patch create mode 100644 linux-next-cherry-picks/0164-i40iw-Do-not-poll-CCQ-after-it-is-destroyed.patch create mode 100644 linux-next-cherry-picks/0165-i40iw-Utilize-iwdev-reset-during-PCI-function-reset.patch create mode 100644 linux-next-cherry-picks/0166-i40iw-Release-cm_id-ref-on-PCI-function-reset.patch create mode 100644 linux-next-cherry-picks/0167-i40iw-Free-QP-resources-on-CQP-destroy-QP-failure.patch create mode 100644 linux-next-cherry-picks/0168-i40iw-Add-missing-memory-barrier.patch create mode 100644 linux-next-cherry-picks/0169-i40iw-Update-list-correctly.patch create mode 100644 linux-next-cherry-picks/0170-i40iw-Avoid-memory-leak-of-CQP-request-objects.patch create mode 100644 linux-next-cherry-picks/0171-i40iw-Free-QP-PBLEs-when-the-QP-is-destroyed.patch create mode 100644 linux-next-cherry-picks/0172-IB-i40iw-Fix-error-code-in-i40iw_create_cq.patch create mode 100644 linux-next-cherry-picks/0173-i40iw-Fix-parsing-of-query-commit-FPM-buffers.patch create mode 100644 linux-next-cherry-picks/0174-i40iw-Correct-variable-names.patch create mode 100644 linux-next-cherry-picks/0175-i40iw-Fix-typecast-of-tcp_seq_num.patch create mode 100644 linux-next-cherry-picks/0176-i40iw-Use-correct-alignment-for-CQ0-memory.patch create mode 100644 linux-next-cherry-picks/0177-i40iw-Fix-potential-fcn_id_array-out-of-bounds.patch create mode 100644 linux-next-cherry-picks/0178-i40iw-Simplify-code.patch create mode 100644 linux-next-cherry-picks/0179-i40iw-Fixes-for-static-checker-warnings.patch create mode 100644 linux-next-cherry-picks/0180-i40iw-fix-spelling-mistake-allloc_buf-alloc_buf.patch create mode 100644 linux-next-cherry-picks/0181-i40iw-Improve-CQP-timeout-logic.patch create mode 100644 linux-next-cherry-picks/0182-RDMA-i40iw-Remove-unused-argument.patch create mode 100644 linux-next-cherry-picks/0183-RDMA-i40iw-use-designated-initializers.patch create mode 100644 linux-next-cherry-picks/0184-i40iw-make-some-structures-const.patch diff --git a/linux-next-cherry-picks/0159-RDMA-i40iw-Fix-device-initialization-error-path.patch b/linux-next-cherry-picks/0159-RDMA-i40iw-Fix-device-initialization-error-path.patch new file mode 100644 index 0000000..02350d4 --- /dev/null +++ b/linux-next-cherry-picks/0159-RDMA-i40iw-Fix-device-initialization-error-path.patch @@ -0,0 +1,75 @@ +From c0c643e16f9b00332cbbf3954556652dfa4ed5a3 Mon Sep 17 00:00:00 2001 +From: Mustafa Ismail +Date: Wed, 10 May 2017 23:32:14 -0500 +Subject: [PATCH 03583/13040] RDMA/i40iw: Fix device initialization error path + +Some error paths in i40iw_initialize_dev are doing +additional and unnecessary work before exiting. +Correctly free resources allocated prior to error +and return with correct status code. + +Signed-off-by: Mustafa Ismail +Signed-off-by: Henry Orosco +Signed-off-by: Doug Ledford +--- + drivers/infiniband/hw/i40iw/i40iw_main.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +diff --git a/drivers/infiniband/hw/i40iw/i40iw_main.c b/drivers/infiniband/hw/i40iw/i40iw_main.c +index 2728af3..a3f18a2 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_main.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_main.c +@@ -1319,13 +1319,13 @@ static enum i40iw_status_code i40iw_initialize_dev(struct i40iw_device *iwdev, + status = i40iw_obj_aligned_mem(iwdev, &mem, I40IW_QUERY_FPM_BUF_SIZE, + I40IW_FPM_QUERY_BUF_ALIGNMENT_MASK); + if (status) +- goto exit; ++ goto error; + info.fpm_query_buf_pa = mem.pa; + info.fpm_query_buf = mem.va; + status = i40iw_obj_aligned_mem(iwdev, &mem, I40IW_COMMIT_FPM_BUF_SIZE, + I40IW_FPM_COMMIT_BUF_ALIGNMENT_MASK); + if (status) +- goto exit; ++ goto error; + info.fpm_commit_buf_pa = mem.pa; + info.fpm_commit_buf = mem.va; + info.hmc_fn_id = ldev->fid; +@@ -1347,11 +1347,9 @@ static enum i40iw_status_code i40iw_initialize_dev(struct i40iw_device *iwdev, + info.exception_lan_queue = 1; + info.vchnl_send = i40iw_virtchnl_send; + status = i40iw_device_init(&iwdev->sc_dev, &info); +-exit: +- if (status) { +- kfree(iwdev->hmc_info_mem); +- iwdev->hmc_info_mem = NULL; +- } ++ ++ if (status) ++ goto error; + memset(&vsi_info, 0, sizeof(vsi_info)); + vsi_info.dev = &iwdev->sc_dev; + vsi_info.back_vsi = (void *)iwdev; +@@ -1362,11 +1360,19 @@ static enum i40iw_status_code i40iw_initialize_dev(struct i40iw_device *iwdev, + memset(&stats_info, 0, sizeof(stats_info)); + stats_info.fcn_id = ldev->fid; + stats_info.pestat = kzalloc(sizeof(*stats_info.pestat), GFP_KERNEL); ++ if (!stats_info.pestat) { ++ status = I40IW_ERR_NO_MEMORY; ++ goto error; ++ } + stats_info.stats_initialize = true; + if (stats_info.pestat) + i40iw_vsi_stats_init(&iwdev->vsi, &stats_info); + } + return status; ++error: ++ kfree(iwdev->hmc_info_mem); ++ iwdev->hmc_info_mem = NULL; ++ return status; + } + + /** +-- +2.1.3 + diff --git a/linux-next-cherry-picks/0160-RDMA-i40iw-Remove-MSS-change-support.patch b/linux-next-cherry-picks/0160-RDMA-i40iw-Remove-MSS-change-support.patch new file mode 100644 index 0000000..8a7aae6 --- /dev/null +++ b/linux-next-cherry-picks/0160-RDMA-i40iw-Remove-MSS-change-support.patch @@ -0,0 +1,168 @@ +From f300ba2d1ef1cb8411daa5e1ae44acfa7b88236c Mon Sep 17 00:00:00 2001 +From: Shiraz Saleem +Date: Fri, 19 May 2017 16:14:02 -0500 +Subject: [PATCH 03584/13040] RDMA/i40iw: Remove MSS change support + +MSS change on active QPs is not supported. Store new MSS +value for new QPs only. Remove code to modify MSS on the fly. +This also resolves a crash on QP modify to QP 0. + +BUG: unable to handle kernel NULL pointer dereference at 0000000000000008 +IP: i40iw_sc_qp_modify+0x22/0x280 [i40iw] +Oops: 0000 [#1] SMP KASAN +CPU: 2 PID: 1236 Comm: kworker/u16:4 Not tainted 4.12.0-rc1 #5 +Hardware name: Gigabyte Technology Co., Ltd. To be filled by O.E.M./Q87M-D2H, +BIOS F7 01/17/2014 +Workqueue: l2params i40iw_l2params_worker [i40iw] +task: ffff88070f5a9b40 task.stack: ffff88070f5a0000 +RIP: 0010:i40iw_sc_qp_modify+0x22/0x280 [i40iw] +... +Call Trace: +i40iw_exec_cqp_cmd+0x2ce/0x410 [i40iw] +? _raw_spin_lock_irqsave+0x6f/0x80 +? i40iw_process_cqp_cmd+0x1d/0x80 [i40iw] +i40iw_process_cqp_cmd+0x7c/0x80 [i40iw] +i40iw_handle_cqp_op+0x2f/0x200 [i40iw] +? trace_hardirqs_off+0xd/0x10 +? _raw_spin_unlock_irqrestore+0x46/0x50 +i40iw_hw_modify_qp+0x5e/0x90 [i40iw] +i40iw_qp_mss_modify+0x52/0x60 [i40iw] +i40iw_change_l2params+0x145/0x160 [i40iw] +i40iw_l2params_worker+0x1f/0x40 [i40iw] +process_one_work+0x1f5/0x650 +? process_one_work+0x161/0x650 +worker_thread+0x48/0x3b0 +kthread+0x112/0x150 +? process_one_work+0x650/0x650 +? kthread_create_on_node+0x40/0x40 +ret_from_fork+0x2e/0x40 +Code: 2e 0f 1f 84 00 00 00 00 00 55 48 89 e5 41 56 41 55 41 89 cd 41 54 49 89 fc +53 48 89 f3 48 89 d6 48 83 ec 08 48 8b 87 10 01 00 00 <48> 8b 40 08 4c 8b b0 40 04 +00 00 4c 89 f7 e8 1b e5 ff ff 48 85 +RIP: i40iw_sc_qp_modify+0x22/0x280 [i40iw] RSP: ffff88070f5a7c28 +CR2: 0000000000000008 +---[ end trace 77a405931e296060 ]--- + +Reported-by: Stefan Assmann +Signed-off-by: Shiraz Saleem +Signed-off-by: Doug Ledford +--- + drivers/infiniband/hw/i40iw/i40iw_ctrl.c | 12 +----------- + drivers/infiniband/hw/i40iw/i40iw_osdep.h | 1 - + drivers/infiniband/hw/i40iw/i40iw_type.h | 2 -- + drivers/infiniband/hw/i40iw/i40iw_utils.c | 17 ----------------- + 4 files changed, 1 insertion(+), 31 deletions(-) + +diff --git a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c +index f82483b..a027e20 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c +@@ -285,28 +285,20 @@ void i40iw_change_l2params(struct i40iw_sc_vsi *vsi, struct i40iw_l2params *l2pa + struct i40iw_sc_dev *dev = vsi->dev; + struct i40iw_sc_qp *qp = NULL; + bool qs_handle_change = false; +- bool mss_change = false; + unsigned long flags; + u16 qs_handle; + int i; + +- if (vsi->mss != l2params->mss) { +- mss_change = true; +- vsi->mss = l2params->mss; +- } ++ vsi->mss = l2params->mss; + + i40iw_fill_qos_list(l2params->qs_handle_list); + for (i = 0; i < I40IW_MAX_USER_PRIORITY; i++) { + qs_handle = l2params->qs_handle_list[i]; + if (vsi->qos[i].qs_handle != qs_handle) + qs_handle_change = true; +- else if (!mss_change) +- continue; /* no MSS nor qs handle change */ + spin_lock_irqsave(&vsi->qos[i].lock, flags); + qp = i40iw_get_qp(&vsi->qos[i].qplist, qp); + while (qp) { +- if (mss_change) +- i40iw_qp_mss_modify(dev, qp); + if (qs_handle_change) { + qp->qs_handle = qs_handle; + /* issue cqp suspend command */ +@@ -2395,7 +2387,6 @@ static enum i40iw_status_code i40iw_sc_qp_modify( + + set_64bit_val(wqe, + 8, +- LS_64(info->new_mss, I40IW_CQPSQ_QP_NEWMSS) | + LS_64(term_len, I40IW_CQPSQ_QP_TERMLEN)); + + set_64bit_val(wqe, 16, qp->hw_host_ctx_pa); +@@ -2410,7 +2401,6 @@ static enum i40iw_status_code i40iw_sc_qp_modify( + LS_64(info->cq_num_valid, I40IW_CQPSQ_QP_CQNUMVALID) | + LS_64(info->force_loopback, I40IW_CQPSQ_QP_FORCELOOPBACK) | + LS_64(qp->qp_type, I40IW_CQPSQ_QP_QPTYPE) | +- LS_64(info->mss_change, I40IW_CQPSQ_QP_MSSCHANGE) | + LS_64(info->static_rsrc, I40IW_CQPSQ_QP_STATRSRC) | + LS_64(info->remove_hash_idx, I40IW_CQPSQ_QP_REMOVEHASHENTRY) | + LS_64(term_actions, I40IW_CQPSQ_QP_TERMACT) | +diff --git a/drivers/infiniband/hw/i40iw/i40iw_osdep.h b/drivers/infiniband/hw/i40iw/i40iw_osdep.h +index aa66c1c..f27be3e 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_osdep.h ++++ b/drivers/infiniband/hw/i40iw/i40iw_osdep.h +@@ -199,7 +199,6 @@ void i40iw_cqp_spawn_worker(struct i40iw_sc_dev *dev, + struct i40iw_virtchnl_work_info *work_info, u32 iw_vf_idx); + void *i40iw_remove_head(struct list_head *list); + void i40iw_qp_suspend_resume(struct i40iw_sc_dev *dev, struct i40iw_sc_qp *qp, bool suspend); +-void i40iw_qp_mss_modify(struct i40iw_sc_dev *dev, struct i40iw_sc_qp *qp); + + void i40iw_term_modify_qp(struct i40iw_sc_qp *qp, u8 next_state, u8 term, u8 term_len); + void i40iw_terminate_done(struct i40iw_sc_qp *qp, int timeout_occurred); +diff --git a/drivers/infiniband/hw/i40iw/i40iw_type.h b/drivers/infiniband/hw/i40iw/i40iw_type.h +index 7b76259..959ec81 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_type.h ++++ b/drivers/infiniband/hw/i40iw/i40iw_type.h +@@ -541,7 +541,6 @@ struct i40iw_create_qp_info { + struct i40iw_modify_qp_info { + u64 rx_win0; + u64 rx_win1; +- u16 new_mss; + u8 next_iwarp_state; + u8 termlen; + bool ord_valid; +@@ -554,7 +553,6 @@ struct i40iw_modify_qp_info { + bool dont_send_term; + bool dont_send_fin; + bool cached_var_valid; +- bool mss_change; + bool force_loopback; + }; + +diff --git a/drivers/infiniband/hw/i40iw/i40iw_utils.c b/drivers/infiniband/hw/i40iw/i40iw_utils.c +index 409a378..56d9869 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_utils.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_utils.c +@@ -757,23 +757,6 @@ void i40iw_qp_suspend_resume(struct i40iw_sc_dev *dev, struct i40iw_sc_qp *qp, b + } + + /** +- * i40iw_qp_mss_modify - modify mss for qp +- * @dev: hardware control device structure +- * @qp: hardware control qp +- */ +-void i40iw_qp_mss_modify(struct i40iw_sc_dev *dev, struct i40iw_sc_qp *qp) +-{ +- struct i40iw_device *iwdev = (struct i40iw_device *)dev->back_dev; +- struct i40iw_qp *iwqp = (struct i40iw_qp *)qp->back_qp; +- struct i40iw_modify_qp_info info; +- +- memset(&info, 0, sizeof(info)); +- info.mss_change = true; +- info.new_mss = qp->vsi->mss; +- i40iw_hw_modify_qp(iwdev, iwqp, &info, false); +-} +- +-/** + * i40iw_term_modify_qp - modify qp for term message + * @qp: hardware control qp + * @next_state: qp's next state +-- +2.1.3 + diff --git a/linux-next-cherry-picks/0161-RDMA-i40iw-fix-duplicated-code-for-different-branche.patch b/linux-next-cherry-picks/0161-RDMA-i40iw-fix-duplicated-code-for-different-branche.patch new file mode 100644 index 0000000..c1180ca --- /dev/null +++ b/linux-next-cherry-picks/0161-RDMA-i40iw-fix-duplicated-code-for-different-branche.patch @@ -0,0 +1,36 @@ +From e80bd98d1ff011beec872a8ebbb73930507d6a13 Mon Sep 17 00:00:00 2001 +From: "Gustavo A. R. Silva" +Date: Thu, 18 May 2017 13:11:17 -0500 +Subject: [PATCH 03585/13040] RDMA/i40iw: fix duplicated code for different + branches + +Refactor code to avoid identical code for different branches. + +Addresses-Coverity-ID: 1357356 +Reviewed-by: Yuval Shaia +Signed-off-by: Gustavo A. R. Silva +Acked-by: Shiraz Saleem +Signed-off-by: Doug Ledford +--- + drivers/infiniband/hw/i40iw/i40iw_virtchnl.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/drivers/infiniband/hw/i40iw/i40iw_virtchnl.c b/drivers/infiniband/hw/i40iw/i40iw_virtchnl.c +index f4d1368..48fd327 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_virtchnl.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_virtchnl.c +@@ -443,10 +443,7 @@ enum i40iw_status_code i40iw_vchnl_recv_pf(struct i40iw_sc_dev *dev, + if (!dev->vchnl_up) + return I40IW_ERR_NOT_READY; + if (vchnl_msg->iw_op_code == I40IW_VCHNL_OP_GET_VER) { +- if (vchnl_msg->iw_op_ver != I40IW_VCHNL_OP_GET_VER_V0) +- vchnl_pf_send_get_ver_resp(dev, vf_id, vchnl_msg); +- else +- vchnl_pf_send_get_ver_resp(dev, vf_id, vchnl_msg); ++ vchnl_pf_send_get_ver_resp(dev, vf_id, vchnl_msg); + return I40IW_SUCCESS; + } + for (iw_vf_idx = 0; iw_vf_idx < I40IW_MAX_PE_ENABLED_VF_COUNT; iw_vf_idx++) { +-- +2.1.3 + diff --git a/linux-next-cherry-picks/0162-i40iw_main-Remove-deprecated-create_singlethread_wor.patch b/linux-next-cherry-picks/0162-i40iw_main-Remove-deprecated-create_singlethread_wor.patch new file mode 100644 index 0000000..6b262b1 --- /dev/null +++ b/linux-next-cherry-picks/0162-i40iw_main-Remove-deprecated-create_singlethread_wor.patch @@ -0,0 +1,37 @@ +From 73b976954360b4b37570ab001e85d8dde0c345b7 Mon Sep 17 00:00:00 2001 +From: Bhaktipriya Shridhar +Date: Mon, 15 Aug 2016 23:40:09 +0530 +Subject: [PATCH] i40iw_main: Remove deprecated create_singlethread_workqueue + +alloc_ordered_workqueue() with WQ_MEM_RECLAIM set, replaces +deprecated create_singlethread_workqueue(). This is the identity +conversion. + +The workqueue "virtchnl_wq" queues work items i40iw_cqp_generic_worker +and i40iw_cqp_manage_hmc_fcn_worker. It has been identity converted. + +WQ_MEM_RECLAIM has been set to ensure forward progress under memory +pressure. + +Signed-off-by: Bhaktipriya Shridhar +Signed-off-by: Doug Ledford +--- + drivers/infiniband/hw/i40iw/i40iw_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/i40iw/i40iw_main.c b/drivers/infiniband/hw/i40iw/i40iw_main.c +index 6e90813..798335f 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_main.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_main.c +@@ -1613,7 +1613,7 @@ static int i40iw_open(struct i40e_info *ldev, struct i40e_client *client) + status = i40iw_hmc_init_pble(&iwdev->sc_dev, iwdev->pble_rsrc); + if (status) + break; +- iwdev->virtchnl_wq = create_singlethread_workqueue("iwvch"); ++ iwdev->virtchnl_wq = alloc_ordered_workqueue("iwvch", WQ_MEM_RECLAIM); + i40iw_register_notifiers(); + iwdev->init_state = INET_NOTIFIER; + status = i40iw_add_mac_ip(iwdev); +-- +2.1.3 + diff --git a/linux-next-cherry-picks/0163-i40iw-Fix-order-of-cleanup-in-close.patch b/linux-next-cherry-picks/0163-i40iw-Fix-order-of-cleanup-in-close.patch new file mode 100644 index 0000000..7179de4 --- /dev/null +++ b/linux-next-cherry-picks/0163-i40iw-Fix-order-of-cleanup-in-close.patch @@ -0,0 +1,51 @@ +From be8822db62ddda6d316d2dd682679732ed2f0abf Mon Sep 17 00:00:00 2001 +From: Mustafa Ismail +Date: Fri, 23 Jun 2017 16:03:55 -0500 +Subject: [PATCH 12647/13040] i40iw: Fix order of cleanup in close + +The order for calling i40iw_destroy_pble_pool is incorrect. +Also, add PBLE_CHUNK_MEM init state to track pble pool +creation and destruction. + +Signed-off-by: Mustafa Ismail +Signed-off-by: Henry Orosco +Signed-off-by: Doug Ledford +--- + drivers/infiniband/hw/i40iw/i40iw_main.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/infiniband/hw/i40iw/i40iw_main.c b/drivers/infiniband/hw/i40iw/i40iw_main.c +index e0f47cc..8fc61b3 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_main.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_main.c +@@ -1474,6 +1474,9 @@ static void i40iw_deinit_device(struct i40iw_device *iwdev, bool reset) + unregister_inet6addr_notifier(&i40iw_inetaddr6_notifier); + } + /* fallthrough */ ++ case PBLE_CHUNK_MEM: ++ i40iw_destroy_pble_pool(dev, iwdev->pble_rsrc); ++ /* fallthrough */ + case CEQ_CREATED: + i40iw_dele_ceqs(iwdev, reset); + /* fallthrough */ +@@ -1489,9 +1492,6 @@ static void i40iw_deinit_device(struct i40iw_device *iwdev, bool reset) + case CCQ_CREATED: + i40iw_destroy_ccq(iwdev, reset); + /* fallthrough */ +- case PBLE_CHUNK_MEM: +- i40iw_destroy_pble_pool(dev, iwdev->pble_rsrc); +- /* fallthrough */ + case HMC_OBJS_CREATED: + i40iw_del_hmc_objects(dev, dev->hmc_info, true, reset); + /* fallthrough */ +@@ -1670,6 +1670,7 @@ static int i40iw_open(struct i40e_info *ldev, struct i40e_client *client) + status = i40iw_hmc_init_pble(&iwdev->sc_dev, iwdev->pble_rsrc); + if (status) + break; ++ iwdev->init_state = PBLE_CHUNK_MEM; + iwdev->virtchnl_wq = alloc_ordered_workqueue("iwvch", WQ_MEM_RECLAIM); + i40iw_register_notifiers(); + iwdev->init_state = INET_NOTIFIER; +-- +2.1.3 + diff --git a/linux-next-cherry-picks/0164-i40iw-Do-not-poll-CCQ-after-it-is-destroyed.patch b/linux-next-cherry-picks/0164-i40iw-Do-not-poll-CCQ-after-it-is-destroyed.patch new file mode 100644 index 0000000..ee4f51a --- /dev/null +++ b/linux-next-cherry-picks/0164-i40iw-Do-not-poll-CCQ-after-it-is-destroyed.patch @@ -0,0 +1,32 @@ +From 415920aa174666c0ac8c47eee974acc9f49efec4 Mon Sep 17 00:00:00 2001 +From: Mustafa Ismail +Date: Fri, 23 Jun 2017 16:03:56 -0500 +Subject: [PATCH 12648/13040] i40iw: Do not poll CCQ after it is destroyed + +Control Queue Pair (CQP) OPs, in this case - Update SDs, +cannot poll the Control Completion Queue (CCQ) after CCQ is +destroyed. Instead, poll via registers. + +Signed-off-by: Mustafa Ismail +Signed-off-by: Henry Orosco +Signed-off-by: Doug Ledford +--- + drivers/infiniband/hw/i40iw/i40iw_ctrl.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c +index a027e20..9ec1ae9 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c +@@ -1970,6 +1970,8 @@ static enum i40iw_status_code i40iw_sc_ccq_destroy(struct i40iw_sc_cq *ccq, + ret_code = i40iw_cqp_poll_registers(cqp, tail, 1000); + } + ++ cqp->process_cqp_sds = i40iw_update_sds_noccq; ++ + return ret_code; + } + +-- +2.1.3 + diff --git a/linux-next-cherry-picks/0165-i40iw-Utilize-iwdev-reset-during-PCI-function-reset.patch b/linux-next-cherry-picks/0165-i40iw-Utilize-iwdev-reset-during-PCI-function-reset.patch new file mode 100644 index 0000000..69fb6d4 --- /dev/null +++ b/linux-next-cherry-picks/0165-i40iw-Utilize-iwdev-reset-during-PCI-function-reset.patch @@ -0,0 +1,213 @@ +From 6c1d94de4e75160d3ea5af3bf51d290341db1d44 Mon Sep 17 00:00:00 2001 +From: Shiraz Saleem +Date: Fri, 23 Jun 2017 16:03:57 -0500 +Subject: [PATCH 12649/13040] i40iw: Utilize iwdev->reset during PCI function + reset + +Utilize iwdev->reset on a PCI function reset notification +instead of passing in reset flag for resource clean-up. + +Signed-off-by: Shiraz Saleem +Signed-off-by: Henry Orosco +Signed-off-by: Doug Ledford +--- + drivers/infiniband/hw/i40iw/i40iw_main.c | 51 +++++++++++++++----------------- + 1 file changed, 24 insertions(+), 27 deletions(-) + +diff --git a/drivers/infiniband/hw/i40iw/i40iw_main.c b/drivers/infiniband/hw/i40iw/i40iw_main.c +index 8fc61b3..3bad7d9 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_main.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_main.c +@@ -274,13 +274,12 @@ static void i40iw_disable_irq(struct i40iw_sc_dev *dev, + /** + * i40iw_destroy_aeq - destroy aeq + * @iwdev: iwarp device +- * @reset: true if called before reset + * + * Issue a destroy aeq request and + * free the resources associated with the aeq + * The function is called during driver unload + */ +-static void i40iw_destroy_aeq(struct i40iw_device *iwdev, bool reset) ++static void i40iw_destroy_aeq(struct i40iw_device *iwdev) + { + enum i40iw_status_code status = I40IW_ERR_NOT_READY; + struct i40iw_sc_dev *dev = &iwdev->sc_dev; +@@ -288,7 +287,7 @@ static void i40iw_destroy_aeq(struct i40iw_device *iwdev, bool reset) + + if (!iwdev->msix_shared) + i40iw_disable_irq(dev, iwdev->iw_msixtbl, (void *)iwdev); +- if (reset) ++ if (iwdev->reset) + goto exit; + + if (!dev->aeq_ops->aeq_destroy(&aeq->sc_aeq, 0, 1)) +@@ -304,19 +303,17 @@ static void i40iw_destroy_aeq(struct i40iw_device *iwdev, bool reset) + * i40iw_destroy_ceq - destroy ceq + * @iwdev: iwarp device + * @iwceq: ceq to be destroyed +- * @reset: true if called before reset + * + * Issue a destroy ceq request and + * free the resources associated with the ceq + */ + static void i40iw_destroy_ceq(struct i40iw_device *iwdev, +- struct i40iw_ceq *iwceq, +- bool reset) ++ struct i40iw_ceq *iwceq) + { + enum i40iw_status_code status; + struct i40iw_sc_dev *dev = &iwdev->sc_dev; + +- if (reset) ++ if (iwdev->reset) + goto exit; + + status = dev->ceq_ops->ceq_destroy(&iwceq->sc_ceq, 0, 1); +@@ -335,12 +332,11 @@ static void i40iw_destroy_ceq(struct i40iw_device *iwdev, + /** + * i40iw_dele_ceqs - destroy all ceq's + * @iwdev: iwarp device +- * @reset: true if called before reset + * + * Go through all of the device ceq's and for each ceq + * disable the ceq interrupt and destroy the ceq + */ +-static void i40iw_dele_ceqs(struct i40iw_device *iwdev, bool reset) ++static void i40iw_dele_ceqs(struct i40iw_device *iwdev) + { + u32 i = 0; + struct i40iw_sc_dev *dev = &iwdev->sc_dev; +@@ -349,32 +345,31 @@ static void i40iw_dele_ceqs(struct i40iw_device *iwdev, bool reset) + + if (iwdev->msix_shared) { + i40iw_disable_irq(dev, msix_vec, (void *)iwdev); +- i40iw_destroy_ceq(iwdev, iwceq, reset); ++ i40iw_destroy_ceq(iwdev, iwceq); + iwceq++; + i++; + } + + for (msix_vec++; i < iwdev->ceqs_count; i++, msix_vec++, iwceq++) { + i40iw_disable_irq(dev, msix_vec, (void *)iwceq); +- i40iw_destroy_ceq(iwdev, iwceq, reset); ++ i40iw_destroy_ceq(iwdev, iwceq); + } + } + + /** + * i40iw_destroy_ccq - destroy control cq + * @iwdev: iwarp device +- * @reset: true if called before reset + * + * Issue destroy ccq request and + * free the resources associated with the ccq + */ +-static void i40iw_destroy_ccq(struct i40iw_device *iwdev, bool reset) ++static void i40iw_destroy_ccq(struct i40iw_device *iwdev) + { + struct i40iw_sc_dev *dev = &iwdev->sc_dev; + struct i40iw_ccq *ccq = &iwdev->ccq; + enum i40iw_status_code status = 0; + +- if (!reset) ++ if (!iwdev->reset) + status = dev->ccq_ops->ccq_destroy(dev->ccq, 0, true); + if (status) + i40iw_pr_err("ccq destroy failed %d\n", status); +@@ -810,7 +805,7 @@ static enum i40iw_status_code i40iw_setup_ceqs(struct i40iw_device *iwdev, + iwceq->msix_idx = msix_vec->idx; + status = i40iw_configure_ceq_vector(iwdev, iwceq, ceq_id, msix_vec); + if (status) { +- i40iw_destroy_ceq(iwdev, iwceq, false); ++ i40iw_destroy_ceq(iwdev, iwceq); + break; + } + i40iw_enable_intr(&iwdev->sc_dev, msix_vec->idx); +@@ -912,7 +907,7 @@ static enum i40iw_status_code i40iw_setup_aeq(struct i40iw_device *iwdev) + + status = i40iw_configure_aeq_vector(iwdev); + if (status) { +- i40iw_destroy_aeq(iwdev, false); ++ i40iw_destroy_aeq(iwdev); + return status; + } + +@@ -1442,12 +1437,11 @@ static enum i40iw_status_code i40iw_save_msix_info(struct i40iw_device *iwdev, + /** + * i40iw_deinit_device - clean up the device resources + * @iwdev: iwarp device +- * @reset: true if called before reset + * + * Destroy the ib device interface, remove the mac ip entry and ipv4/ipv6 addresses, + * destroy the device queues and free the pble and the hmc objects + */ +-static void i40iw_deinit_device(struct i40iw_device *iwdev, bool reset) ++static void i40iw_deinit_device(struct i40iw_device *iwdev) + { + struct i40e_info *ldev = iwdev->ldev; + +@@ -1464,7 +1458,7 @@ static void i40iw_deinit_device(struct i40iw_device *iwdev, bool reset) + i40iw_destroy_rdma_device(iwdev->iwibdev); + /* fallthrough */ + case IP_ADDR_REGISTERED: +- if (!reset) ++ if (!iwdev->reset) + i40iw_del_macip_entry(iwdev, (u8)iwdev->mac_ip_table_idx); + /* fallthrough */ + case INET_NOTIFIER: +@@ -1478,22 +1472,22 @@ static void i40iw_deinit_device(struct i40iw_device *iwdev, bool reset) + i40iw_destroy_pble_pool(dev, iwdev->pble_rsrc); + /* fallthrough */ + case CEQ_CREATED: +- i40iw_dele_ceqs(iwdev, reset); ++ i40iw_dele_ceqs(iwdev); + /* fallthrough */ + case AEQ_CREATED: +- i40iw_destroy_aeq(iwdev, reset); ++ i40iw_destroy_aeq(iwdev); + /* fallthrough */ + case IEQ_CREATED: +- i40iw_puda_dele_resources(&iwdev->vsi, I40IW_PUDA_RSRC_TYPE_IEQ, reset); ++ i40iw_puda_dele_resources(&iwdev->vsi, I40IW_PUDA_RSRC_TYPE_IEQ, iwdev->reset); + /* fallthrough */ + case ILQ_CREATED: +- i40iw_puda_dele_resources(&iwdev->vsi, I40IW_PUDA_RSRC_TYPE_ILQ, reset); ++ i40iw_puda_dele_resources(&iwdev->vsi, I40IW_PUDA_RSRC_TYPE_ILQ, iwdev->reset); + /* fallthrough */ + case CCQ_CREATED: +- i40iw_destroy_ccq(iwdev, reset); ++ i40iw_destroy_ccq(iwdev); + /* fallthrough */ + case HMC_OBJS_CREATED: +- i40iw_del_hmc_objects(dev, dev->hmc_info, true, reset); ++ i40iw_del_hmc_objects(dev, dev->hmc_info, true, iwdev->reset); + /* fallthrough */ + case CQP_CREATED: + i40iw_destroy_cqp(iwdev, true); +@@ -1694,7 +1688,7 @@ static int i40iw_open(struct i40e_info *ldev, struct i40e_client *client) + } while (0); + + i40iw_pr_err("status = %d last completion = %d\n", status, iwdev->init_state); +- i40iw_deinit_device(iwdev, false); ++ i40iw_deinit_device(iwdev); + return -ERESTART; + } + +@@ -1775,9 +1769,12 @@ static void i40iw_close(struct i40e_info *ldev, struct i40e_client *client, bool + iwdev = &hdl->device; + iwdev->closing = true; + ++ if (reset) ++ iwdev->reset = true; ++ + i40iw_cm_disconnect_all(iwdev); + destroy_workqueue(iwdev->virtchnl_wq); +- i40iw_deinit_device(iwdev, reset); ++ i40iw_deinit_device(iwdev); + } + + /** +-- +2.1.3 + diff --git a/linux-next-cherry-picks/0166-i40iw-Release-cm_id-ref-on-PCI-function-reset.patch b/linux-next-cherry-picks/0166-i40iw-Release-cm_id-ref-on-PCI-function-reset.patch new file mode 100644 index 0000000..cd5f7e1 --- /dev/null +++ b/linux-next-cherry-picks/0166-i40iw-Release-cm_id-ref-on-PCI-function-reset.patch @@ -0,0 +1,45 @@ +From 6327cb09dfda103f7255ef218ac18697b293554a Mon Sep 17 00:00:00 2001 +From: Shiraz Saleem +Date: Fri, 23 Jun 2017 16:03:58 -0500 +Subject: [PATCH 12650/13040] i40iw: Release cm_id ref on PCI function reset + +On PCI function reset, cm_id reference is not released +which causes an application hang, as it waits on the +cm_id to be released on rdma_destroy. + +To fix this, call i40iw_cm_disconn during a PCI function +reset to clean-up resources and release cm_id reference. + +Signed-off-by: Shiraz Saleem +Signed-off-by: Henry Orosco +Signed-off-by: Doug Ledford +--- + drivers/infiniband/hw/i40iw/i40iw_cm.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/i40iw/i40iw_cm.c b/drivers/infiniband/hw/i40iw/i40iw_cm.c +index 6ae98aa..5a2fa74 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_cm.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_cm.c +@@ -3487,7 +3487,8 @@ static void i40iw_cm_disconn_true(struct i40iw_qp *iwqp) + if (((original_hw_tcp_state == I40IW_TCP_STATE_CLOSED) || + (original_hw_tcp_state == I40IW_TCP_STATE_TIME_WAIT) || + (last_ae == I40IW_AE_RDMAP_ROE_BAD_LLP_CLOSE) || +- (last_ae == I40IW_AE_LLP_CONNECTION_RESET))) { ++ (last_ae == I40IW_AE_LLP_CONNECTION_RESET) || ++ iwdev->reset)) { + issue_close = 1; + iwqp->cm_id = NULL; + if (!iwqp->flush_issued) { +@@ -4265,6 +4266,8 @@ void i40iw_cm_disconnect_all(struct i40iw_device *iwdev) + cm_node = container_of(list_node, struct i40iw_cm_node, connected_entry); + attr.qp_state = IB_QPS_ERR; + i40iw_modify_qp(&cm_node->iwqp->ibqp, &attr, IB_QP_STATE, NULL); ++ if (iwdev->reset) ++ i40iw_cm_disconn(cm_node->iwqp); + i40iw_rem_ref_cm_node(cm_node); + } + } +-- +2.1.3 + diff --git a/linux-next-cherry-picks/0167-i40iw-Free-QP-resources-on-CQP-destroy-QP-failure.patch b/linux-next-cherry-picks/0167-i40iw-Free-QP-resources-on-CQP-destroy-QP-failure.patch new file mode 100644 index 0000000..b419b18 --- /dev/null +++ b/linux-next-cherry-picks/0167-i40iw-Free-QP-resources-on-CQP-destroy-QP-failure.patch @@ -0,0 +1,39 @@ +From b5e452a04a10f12763f9836d3d3999f3bb1e56fb Mon Sep 17 00:00:00 2001 +From: Shiraz Saleem +Date: Fri, 23 Jun 2017 16:03:59 -0500 +Subject: [PATCH 12651/13040] i40iw: Free QP resources on CQP destroy QP + failure + +Current flow leaves software QP structures in memory if +Control Queue Pair (CQP) destroy QP OP fails. To fix this, +free QP resources on fail of CQP destroy QP OP. + +Signed-off-by: Shiraz Saleem +Signed-off-by: Henry Orosco +Signed-off-by: Doug Ledford +--- + drivers/infiniband/hw/i40iw/i40iw_utils.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/infiniband/hw/i40iw/i40iw_utils.c b/drivers/infiniband/hw/i40iw/i40iw_utils.c +index 56d9869..ded8e48 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_utils.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_utils.c +@@ -546,8 +546,12 @@ void i40iw_rem_ref(struct ib_qp *ibqp) + cqp_info->in.u.qp_destroy.scratch = (uintptr_t)cqp_request; + cqp_info->in.u.qp_destroy.remove_hash_idx = true; + status = i40iw_handle_cqp_op(iwdev, cqp_request); +- if (status) +- i40iw_pr_err("CQP-OP Destroy QP fail"); ++ if (!status) ++ return; ++ ++ i40iw_rem_pdusecount(iwqp->iwpd, iwdev); ++ i40iw_free_qp_resources(iwdev, iwqp, qp_num); ++ i40iw_rem_devusecount(iwdev); + } + + /** +-- +2.1.3 + diff --git a/linux-next-cherry-picks/0168-i40iw-Add-missing-memory-barrier.patch b/linux-next-cherry-picks/0168-i40iw-Add-missing-memory-barrier.patch new file mode 100644 index 0000000..2a15dac --- /dev/null +++ b/linux-next-cherry-picks/0168-i40iw-Add-missing-memory-barrier.patch @@ -0,0 +1,31 @@ +From c5c9d27e6c79ab3ab36092fe67fb7f2c6a120171 Mon Sep 17 00:00:00 2001 +From: Henry Orosco +Date: Fri, 23 Jun 2017 16:04:00 -0500 +Subject: [PATCH 12652/13040] i40iw: Add missing memory barrier + +Add missing write memory barrier before writing the +header containing valid bit to the WQE in i40iw_puda_send. + +Signed-off-by: Henry Orosco +Signed-off-by: Doug Ledford +--- + drivers/infiniband/hw/i40iw/i40iw_puda.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/infiniband/hw/i40iw/i40iw_puda.c b/drivers/infiniband/hw/i40iw/i40iw_puda.c +index db41ab4..1bb1681 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_puda.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_puda.c +@@ -408,6 +408,9 @@ enum i40iw_status_code i40iw_puda_send(struct i40iw_sc_qp *qp, + set_64bit_val(wqe, 0, info->paddr); + set_64bit_val(wqe, 8, LS_64(info->len, I40IWQPSQ_FRAG_LEN)); + set_64bit_val(wqe, 16, header[0]); ++ ++ /* Ensure all data is written before writing valid bit */ ++ wmb(); + set_64bit_val(wqe, 24, header[1]); + + i40iw_debug_buf(qp->dev, I40IW_DEBUG_PUDA, "PUDA SEND WQE", wqe, 32); +-- +2.1.3 + diff --git a/linux-next-cherry-picks/0169-i40iw-Update-list-correctly.patch b/linux-next-cherry-picks/0169-i40iw-Update-list-correctly.patch new file mode 100644 index 0000000..d3c6e64 --- /dev/null +++ b/linux-next-cherry-picks/0169-i40iw-Update-list-correctly.patch @@ -0,0 +1,33 @@ +From c709d7f229a273c7c5664e9dfe5432b031842d0c Mon Sep 17 00:00:00 2001 +From: Henry Orosco +Date: Fri, 23 Jun 2017 16:04:01 -0500 +Subject: [PATCH 12653/13040] i40iw: Update list correctly + +To avoid infinite loop, in i40iw_ieq_handle_exception, update +plist inside while loop. + +Signed-off-by: Henry Orosco +Signed-off-by: Doug Ledford +--- + drivers/infiniband/hw/i40iw/i40iw_puda.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/i40iw/i40iw_puda.c b/drivers/infiniband/hw/i40iw/i40iw_puda.c +index 1bb1681..71050c5 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_puda.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_puda.c +@@ -1414,10 +1414,10 @@ static void i40iw_ieq_handle_exception(struct i40iw_puda_rsrc *ieq, + + if (!list_empty(rxlist)) { + tmpbuf = (struct i40iw_puda_buf *)rxlist->next; +- plist = &tmpbuf->list; + while ((struct list_head *)tmpbuf != rxlist) { + if ((int)(buf->seqnum - tmpbuf->seqnum) < 0) + break; ++ plist = &tmpbuf->list; + tmpbuf = (struct i40iw_puda_buf *)plist->next; + } + /* Insert buf before tmpbuf */ +-- +2.1.3 + diff --git a/linux-next-cherry-picks/0170-i40iw-Avoid-memory-leak-of-CQP-request-objects.patch b/linux-next-cherry-picks/0170-i40iw-Avoid-memory-leak-of-CQP-request-objects.patch new file mode 100644 index 0000000..257f7a7 --- /dev/null +++ b/linux-next-cherry-picks/0170-i40iw-Avoid-memory-leak-of-CQP-request-objects.patch @@ -0,0 +1,126 @@ +From 44b99f88cdd5b47046c511aa64ae71ad2c9e5b1e Mon Sep 17 00:00:00 2001 +From: Shiraz Saleem +Date: Fri, 23 Jun 2017 16:04:02 -0500 +Subject: [PATCH 12654/13040] i40iw: Avoid memory leak of CQP request objects + +Control Queue Pair (CQP) request objects, which have +not received a completion upon interface close, remain +in memory. + +To fix this, identify and free all pending CQP request +objects during destroy CQP OP. + +Signed-off-by: Shiraz Saleem +Signed-off-by: Henry Orosco +Signed-off-by: Doug Ledford +--- + drivers/infiniband/hw/i40iw/i40iw.h | 1 + + drivers/infiniband/hw/i40iw/i40iw_main.c | 2 ++ + drivers/infiniband/hw/i40iw/i40iw_utils.c | 52 +++++++++++++++++++++++++++++++ + 3 files changed, 55 insertions(+) + +diff --git a/drivers/infiniband/hw/i40iw/i40iw.h b/drivers/infiniband/hw/i40iw/i40iw.h +index da2eb5a..9b15664 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw.h ++++ b/drivers/infiniband/hw/i40iw/i40iw.h +@@ -527,6 +527,7 @@ enum i40iw_status_code i40iw_add_mac_addr(struct i40iw_device *iwdev, + int i40iw_modify_qp(struct ib_qp *, struct ib_qp_attr *, int, struct ib_udata *); + void i40iw_cq_wq_destroy(struct i40iw_device *iwdev, struct i40iw_sc_cq *cq); + ++void i40iw_cleanup_pending_cqp_op(struct i40iw_device *iwdev); + void i40iw_rem_pdusecount(struct i40iw_pd *iwpd, struct i40iw_device *iwdev); + void i40iw_add_pdusecount(struct i40iw_pd *iwpd); + void i40iw_rem_devusecount(struct i40iw_device *iwdev); +diff --git a/drivers/infiniband/hw/i40iw/i40iw_main.c b/drivers/infiniband/hw/i40iw/i40iw_main.c +index 3bad7d9..ae8463f 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_main.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_main.c +@@ -243,6 +243,8 @@ static void i40iw_destroy_cqp(struct i40iw_device *iwdev, bool free_hwcqp) + if (free_hwcqp) + dev->cqp_ops->cqp_destroy(dev->cqp); + ++ i40iw_cleanup_pending_cqp_op(iwdev); ++ + i40iw_free_dma_mem(dev->hw, &cqp->sq); + kfree(cqp->scratch_array); + iwdev->cqp.scratch_array = NULL; +diff --git a/drivers/infiniband/hw/i40iw/i40iw_utils.c b/drivers/infiniband/hw/i40iw/i40iw_utils.c +index ded8e48..e311ec5 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_utils.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_utils.c +@@ -337,6 +337,7 @@ struct i40iw_cqp_request *i40iw_get_cqp_request(struct i40iw_cqp *cqp, bool wait + */ + void i40iw_free_cqp_request(struct i40iw_cqp *cqp, struct i40iw_cqp_request *cqp_request) + { ++ struct i40iw_device *iwdev = container_of(cqp, struct i40iw_device, cqp); + unsigned long flags; + + if (cqp_request->dynamic) { +@@ -350,6 +351,7 @@ void i40iw_free_cqp_request(struct i40iw_cqp *cqp, struct i40iw_cqp_request *cqp + list_add_tail(&cqp_request->list, &cqp->cqp_avail_reqs); + spin_unlock_irqrestore(&cqp->req_lock, flags); + } ++ wake_up(&iwdev->close_wq); + } + + /** +@@ -365,6 +367,56 @@ void i40iw_put_cqp_request(struct i40iw_cqp *cqp, + } + + /** ++ * i40iw_free_pending_cqp_request -free pending cqp request objs ++ * @cqp: cqp ptr ++ * @cqp_request: to be put back in cqp list ++ */ ++static void i40iw_free_pending_cqp_request(struct i40iw_cqp *cqp, ++ struct i40iw_cqp_request *cqp_request) ++{ ++ struct i40iw_device *iwdev = container_of(cqp, struct i40iw_device, cqp); ++ ++ if (cqp_request->waiting) { ++ cqp_request->compl_info.error = true; ++ cqp_request->request_done = true; ++ wake_up(&cqp_request->waitq); ++ } ++ i40iw_put_cqp_request(cqp, cqp_request); ++ wait_event_timeout(iwdev->close_wq, ++ !atomic_read(&cqp_request->refcount), ++ 1000); ++} ++ ++/** ++ * i40iw_cleanup_pending_cqp_op - clean-up cqp with no completions ++ * @iwdev: iwarp device ++ */ ++void i40iw_cleanup_pending_cqp_op(struct i40iw_device *iwdev) ++{ ++ struct i40iw_sc_dev *dev = &iwdev->sc_dev; ++ struct i40iw_cqp *cqp = &iwdev->cqp; ++ struct i40iw_cqp_request *cqp_request = NULL; ++ struct cqp_commands_info *pcmdinfo = NULL; ++ u32 i, pending_work, wqe_idx; ++ ++ pending_work = I40IW_RING_WORK_AVAILABLE(cqp->sc_cqp.sq_ring); ++ wqe_idx = I40IW_RING_GETCURRENT_TAIL(cqp->sc_cqp.sq_ring); ++ for (i = 0; i < pending_work; i++) { ++ cqp_request = (struct i40iw_cqp_request *)(unsigned long)cqp->scratch_array[wqe_idx]; ++ if (cqp_request) ++ i40iw_free_pending_cqp_request(cqp, cqp_request); ++ wqe_idx = (wqe_idx + 1) % I40IW_RING_GETSIZE(cqp->sc_cqp.sq_ring); ++ } ++ ++ while (!list_empty(&dev->cqp_cmd_head)) { ++ pcmdinfo = (struct cqp_commands_info *)i40iw_remove_head(&dev->cqp_cmd_head); ++ cqp_request = container_of(pcmdinfo, struct i40iw_cqp_request, info); ++ if (cqp_request) ++ i40iw_free_pending_cqp_request(cqp, cqp_request); ++ } ++} ++ ++/** + * i40iw_free_qp - callback after destroy cqp completes + * @cqp_request: cqp request for destroy qp + * @num: not used +-- +2.1.3 + diff --git a/linux-next-cherry-picks/0171-i40iw-Free-QP-PBLEs-when-the-QP-is-destroyed.patch b/linux-next-cherry-picks/0171-i40iw-Free-QP-PBLEs-when-the-QP-is-destroyed.patch new file mode 100644 index 0000000..8dfdc45 --- /dev/null +++ b/linux-next-cherry-picks/0171-i40iw-Free-QP-PBLEs-when-the-QP-is-destroyed.patch @@ -0,0 +1,95 @@ +From af56e53ccd29bda062a1ae75276dc9c0f8eedf47 Mon Sep 17 00:00:00 2001 +From: Tatyana Nikolova +Date: Wed, 5 Jul 2017 21:25:33 -0500 +Subject: [PATCH 12655/13040] i40iw: Free QP PBLEs when the QP is destroyed + +If the physical buffer list entries (PBLEs) of a QP are freed +up at i40iw_dereg_mr, they can be assigned to a newly +created QP before the previous QP is destroyed. Fix this +by freeing PBLEs only when the QP is destroyed. + +Signed-off-by: Tatyana Nikolova +Signed-off-by: Faisal Latif +Signed-off-by: Doug Ledford +--- + drivers/infiniband/hw/i40iw/i40iw_verbs.c | 15 +++++++++++---- + drivers/infiniband/hw/i40iw/i40iw_verbs.h | 2 +- + 2 files changed, 12 insertions(+), 5 deletions(-) + +diff --git a/drivers/infiniband/hw/i40iw/i40iw_verbs.c b/drivers/infiniband/hw/i40iw/i40iw_verbs.c +index 4dbe61e..4aa0264c 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_verbs.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_verbs.c +@@ -426,9 +426,13 @@ void i40iw_free_qp_resources(struct i40iw_device *iwdev, + struct i40iw_qp *iwqp, + u32 qp_num) + { ++ struct i40iw_pbl *iwpbl = &iwqp->iwpbl; ++ + i40iw_dealloc_push_page(iwdev, &iwqp->sc_qp); + if (qp_num) + i40iw_free_resource(iwdev, iwdev->allocated_qps, qp_num); ++ if (iwpbl->pbl_allocated) ++ i40iw_free_pble(iwdev->pble_rsrc, &iwpbl->pble_alloc); + i40iw_free_dma_mem(iwdev->sc_dev.hw, &iwqp->q2_ctx_mem); + i40iw_free_dma_mem(iwdev->sc_dev.hw, &iwqp->kqp.dma_mem); + kfree(iwqp->kqp.wrid_mem); +@@ -483,7 +487,7 @@ static int i40iw_setup_virt_qp(struct i40iw_device *iwdev, + struct i40iw_qp *iwqp, + struct i40iw_qp_init_info *init_info) + { +- struct i40iw_pbl *iwpbl = iwqp->iwpbl; ++ struct i40iw_pbl *iwpbl = &iwqp->iwpbl; + struct i40iw_qp_mr *qpmr = &iwpbl->qp_mr; + + iwqp->page = qpmr->sq_page; +@@ -688,19 +692,22 @@ static struct ib_qp *i40iw_create_qp(struct ib_pd *ibpd, + ucontext = to_ucontext(ibpd->uobject->context); + + if (req.user_wqe_buffers) { ++ struct i40iw_pbl *iwpbl; ++ + spin_lock_irqsave( + &ucontext->qp_reg_mem_list_lock, flags); +- iwqp->iwpbl = i40iw_get_pbl( ++ iwpbl = i40iw_get_pbl( + (unsigned long)req.user_wqe_buffers, + &ucontext->qp_reg_mem_list); + spin_unlock_irqrestore( + &ucontext->qp_reg_mem_list_lock, flags); + +- if (!iwqp->iwpbl) { ++ if (!iwpbl) { + err_code = -ENODATA; + i40iw_pr_err("no pbl info\n"); + goto error; + } ++ memcpy(&iwqp->iwpbl, iwpbl, sizeof(iwqp->iwpbl)); + } + } + err_code = i40iw_setup_virt_qp(iwdev, iwqp, &init_info); +@@ -2063,7 +2070,7 @@ static int i40iw_dereg_mr(struct ib_mr *ib_mr) + ucontext = to_ucontext(ibpd->uobject->context); + i40iw_del_memlist(iwmr, ucontext); + } +- if (iwpbl->pbl_allocated) ++ if (iwpbl->pbl_allocated && iwmr->type != IW_MEMREG_TYPE_QP) + i40iw_free_pble(iwdev->pble_rsrc, palloc); + kfree(iwmr); + return 0; +diff --git a/drivers/infiniband/hw/i40iw/i40iw_verbs.h b/drivers/infiniband/hw/i40iw/i40iw_verbs.h +index 07c3fec..9067443 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_verbs.h ++++ b/drivers/infiniband/hw/i40iw/i40iw_verbs.h +@@ -170,7 +170,7 @@ struct i40iw_qp { + struct i40iw_qp_kmode kqp; + struct i40iw_dma_mem host_ctx; + struct timer_list terminate_timer; +- struct i40iw_pbl *iwpbl; ++ struct i40iw_pbl iwpbl; + struct i40iw_dma_mem q2_ctx_mem; + struct i40iw_dma_mem ietf_mem; + struct completion sq_drained; +-- +2.1.3 + diff --git a/linux-next-cherry-picks/0172-IB-i40iw-Fix-error-code-in-i40iw_create_cq.patch b/linux-next-cherry-picks/0172-IB-i40iw-Fix-error-code-in-i40iw_create_cq.patch new file mode 100644 index 0000000..1dc2c71 --- /dev/null +++ b/linux-next-cherry-picks/0172-IB-i40iw-Fix-error-code-in-i40iw_create_cq.patch @@ -0,0 +1,36 @@ +From 6031e079aa4656743298ea235b894ee883f45c71 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Thu, 13 Jul 2017 10:47:22 +0300 +Subject: [PATCH 12658/13040] IB/i40iw: Fix error code in i40iw_create_cq() + +We accidentally forgot to set the error code if ib_copy_from_udata() +fails. It means we return ERR_PTR(0) which is NULL and results in a +NULL dereference in the callers. + +Fixes: d37498417947 ("i40iw: add files for iwarp interface") +Signed-off-by: Dan Carpenter +Acked-by: Shiraz Saleem +Signed-off-by: Doug Ledford +--- + drivers/infiniband/hw/i40iw/i40iw_verbs.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/i40iw/i40iw_verbs.c b/drivers/infiniband/hw/i40iw/i40iw_verbs.c +index 4aa0264c..02d871d 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_verbs.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_verbs.c +@@ -1168,8 +1168,10 @@ static struct ib_cq *i40iw_create_cq(struct ib_device *ibdev, + memset(&req, 0, sizeof(req)); + iwcq->user_mode = true; + ucontext = to_ucontext(context); +- if (ib_copy_from_udata(&req, udata, sizeof(struct i40iw_create_cq_req))) ++ if (ib_copy_from_udata(&req, udata, sizeof(struct i40iw_create_cq_req))) { ++ err_code = -EFAULT; + goto cq_free_resources; ++ } + + spin_lock_irqsave(&ucontext->cq_reg_mem_list_lock, flags); + iwpbl = i40iw_get_pbl((unsigned long)req.user_cq_buffer, +-- +2.1.3 + diff --git a/linux-next-cherry-picks/0173-i40iw-Fix-parsing-of-query-commit-FPM-buffers.patch b/linux-next-cherry-picks/0173-i40iw-Fix-parsing-of-query-commit-FPM-buffers.patch new file mode 100644 index 0000000..fa528fa --- /dev/null +++ b/linux-next-cherry-picks/0173-i40iw-Fix-parsing-of-query-commit-FPM-buffers.patch @@ -0,0 +1,218 @@ +From f67ace2d8868d06710ceea1b10b124eead5040da Mon Sep 17 00:00:00 2001 +From: Chien Tin Tung +Date: Tue, 8 Aug 2017 20:38:43 -0500 +Subject: [PATCH 12860/13040] i40iw: Fix parsing of query/commit FPM buffers + +Parsing of commit/query Host Memory Cache Function Private Memory +is not skipping over reserved fields and incorrectly assigning +those values into object's base/cnt/max_cnt fields. Skip over +reserved fields and set correct values. Also correct memory +alignment requirement for commit/query FPM buffers. + +Signed-off-by: Chien Tin Tung +Signed-off-by: Shiraz Saleem +Signed-off-by: Christopher N Bednarz +Signed-off-by: Henry Orosco +Signed-off-by: Doug Ledford +--- + drivers/infiniband/hw/i40iw/i40iw_ctrl.c | 121 +++++++++++++++++++++---------- + drivers/infiniband/hw/i40iw/i40iw_d.h | 4 +- + 2 files changed, 83 insertions(+), 42 deletions(-) + +diff --git a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c +index 9ec1ae9..ef4a73c 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c +@@ -130,20 +130,32 @@ static enum i40iw_status_code i40iw_sc_parse_fpm_commit_buf( + u64 base = 0; + u32 i, j; + u32 k = 0; +- u32 low; + + /* copy base values in obj_info */ +- for (i = I40IW_HMC_IW_QP, j = 0; +- i <= I40IW_HMC_IW_PBLE; i++, j += 8) { ++ for (i = I40IW_HMC_IW_QP, j = 0; i <= I40IW_HMC_IW_PBLE; i++, j += 8) { ++ if ((i == I40IW_HMC_IW_SRQ) || ++ (i == I40IW_HMC_IW_FSIMC) || ++ (i == I40IW_HMC_IW_FSIAV)) { ++ info[i].base = 0; ++ info[i].cnt = 0; ++ continue; ++ } + get_64bit_val(buf, j, &temp); + info[i].base = RS_64_1(temp, 32) * 512; + if (info[i].base > base) { + base = info[i].base; + k = i; + } +- low = (u32)(temp); +- if (low) +- info[i].cnt = low; ++ if (i == I40IW_HMC_IW_APBVT_ENTRY) { ++ info[i].cnt = 1; ++ continue; ++ } ++ if (i == I40IW_HMC_IW_QP) ++ info[i].cnt = (u32)RS_64(temp, I40IW_QUERY_FPM_MAX_QPS); ++ else if (i == I40IW_HMC_IW_CQ) ++ info[i].cnt = (u32)RS_64(temp, I40IW_QUERY_FPM_MAX_CQS); ++ else ++ info[i].cnt = (u32)(temp); + } + size = info[k].cnt * info[k].size + info[k].base; + if (size & 0x1FFFFF) +@@ -155,6 +167,31 @@ static enum i40iw_status_code i40iw_sc_parse_fpm_commit_buf( + } + + /** ++ * i40iw_sc_decode_fpm_query() - Decode a 64 bit value into max count and size ++ * @buf: ptr to fpm query buffer ++ * @buf_idx: index into buf ++ * @info: ptr to i40iw_hmc_obj_info struct ++ * @rsrc_idx: resource index into info ++ * ++ * Decode a 64 bit value from fpm query buffer into max count and size ++ */ ++static u64 i40iw_sc_decode_fpm_query(u64 *buf, ++ u32 buf_idx, ++ struct i40iw_hmc_obj_info *obj_info, ++ u32 rsrc_idx) ++{ ++ u64 temp; ++ u32 size; ++ ++ get_64bit_val(buf, buf_idx, &temp); ++ obj_info[rsrc_idx].max_cnt = (u32)temp; ++ size = (u32)RS_64_1(temp, 32); ++ obj_info[rsrc_idx].size = LS_64_1(1, size); ++ ++ return temp; ++} ++ ++/** + * i40iw_sc_parse_fpm_query_buf() - parses fpm query buffer + * @buf: ptr to fpm query buffer + * @info: ptr to i40iw_hmc_obj_info struct +@@ -168,9 +205,9 @@ static enum i40iw_status_code i40iw_sc_parse_fpm_query_buf( + struct i40iw_hmc_info *hmc_info, + struct i40iw_hmc_fpm_misc *hmc_fpm_misc) + { +- u64 temp; + struct i40iw_hmc_obj_info *obj_info; +- u32 i, j, size; ++ u64 temp; ++ u32 size; + u16 max_pe_sds; + + obj_info = hmc_info->hmc_obj; +@@ -185,41 +222,52 @@ static enum i40iw_status_code i40iw_sc_parse_fpm_query_buf( + hmc_fpm_misc->max_sds = max_pe_sds; + hmc_info->sd_table.sd_cnt = max_pe_sds + hmc_info->first_sd_index; + +- for (i = I40IW_HMC_IW_QP, j = 8; +- i <= I40IW_HMC_IW_ARP; i++, j += 8) { +- get_64bit_val(buf, j, &temp); +- if (i == I40IW_HMC_IW_QP) +- obj_info[i].max_cnt = (u32)RS_64(temp, I40IW_QUERY_FPM_MAX_QPS); +- else if (i == I40IW_HMC_IW_CQ) +- obj_info[i].max_cnt = (u32)RS_64(temp, I40IW_QUERY_FPM_MAX_CQS); +- else +- obj_info[i].max_cnt = (u32)temp; ++ get_64bit_val(buf, 8, &temp); ++ obj_info[I40IW_HMC_IW_QP].max_cnt = (u32)RS_64(temp, I40IW_QUERY_FPM_MAX_QPS); ++ size = (u32)RS_64_1(temp, 32); ++ obj_info[I40IW_HMC_IW_QP].size = LS_64_1(1, size); + +- size = (u32)RS_64_1(temp, 32); +- obj_info[i].size = ((u64)1 << size); +- } +- for (i = I40IW_HMC_IW_MR, j = 48; +- i <= I40IW_HMC_IW_PBLE; i++, j += 8) { +- get_64bit_val(buf, j, &temp); +- obj_info[i].max_cnt = (u32)temp; +- size = (u32)RS_64_1(temp, 32); +- obj_info[i].size = LS_64_1(1, size); +- } ++ get_64bit_val(buf, 16, &temp); ++ obj_info[I40IW_HMC_IW_CQ].max_cnt = (u32)RS_64(temp, I40IW_QUERY_FPM_MAX_CQS); ++ size = (u32)RS_64_1(temp, 32); ++ obj_info[I40IW_HMC_IW_CQ].size = LS_64_1(1, size); ++ ++ i40iw_sc_decode_fpm_query(buf, 32, obj_info, I40IW_HMC_IW_HTE); ++ i40iw_sc_decode_fpm_query(buf, 40, obj_info, I40IW_HMC_IW_ARP); ++ ++ obj_info[I40IW_HMC_IW_APBVT_ENTRY].size = 8192; ++ obj_info[I40IW_HMC_IW_APBVT_ENTRY].max_cnt = 1; ++ ++ i40iw_sc_decode_fpm_query(buf, 48, obj_info, I40IW_HMC_IW_MR); ++ i40iw_sc_decode_fpm_query(buf, 56, obj_info, I40IW_HMC_IW_XF); + +- get_64bit_val(buf, 120, &temp); +- hmc_fpm_misc->max_ceqs = (u8)RS_64(temp, I40IW_QUERY_FPM_MAX_CEQS); +- get_64bit_val(buf, 120, &temp); +- hmc_fpm_misc->ht_multiplier = RS_64(temp, I40IW_QUERY_FPM_HTMULTIPLIER); +- get_64bit_val(buf, 120, &temp); +- hmc_fpm_misc->timer_bucket = RS_64(temp, I40IW_QUERY_FPM_TIMERBUCKET); + get_64bit_val(buf, 64, &temp); ++ obj_info[I40IW_HMC_IW_XFFL].max_cnt = (u32)temp; ++ obj_info[I40IW_HMC_IW_XFFL].size = 4; + hmc_fpm_misc->xf_block_size = RS_64(temp, I40IW_QUERY_FPM_XFBLOCKSIZE); + if (!hmc_fpm_misc->xf_block_size) + return I40IW_ERR_INVALID_SIZE; ++ ++ i40iw_sc_decode_fpm_query(buf, 72, obj_info, I40IW_HMC_IW_Q1); ++ + get_64bit_val(buf, 80, &temp); ++ obj_info[I40IW_HMC_IW_Q1FL].max_cnt = (u32)temp; ++ obj_info[I40IW_HMC_IW_Q1FL].size = 4; + hmc_fpm_misc->q1_block_size = RS_64(temp, I40IW_QUERY_FPM_Q1BLOCKSIZE); + if (!hmc_fpm_misc->q1_block_size) + return I40IW_ERR_INVALID_SIZE; ++ ++ i40iw_sc_decode_fpm_query(buf, 88, obj_info, I40IW_HMC_IW_TIMER); ++ ++ get_64bit_val(buf, 112, &temp); ++ obj_info[I40IW_HMC_IW_PBLE].max_cnt = (u32)temp; ++ obj_info[I40IW_HMC_IW_PBLE].size = 8; ++ ++ get_64bit_val(buf, 120, &temp); ++ hmc_fpm_misc->max_ceqs = (u8)RS_64(temp, I40IW_QUERY_FPM_MAX_CEQS); ++ hmc_fpm_misc->ht_multiplier = RS_64(temp, I40IW_QUERY_FPM_HTMULTIPLIER); ++ hmc_fpm_misc->timer_bucket = RS_64(temp, I40IW_QUERY_FPM_TIMERBUCKET); ++ + return 0; + } + +@@ -3392,13 +3440,6 @@ enum i40iw_status_code i40iw_sc_init_iw_hmc(struct i40iw_sc_dev *dev, u8 hmc_fn_ + hmc_info->sd_table.sd_entry = virt_mem.va; + } + +- /* fill size of objects which are fixed */ +- hmc_info->hmc_obj[I40IW_HMC_IW_XFFL].size = 4; +- hmc_info->hmc_obj[I40IW_HMC_IW_Q1FL].size = 4; +- hmc_info->hmc_obj[I40IW_HMC_IW_PBLE].size = 8; +- hmc_info->hmc_obj[I40IW_HMC_IW_APBVT_ENTRY].size = 8192; +- hmc_info->hmc_obj[I40IW_HMC_IW_APBVT_ENTRY].max_cnt = 1; +- + return ret_code; + } + +diff --git a/drivers/infiniband/hw/i40iw/i40iw_d.h b/drivers/infiniband/hw/i40iw/i40iw_d.h +index a39ac12..2ebaadb 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_d.h ++++ b/drivers/infiniband/hw/i40iw/i40iw_d.h +@@ -1507,8 +1507,8 @@ enum { + I40IW_CQ0_ALIGNMENT_MASK = (256 - 1), + I40IW_HOST_CTX_ALIGNMENT_MASK = (4 - 1), + I40IW_SHADOWAREA_MASK = (128 - 1), +- I40IW_FPM_QUERY_BUF_ALIGNMENT_MASK = 0, +- I40IW_FPM_COMMIT_BUF_ALIGNMENT_MASK = 0 ++ I40IW_FPM_QUERY_BUF_ALIGNMENT_MASK = (4 - 1), ++ I40IW_FPM_COMMIT_BUF_ALIGNMENT_MASK = (4 - 1) + }; + + enum i40iw_alignment { +-- +2.1.3 + diff --git a/linux-next-cherry-picks/0174-i40iw-Correct-variable-names.patch b/linux-next-cherry-picks/0174-i40iw-Correct-variable-names.patch new file mode 100644 index 0000000..a8d8fab --- /dev/null +++ b/linux-next-cherry-picks/0174-i40iw-Correct-variable-names.patch @@ -0,0 +1,63 @@ +From 8129331f01a683ed8d9a9a65ed01b5c6ad26403a Mon Sep 17 00:00:00 2001 +From: Mustafa Ismail +Date: Tue, 8 Aug 2017 20:38:44 -0500 +Subject: [PATCH 12861/13040] i40iw: Correct variable names + +Fix incorrect naming of status code and struct. Use inline +instead of immediate. + +Signed-off-by: Mustafa Ismail +Signed-off-by: Henry Orosco +Signed-off-by: Doug Ledford +--- + drivers/infiniband/hw/i40iw/i40iw_status.h | 2 +- + drivers/infiniband/hw/i40iw/i40iw_uk.c | 6 +++--- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/infiniband/hw/i40iw/i40iw_status.h b/drivers/infiniband/hw/i40iw/i40iw_status.h +index 91c4217..f7013f1 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_status.h ++++ b/drivers/infiniband/hw/i40iw/i40iw_status.h +@@ -62,7 +62,7 @@ enum i40iw_status_code { + I40IW_ERR_INVALID_ALIGNMENT = -23, + I40IW_ERR_FLUSHED_QUEUE = -24, + I40IW_ERR_INVALID_PUSH_PAGE_INDEX = -25, +- I40IW_ERR_INVALID_IMM_DATA_SIZE = -26, ++ I40IW_ERR_INVALID_INLINE_DATA_SIZE = -26, + I40IW_ERR_TIMEOUT = -27, + I40IW_ERR_OPCODE_MISMATCH = -28, + I40IW_ERR_CQP_COMPL_ERROR = -29, +diff --git a/drivers/infiniband/hw/i40iw/i40iw_uk.c b/drivers/infiniband/hw/i40iw/i40iw_uk.c +index b0d3a0e..70a6b41 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_uk.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_uk.c +@@ -435,7 +435,7 @@ static enum i40iw_status_code i40iw_inline_rdma_write(struct i40iw_qp_uk *qp, + + op_info = &info->op.inline_rdma_write; + if (op_info->len > I40IW_MAX_INLINE_DATA_SIZE) +- return I40IW_ERR_INVALID_IMM_DATA_SIZE; ++ return I40IW_ERR_INVALID_INLINE_DATA_SIZE; + + ret_code = i40iw_inline_data_size_to_wqesize(op_info->len, &wqe_size); + if (ret_code) +@@ -511,7 +511,7 @@ static enum i40iw_status_code i40iw_inline_send(struct i40iw_qp_uk *qp, + + op_info = &info->op.inline_send; + if (op_info->len > I40IW_MAX_INLINE_DATA_SIZE) +- return I40IW_ERR_INVALID_IMM_DATA_SIZE; ++ return I40IW_ERR_INVALID_INLINE_DATA_SIZE; + + ret_code = i40iw_inline_data_size_to_wqesize(op_info->len, &wqe_size); + if (ret_code) +@@ -1187,7 +1187,7 @@ enum i40iw_status_code i40iw_inline_data_size_to_wqesize(u32 data_size, + u8 *wqe_size) + { + if (data_size > I40IW_MAX_INLINE_DATA_SIZE) +- return I40IW_ERR_INVALID_IMM_DATA_SIZE; ++ return I40IW_ERR_INVALID_INLINE_DATA_SIZE; + + if (data_size <= 16) + *wqe_size = I40IW_QP_WQE_MIN_SIZE; +-- +2.1.3 + diff --git a/linux-next-cherry-picks/0175-i40iw-Fix-typecast-of-tcp_seq_num.patch b/linux-next-cherry-picks/0175-i40iw-Fix-typecast-of-tcp_seq_num.patch new file mode 100644 index 0000000..89dd6af --- /dev/null +++ b/linux-next-cherry-picks/0175-i40iw-Fix-typecast-of-tcp_seq_num.patch @@ -0,0 +1,31 @@ +From 29c2415a6669bab354f0aa3445777fe147c7a05d Mon Sep 17 00:00:00 2001 +From: Mustafa Ismail +Date: Tue, 8 Aug 2017 20:38:46 -0500 +Subject: [PATCH 12862/13040] i40iw: Fix typecast of tcp_seq_num + +The typecast of tcp_seq_num incorrectly uses u8. Fix by +casting to u32. + +Signed-off-by: Mustafa Ismail +Signed-off-by: Henry Orosco +Signed-off-by: Doug Ledford +--- + drivers/infiniband/hw/i40iw/i40iw_uk.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/i40iw/i40iw_uk.c b/drivers/infiniband/hw/i40iw/i40iw_uk.c +index 70a6b41..1060725 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_uk.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_uk.c +@@ -784,7 +784,7 @@ static enum i40iw_status_code i40iw_cq_poll_completion(struct i40iw_cq_uk *cq, + get_64bit_val(cqe, 0, &qword0); + get_64bit_val(cqe, 16, &qword2); + +- info->tcp_seq_num = (u8)RS_64(qword0, I40IWCQ_TCPSEQNUM); ++ info->tcp_seq_num = (u32)RS_64(qword0, I40IWCQ_TCPSEQNUM); + + info->qp_id = (u32)RS_64(qword2, I40IWCQ_QPID); + +-- +2.1.3 + diff --git a/linux-next-cherry-picks/0176-i40iw-Use-correct-alignment-for-CQ0-memory.patch b/linux-next-cherry-picks/0176-i40iw-Use-correct-alignment-for-CQ0-memory.patch new file mode 100644 index 0000000..e8407a9 --- /dev/null +++ b/linux-next-cherry-picks/0176-i40iw-Use-correct-alignment-for-CQ0-memory.patch @@ -0,0 +1,31 @@ +From a28f047e5f9b987d614eeee34388087ffdda3e53 Mon Sep 17 00:00:00 2001 +From: Christopher N Bednarz +Date: Tue, 8 Aug 2017 20:38:47 -0500 +Subject: [PATCH 12863/13040] i40iw: Use correct alignment for CQ0 memory + +Utilize correct alignment variable when allocating +DMA memory for CQ0. + +Signed-off-by: Christopher N Bednarz +Signed-off-by: Henry Orosco +Signed-off-by: Doug Ledford +--- + drivers/infiniband/hw/i40iw/i40iw_puda.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/i40iw/i40iw_puda.c b/drivers/infiniband/hw/i40iw/i40iw_puda.c +index 71050c5..7f5583d 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_puda.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_puda.c +@@ -685,7 +685,7 @@ static enum i40iw_status_code i40iw_puda_cq_create(struct i40iw_puda_rsrc *rsrc) + cqsize = rsrc->cq_size * (sizeof(struct i40iw_cqe)); + tsize = cqsize + sizeof(struct i40iw_cq_shadow_area); + ret = i40iw_allocate_dma_mem(dev->hw, &rsrc->cqmem, tsize, +- I40IW_CQ0_ALIGNMENT_MASK); ++ I40IW_CQ0_ALIGNMENT); + if (ret) + return ret; + +-- +2.1.3 + diff --git a/linux-next-cherry-picks/0177-i40iw-Fix-potential-fcn_id_array-out-of-bounds.patch b/linux-next-cherry-picks/0177-i40iw-Fix-potential-fcn_id_array-out-of-bounds.patch new file mode 100644 index 0000000..dcf6fbc --- /dev/null +++ b/linux-next-cherry-picks/0177-i40iw-Fix-potential-fcn_id_array-out-of-bounds.patch @@ -0,0 +1,31 @@ +From aa939c12ab8a0c094420ad1b909a957ac590e43e Mon Sep 17 00:00:00 2001 +From: Christopher N Bednarz +Date: Tue, 8 Aug 2017 20:38:48 -0500 +Subject: [PATCH 12864/13040] i40iw: Fix potential fcn_id_array out of bounds + +Avoid out of bounds error by utilizing I40IW_MAX_STATS_COUNT +instead of I40IW_INVALID_FCN_ID. + +Signed-off-by: Christopher N Bednarz +Signed-off-by: Henry Orosco +Signed-off-by: Doug Ledford +--- + drivers/infiniband/hw/i40iw/i40iw_ctrl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c +index ef4a73c..a49ff2e 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c +@@ -4881,7 +4881,7 @@ void i40iw_vsi_stats_free(struct i40iw_sc_vsi *vsi) + { + u8 fcn_id = vsi->fcn_id; + +- if ((vsi->stats_fcn_id_alloc) && (fcn_id != I40IW_INVALID_FCN_ID)) ++ if (vsi->stats_fcn_id_alloc && fcn_id < I40IW_MAX_STATS_COUNT) + vsi->dev->fcn_id_array[fcn_id] = false; + i40iw_hw_stats_stop_timer(vsi); + } +-- +2.1.3 + diff --git a/linux-next-cherry-picks/0178-i40iw-Simplify-code.patch b/linux-next-cherry-picks/0178-i40iw-Simplify-code.patch new file mode 100644 index 0000000..71c8e54 --- /dev/null +++ b/linux-next-cherry-picks/0178-i40iw-Simplify-code.patch @@ -0,0 +1,45 @@ +From 02654b5ae1a45c0e31060816231086685cfcd841 Mon Sep 17 00:00:00 2001 +From: Christophe Jaillet +Date: Sun, 16 Jul 2017 13:09:23 +0200 +Subject: [PATCH 12882/13040] i40iw: Simplify code + +Axe a few lines of code and re-use existing error handling path to avoid +code duplication. + +Signed-off-by: Christophe JAILLET +Acked-by: Shiraz Saleem +Signed-off-by: Doug Ledford +--- + drivers/infiniband/hw/i40iw/i40iw_pble.c | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +diff --git a/drivers/infiniband/hw/i40iw/i40iw_pble.c b/drivers/infiniband/hw/i40iw/i40iw_pble.c +index c87ba16..540aab5 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_pble.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_pble.c +@@ -269,10 +269,8 @@ static enum i40iw_status_code add_bp_pages(struct i40iw_sc_dev *dev, + status = i40iw_add_sd_table_entry(dev->hw, hmc_info, + info->idx.sd_idx, I40IW_SD_TYPE_PAGED, + I40IW_HMC_DIRECT_BP_SIZE); +- if (status) { +- i40iw_free_vmalloc_mem(dev->hw, chunk); +- return status; +- } ++ if (status) ++ goto error; + if (!dev->is_pf) { + status = i40iw_vchnl_vf_add_hmc_objs(dev, I40IW_HMC_IW_PBLE, + fpm_to_idx(pble_rsrc, +@@ -280,8 +278,7 @@ static enum i40iw_status_code add_bp_pages(struct i40iw_sc_dev *dev, + (info->pages << PBLE_512_SHIFT)); + if (status) { + i40iw_pr_err("allocate PBLEs in the PF. Error %i\n", status); +- i40iw_free_vmalloc_mem(dev->hw, chunk); +- return status; ++ goto error; + } + } + addr = chunk->vaddr; +-- +2.1.3 + diff --git a/linux-next-cherry-picks/0179-i40iw-Fixes-for-static-checker-warnings.patch b/linux-next-cherry-picks/0179-i40iw-Fixes-for-static-checker-warnings.patch new file mode 100644 index 0000000..9b4a533 --- /dev/null +++ b/linux-next-cherry-picks/0179-i40iw-Fixes-for-static-checker-warnings.patch @@ -0,0 +1,58 @@ +From 83fb1c89e7ee5bb16397b294ccfbd65a9a22e402 Mon Sep 17 00:00:00 2001 +From: Shiraz Saleem +Date: Wed, 19 Jul 2017 13:55:26 -0500 +Subject: [PATCH 12883/13040] i40iw: Fixes for static checker warnings + +Remove NULL check for cm_node->listener in i40iw_accept +as listener is always present at this point. + +Remove the check for cm_node->accept_pend and related code +in i40iw_cm_event_connected as the cm_node in this context +is only pertinent to active node and cm_node->accept_pend +is always 0. + +This fixes the following smatch warnings, + +drivers/infiniband/hw/i40iw/i40iw_cm.c:3691 i40iw_accept() +error: we previously assumed 'cm_node->listener' could be null + +drivers/infiniband/hw/i40iw/i40iw_cm.c:4061 i40iw_cm_event_connected() +error: we previously assumed 'cm_node->listener' could be null + +Reported-by: Dan Carpenter +Signed-off-by: Shiraz Saleem +Signed-off-by: Doug Ledford +--- + drivers/infiniband/hw/i40iw/i40iw_cm.c | 9 +-------- + 1 file changed, 1 insertion(+), 8 deletions(-) + +diff --git a/drivers/infiniband/hw/i40iw/i40iw_cm.c b/drivers/infiniband/hw/i40iw/i40iw_cm.c +index 5a2fa74..a2b1350 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_cm.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_cm.c +@@ -3687,8 +3687,6 @@ int i40iw_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) + + cm_node->accelerated = 1; + if (cm_node->accept_pend) { +- if (!cm_node->listener) +- i40iw_pr_err("cm_node->listener NULL for passive node\n"); + atomic_dec(&cm_node->listener->pend_accepts_cnt); + cm_node->accept_pend = 0; + } +@@ -4056,12 +4054,7 @@ static void i40iw_cm_event_connected(struct i40iw_cm_event *event) + i40iw_modify_qp(&iwqp->ibqp, &attr, IB_QP_STATE, NULL); + + cm_node->accelerated = 1; +- if (cm_node->accept_pend) { +- if (!cm_node->listener) +- i40iw_pr_err("listener is null for passive node\n"); +- atomic_dec(&cm_node->listener->pend_accepts_cnt); +- cm_node->accept_pend = 0; +- } ++ + return; + + error: +-- +2.1.3 + diff --git a/linux-next-cherry-picks/0180-i40iw-fix-spelling-mistake-allloc_buf-alloc_buf.patch b/linux-next-cherry-picks/0180-i40iw-fix-spelling-mistake-allloc_buf-alloc_buf.patch new file mode 100644 index 0000000..c4741ee --- /dev/null +++ b/linux-next-cherry-picks/0180-i40iw-fix-spelling-mistake-allloc_buf-alloc_buf.patch @@ -0,0 +1,42 @@ +From 5a5a3d0cfe6b3c99585d7763cd966ec1654bc4e3 Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Fri, 21 Jul 2017 23:19:33 +0100 +Subject: [PATCH 12886/13040] i40iw: fix spelling mistake: "allloc_buf" -> + "alloc_buf" + +Trivial fix to spelling mistake in i40iw_debug message and +also split up a couple of lines that are too long and cause +checkpatch warnings + +Signed-off-by: Colin Ian King +Signed-off-by: Doug Ledford +--- + drivers/infiniband/hw/i40iw/i40iw_puda.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/infiniband/hw/i40iw/i40iw_puda.c b/drivers/infiniband/hw/i40iw/i40iw_puda.c +index 71050c5..40c3137 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_puda.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_puda.c +@@ -949,14 +949,16 @@ enum i40iw_status_code i40iw_puda_create_rsrc(struct i40iw_sc_vsi *vsi, + ret = i40iw_puda_qp_create(rsrc); + } + if (ret) { +- i40iw_debug(dev, I40IW_DEBUG_PUDA, "[%s] error qp_create\n", __func__); ++ i40iw_debug(dev, I40IW_DEBUG_PUDA, "[%s] error qp_create\n", ++ __func__); + goto error; + } + rsrc->completion = PUDA_QP_CREATED; + + ret = i40iw_puda_allocbufs(rsrc, info->tx_buf_cnt + info->rq_size); + if (ret) { +- i40iw_debug(dev, I40IW_DEBUG_PUDA, "[%s] error allloc_buf\n", __func__); ++ i40iw_debug(dev, I40IW_DEBUG_PUDA, "[%s] error alloc_buf\n", ++ __func__); + goto error; + } + +-- +2.1.3 + diff --git a/linux-next-cherry-picks/0181-i40iw-Improve-CQP-timeout-logic.patch b/linux-next-cherry-picks/0181-i40iw-Improve-CQP-timeout-logic.patch new file mode 100644 index 0000000..fdffef4 --- /dev/null +++ b/linux-next-cherry-picks/0181-i40iw-Improve-CQP-timeout-logic.patch @@ -0,0 +1,138 @@ +From d26875b43d45644e87f4c0b6bb2d7abf3c61d529 Mon Sep 17 00:00:00 2001 +From: Shiraz Saleem +Date: Tue, 8 Aug 2017 20:38:45 -0500 +Subject: [PATCH 12925/13040] i40iw: Improve CQP timeout logic + +The current timeout logic for Control Queue-Pair (CQP) OPs +does not take into account whether CQP makes progress but +rather blindly waits for a large timeout value, 100000 jiffies +for the completion event. Improve this by setting the timeout +based on whether the CQP is making progress or not. If the CQP +is hung, the timeout will happen sooner, in 5000 jiffies. Each +time the CQP progress is detetcted, the timeout extends by 5000 +jiffies. + +Signed-off-by: Shiraz Saleem +Signed-off-by: Christopher N Bednarz +Signed-off-by: Henry Orosco +Signed-off-by: Doug Ledford +--- + drivers/infiniband/hw/i40iw/i40iw_ctrl.c | 11 +++++++++++ + drivers/infiniband/hw/i40iw/i40iw_p.h | 14 +++++++++----- + drivers/infiniband/hw/i40iw/i40iw_type.h | 5 +++++ + drivers/infiniband/hw/i40iw/i40iw_utils.c | 22 ++++++++++++++-------- + 4 files changed, 39 insertions(+), 13 deletions(-) + +diff --git a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c +index a49ff2e..d1f5345 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c +@@ -54,6 +54,17 @@ static inline void i40iw_insert_wqe_hdr(u64 *wqe, u64 header) + set_64bit_val(wqe, 24, header); + } + ++void i40iw_check_cqp_progress(struct i40iw_cqp_timeout *cqp_timeout, struct i40iw_sc_dev *dev) ++{ ++ if (cqp_timeout->compl_cqp_cmds != dev->cqp_cmd_stats[OP_COMPLETED_COMMANDS]) { ++ cqp_timeout->compl_cqp_cmds = dev->cqp_cmd_stats[OP_COMPLETED_COMMANDS]; ++ cqp_timeout->count = 0; ++ } else { ++ if (dev->cqp_cmd_stats[OP_REQUESTED_COMMANDS] != cqp_timeout->compl_cqp_cmds) ++ cqp_timeout->count++; ++ } ++} ++ + /** + * i40iw_get_cqp_reg_info - get head and tail for cqp using registers + * @cqp: struct for cqp hw +diff --git a/drivers/infiniband/hw/i40iw/i40iw_p.h b/drivers/infiniband/hw/i40iw/i40iw_p.h +index 28a92fe..e217a12 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_p.h ++++ b/drivers/infiniband/hw/i40iw/i40iw_p.h +@@ -35,11 +35,13 @@ + #ifndef I40IW_P_H + #define I40IW_P_H + +-#define PAUSE_TIMER_VALUE 0xFFFF +-#define REFRESH_THRESHOLD 0x7FFF +-#define HIGH_THRESHOLD 0x800 +-#define LOW_THRESHOLD 0x200 +-#define ALL_TC2PFC 0xFF ++#define PAUSE_TIMER_VALUE 0xFFFF ++#define REFRESH_THRESHOLD 0x7FFF ++#define HIGH_THRESHOLD 0x800 ++#define LOW_THRESHOLD 0x200 ++#define ALL_TC2PFC 0xFF ++#define CQP_COMPL_WAIT_TIME 0x3E8 ++#define CQP_TIMEOUT_THRESHOLD 5 + + void i40iw_debug_buf(struct i40iw_sc_dev *dev, enum i40iw_debug_flag mask, + char *desc, u64 *buf, u32 size); +@@ -51,6 +53,8 @@ void i40iw_sc_cqp_post_sq(struct i40iw_sc_cqp *cqp); + + u64 *i40iw_sc_cqp_get_next_send_wqe(struct i40iw_sc_cqp *cqp, u64 scratch); + ++void i40iw_check_cqp_progress(struct i40iw_cqp_timeout *cqp_timeout, struct i40iw_sc_dev *dev); ++ + enum i40iw_status_code i40iw_sc_mr_fast_register(struct i40iw_sc_qp *qp, + struct i40iw_fast_reg_stag_info *info, + bool post_sq); +diff --git a/drivers/infiniband/hw/i40iw/i40iw_type.h b/drivers/infiniband/hw/i40iw/i40iw_type.h +index 959ec81..63118f6 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_type.h ++++ b/drivers/infiniband/hw/i40iw/i40iw_type.h +@@ -1345,4 +1345,9 @@ struct i40iw_virtchnl_work_info { + void *worker_vf_dev; + }; + ++struct i40iw_cqp_timeout { ++ u64 compl_cqp_cmds; ++ u8 count; ++}; ++ + #endif +diff --git a/drivers/infiniband/hw/i40iw/i40iw_utils.c b/drivers/infiniband/hw/i40iw/i40iw_utils.c +index e311ec5..62f1f45 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_utils.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_utils.c +@@ -445,23 +445,29 @@ static int i40iw_wait_event(struct i40iw_device *iwdev, + { + struct cqp_commands_info *info = &cqp_request->info; + struct i40iw_cqp *iwcqp = &iwdev->cqp; ++ struct i40iw_cqp_timeout cqp_timeout; + bool cqp_error = false; + int err_code = 0; +- int timeout_ret = 0; ++ memset(&cqp_timeout, 0, sizeof(cqp_timeout)); ++ cqp_timeout.compl_cqp_cmds = iwdev->sc_dev.cqp_cmd_stats[OP_COMPLETED_COMMANDS]; ++ do { ++ if (wait_event_timeout(cqp_request->waitq, ++ cqp_request->request_done, CQP_COMPL_WAIT_TIME)) ++ break; + +- timeout_ret = wait_event_timeout(cqp_request->waitq, +- cqp_request->request_done, +- I40IW_EVENT_TIMEOUT); +- if (!timeout_ret) { +- i40iw_pr_err("error cqp command 0x%x timed out ret = %d\n", +- info->cqp_cmd, timeout_ret); ++ i40iw_check_cqp_progress(&cqp_timeout, &iwdev->sc_dev); ++ ++ if (cqp_timeout.count < CQP_TIMEOUT_THRESHOLD) ++ continue; ++ ++ i40iw_pr_err("error cqp command 0x%x timed out", info->cqp_cmd); + err_code = -ETIME; + if (!iwdev->reset) { + iwdev->reset = true; + i40iw_request_reset(iwdev); + } + goto done; +- } ++ } while (1); + cqp_error = cqp_request->compl_info.error; + if (cqp_error) { + i40iw_pr_err("error cqp command 0x%x completion maj = 0x%x min=0x%x\n", +-- +2.1.3 + diff --git a/linux-next-cherry-picks/0182-RDMA-i40iw-Remove-unused-argument.patch b/linux-next-cherry-picks/0182-RDMA-i40iw-Remove-unused-argument.patch new file mode 100644 index 0000000..4c009f3 --- /dev/null +++ b/linux-next-cherry-picks/0182-RDMA-i40iw-Remove-unused-argument.patch @@ -0,0 +1,84 @@ +From accbef5cc624be745c1de903dd3a05681aaa0ac1 Mon Sep 17 00:00:00 2001 +From: Yuval Shaia +Date: Thu, 24 Aug 2017 20:11:42 +0300 +Subject: [PATCH 12963/13040] RDMA/i40iw: Remove unused argument + +None of the calls to i40iw_netdev_vlan_ipv6 are using mac so let's +remove it from func's args-list. + +Signed-off-by: Yuval Shaia +Signed-off-by: Doug Ledford +--- + drivers/infiniband/hw/i40iw/i40iw_cm.c | 18 ++++++------------ + 1 file changed, 6 insertions(+), 12 deletions(-) + +diff --git a/drivers/infiniband/hw/i40iw/i40iw_cm.c b/drivers/infiniband/hw/i40iw/i40iw_cm.c +index a2b1350..14f36ba 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_cm.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_cm.c +@@ -1582,15 +1582,14 @@ static enum i40iw_status_code i40iw_del_multiple_qhash( + } + + /** +- * i40iw_netdev_vlan_ipv6 - Gets the netdev and mac ++ * i40iw_netdev_vlan_ipv6 - Gets the netdev and vlan + * @addr: local IPv6 address + * @vlan_id: vlan id for the given IPv6 address +- * @mac: mac address for the given IPv6 address + * + * Returns the net_device of the IPv6 address and also sets the +- * vlan id and mac for that address. ++ * vlan id for that address. + */ +-static struct net_device *i40iw_netdev_vlan_ipv6(u32 *addr, u16 *vlan_id, u8 *mac) ++static struct net_device *i40iw_netdev_vlan_ipv6(u32 *addr, u16 *vlan_id) + { + struct net_device *ip_dev = NULL; + struct in6_addr laddr6; +@@ -1600,15 +1599,11 @@ static struct net_device *i40iw_netdev_vlan_ipv6(u32 *addr, u16 *vlan_id, u8 *ma + i40iw_copy_ip_htonl(laddr6.in6_u.u6_addr32, addr); + if (vlan_id) + *vlan_id = I40IW_NO_VLAN; +- if (mac) +- eth_zero_addr(mac); + rcu_read_lock(); + for_each_netdev_rcu(&init_net, ip_dev) { + if (ipv6_chk_addr(&init_net, &laddr6, ip_dev, 1)) { + if (vlan_id) + *vlan_id = rdma_vlan_dev_vlan_id(ip_dev); +- if (ip_dev->dev_addr && mac) +- ether_addr_copy(mac, ip_dev->dev_addr); + break; + } + } +@@ -3588,7 +3583,7 @@ int i40iw_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) + cm_node->vlan_id = i40iw_get_vlan_ipv4(cm_node->loc_addr); + } else { + cm_node->ipv4 = false; +- i40iw_netdev_vlan_ipv6(cm_node->loc_addr, &cm_node->vlan_id, NULL); ++ i40iw_netdev_vlan_ipv6(cm_node->loc_addr, &cm_node->vlan_id); + } + i40iw_debug(cm_node->dev, + I40IW_DEBUG_CM, +@@ -3787,7 +3782,7 @@ int i40iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) + raddr6->sin6_addr.in6_u.u6_addr32); + cm_info.loc_port = ntohs(laddr6->sin6_port); + cm_info.rem_port = ntohs(raddr6->sin6_port); +- i40iw_netdev_vlan_ipv6(cm_info.loc_addr, &cm_info.vlan_id, NULL); ++ i40iw_netdev_vlan_ipv6(cm_info.loc_addr, &cm_info.vlan_id); + } + cm_info.cm_id = cm_id; + cm_info.tos = cm_id->tos; +@@ -3929,8 +3924,7 @@ int i40iw_create_listen(struct iw_cm_id *cm_id, int backlog) + cm_info.loc_port = ntohs(laddr6->sin6_port); + if (ipv6_addr_type(&laddr6->sin6_addr) != IPV6_ADDR_ANY) + i40iw_netdev_vlan_ipv6(cm_info.loc_addr, +- &cm_info.vlan_id, +- NULL); ++ &cm_info.vlan_id); + else + wildcard = true; + } +-- +2.1.3 + diff --git a/linux-next-cherry-picks/0183-RDMA-i40iw-use-designated-initializers.patch b/linux-next-cherry-picks/0183-RDMA-i40iw-use-designated-initializers.patch new file mode 100644 index 0000000..6bdf4fa --- /dev/null +++ b/linux-next-cherry-picks/0183-RDMA-i40iw-use-designated-initializers.patch @@ -0,0 +1,240 @@ +From 7f6856b789ff13ccfd317c936e4b161c0bbd88a3 Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Fri, 16 Dec 2016 17:05:42 -0800 +Subject: [PATCH] RDMA/i40iw: use designated initializers + +Prepare to mark sensitive kernel structures for randomization by making +sure they're using designated initializers. These were identified during +allyesconfig builds of x86, arm, and arm64, with most initializer fixes +extracted from grsecurity. + +Signed-off-by: Kees Cook +Acked-by: Shiraz Saleem +Signed-off-by: Doug Ledford +--- + drivers/infiniband/hw/i40iw/i40iw_ctrl.c | 128 +++++++++++++++---------------- + drivers/infiniband/hw/i40iw/i40iw_uk.c | 34 ++++---- + 2 files changed, 80 insertions(+), 82 deletions(-) + +diff --git a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c +index 98923a8..dced4f4 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c +@@ -4851,46 +4851,46 @@ void i40iw_vsi_stats_free(struct i40iw_sc_vsi *vsi) + } + + static struct i40iw_cqp_ops iw_cqp_ops = { +- i40iw_sc_cqp_init, +- i40iw_sc_cqp_create, +- i40iw_sc_cqp_post_sq, +- i40iw_sc_cqp_get_next_send_wqe, +- i40iw_sc_cqp_destroy, +- i40iw_sc_poll_for_cqp_op_done ++ .cqp_init = i40iw_sc_cqp_init, ++ .cqp_create = i40iw_sc_cqp_create, ++ .cqp_post_sq = i40iw_sc_cqp_post_sq, ++ .cqp_get_next_send_wqe = i40iw_sc_cqp_get_next_send_wqe, ++ .cqp_destroy = i40iw_sc_cqp_destroy, ++ .poll_for_cqp_op_done = i40iw_sc_poll_for_cqp_op_done + }; + + static struct i40iw_ccq_ops iw_ccq_ops = { +- i40iw_sc_ccq_init, +- i40iw_sc_ccq_create, +- i40iw_sc_ccq_destroy, +- i40iw_sc_ccq_create_done, +- i40iw_sc_ccq_get_cqe_info, +- i40iw_sc_ccq_arm ++ .ccq_init = i40iw_sc_ccq_init, ++ .ccq_create = i40iw_sc_ccq_create, ++ .ccq_destroy = i40iw_sc_ccq_destroy, ++ .ccq_create_done = i40iw_sc_ccq_create_done, ++ .ccq_get_cqe_info = i40iw_sc_ccq_get_cqe_info, ++ .ccq_arm = i40iw_sc_ccq_arm + }; + + static struct i40iw_ceq_ops iw_ceq_ops = { +- i40iw_sc_ceq_init, +- i40iw_sc_ceq_create, +- i40iw_sc_cceq_create_done, +- i40iw_sc_cceq_destroy_done, +- i40iw_sc_cceq_create, +- i40iw_sc_ceq_destroy, +- i40iw_sc_process_ceq ++ .ceq_init = i40iw_sc_ceq_init, ++ .ceq_create = i40iw_sc_ceq_create, ++ .cceq_create_done = i40iw_sc_cceq_create_done, ++ .cceq_destroy_done = i40iw_sc_cceq_destroy_done, ++ .cceq_create = i40iw_sc_cceq_create, ++ .ceq_destroy = i40iw_sc_ceq_destroy, ++ .process_ceq = i40iw_sc_process_ceq + }; + + static struct i40iw_aeq_ops iw_aeq_ops = { +- i40iw_sc_aeq_init, +- i40iw_sc_aeq_create, +- i40iw_sc_aeq_destroy, +- i40iw_sc_get_next_aeqe, +- i40iw_sc_repost_aeq_entries, +- i40iw_sc_aeq_create_done, +- i40iw_sc_aeq_destroy_done ++ .aeq_init = i40iw_sc_aeq_init, ++ .aeq_create = i40iw_sc_aeq_create, ++ .aeq_destroy = i40iw_sc_aeq_destroy, ++ .get_next_aeqe = i40iw_sc_get_next_aeqe, ++ .repost_aeq_entries = i40iw_sc_repost_aeq_entries, ++ .aeq_create_done = i40iw_sc_aeq_create_done, ++ .aeq_destroy_done = i40iw_sc_aeq_destroy_done + }; + + /* iwarp pd ops */ + static struct i40iw_pd_ops iw_pd_ops = { +- i40iw_sc_pd_init, ++ .pd_init = i40iw_sc_pd_init, + }; + + static struct i40iw_priv_qp_ops iw_priv_qp_ops = { +@@ -4909,53 +4909,51 @@ static struct i40iw_priv_qp_ops iw_priv_qp_ops = { + }; + + static struct i40iw_priv_cq_ops iw_priv_cq_ops = { +- i40iw_sc_cq_init, +- i40iw_sc_cq_create, +- i40iw_sc_cq_destroy, +- i40iw_sc_cq_modify, ++ .cq_init = i40iw_sc_cq_init, ++ .cq_create = i40iw_sc_cq_create, ++ .cq_destroy = i40iw_sc_cq_destroy, ++ .cq_modify = i40iw_sc_cq_modify, + }; + + static struct i40iw_mr_ops iw_mr_ops = { +- i40iw_sc_alloc_stag, +- i40iw_sc_mr_reg_non_shared, +- i40iw_sc_mr_reg_shared, +- i40iw_sc_dealloc_stag, +- i40iw_sc_query_stag, +- i40iw_sc_mw_alloc ++ .alloc_stag = i40iw_sc_alloc_stag, ++ .mr_reg_non_shared = i40iw_sc_mr_reg_non_shared, ++ .mr_reg_shared = i40iw_sc_mr_reg_shared, ++ .dealloc_stag = i40iw_sc_dealloc_stag, ++ .query_stag = i40iw_sc_query_stag, ++ .mw_alloc = i40iw_sc_mw_alloc + }; + + static struct i40iw_cqp_misc_ops iw_cqp_misc_ops = { +- i40iw_sc_manage_push_page, +- i40iw_sc_manage_hmc_pm_func_table, +- i40iw_sc_set_hmc_resource_profile, +- i40iw_sc_commit_fpm_values, +- i40iw_sc_query_fpm_values, +- i40iw_sc_static_hmc_pages_allocated, +- i40iw_sc_add_arp_cache_entry, +- i40iw_sc_del_arp_cache_entry, +- i40iw_sc_query_arp_cache_entry, +- i40iw_sc_manage_apbvt_entry, +- i40iw_sc_manage_qhash_table_entry, +- i40iw_sc_alloc_local_mac_ipaddr_entry, +- i40iw_sc_add_local_mac_ipaddr_entry, +- i40iw_sc_del_local_mac_ipaddr_entry, +- i40iw_sc_cqp_nop, +- i40iw_sc_commit_fpm_values_done, +- i40iw_sc_query_fpm_values_done, +- i40iw_sc_manage_hmc_pm_func_table_done, +- i40iw_sc_suspend_qp, +- i40iw_sc_resume_qp ++ .manage_push_page = i40iw_sc_manage_push_page, ++ .manage_hmc_pm_func_table = i40iw_sc_manage_hmc_pm_func_table, ++ .set_hmc_resource_profile = i40iw_sc_set_hmc_resource_profile, ++ .commit_fpm_values = i40iw_sc_commit_fpm_values, ++ .query_fpm_values = i40iw_sc_query_fpm_values, ++ .static_hmc_pages_allocated = i40iw_sc_static_hmc_pages_allocated, ++ .add_arp_cache_entry = i40iw_sc_add_arp_cache_entry, ++ .del_arp_cache_entry = i40iw_sc_del_arp_cache_entry, ++ .query_arp_cache_entry = i40iw_sc_query_arp_cache_entry, ++ .manage_apbvt_entry = i40iw_sc_manage_apbvt_entry, ++ .manage_qhash_table_entry = i40iw_sc_manage_qhash_table_entry, ++ .alloc_local_mac_ipaddr_table_entry = i40iw_sc_alloc_local_mac_ipaddr_entry, ++ .add_local_mac_ipaddr_entry = i40iw_sc_add_local_mac_ipaddr_entry, ++ .del_local_mac_ipaddr_entry = i40iw_sc_del_local_mac_ipaddr_entry, ++ .cqp_nop = i40iw_sc_cqp_nop, ++ .commit_fpm_values_done = i40iw_sc_commit_fpm_values_done, ++ .query_fpm_values_done = i40iw_sc_query_fpm_values_done, ++ .manage_hmc_pm_func_table_done = i40iw_sc_manage_hmc_pm_func_table_done, ++ .update_suspend_qp = i40iw_sc_suspend_qp, ++ .update_resume_qp = i40iw_sc_resume_qp + }; + + static struct i40iw_hmc_ops iw_hmc_ops = { +- i40iw_sc_init_iw_hmc, +- i40iw_sc_parse_fpm_query_buf, +- i40iw_sc_configure_iw_fpm, +- i40iw_sc_parse_fpm_commit_buf, +- i40iw_sc_create_hmc_obj, +- i40iw_sc_del_hmc_obj, +- NULL, +- NULL ++ .init_iw_hmc = i40iw_sc_init_iw_hmc, ++ .parse_fpm_query_buf = i40iw_sc_parse_fpm_query_buf, ++ .configure_iw_fpm = i40iw_sc_configure_iw_fpm, ++ .parse_fpm_commit_buf = i40iw_sc_parse_fpm_commit_buf, ++ .create_hmc_object = i40iw_sc_create_hmc_obj, ++ .del_hmc_object = i40iw_sc_del_hmc_obj + }; + + /** +diff --git a/drivers/infiniband/hw/i40iw/i40iw_uk.c b/drivers/infiniband/hw/i40iw/i40iw_uk.c +index 2800f79..b0d3a0e 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_uk.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_uk.c +@@ -913,29 +913,29 @@ enum i40iw_status_code i40iw_get_wqe_shift(u32 wqdepth, u32 sge, u32 inline_data + } + + static struct i40iw_qp_uk_ops iw_qp_uk_ops = { +- i40iw_qp_post_wr, +- i40iw_qp_ring_push_db, +- i40iw_rdma_write, +- i40iw_rdma_read, +- i40iw_send, +- i40iw_inline_rdma_write, +- i40iw_inline_send, +- i40iw_stag_local_invalidate, +- i40iw_mw_bind, +- i40iw_post_receive, +- i40iw_nop ++ .iw_qp_post_wr = i40iw_qp_post_wr, ++ .iw_qp_ring_push_db = i40iw_qp_ring_push_db, ++ .iw_rdma_write = i40iw_rdma_write, ++ .iw_rdma_read = i40iw_rdma_read, ++ .iw_send = i40iw_send, ++ .iw_inline_rdma_write = i40iw_inline_rdma_write, ++ .iw_inline_send = i40iw_inline_send, ++ .iw_stag_local_invalidate = i40iw_stag_local_invalidate, ++ .iw_mw_bind = i40iw_mw_bind, ++ .iw_post_receive = i40iw_post_receive, ++ .iw_post_nop = i40iw_nop + }; + + static struct i40iw_cq_ops iw_cq_ops = { +- i40iw_cq_request_notification, +- i40iw_cq_poll_completion, +- i40iw_cq_post_entries, +- i40iw_clean_cq ++ .iw_cq_request_notification = i40iw_cq_request_notification, ++ .iw_cq_poll_completion = i40iw_cq_poll_completion, ++ .iw_cq_post_entries = i40iw_cq_post_entries, ++ .iw_cq_clean = i40iw_clean_cq + }; + + static struct i40iw_device_uk_ops iw_device_uk_ops = { +- i40iw_cq_uk_init, +- i40iw_qp_uk_init, ++ .iwarp_cq_uk_init = i40iw_cq_uk_init, ++ .iwarp_qp_uk_init = i40iw_qp_uk_init, + }; + + /** +-- +2.1.3 + diff --git a/linux-next-cherry-picks/0184-i40iw-make-some-structures-const.patch b/linux-next-cherry-picks/0184-i40iw-make-some-structures-const.patch new file mode 100644 index 0000000..9c64812 --- /dev/null +++ b/linux-next-cherry-picks/0184-i40iw-make-some-structures-const.patch @@ -0,0 +1,47 @@ +From cfeca08faf452acaf807576859275968cdb7e7a2 Mon Sep 17 00:00:00 2001 +From: Bhumika Goyal +Date: Mon, 28 Aug 2017 21:51:23 +0530 +Subject: [PATCH 12991/13040] i40iw: make some structures const + +Make some structures const as they are only used during a copy +operation. + +Signed-off-by: Bhumika Goyal +Signed-off-by: Doug Ledford +--- + drivers/infiniband/hw/i40iw/i40iw_uk.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/infiniband/hw/i40iw/i40iw_uk.c b/drivers/infiniband/hw/i40iw/i40iw_uk.c +index 1060725..0aadb7a 100644 +--- a/drivers/infiniband/hw/i40iw/i40iw_uk.c ++++ b/drivers/infiniband/hw/i40iw/i40iw_uk.c +@@ -912,7 +912,7 @@ enum i40iw_status_code i40iw_get_wqe_shift(u32 wqdepth, u32 sge, u32 inline_data + return 0; + } + +-static struct i40iw_qp_uk_ops iw_qp_uk_ops = { ++static const struct i40iw_qp_uk_ops iw_qp_uk_ops = { + .iw_qp_post_wr = i40iw_qp_post_wr, + .iw_qp_ring_push_db = i40iw_qp_ring_push_db, + .iw_rdma_write = i40iw_rdma_write, +@@ -926,14 +926,14 @@ static struct i40iw_qp_uk_ops iw_qp_uk_ops = { + .iw_post_nop = i40iw_nop + }; + +-static struct i40iw_cq_ops iw_cq_ops = { ++static const struct i40iw_cq_ops iw_cq_ops = { + .iw_cq_request_notification = i40iw_cq_request_notification, + .iw_cq_poll_completion = i40iw_cq_poll_completion, + .iw_cq_post_entries = i40iw_cq_post_entries, + .iw_cq_clean = i40iw_clean_cq + }; + +-static struct i40iw_device_uk_ops iw_device_uk_ops = { ++static const struct i40iw_device_uk_ops iw_device_uk_ops = { + .iwarp_cq_uk_init = i40iw_cq_uk_init, + .iwarp_qp_uk_init = i40iw_qp_uk_init, + }; +-- +2.1.3 + -- 2.41.0