[PATCH net] octeontx2-af: fix partial NIX Tx scheduler queue allocation

Ratheesh Kannoth posted 1 patch 3 hours ago
.../ethernet/marvell/octeontx2/af/rvu_nix.c   | 33 +++++++++++++++----
1 file changed, 26 insertions(+), 7 deletions(-)
[PATCH net] octeontx2-af: fix partial NIX Tx scheduler queue allocation
Posted by Ratheesh Kannoth 3 hours ago
nix_txsch_alloc() could return success after allocating fewer Tx
scheduler queues than requested, or after failing to allocate a
queue under the fixed topology mapping. Propagate allocation
failures to the mailbox handler and roll back any partially
allocated queue indices on error.

Fixes: 5d9b976d4480 ("octeontx2-af: Support fixed transmit scheduler topology")
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
---
 .../ethernet/marvell/octeontx2/af/rvu_nix.c   | 33 +++++++++++++++----
 1 file changed, 26 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
index 153eb57bad06..28e70bae51ca 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
@@ -2195,12 +2195,14 @@ static int nix_check_txschq_alloc_req(struct rvu *rvu, int lvl, u16 pcifunc,
 	return 0;
 }
 
-static void nix_txsch_alloc(struct rvu *rvu, struct nix_txsch *txsch,
-			    struct nix_txsch_alloc_rsp *rsp,
-			    int lvl, int start, int end)
+static int nix_txsch_alloc(struct rvu *rvu, struct nix_txsch *txsch,
+			   struct nix_txsch_alloc_rsp *rsp,
+			   int lvl, int start, int end)
 {
+	int want_contig = rsp->schq_contig[lvl];
 	struct rvu_hwinfo *hw = rvu->hw;
 	u16 pcifunc = rsp->hdr.pcifunc;
+	int want = rsp->schq[lvl];
 	int idx, schq;
 
 	/* For traffic aggregating levels, queue alloc is based
@@ -2221,7 +2223,7 @@ static void nix_txsch_alloc(struct rvu *rvu, struct nix_txsch *txsch,
 			rsp->schq[lvl] = 1;
 			rsp->schq_list[lvl][0] = start;
 		}
-		return;
+		return 0;
 	}
 
 	/* Adjust the queue request count if HW supports
@@ -2233,7 +2235,7 @@ static void nix_txsch_alloc(struct rvu *rvu, struct nix_txsch *txsch,
 		if (idx >= (end - start) || test_bit(schq, txsch->schq.bmap)) {
 			rsp->schq_contig[lvl] = 0;
 			rsp->schq[lvl] = 0;
-			return;
+			return -ENOMEM;
 		}
 
 		if (rsp->schq_contig[lvl]) {
@@ -2246,7 +2248,7 @@ static void nix_txsch_alloc(struct rvu *rvu, struct nix_txsch *txsch,
 			set_bit(schq, txsch->schq.bmap);
 			rsp->schq_list[lvl][0] = schq;
 		}
-		return;
+		return 0;
 	}
 
 	/* Allocate contiguous queue indices requesty first */
@@ -2277,6 +2279,22 @@ static void nix_txsch_alloc(struct rvu *rvu, struct nix_txsch *txsch,
 		/* Update how many were allocated */
 		rsp->schq[lvl] = idx;
 	}
+
+	if ((want_contig && !rsp->schq_contig[lvl]) || (want && !rsp->schq[lvl]))
+		goto err;
+
+	return 0;
+
+err:
+	for (idx = 0; idx < rsp->schq_contig[lvl]; idx++)
+		clear_bit(rsp->schq_contig_list[lvl][idx], txsch->schq.bmap);
+
+	for (idx = 0; idx < rsp->schq[lvl]; idx++)
+		clear_bit(rsp->schq_list[lvl][idx], txsch->schq.bmap);
+
+	rsp->schq_contig[lvl] = 0;
+	rsp->schq[lvl] = 0;
+	return -ENOMEM;
 }
 
 int rvu_mbox_handler_nix_txsch_alloc(struct rvu *rvu,
@@ -2335,7 +2353,8 @@ int rvu_mbox_handler_nix_txsch_alloc(struct rvu *rvu,
 			end = txsch->schq.max;
 		}
 
-		nix_txsch_alloc(rvu, txsch, rsp, lvl, start, end);
+		if (nix_txsch_alloc(rvu, txsch, rsp, lvl, start, end))
+			goto err;
 
 		/* Reset queue config */
 		for (idx = 0; idx < req->schq_contig[lvl]; idx++) {
-- 
2.43.0