On Wed, Jan 15, 2020 at 05:49:13PM +0800, Yixian Liu wrote: > diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c > index fa38582..ad7ed07 100644 > +++ b/drivers/infiniband/hw/hns/hns_roce_qp.c > @@ -56,10 +56,16 @@ static void flush_work_handle(struct work_struct *work) > attr_mask = IB_QP_STATE; > attr.qp_state = IB_QPS_ERR; > > - ret = hns_roce_modify_qp(&hr_qp->ibqp, &attr, attr_mask, NULL); > - if (ret) > - dev_err(dev, "Modify QP to error state failed(%d) during CQE flush\n", > - ret); > + while (atomic_read(&hr_qp->flush_cnt)) { > + ret = hns_roce_modify_qp(&hr_qp->ibqp, &attr, attr_mask, NULL); > + if (ret) > + dev_err(dev, "Modify QP to error state failed(%d) during CQE flush\n", > + ret); > + > + /* If flush_cnt larger than 1, only need one more time flush */ > + if (atomic_dec_and_test(&hr_qp->flush_cnt)) > + atomic_set(&hr_qp->flush_cnt, 1); > + } And this while loop is just if (atomic_xchg(&hr_qp->flush_cnt, 0)) { [..] } I'm not even sure this needs to be a counter, all you need is set_bit() and test_and_clear() Jason