RDMA/irdma: Do not hold qos mutex twice on QP resume
authorMustafa Ismail <mustafa.ismail@intel.com>
Tue, 19 Oct 2021 15:16:54 +0000 (10:16 -0500)
committerJason Gunthorpe <jgg@nvidia.com>
Tue, 19 Oct 2021 23:22:01 +0000 (20:22 -0300)
When irdma_ws_add fails, irdma_ws_remove is used to cleanup the leaf node.
This lead to holding the qos mutex twice in the QP resume path. Fix this
by avoiding the call to irdma_ws_remove and unwinding the error in
irdma_ws_add. This skips the call to irdma_tc_in_use function which is not
needed in the error unwind cases.

Fixes: 3ae331c75128 ("RDMA/irdma: Add QoS definitions")
Link: https://lore.kernel.org/r/20211019151654.1943-2-shiraz.saleem@intel.com
Signed-off-by: Mustafa Ismail <mustafa.ismail@intel.com>
Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
drivers/infiniband/hw/irdma/ws.c

index b68c575..b0d6ee0 100644 (file)
@@ -330,8 +330,10 @@ enum irdma_status_code irdma_ws_add(struct irdma_sc_vsi *vsi, u8 user_pri)
 
                tc_node->enable = true;
                ret = irdma_ws_cqp_cmd(vsi, tc_node, IRDMA_OP_WS_MODIFY_NODE);
-               if (ret)
+               if (ret) {
+                       vsi->unregister_qset(vsi, tc_node);
                        goto reg_err;
+               }
        }
        ibdev_dbg(to_ibdev(vsi->dev),
                  "WS: Using node %d which represents VSI %d TC %d\n",
@@ -350,6 +352,10 @@ enum irdma_status_code irdma_ws_add(struct irdma_sc_vsi *vsi, u8 user_pri)
        }
        goto exit;
 
+reg_err:
+       irdma_ws_cqp_cmd(vsi, tc_node, IRDMA_OP_WS_DELETE_NODE);
+       list_del(&tc_node->siblings);
+       irdma_free_node(vsi, tc_node);
 leaf_add_err:
        if (list_empty(&vsi_node->child_list_head)) {
                if (irdma_ws_cqp_cmd(vsi, vsi_node, IRDMA_OP_WS_DELETE_NODE))
@@ -369,11 +375,6 @@ vsi_add_err:
 exit:
        mutex_unlock(&vsi->dev->ws_mutex);
        return ret;
-
-reg_err:
-       mutex_unlock(&vsi->dev->ws_mutex);
-       irdma_ws_remove(vsi, user_pri);
-       return ret;
 }
 
 /**