diff options
author | Steve Wise <swise@opengridcomputing.com> | 2010-05-20 17:57:49 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2010-05-25 00:08:01 -0400 |
commit | 7ec45b923446d484eb39434e18d354666426e606 (patch) | |
tree | 9f303610291ed6a855c6af84444909f2315f08b9 /drivers/infiniband | |
parent | 84172dee05cbce6ae791eac481ef4d8590cda791 (diff) |
RDMA/cxgb4: Fix overflow bug in CQ arm
- wrap cq->cqidx_inc based on cq size.
- optimize t4_arm_cq logic.
Signed-off-by: Steve Wise <swise@opengridcomputing.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/hw/cxgb4/t4.h | 31 |
1 files changed, 12 insertions, 19 deletions
diff --git a/drivers/infiniband/hw/cxgb4/t4.h b/drivers/infiniband/hw/cxgb4/t4.h index 712bc5620d3e..333abd3c7264 100644 --- a/drivers/infiniband/hw/cxgb4/t4.h +++ b/drivers/infiniband/hw/cxgb4/t4.h | |||
@@ -449,25 +449,17 @@ struct t4_cq { | |||
449 | static inline int t4_arm_cq(struct t4_cq *cq, int se) | 449 | static inline int t4_arm_cq(struct t4_cq *cq, int se) |
450 | { | 450 | { |
451 | u32 val; | 451 | u32 val; |
452 | u16 inc; | 452 | |
453 | 453 | while (cq->cidx_inc > CIDXINC_MASK) { | |
454 | do { | 454 | val = SEINTARM(0) | CIDXINC(CIDXINC_MASK) | TIMERREG(7) | |
455 | /* | 455 | INGRESSQID(cq->cqid); |
456 | * inc must be less the both the max update value -and- | ||
457 | * the size of the CQ. | ||
458 | */ | ||
459 | inc = cq->cidx_inc <= CIDXINC_MASK ? cq->cidx_inc : | ||
460 | CIDXINC_MASK; | ||
461 | inc = inc <= (cq->size - 1) ? inc : (cq->size - 1); | ||
462 | if (inc == cq->cidx_inc) | ||
463 | val = SEINTARM(se) | CIDXINC(inc) | TIMERREG(6) | | ||
464 | INGRESSQID(cq->cqid); | ||
465 | else | ||
466 | val = SEINTARM(0) | CIDXINC(inc) | TIMERREG(7) | | ||
467 | INGRESSQID(cq->cqid); | ||
468 | cq->cidx_inc -= inc; | ||
469 | writel(val, cq->gts); | 456 | writel(val, cq->gts); |
470 | } while (cq->cidx_inc); | 457 | cq->cidx_inc -= CIDXINC_MASK; |
458 | } | ||
459 | val = SEINTARM(se) | CIDXINC(cq->cidx_inc) | TIMERREG(6) | | ||
460 | INGRESSQID(cq->cqid); | ||
461 | writel(val, cq->gts); | ||
462 | cq->cidx_inc = 0; | ||
471 | return 0; | 463 | return 0; |
472 | } | 464 | } |
473 | 465 | ||
@@ -488,7 +480,8 @@ static inline void t4_swcq_consume(struct t4_cq *cq) | |||
488 | static inline void t4_hwcq_consume(struct t4_cq *cq) | 480 | static inline void t4_hwcq_consume(struct t4_cq *cq) |
489 | { | 481 | { |
490 | cq->bits_type_ts = cq->queue[cq->cidx].bits_type_ts; | 482 | cq->bits_type_ts = cq->queue[cq->cidx].bits_type_ts; |
491 | cq->cidx_inc++; | 483 | if (++cq->cidx_inc == cq->size) |
484 | cq->cidx_inc = 0; | ||
492 | if (++cq->cidx == cq->size) { | 485 | if (++cq->cidx == cq->size) { |
493 | cq->cidx = 0; | 486 | cq->cidx = 0; |
494 | cq->gen ^= 1; | 487 | cq->gen ^= 1; |