mutex_lock(&vsi->qos[user_pri].qos_mutex); if (!list_empty(&vsi->qos[user_pri].qplist)) {
mutex_unlock(&vsi->qos[user_pri].qos_mutex); returntrue;
}
/* Check if the traffic class associated with the given user priority *isinusebyanyotheruserpriority.Ifso,nothinglefttodo
*/ for (i = 0; i < IRDMA_MAX_USER_PRIORITY; i++) { if (vsi->qos[i].traffic_class == vsi->qos[user_pri].traffic_class &&
!list_empty(&vsi->qos[i].qplist)) {
mutex_unlock(&vsi->qos[user_pri].qos_mutex); returntrue;
}
}
mutex_unlock(&vsi->qos[user_pri].qos_mutex);
traffic_class = vsi->qos[user_pri].traffic_class; for (i = 0; i < IRDMA_MAX_USER_PRIORITY; i++) if (vsi->qos[i].traffic_class == traffic_class)
vsi->qos[i].valid = false;
ws_tree_root = vsi->dev->ws_tree_root; if (!ws_tree_root) return;
vsi_node = ws_find_node(ws_tree_root, vsi->vsi_idx,
WS_MATCH_TYPE_VSI); if (!vsi_node) return;
tc_node = ws_find_node(vsi_node,
vsi->qos[user_pri].traffic_class,
WS_MATCH_TYPE_TC); if (!tc_node) return;
irdma_ws_cqp_cmd(vsi, tc_node, IRDMA_OP_WS_DELETE_NODE);
vsi->unregister_qset(vsi, tc_node);
list_del(&tc_node->siblings);
irdma_free_node(vsi, tc_node); /* Check if VSI node can be freed */ if (list_empty(&vsi_node->child_list_head)) {
irdma_ws_cqp_cmd(vsi, vsi_node, IRDMA_OP_WS_DELETE_NODE);
list_del(&vsi_node->siblings);
irdma_free_node(vsi, vsi_node); /* Free head node there are no remaining VSI nodes */ if (list_empty(&ws_tree_root->child_list_head)) {
irdma_ws_cqp_cmd(vsi, ws_tree_root,
IRDMA_OP_WS_DELETE_NODE);
irdma_free_node(vsi, ws_tree_root);
vsi->dev->ws_tree_root = NULL;
}
}
}
/** *irdma_ws_add-Buildworkschedulertree,setRDMAqs_handle *@vsi:vsipointer *@user_pri:userpriority
*/ int irdma_ws_add(struct irdma_sc_vsi *vsi, u8 user_pri)
{ struct irdma_ws_node *ws_tree_root; struct irdma_ws_node *vsi_node; struct irdma_ws_node *tc_node;
u16 traffic_class; int ret = 0; int i;
mutex_lock(&vsi->dev->ws_mutex); if (vsi->tc_change_pending) {
ret = -EBUSY; gotoexit;
}
if (vsi->qos[user_pri].valid) gotoexit;
ws_tree_root = vsi->dev->ws_tree_root; if (!ws_tree_root) {
ibdev_dbg(to_ibdev(vsi->dev), "WS: Creating root node\n");
ws_tree_root = irdma_alloc_node(vsi, user_pri,
WS_NODE_TYPE_PARENT, NULL); if (!ws_tree_root) {
ret = -ENOMEM; gotoexit;
}
ret = irdma_ws_cqp_cmd(vsi, ws_tree_root, IRDMA_OP_WS_ADD_NODE); if (ret) {
irdma_free_node(vsi, ws_tree_root); gotoexit;
}
vsi->dev->ws_tree_root = ws_tree_root;
}
/* Find a second tier node that matches the VSI */
vsi_node = ws_find_node(ws_tree_root, vsi->vsi_idx,
WS_MATCH_TYPE_VSI);
/* If VSI node doesn't exist, add one */ if (!vsi_node) {
ibdev_dbg(to_ibdev(vsi->dev), "WS: Node not found matching VSI %d\n",
vsi->vsi_idx);
vsi_node = irdma_alloc_node(vsi, user_pri, WS_NODE_TYPE_PARENT,
ws_tree_root); if (!vsi_node) {
ret = -ENOMEM; goto vsi_add_err;
}
ret = irdma_ws_cqp_cmd(vsi, vsi_node, IRDMA_OP_WS_ADD_NODE); if (ret) {
irdma_free_node(vsi, vsi_node); goto vsi_add_err;
}
ibdev_dbg(to_ibdev(vsi->dev), "WS: Using node %d which represents VSI %d\n",
vsi_node->index, vsi->vsi_idx);
traffic_class = vsi->qos[user_pri].traffic_class;
tc_node = ws_find_node(vsi_node, traffic_class,
WS_MATCH_TYPE_TC); if (!tc_node) { /* Add leaf node */
ibdev_dbg(to_ibdev(vsi->dev), "WS: Node not found matching VSI %d and TC %d\n",
vsi->vsi_idx, traffic_class);
tc_node = irdma_alloc_node(vsi, user_pri, WS_NODE_TYPE_LEAF,
vsi_node); if (!tc_node) {
ret = -ENOMEM; goto leaf_add_err;
}
ret = irdma_ws_cqp_cmd(vsi, tc_node, IRDMA_OP_WS_ADD_NODE); if (ret) {
irdma_free_node(vsi, tc_node); goto leaf_add_err;
}
list_add(&tc_node->siblings, &vsi_node->child_list_head); /* *callbacktoLANtoupdatetheLANtreewithournode
*/
ret = vsi->register_qset(vsi, tc_node); if (ret) goto reg_err;
tc_node->enable = true;
ret = irdma_ws_cqp_cmd(vsi, tc_node, IRDMA_OP_WS_MODIFY_NODE); 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",
tc_node->index, vsi->vsi_idx, traffic_class); /* *IteratethroughotherUPsandupdatetheQShandleiftheyhave *amatchingtrafficclass.
*/ for (i = 0; i < IRDMA_MAX_USER_PRIORITY; i++) { if (vsi->qos[i].traffic_class == traffic_class) {
vsi->qos[i].qs_handle = tc_node->qs_handle;
vsi->qos[i].lan_qos_handle = tc_node->lan_qs_handle;
vsi->qos[i].l2_sched_node_id = tc_node->l2_sched_node_id;
vsi->qos[i].valid = true;
}
} gotoexit;
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)) gotoexit;
list_del(&vsi_node->siblings);
irdma_free_node(vsi, vsi_node);
}
vsi_add_err: /* Free head node there are no remaining VSI nodes */ if (list_empty(&ws_tree_root->child_list_head)) {
irdma_ws_cqp_cmd(vsi, ws_tree_root, IRDMA_OP_WS_DELETE_NODE);
vsi->dev->ws_tree_root = NULL;
irdma_free_node(vsi, ws_tree_root);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.