RDMA/cxgb3: test before subtraction on unsigned
Subsystems (3)
PATCH 1/1 RDMA/cxgb3: test before subtraction on unsigned
I think there's someting wrong in iwch_post_send():
// vi drivers/infiniband/hw/cxgb3/iwch_qp.c +353 int iwch_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
struct ib_send_wr **bad_wr)
{
...
u32 num_wrs;
...
num_wrs = Q_FREECNT(qhp->wq.sq_rptr, qhp->wq.sq_wptr,
qhp->wq.sq_size_log2);
if (num_wrs <= 0) {
spin_unlock_irqrestore(&qhp->lock, flag);
return -ENOMEM;
}// vi drivers/infiniband/hw/cxgb3/cxio_wr.h +50
#define Q_FREECNT(rptr,wptr,size_log2) ((1UL<<size_log2)-((wptr)-(rptr)))
Since num_wrs is unsigned, I think the test should occur before the subtraction, right? please review. ------------------------------>8-------------8<--------------------------------- num_wrs is unsigned so test before the subtraction.
---
drivers/infiniband/hw/cxgb3/iwch_qp.c +4 -3
@@ -369,12 +369,13 @@ int iwch_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,spin_unlock_irqrestore (&qhp->lock, flag);return -EINVAL ; } - num_wrs =Q_FREECNT (qhp->wq.sq_rptr, qhp->wq.sq_wptr, - qhp->wq.sq_size_log2); -if (num_wrs <=0 ) { +if ((1UL << qhp->wq.sq_size_log2) + qhp->wq.sq_rptr <= + qhp->wq.sq_wptr) {spin_unlock_irqrestore (&qhp->lock, flag);return -ENOMEM ; } + num_wrs =Q_FREECNT (qhp->wq.sq_rptr, qhp->wq.sq_wptr, + qhp->wq.sq_size_log2);while (wr) {if (num_wrs ==0 ) { err = -ENOMEM ;
Quoted 39 lines · Roel Kluin
I think there's someting wrong in
iwch_post_send():// vi
drivers/infiniband/hw/cxgb3/iwch_qp.c+353 int iwch_post_send(structib_qp*ibqp, structib_send_wr*wr,
structib_send_wr**bad_wr){ ... u32 num_wrs; ... num_wrs = Q_FREECNT(qhp->wq.sq_rptr, qhp->wq.sq_wptr, qhp->wq.sq_size_log2); if (num_wrs <= 0) { spin_unlock_irqrestore(&qhp->lock, flag); return -ENOMEM; }// vi
drivers/infiniband/hw/cxgb3/cxio_wr.h+50
#defineQ_FREECNT(rptr,wptr,size_log2)((1UL<<size_log2)-((wptr)-(rptr)))Since
num_wrsis unsigned, I think the test should occur before the subtraction, right? please review. ------------------------------>8-------------8<---------------------------------num_wrsis unsigned so test before the subtraction.Signed-off-by Roel Kluin <[email protected]>---
drivers/infiniband/hw/cxgb3/iwch_qp.c +0
-3@@ -369,12 +369,13 @@ int iwch_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,spin_unlock_irqrestore (&qhp->lock, flag);return -EINVAL ; } - num_wrs =Q_FREECNT (qhp->wq.sq_rptr, qhp->wq.sq_wptr, - qhp->wq.sq_size_log2); -if (num_wrs <=0 ) {
drivers/infiniband/hw/cxgb3/iwch_qp.c int iwch_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, · line 381
Quoted 10 lines
drivers/infiniband/hw/cxgb3/iwch_qp.c +4
-0+if ((1UL << qhp->wq.sq_size_log2) + qhp->wq.sq_rptr <= + qhp->wq.sq_wptr) {spin_unlock_irqrestore (&qhp->lock, flag);return -ENOMEM ; } + num_wrs =Q_FREECNT (qhp->wq.sq_rptr, qhp->wq.sq_wptr, + qhp->wq.sq_size_log2);while (wr) {if (num_wrs ==0 ) { err = -ENOMEM ;
I think the test is just wrong. It should be:
if (num_wrs == 0).
Q_FREECNT() will not return < 0. The free count is either zero if it is full, or non zero count of the number of free elements.
Steve.