diff --git a/drivers/net/ethernet/netronome/nfp/abm/qdisc.c b/drivers/net/ethernet/netronome/nfp/abm/qdisc.c index 151d2dafbc76588fd30137681eb66160e8340255..1b3c0b5b52bf1e2e87a849b86f60ea027dbbfd01 100644 --- a/drivers/net/ethernet/netronome/nfp/abm/qdisc.c +++ b/drivers/net/ethernet/netronome/nfp/abm/qdisc.c @@ -196,7 +196,7 @@ nfp_abm_qdisc_replace(struct net_device *netdev, struct nfp_abm_link *alink, if (*qdisc) { if (WARN_ON((*qdisc)->type != type)) return -EINVAL; - return 0; + return 1; } *qdisc = nfp_abm_qdisc_alloc(netdev, alink, type, parent_handle, handle, @@ -357,11 +357,24 @@ nfp_abm_red_replace(struct net_device *netdev, struct nfp_abm_link *alink, i = nfp_abm_red_find(alink, opt); existing = i >= 0; - if (ret) { + if (ret < 0) { err = ret; goto err_destroy; } + /* If limit != 0 child gets reset */ + if (opt->set.limit) { + if (nfp_abm_qdisc_child_valid(qdisc, 0)) + qdisc->children[0]->use_cnt--; + qdisc->children[0] = NULL; + } else { + /* Qdisc was just allocated without a limit will use noop_qdisc, + * i.e. a block hole. + */ + if (!ret) + qdisc->children[0] = NFP_QDISC_UNTRACKED; + } + if (!nfp_abm_red_check_params(alink, opt)) { err = -EINVAL; goto err_destroy; @@ -533,10 +546,14 @@ nfp_abm_mq_create(struct net_device *netdev, struct nfp_abm_link *alink, struct tc_mq_qopt_offload *opt) { struct nfp_qdisc *qdisc; + int ret; - return nfp_abm_qdisc_replace(netdev, alink, NFP_QDISC_MQ, - TC_H_ROOT, opt->handle, - alink->total_queues, &qdisc); + ret = nfp_abm_qdisc_replace(netdev, alink, NFP_QDISC_MQ, + TC_H_ROOT, opt->handle, alink->total_queues, + &qdisc); + if (ret < 0) + return ret; + return 0; } int nfp_abm_setup_tc_mq(struct net_device *netdev, struct nfp_abm_link *alink,