Commit 7ec45b92 authored by Steve Wise's avatar Steve Wise Committed by Roland Dreier

RDMA/cxgb4: Fix overflow bug in CQ arm

- wrap cq->cqidx_inc based on cq size.
- optimize t4_arm_cq logic.
Signed-off-by: default avatarSteve Wise <swise@opengridcomputing.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent 84172dee
...@@ -449,25 +449,17 @@ struct t4_cq { ...@@ -449,25 +449,17 @@ struct t4_cq {
static inline int t4_arm_cq(struct t4_cq *cq, int se) static inline int t4_arm_cq(struct t4_cq *cq, int se)
{ {
u32 val; u32 val;
u16 inc;
while (cq->cidx_inc > CIDXINC_MASK) {
do { val = SEINTARM(0) | CIDXINC(CIDXINC_MASK) | TIMERREG(7) |
/* INGRESSQID(cq->cqid);
* inc must be less the both the max update value -and-
* the size of the CQ.
*/
inc = cq->cidx_inc <= CIDXINC_MASK ? cq->cidx_inc :
CIDXINC_MASK;
inc = inc <= (cq->size - 1) ? inc : (cq->size - 1);
if (inc == cq->cidx_inc)
val = SEINTARM(se) | CIDXINC(inc) | TIMERREG(6) |
INGRESSQID(cq->cqid);
else
val = SEINTARM(0) | CIDXINC(inc) | TIMERREG(7) |
INGRESSQID(cq->cqid);
cq->cidx_inc -= inc;
writel(val, cq->gts); writel(val, cq->gts);
} while (cq->cidx_inc); cq->cidx_inc -= CIDXINC_MASK;
}
val = SEINTARM(se) | CIDXINC(cq->cidx_inc) | TIMERREG(6) |
INGRESSQID(cq->cqid);
writel(val, cq->gts);
cq->cidx_inc = 0;
return 0; return 0;
} }
...@@ -488,7 +480,8 @@ static inline void t4_swcq_consume(struct t4_cq *cq) ...@@ -488,7 +480,8 @@ static inline void t4_swcq_consume(struct t4_cq *cq)
static inline void t4_hwcq_consume(struct t4_cq *cq) static inline void t4_hwcq_consume(struct t4_cq *cq)
{ {
cq->bits_type_ts = cq->queue[cq->cidx].bits_type_ts; cq->bits_type_ts = cq->queue[cq->cidx].bits_type_ts;
cq->cidx_inc++; if (++cq->cidx_inc == cq->size)
cq->cidx_inc = 0;
if (++cq->cidx == cq->size) { if (++cq->cidx == cq->size) {
cq->cidx = 0; cq->cidx = 0;
cq->gen ^= 1; cq->gen ^= 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment