aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/cxgb4/qp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/cxgb4/qp.c')
-rw-r--r--drivers/infiniband/hw/cxgb4/qp.c47
1 files changed, 44 insertions, 3 deletions
diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c
index beec66758aec..ba1343ee1414 100644
--- a/drivers/infiniband/hw/cxgb4/qp.c
+++ b/drivers/infiniband/hw/cxgb4/qp.c
@@ -42,6 +42,11 @@ static int ocqp_support = 1;
42module_param(ocqp_support, int, 0644); 42module_param(ocqp_support, int, 0644);
43MODULE_PARM_DESC(ocqp_support, "Support on-chip SQs (default=1)"); 43MODULE_PARM_DESC(ocqp_support, "Support on-chip SQs (default=1)");
44 44
45int db_fc_threshold = 2000;
46module_param(db_fc_threshold, int, 0644);
47MODULE_PARM_DESC(db_fc_threshold, "QP count/threshold that triggers automatic "
48 "db flow control mode (default = 2000)");
49
45static void set_state(struct c4iw_qp *qhp, enum c4iw_qp_state state) 50static void set_state(struct c4iw_qp *qhp, enum c4iw_qp_state state)
46{ 51{
47 unsigned long flag; 52 unsigned long flag;
@@ -1143,13 +1148,19 @@ static int ring_kernel_db(struct c4iw_qp *qhp, u32 qid, u16 inc)
1143 1148
1144 mutex_lock(&qhp->rhp->db_mutex); 1149 mutex_lock(&qhp->rhp->db_mutex);
1145 do { 1150 do {
1146 if (cxgb4_dbfifo_count(qhp->rhp->rdev.lldi.ports[0], 1) < 768) { 1151
1152 /*
1153 * The interrupt threshold is dbfifo_int_thresh << 6. So
1154 * make sure we don't cross that and generate an interrupt.
1155 */
1156 if (cxgb4_dbfifo_count(qhp->rhp->rdev.lldi.ports[0], 1) <
1157 (qhp->rhp->rdev.lldi.dbfifo_int_thresh << 5)) {
1147 writel(V_QID(qid) | V_PIDX(inc), qhp->wq.db); 1158 writel(V_QID(qid) | V_PIDX(inc), qhp->wq.db);
1148 break; 1159 break;
1149 } 1160 }
1150 set_current_state(TASK_UNINTERRUPTIBLE); 1161 set_current_state(TASK_UNINTERRUPTIBLE);
1151 schedule_timeout(usecs_to_jiffies(delay)); 1162 schedule_timeout(usecs_to_jiffies(delay));
1152 delay = min(delay << 1, 200000); 1163 delay = min(delay << 1, 2000);
1153 } while (1); 1164 } while (1);
1154 mutex_unlock(&qhp->rhp->db_mutex); 1165 mutex_unlock(&qhp->rhp->db_mutex);
1155 return 0; 1166 return 0;
@@ -1388,6 +1399,14 @@ out:
1388 return ret; 1399 return ret;
1389} 1400}
1390 1401
1402static int enable_qp_db(int id, void *p, void *data)
1403{
1404 struct c4iw_qp *qp = p;
1405
1406 t4_enable_wq_db(&qp->wq);
1407 return 0;
1408}
1409
1391int c4iw_destroy_qp(struct ib_qp *ib_qp) 1410int c4iw_destroy_qp(struct ib_qp *ib_qp)
1392{ 1411{
1393 struct c4iw_dev *rhp; 1412 struct c4iw_dev *rhp;
@@ -1405,7 +1424,16 @@ int c4iw_destroy_qp(struct ib_qp *ib_qp)
1405 c4iw_modify_qp(rhp, qhp, C4IW_QP_ATTR_NEXT_STATE, &attrs, 0); 1424 c4iw_modify_qp(rhp, qhp, C4IW_QP_ATTR_NEXT_STATE, &attrs, 0);
1406 wait_event(qhp->wait, !qhp->ep); 1425 wait_event(qhp->wait, !qhp->ep);
1407 1426
1408 remove_handle(rhp, &rhp->qpidr, qhp->wq.sq.qid); 1427 spin_lock_irq(&rhp->lock);
1428 remove_handle_nolock(rhp, &rhp->qpidr, qhp->wq.sq.qid);
1429 rhp->qpcnt--;
1430 BUG_ON(rhp->qpcnt < 0);
1431 if (rhp->qpcnt <= db_fc_threshold && rhp->db_state == FLOW_CONTROL) {
1432 rhp->rdev.stats.db_state_transitions++;
1433 rhp->db_state = NORMAL;
1434 idr_for_each(&rhp->qpidr, enable_qp_db, NULL);
1435 }
1436 spin_unlock_irq(&rhp->lock);
1409 atomic_dec(&qhp->refcnt); 1437 atomic_dec(&qhp->refcnt);
1410 wait_event(qhp->wait, !atomic_read(&qhp->refcnt)); 1438 wait_event(qhp->wait, !atomic_read(&qhp->refcnt));
1411 1439
@@ -1419,6 +1447,14 @@ int c4iw_destroy_qp(struct ib_qp *ib_qp)
1419 return 0; 1447 return 0;
1420} 1448}
1421 1449
1450static int disable_qp_db(int id, void *p, void *data)
1451{
1452 struct c4iw_qp *qp = p;
1453
1454 t4_disable_wq_db(&qp->wq);
1455 return 0;
1456}
1457
1422struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs, 1458struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs,
1423 struct ib_udata *udata) 1459 struct ib_udata *udata)
1424{ 1460{
@@ -1508,6 +1544,11 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs,
1508 spin_lock_irq(&rhp->lock); 1544 spin_lock_irq(&rhp->lock);
1509 if (rhp->db_state != NORMAL) 1545 if (rhp->db_state != NORMAL)
1510 t4_disable_wq_db(&qhp->wq); 1546 t4_disable_wq_db(&qhp->wq);
1547 if (++rhp->qpcnt > db_fc_threshold && rhp->db_state == NORMAL) {
1548 rhp->rdev.stats.db_state_transitions++;
1549 rhp->db_state = FLOW_CONTROL;
1550 idr_for_each(&rhp->qpidr, disable_qp_db, NULL);
1551 }
1511 ret = insert_handle_nolock(rhp, &rhp->qpidr, qhp, qhp->wq.sq.qid); 1552 ret = insert_handle_nolock(rhp, &rhp->qpidr, qhp, qhp->wq.sq.qid);
1512 spin_unlock_irq(&rhp->lock); 1553 spin_unlock_irq(&rhp->lock);
1513 if (ret) 1554 if (ret)