aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWei Hu (Xavier) <xavier.huwei@huawei.com>2016-11-29 18:10:25 -0500
committerDoug Ledford <dledford@redhat.com>2016-12-03 14:20:42 -0500
commitd838c481e025db374171e16d5cc463b85cffec9f (patch)
tree821fe6dafe52c1e4789c6123b6ce7956bc78f1b6
parente84e40be8e7bc29599da7056b340490d25ff87b5 (diff)
IB/hns: Fix the bug when destroy qp
If send queue is still working when qp is in reset state by modify qp in destroy qp function, hardware will hold on and don't work in hip06 SoC. In current codes, RoCE driver check hardware pointer of sending and hardware pointer of processing to ensure that hardware has processed all the dbs of this qp. But while the environment of wire becomes not good, The checking time maybe too long. In order to solve this problem, RoCE driver created a workqueue at probe function. If there is a timeout when checking the status of qp, driver initialize work entry and push it into the workqueue, Work function will finish checking and release the related resources later. Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com> Signed-off-by: Lijun Ou <oulijun@huawei.com> Signed-off-by: Dongdong Huang(Donald) <hdd.huang@huawei.com> Signed-off-by: Salil Mehta <salil.mehta@huawei.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_common.h40
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_hw_v1.c435
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_hw_v1.h23
3 files changed, 402 insertions, 96 deletions
diff --git a/drivers/infiniband/hw/hns/hns_roce_common.h b/drivers/infiniband/hw/hns/hns_roce_common.h
index 0dcb620e91dd..a0556323a678 100644
--- a/drivers/infiniband/hw/hns/hns_roce_common.h
+++ b/drivers/infiniband/hw/hns/hns_roce_common.h
@@ -57,6 +57,32 @@
57#define roce_set_bit(origin, shift, val) \ 57#define roce_set_bit(origin, shift, val) \
58 roce_set_field((origin), (1ul << (shift)), (shift), (val)) 58 roce_set_field((origin), (1ul << (shift)), (shift), (val))
59 59
60/*
61 * roce_hw_index_cmp_lt - Compare two hardware index values in hisilicon
62 * SOC, check if a is less than b.
63 * @a: hardware index value
64 * @b: hardware index value
65 * @bits: the number of bits of a and b, range: 0~31.
66 *
67 * Hardware index increases continuously till max value, and then restart
68 * from zero, again and again. Because the bits of reg field is often
69 * limited, the reg field can only hold the low bits of the hardware index
70 * in hisilicon SOC.
71 * In some scenes we need to compare two values(a,b) getted from two reg
72 * fields in this driver, for example:
73 * If a equals 0xfffe, b equals 0x1 and bits equals 16, we think b has
74 * incresed from 0xffff to 0x1 and a is less than b.
75 * If a equals 0xfffe, b equals 0x0xf001 and bits equals 16, we think a
76 * is bigger than b.
77 *
78 * Return true on a less than b, otherwise false.
79 */
80#define roce_hw_index_mask(bits) ((1ul << (bits)) - 1)
81#define roce_hw_index_shift(bits) (32 - (bits))
82#define roce_hw_index_cmp_lt(a, b, bits) \
83 ((int)((((a) - (b)) & roce_hw_index_mask(bits)) << \
84 roce_hw_index_shift(bits)) < 0)
85
60#define ROCEE_GLB_CFG_ROCEE_DB_SQ_MODE_S 3 86#define ROCEE_GLB_CFG_ROCEE_DB_SQ_MODE_S 3
61#define ROCEE_GLB_CFG_ROCEE_DB_OTH_MODE_S 4 87#define ROCEE_GLB_CFG_ROCEE_DB_OTH_MODE_S 4
62 88
@@ -245,10 +271,22 @@
245#define ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_M \ 271#define ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_M \
246 (((1UL << 28) - 1) << ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_S) 272 (((1UL << 28) - 1) << ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_S)
247 273
274#define ROCEE_SDB_PTR_CMP_BITS 28
275
248#define ROCEE_SDB_INV_CNT_SDB_INV_CNT_S 0 276#define ROCEE_SDB_INV_CNT_SDB_INV_CNT_S 0
249#define ROCEE_SDB_INV_CNT_SDB_INV_CNT_M \ 277#define ROCEE_SDB_INV_CNT_SDB_INV_CNT_M \
250 (((1UL << 16) - 1) << ROCEE_SDB_INV_CNT_SDB_INV_CNT_S) 278 (((1UL << 16) - 1) << ROCEE_SDB_INV_CNT_SDB_INV_CNT_S)
251 279
280#define ROCEE_SDB_RETRY_CNT_SDB_RETRY_CT_S 0
281#define ROCEE_SDB_RETRY_CNT_SDB_RETRY_CT_M \
282 (((1UL << 16) - 1) << ROCEE_SDB_RETRY_CNT_SDB_RETRY_CT_S)
283
284#define ROCEE_SDB_CNT_CMP_BITS 16
285
286#define ROCEE_TSP_BP_ST_QH_FIFO_ENTRY_S 20
287
288#define ROCEE_CNT_CLR_CE_CNT_CLR_CE_S 0
289
252/*************ROCEE_REG DEFINITION****************/ 290/*************ROCEE_REG DEFINITION****************/
253#define ROCEE_VENDOR_ID_REG 0x0 291#define ROCEE_VENDOR_ID_REG 0x0
254#define ROCEE_VENDOR_PART_ID_REG 0x4 292#define ROCEE_VENDOR_PART_ID_REG 0x4
@@ -317,6 +355,8 @@
317#define ROCEE_SDB_ISSUE_PTR_REG 0x758 355#define ROCEE_SDB_ISSUE_PTR_REG 0x758
318#define ROCEE_SDB_SEND_PTR_REG 0x75C 356#define ROCEE_SDB_SEND_PTR_REG 0x75C
319#define ROCEE_SDB_INV_CNT_REG 0x9A4 357#define ROCEE_SDB_INV_CNT_REG 0x9A4
358#define ROCEE_SDB_RETRY_CNT_REG 0x9AC
359#define ROCEE_TSP_BP_ST_REG 0x9EC
320#define ROCEE_ECC_UCERR_ALM0_REG 0xB34 360#define ROCEE_ECC_UCERR_ALM0_REG 0xB34
321#define ROCEE_ECC_CERR_ALM0_REG 0xB40 361#define ROCEE_ECC_CERR_ALM0_REG 0xB40
322 362
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
index 125ab90157f6..aee1d01ca70c 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
@@ -948,6 +948,38 @@ int hns_roce_v1_reset(struct hns_roce_dev *hr_dev, bool dereset)
948 return ret; 948 return ret;
949} 949}
950 950
951static int hns_roce_des_qp_init(struct hns_roce_dev *hr_dev)
952{
953 struct device *dev = &hr_dev->pdev->dev;
954 struct hns_roce_v1_priv *priv;
955 struct hns_roce_des_qp *des_qp;
956
957 priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
958 des_qp = &priv->des_qp;
959
960 des_qp->requeue_flag = 1;
961 des_qp->qp_wq = create_singlethread_workqueue("hns_roce_destroy_qp");
962 if (!des_qp->qp_wq) {
963 dev_err(dev, "Create destroy qp workqueue failed!\n");
964 return -ENOMEM;
965 }
966
967 return 0;
968}
969
970static void hns_roce_des_qp_free(struct hns_roce_dev *hr_dev)
971{
972 struct hns_roce_v1_priv *priv;
973 struct hns_roce_des_qp *des_qp;
974
975 priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
976 des_qp = &priv->des_qp;
977
978 des_qp->requeue_flag = 0;
979 flush_workqueue(des_qp->qp_wq);
980 destroy_workqueue(des_qp->qp_wq);
981}
982
951void hns_roce_v1_profile(struct hns_roce_dev *hr_dev) 983void hns_roce_v1_profile(struct hns_roce_dev *hr_dev)
952{ 984{
953 int i = 0; 985 int i = 0;
@@ -1050,8 +1082,6 @@ int hns_roce_v1_init(struct hns_roce_dev *hr_dev)
1050 goto error_failed_raq_init; 1082 goto error_failed_raq_init;
1051 } 1083 }
1052 1084
1053 hns_roce_port_enable(hr_dev, HNS_ROCE_PORT_UP);
1054
1055 ret = hns_roce_bt_init(hr_dev); 1085 ret = hns_roce_bt_init(hr_dev);
1056 if (ret) { 1086 if (ret) {
1057 dev_err(dev, "bt init failed!\n"); 1087 dev_err(dev, "bt init failed!\n");
@@ -1064,13 +1094,23 @@ int hns_roce_v1_init(struct hns_roce_dev *hr_dev)
1064 goto error_failed_tptr_init; 1094 goto error_failed_tptr_init;
1065 } 1095 }
1066 1096
1097 ret = hns_roce_des_qp_init(hr_dev);
1098 if (ret) {
1099 dev_err(dev, "des qp init failed!\n");
1100 goto error_failed_des_qp_init;
1101 }
1102
1103 hns_roce_port_enable(hr_dev, HNS_ROCE_PORT_UP);
1104
1067 return 0; 1105 return 0;
1068 1106
1107error_failed_des_qp_init:
1108 hns_roce_tptr_free(hr_dev);
1109
1069error_failed_tptr_init: 1110error_failed_tptr_init:
1070 hns_roce_bt_free(hr_dev); 1111 hns_roce_bt_free(hr_dev);
1071 1112
1072error_failed_bt_init: 1113error_failed_bt_init:
1073 hns_roce_port_enable(hr_dev, HNS_ROCE_PORT_DOWN);
1074 hns_roce_raq_free(hr_dev); 1114 hns_roce_raq_free(hr_dev);
1075 1115
1076error_failed_raq_init: 1116error_failed_raq_init:
@@ -1080,9 +1120,10 @@ error_failed_raq_init:
1080 1120
1081void hns_roce_v1_exit(struct hns_roce_dev *hr_dev) 1121void hns_roce_v1_exit(struct hns_roce_dev *hr_dev)
1082{ 1122{
1123 hns_roce_port_enable(hr_dev, HNS_ROCE_PORT_DOWN);
1124 hns_roce_des_qp_free(hr_dev);
1083 hns_roce_tptr_free(hr_dev); 1125 hns_roce_tptr_free(hr_dev);
1084 hns_roce_bt_free(hr_dev); 1126 hns_roce_bt_free(hr_dev);
1085 hns_roce_port_enable(hr_dev, HNS_ROCE_PORT_DOWN);
1086 hns_roce_raq_free(hr_dev); 1127 hns_roce_raq_free(hr_dev);
1087 hns_roce_db_free(hr_dev); 1128 hns_roce_db_free(hr_dev);
1088} 1129}
@@ -2906,132 +2947,334 @@ int hns_roce_v1_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
2906 hns_roce_v1_q_sqp(ibqp, qp_attr, qp_attr_mask, qp_init_attr) : 2947 hns_roce_v1_q_sqp(ibqp, qp_attr, qp_attr_mask, qp_init_attr) :
2907 hns_roce_v1_q_qp(ibqp, qp_attr, qp_attr_mask, qp_init_attr); 2948 hns_roce_v1_q_qp(ibqp, qp_attr, qp_attr_mask, qp_init_attr);
2908} 2949}
2909static void hns_roce_v1_destroy_qp_common(struct hns_roce_dev *hr_dev, 2950
2910 struct hns_roce_qp *hr_qp, 2951static int check_qp_db_process_status(struct hns_roce_dev *hr_dev,
2911 int is_user) 2952 struct hns_roce_qp *hr_qp,
2953 u32 sdb_issue_ptr,
2954 u32 *sdb_inv_cnt,
2955 u32 *wait_stage)
2912{ 2956{
2913 u32 sdbinvcnt;
2914 unsigned long end = 0;
2915 u32 sdbinvcnt_val;
2916 u32 sdbsendptr_val;
2917 u32 sdbisusepr_val;
2918 struct hns_roce_cq *send_cq, *recv_cq;
2919 struct device *dev = &hr_dev->pdev->dev; 2957 struct device *dev = &hr_dev->pdev->dev;
2958 u32 sdb_retry_cnt, old_retry;
2959 u32 sdb_send_ptr, old_send;
2960 u32 success_flags = 0;
2961 u32 cur_cnt, old_cnt;
2962 unsigned long end;
2963 u32 send_ptr;
2964 u32 inv_cnt;
2965 u32 tsp_st;
2966
2967 if (*wait_stage > HNS_ROCE_V1_DB_STAGE2 ||
2968 *wait_stage < HNS_ROCE_V1_DB_STAGE1) {
2969 dev_err(dev, "QP(0x%lx) db status wait stage(%d) error!\n",
2970 hr_qp->qpn, *wait_stage);
2971 return -EINVAL;
2972 }
2920 2973
2921 if (hr_qp->ibqp.qp_type == IB_QPT_RC) { 2974 /* Calculate the total timeout for the entire verification process */
2922 if (hr_qp->state != IB_QPS_RESET) { 2975 end = msecs_to_jiffies(HNS_ROCE_V1_CHECK_DB_TIMEOUT_MSECS) + jiffies;
2923 /* 2976
2924 * Set qp to ERR, 2977 if (*wait_stage == HNS_ROCE_V1_DB_STAGE1) {
2925 * waiting for hw complete processing all dbs 2978 /* Query db process status, until hw process completely */
2926 */ 2979 sdb_send_ptr = roce_read(hr_dev, ROCEE_SDB_SEND_PTR_REG);
2927 if (hns_roce_v1_qp_modify(hr_dev, NULL, 2980 while (roce_hw_index_cmp_lt(sdb_send_ptr, sdb_issue_ptr,
2928 to_hns_roce_state( 2981 ROCEE_SDB_PTR_CMP_BITS)) {
2929 (enum ib_qp_state)hr_qp->state), 2982 if (!time_before(jiffies, end)) {
2930 HNS_ROCE_QP_STATE_ERR, NULL, 2983 dev_dbg(dev, "QP(0x%lx) db process stage1 timeout. issue 0x%x send 0x%x.\n",
2931 hr_qp)) 2984 hr_qp->qpn, sdb_issue_ptr,
2932 dev_err(dev, "modify QP %06lx to ERR failed.\n", 2985 sdb_send_ptr);
2933 hr_qp->qpn); 2986 return 0;
2934 2987 }
2935 /* Record issued doorbell */ 2988
2936 sdbisusepr_val = roce_read(hr_dev, 2989 msleep(HNS_ROCE_V1_CHECK_DB_SLEEP_MSECS);
2937 ROCEE_SDB_ISSUE_PTR_REG); 2990 sdb_send_ptr = roce_read(hr_dev,
2938 /*
2939 * Query db process status,
2940 * until hw process completely
2941 */
2942 end = msecs_to_jiffies(
2943 HNS_ROCE_QP_DESTROY_TIMEOUT_MSECS) + jiffies;
2944 do {
2945 sdbsendptr_val = roce_read(hr_dev,
2946 ROCEE_SDB_SEND_PTR_REG); 2991 ROCEE_SDB_SEND_PTR_REG);
2947 if (!time_before(jiffies, end)) { 2992 }
2948 dev_err(dev, "destroy qp(0x%lx) timeout!!!",
2949 hr_qp->qpn);
2950 break;
2951 }
2952 } while ((short)(roce_get_field(sdbsendptr_val,
2953 ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_M,
2954 ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_S) -
2955 roce_get_field(sdbisusepr_val,
2956 ROCEE_SDB_ISSUE_PTR_SDB_ISSUE_PTR_M,
2957 ROCEE_SDB_ISSUE_PTR_SDB_ISSUE_PTR_S)
2958 ) < 0);
2959 2993
2960 /* Get list pointer */ 2994 if (roce_get_field(sdb_issue_ptr,
2961 sdbinvcnt = roce_read(hr_dev, ROCEE_SDB_INV_CNT_REG); 2995 ROCEE_SDB_ISSUE_PTR_SDB_ISSUE_PTR_M,
2996 ROCEE_SDB_ISSUE_PTR_SDB_ISSUE_PTR_S) ==
2997 roce_get_field(sdb_send_ptr,
2998 ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_M,
2999 ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_S)) {
3000 old_send = roce_read(hr_dev, ROCEE_SDB_SEND_PTR_REG);
3001 old_retry = roce_read(hr_dev, ROCEE_SDB_RETRY_CNT_REG);
2962 3002
2963 /* Query db's list status, until hw reversal */
2964 do { 3003 do {
2965 sdbinvcnt_val = roce_read(hr_dev, 3004 tsp_st = roce_read(hr_dev, ROCEE_TSP_BP_ST_REG);
2966 ROCEE_SDB_INV_CNT_REG); 3005 if (roce_get_bit(tsp_st,
3006 ROCEE_TSP_BP_ST_QH_FIFO_ENTRY_S) == 1) {
3007 *wait_stage = HNS_ROCE_V1_DB_WAIT_OK;
3008 return 0;
3009 }
3010
2967 if (!time_before(jiffies, end)) { 3011 if (!time_before(jiffies, end)) {
2968 dev_err(dev, "destroy qp(0x%lx) timeout!!!", 3012 dev_dbg(dev, "QP(0x%lx) db process stage1 timeout when send ptr equals issue ptr.\n"
2969 hr_qp->qpn); 3013 "issue 0x%x send 0x%x.\n",
2970 dev_err(dev, "SdbInvCnt = 0x%x\n", 3014 hr_qp->qpn, sdb_issue_ptr,
2971 sdbinvcnt_val); 3015 sdb_send_ptr);
2972 break; 3016 return 0;
2973 } 3017 }
2974 } while ((short)(roce_get_field(sdbinvcnt_val, 3018
2975 ROCEE_SDB_INV_CNT_SDB_INV_CNT_M, 3019 msleep(HNS_ROCE_V1_CHECK_DB_SLEEP_MSECS);
2976 ROCEE_SDB_INV_CNT_SDB_INV_CNT_S) - 3020
2977 (sdbinvcnt + SDB_INV_CNT_OFFSET)) < 0); 3021 sdb_send_ptr = roce_read(hr_dev,
2978 3022 ROCEE_SDB_SEND_PTR_REG);
2979 /* Modify qp to reset before destroying qp */ 3023 sdb_retry_cnt = roce_read(hr_dev,
2980 if (hns_roce_v1_qp_modify(hr_dev, NULL, 3024 ROCEE_SDB_RETRY_CNT_REG);
2981 to_hns_roce_state( 3025 cur_cnt = roce_get_field(sdb_send_ptr,
2982 (enum ib_qp_state)hr_qp->state), 3026 ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_M,
2983 HNS_ROCE_QP_STATE_RST, NULL, hr_qp)) 3027 ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_S) +
2984 dev_err(dev, "modify QP %06lx to RESET failed.\n", 3028 roce_get_field(sdb_retry_cnt,
2985 hr_qp->qpn); 3029 ROCEE_SDB_RETRY_CNT_SDB_RETRY_CT_M,
3030 ROCEE_SDB_RETRY_CNT_SDB_RETRY_CT_S);
3031 if (!roce_get_bit(tsp_st,
3032 ROCEE_CNT_CLR_CE_CNT_CLR_CE_S)) {
3033 old_cnt = roce_get_field(old_send,
3034 ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_M,
3035 ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_S) +
3036 roce_get_field(old_retry,
3037 ROCEE_SDB_RETRY_CNT_SDB_RETRY_CT_M,
3038 ROCEE_SDB_RETRY_CNT_SDB_RETRY_CT_S);
3039 if (cur_cnt - old_cnt > SDB_ST_CMP_VAL)
3040 success_flags = 1;
3041 } else {
3042 old_cnt = roce_get_field(old_send,
3043 ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_M,
3044 ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_S);
3045 if (cur_cnt - old_cnt > SDB_ST_CMP_VAL)
3046 success_flags = 1;
3047 else {
3048 send_ptr = roce_get_field(old_send,
3049 ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_M,
3050 ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_S) +
3051 roce_get_field(sdb_retry_cnt,
3052 ROCEE_SDB_RETRY_CNT_SDB_RETRY_CT_M,
3053 ROCEE_SDB_RETRY_CNT_SDB_RETRY_CT_S);
3054 roce_set_field(old_send,
3055 ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_M,
3056 ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_S,
3057 send_ptr);
3058 }
3059 }
3060 } while (!success_flags);
3061 }
3062
3063 *wait_stage = HNS_ROCE_V1_DB_STAGE2;
3064
3065 /* Get list pointer */
3066 *sdb_inv_cnt = roce_read(hr_dev, ROCEE_SDB_INV_CNT_REG);
3067 dev_dbg(dev, "QP(0x%lx) db process stage2. inv cnt = 0x%x.\n",
3068 hr_qp->qpn, *sdb_inv_cnt);
3069 }
3070
3071 if (*wait_stage == HNS_ROCE_V1_DB_STAGE2) {
3072 /* Query db's list status, until hw reversal */
3073 inv_cnt = roce_read(hr_dev, ROCEE_SDB_INV_CNT_REG);
3074 while (roce_hw_index_cmp_lt(inv_cnt,
3075 *sdb_inv_cnt + SDB_INV_CNT_OFFSET,
3076 ROCEE_SDB_CNT_CMP_BITS)) {
3077 if (!time_before(jiffies, end)) {
3078 dev_dbg(dev, "QP(0x%lx) db process stage2 timeout. inv cnt 0x%x.\n",
3079 hr_qp->qpn, inv_cnt);
3080 return 0;
3081 }
3082
3083 msleep(HNS_ROCE_V1_CHECK_DB_SLEEP_MSECS);
3084 inv_cnt = roce_read(hr_dev, ROCEE_SDB_INV_CNT_REG);
2986 } 3085 }
3086
3087 *wait_stage = HNS_ROCE_V1_DB_WAIT_OK;
3088 }
3089
3090 return 0;
3091}
3092
3093static int check_qp_reset_state(struct hns_roce_dev *hr_dev,
3094 struct hns_roce_qp *hr_qp,
3095 struct hns_roce_qp_work *qp_work_entry,
3096 int *is_timeout)
3097{
3098 struct device *dev = &hr_dev->pdev->dev;
3099 u32 sdb_issue_ptr;
3100 int ret;
3101
3102 if (hr_qp->state != IB_QPS_RESET) {
3103 /* Set qp to ERR, waiting for hw complete processing all dbs */
3104 ret = hns_roce_v1_modify_qp(&hr_qp->ibqp, NULL, 0, hr_qp->state,
3105 IB_QPS_ERR);
3106 if (ret) {
3107 dev_err(dev, "Modify QP(0x%lx) to ERR failed!\n",
3108 hr_qp->qpn);
3109 return ret;
3110 }
3111
3112 /* Record issued doorbell */
3113 sdb_issue_ptr = roce_read(hr_dev, ROCEE_SDB_ISSUE_PTR_REG);
3114 qp_work_entry->sdb_issue_ptr = sdb_issue_ptr;
3115 qp_work_entry->db_wait_stage = HNS_ROCE_V1_DB_STAGE1;
3116
3117 /* Query db process status, until hw process completely */
3118 ret = check_qp_db_process_status(hr_dev, hr_qp, sdb_issue_ptr,
3119 &qp_work_entry->sdb_inv_cnt,
3120 &qp_work_entry->db_wait_stage);
3121 if (ret) {
3122 dev_err(dev, "Check QP(0x%lx) db process status failed!\n",
3123 hr_qp->qpn);
3124 return ret;
3125 }
3126
3127 if (qp_work_entry->db_wait_stage != HNS_ROCE_V1_DB_WAIT_OK) {
3128 qp_work_entry->sche_cnt = 0;
3129 *is_timeout = 1;
3130 return 0;
3131 }
3132
3133 /* Modify qp to reset before destroying qp */
3134 ret = hns_roce_v1_modify_qp(&hr_qp->ibqp, NULL, 0, hr_qp->state,
3135 IB_QPS_RESET);
3136 if (ret) {
3137 dev_err(dev, "Modify QP(0x%lx) to RST failed!\n",
3138 hr_qp->qpn);
3139 return ret;
3140 }
3141 }
3142
3143 return 0;
3144}
3145
3146static void hns_roce_v1_destroy_qp_work_fn(struct work_struct *work)
3147{
3148 struct hns_roce_qp_work *qp_work_entry;
3149 struct hns_roce_v1_priv *priv;
3150 struct hns_roce_dev *hr_dev;
3151 struct hns_roce_qp *hr_qp;
3152 struct device *dev;
3153 int ret;
3154
3155 qp_work_entry = container_of(work, struct hns_roce_qp_work, work);
3156 hr_dev = to_hr_dev(qp_work_entry->ib_dev);
3157 dev = &hr_dev->pdev->dev;
3158 priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
3159 hr_qp = qp_work_entry->qp;
3160
3161 dev_dbg(dev, "Schedule destroy QP(0x%lx) work.\n", hr_qp->qpn);
3162
3163 qp_work_entry->sche_cnt++;
3164
3165 /* Query db process status, until hw process completely */
3166 ret = check_qp_db_process_status(hr_dev, hr_qp,
3167 qp_work_entry->sdb_issue_ptr,
3168 &qp_work_entry->sdb_inv_cnt,
3169 &qp_work_entry->db_wait_stage);
3170 if (ret) {
3171 dev_err(dev, "Check QP(0x%lx) db process status failed!\n",
3172 hr_qp->qpn);
3173 return;
3174 }
3175
3176 if (qp_work_entry->db_wait_stage != HNS_ROCE_V1_DB_WAIT_OK &&
3177 priv->des_qp.requeue_flag) {
3178 queue_work(priv->des_qp.qp_wq, work);
3179 return;
3180 }
3181
3182 /* Modify qp to reset before destroying qp */
3183 ret = hns_roce_v1_modify_qp(&hr_qp->ibqp, NULL, 0, hr_qp->state,
3184 IB_QPS_RESET);
3185 if (ret) {
3186 dev_err(dev, "Modify QP(0x%lx) to RST failed!\n", hr_qp->qpn);
3187 return;
3188 }
3189
3190 hns_roce_qp_remove(hr_dev, hr_qp);
3191 hns_roce_qp_free(hr_dev, hr_qp);
3192
3193 if (hr_qp->ibqp.qp_type == IB_QPT_RC) {
3194 /* RC QP, release QPN */
3195 hns_roce_release_range_qp(hr_dev, hr_qp->qpn, 1);
3196 kfree(hr_qp);
3197 } else
3198 kfree(hr_to_hr_sqp(hr_qp));
3199
3200 kfree(qp_work_entry);
3201
3202 dev_dbg(dev, "Accomplished destroy QP(0x%lx) work.\n", hr_qp->qpn);
3203}
3204
3205int hns_roce_v1_destroy_qp(struct ib_qp *ibqp)
3206{
3207 struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
3208 struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
3209 struct device *dev = &hr_dev->pdev->dev;
3210 struct hns_roce_qp_work qp_work_entry;
3211 struct hns_roce_qp_work *qp_work;
3212 struct hns_roce_v1_priv *priv;
3213 struct hns_roce_cq *send_cq, *recv_cq;
3214 int is_user = !!ibqp->pd->uobject;
3215 int is_timeout = 0;
3216 int ret;
3217
3218 ret = check_qp_reset_state(hr_dev, hr_qp, &qp_work_entry, &is_timeout);
3219 if (ret) {
3220 dev_err(dev, "QP reset state check failed(%d)!\n", ret);
3221 return ret;
2987 } 3222 }
2988 3223
2989 send_cq = to_hr_cq(hr_qp->ibqp.send_cq); 3224 send_cq = to_hr_cq(hr_qp->ibqp.send_cq);
2990 recv_cq = to_hr_cq(hr_qp->ibqp.recv_cq); 3225 recv_cq = to_hr_cq(hr_qp->ibqp.recv_cq);
2991 3226
2992 hns_roce_lock_cqs(send_cq, recv_cq); 3227 hns_roce_lock_cqs(send_cq, recv_cq);
2993
2994 if (!is_user) { 3228 if (!is_user) {
2995 __hns_roce_v1_cq_clean(recv_cq, hr_qp->qpn, hr_qp->ibqp.srq ? 3229 __hns_roce_v1_cq_clean(recv_cq, hr_qp->qpn, hr_qp->ibqp.srq ?
2996 to_hr_srq(hr_qp->ibqp.srq) : NULL); 3230 to_hr_srq(hr_qp->ibqp.srq) : NULL);
2997 if (send_cq != recv_cq) 3231 if (send_cq != recv_cq)
2998 __hns_roce_v1_cq_clean(send_cq, hr_qp->qpn, NULL); 3232 __hns_roce_v1_cq_clean(send_cq, hr_qp->qpn, NULL);
2999 } 3233 }
3000
3001 hns_roce_qp_remove(hr_dev, hr_qp);
3002
3003 hns_roce_unlock_cqs(send_cq, recv_cq); 3234 hns_roce_unlock_cqs(send_cq, recv_cq);
3004 3235
3005 hns_roce_qp_free(hr_dev, hr_qp); 3236 if (!is_timeout) {
3237 hns_roce_qp_remove(hr_dev, hr_qp);
3238 hns_roce_qp_free(hr_dev, hr_qp);
3006 3239
3007 /* Not special_QP, free their QPN */ 3240 /* RC QP, release QPN */
3008 if ((hr_qp->ibqp.qp_type == IB_QPT_RC) || 3241 if (hr_qp->ibqp.qp_type == IB_QPT_RC)
3009 (hr_qp->ibqp.qp_type == IB_QPT_UC) || 3242 hns_roce_release_range_qp(hr_dev, hr_qp->qpn, 1);
3010 (hr_qp->ibqp.qp_type == IB_QPT_UD)) 3243 }
3011 hns_roce_release_range_qp(hr_dev, hr_qp->qpn, 1);
3012 3244
3013 hns_roce_mtt_cleanup(hr_dev, &hr_qp->mtt); 3245 hns_roce_mtt_cleanup(hr_dev, &hr_qp->mtt);
3014 3246
3015 if (is_user) { 3247 if (is_user)
3016 ib_umem_release(hr_qp->umem); 3248 ib_umem_release(hr_qp->umem);
3017 } else { 3249 else {
3018 kfree(hr_qp->sq.wrid); 3250 kfree(hr_qp->sq.wrid);
3019 kfree(hr_qp->rq.wrid); 3251 kfree(hr_qp->rq.wrid);
3252
3020 hns_roce_buf_free(hr_dev, hr_qp->buff_size, &hr_qp->hr_buf); 3253 hns_roce_buf_free(hr_dev, hr_qp->buff_size, &hr_qp->hr_buf);
3021 } 3254 }
3022}
3023 3255
3024int hns_roce_v1_destroy_qp(struct ib_qp *ibqp) 3256 if (!is_timeout) {
3025{ 3257 if (hr_qp->ibqp.qp_type == IB_QPT_RC)
3026 struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device); 3258 kfree(hr_qp);
3027 struct hns_roce_qp *hr_qp = to_hr_qp(ibqp); 3259 else
3028 3260 kfree(hr_to_hr_sqp(hr_qp));
3029 hns_roce_v1_destroy_qp_common(hr_dev, hr_qp, !!ibqp->pd->uobject); 3261 } else {
3030 3262 qp_work = kzalloc(sizeof(*qp_work), GFP_KERNEL);
3031 if (hr_qp->ibqp.qp_type == IB_QPT_GSI) 3263 if (!qp_work)
3032 kfree(hr_to_hr_sqp(hr_qp)); 3264 return -ENOMEM;
3033 else 3265
3034 kfree(hr_qp); 3266 INIT_WORK(&qp_work->work, hns_roce_v1_destroy_qp_work_fn);
3267 qp_work->ib_dev = &hr_dev->ib_dev;
3268 qp_work->qp = hr_qp;
3269 qp_work->db_wait_stage = qp_work_entry.db_wait_stage;
3270 qp_work->sdb_issue_ptr = qp_work_entry.sdb_issue_ptr;
3271 qp_work->sdb_inv_cnt = qp_work_entry.sdb_inv_cnt;
3272 qp_work->sche_cnt = qp_work_entry.sche_cnt;
3273
3274 priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
3275 queue_work(priv->des_qp.qp_wq, &qp_work->work);
3276 dev_dbg(dev, "Begin destroy QP(0x%lx) work.\n", hr_qp->qpn);
3277 }
3035 3278
3036 return 0; 3279 return 0;
3037} 3280}
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.h b/drivers/infiniband/hw/hns/hns_roce_hw_v1.h
index cf28f1b6492c..1d250c026c10 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.h
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.h
@@ -102,6 +102,12 @@
102#define HNS_ROCE_V1_EXT_ODB_ALFUL \ 102#define HNS_ROCE_V1_EXT_ODB_ALFUL \
103 (HNS_ROCE_V1_EXT_ODB_DEPTH - HNS_ROCE_V1_DB_RSVD) 103 (HNS_ROCE_V1_EXT_ODB_DEPTH - HNS_ROCE_V1_DB_RSVD)
104 104
105#define HNS_ROCE_V1_DB_WAIT_OK 0
106#define HNS_ROCE_V1_DB_STAGE1 1
107#define HNS_ROCE_V1_DB_STAGE2 2
108#define HNS_ROCE_V1_CHECK_DB_TIMEOUT_MSECS 10000
109#define HNS_ROCE_V1_CHECK_DB_SLEEP_MSECS 20
110
105#define HNS_ROCE_BT_RSV_BUF_SIZE (1 << 17) 111#define HNS_ROCE_BT_RSV_BUF_SIZE (1 << 17)
106 112
107#define HNS_ROCE_V1_TPTR_ENTRY_SIZE 2 113#define HNS_ROCE_V1_TPTR_ENTRY_SIZE 2
@@ -144,6 +150,7 @@
144#define SQ_PSN_SHIFT 8 150#define SQ_PSN_SHIFT 8
145#define QKEY_VAL 0x80010000 151#define QKEY_VAL 0x80010000
146#define SDB_INV_CNT_OFFSET 8 152#define SDB_INV_CNT_OFFSET 8
153#define SDB_ST_CMP_VAL 8
147 154
148struct hns_roce_cq_context { 155struct hns_roce_cq_context {
149 u32 cqc_byte_4; 156 u32 cqc_byte_4;
@@ -993,11 +1000,27 @@ struct hns_roce_tptr_table {
993 struct hns_roce_buf_list tptr_buf; 1000 struct hns_roce_buf_list tptr_buf;
994}; 1001};
995 1002
1003struct hns_roce_qp_work {
1004 struct work_struct work;
1005 struct ib_device *ib_dev;
1006 struct hns_roce_qp *qp;
1007 u32 db_wait_stage;
1008 u32 sdb_issue_ptr;
1009 u32 sdb_inv_cnt;
1010 u32 sche_cnt;
1011};
1012
1013struct hns_roce_des_qp {
1014 struct workqueue_struct *qp_wq;
1015 int requeue_flag;
1016};
1017
996struct hns_roce_v1_priv { 1018struct hns_roce_v1_priv {
997 struct hns_roce_db_table db_table; 1019 struct hns_roce_db_table db_table;
998 struct hns_roce_raq_table raq_table; 1020 struct hns_roce_raq_table raq_table;
999 struct hns_roce_bt_table bt_table; 1021 struct hns_roce_bt_table bt_table;
1000 struct hns_roce_tptr_table tptr_table; 1022 struct hns_roce_tptr_table tptr_table;
1023 struct hns_roce_des_qp des_qp;
1001}; 1024};
1002 1025
1003int hns_dsaf_roce_reset(struct fwnode_handle *dsaf_fwnode, bool dereset); 1026int hns_dsaf_roce_reset(struct fwnode_handle *dsaf_fwnode, bool dereset);