Commit ea9dd2e5 authored by Suman Ghosh's avatar Suman Ghosh Committed by David S. Miller
Browse files

octeontx2-af: Unlock contexts in the queue context cache in case of fault detection



NDC caches contexts of frequently used queue's (Rx and Tx queues)
contexts. Due to a HW errata when NDC detects fault/poision while
accessing contexts it could go into an illegal state where a cache
line could get locked forever. To makesure all cache lines in NDC
are available for optimum performance upon fault/lockerror/posion
errors scan through all cache lines in NDC and clear the lock bit.

Fixes: 4a3581cd ("octeontx2-af: NPA AQ instruction enqueue support")
Signed-off-by: default avatarSuman Ghosh <sumang@marvell.com>
Signed-off-by: default avatarSunil Kovvuri Goutham <sgoutham@marvell.com>
Signed-off-by: default avatarSai Krishna <saikrishnag@marvell.com>
Reviewed-by: default avatarSimon Horman <simon.horman@corigine.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ce7ca794
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -884,6 +884,9 @@ int rvu_cpt_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int lf,
int rvu_cpt_ctx_flush(struct rvu *rvu, u16 pcifunc);
int rvu_cpt_init(struct rvu *rvu);

#define NDC_AF_BANK_MASK       GENMASK_ULL(7, 0)
#define NDC_AF_BANK_LINE_MASK  GENMASK_ULL(31, 16)

/* CN10K RVU */
int rvu_set_channels_base(struct rvu *rvu);
void rvu_program_channels(struct rvu *rvu);
@@ -902,6 +905,8 @@ static inline void rvu_dbg_init(struct rvu *rvu) {}
static inline void rvu_dbg_exit(struct rvu *rvu) {}
#endif

int rvu_ndc_fix_locked_cacheline(struct rvu *rvu, int blkaddr);

/* RVU Switch */
void rvu_switch_enable(struct rvu *rvu);
void rvu_switch_disable(struct rvu *rvu);
+3 −4
Original line number Diff line number Diff line
@@ -198,9 +198,6 @@ enum cpt_eng_type {
	CPT_IE_TYPE = 3,
};

#define NDC_MAX_BANK(rvu, blk_addr) (rvu_read64(rvu, \
						blk_addr, NDC_AF_CONST) & 0xFF)

#define rvu_dbg_NULL NULL
#define rvu_dbg_open_NULL NULL

@@ -1448,6 +1445,7 @@ static int ndc_blk_hits_miss_stats(struct seq_file *s, int idx, int blk_addr)
	struct nix_hw *nix_hw;
	struct rvu *rvu;
	int bank, max_bank;
	u64 ndc_af_const;

	if (blk_addr == BLKADDR_NDC_NPA0) {
		rvu = s->private;
@@ -1456,7 +1454,8 @@ static int ndc_blk_hits_miss_stats(struct seq_file *s, int idx, int blk_addr)
		rvu = nix_hw->rvu;
	}

	max_bank = NDC_MAX_BANK(rvu, blk_addr);
	ndc_af_const = rvu_read64(rvu, blk_addr, NDC_AF_CONST);
	max_bank = FIELD_GET(NDC_AF_BANK_MASK, ndc_af_const);
	for (bank = 0; bank < max_bank; bank++) {
		seq_printf(s, "BANK:%d\n", bank);
		seq_printf(s, "\tHits:\t%lld\n",
+15 −1
Original line number Diff line number Diff line
@@ -790,6 +790,7 @@ static int nix_aq_enqueue_wait(struct rvu *rvu, struct rvu_block *block,
	struct nix_aq_res_s *result;
	int timeout = 1000;
	u64 reg, head;
	int ret;

	result = (struct nix_aq_res_s *)aq->res->base;

@@ -813,9 +814,22 @@ static int nix_aq_enqueue_wait(struct rvu *rvu, struct rvu_block *block,
			return -EBUSY;
	}

	if (result->compcode != NIX_AQ_COMP_GOOD)
	if (result->compcode != NIX_AQ_COMP_GOOD) {
		/* TODO: Replace this with some error code */
		if (result->compcode == NIX_AQ_COMP_CTX_FAULT ||
		    result->compcode == NIX_AQ_COMP_LOCKERR ||
		    result->compcode == NIX_AQ_COMP_CTX_POISON) {
			ret = rvu_ndc_fix_locked_cacheline(rvu, BLKADDR_NDC_NIX0_RX);
			ret |= rvu_ndc_fix_locked_cacheline(rvu, BLKADDR_NDC_NIX0_TX);
			ret |= rvu_ndc_fix_locked_cacheline(rvu, BLKADDR_NDC_NIX1_RX);
			ret |= rvu_ndc_fix_locked_cacheline(rvu, BLKADDR_NDC_NIX1_TX);
			if (ret)
				dev_err(rvu->dev,
					"%s: Not able to unlock cachelines\n", __func__);
		}

		return -EBUSY;
	}

	return 0;
}
+56 −2
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@
 * Copyright (C) 2018 Marvell.
 *
 */

#include <linux/bitfield.h>
#include <linux/module.h>
#include <linux/pci.h>

@@ -42,9 +42,18 @@ static int npa_aq_enqueue_wait(struct rvu *rvu, struct rvu_block *block,
			return -EBUSY;
	}

	if (result->compcode != NPA_AQ_COMP_GOOD)
	if (result->compcode != NPA_AQ_COMP_GOOD) {
		/* TODO: Replace this with some error code */
		if (result->compcode == NPA_AQ_COMP_CTX_FAULT ||
		    result->compcode == NPA_AQ_COMP_LOCKERR ||
		    result->compcode == NPA_AQ_COMP_CTX_POISON) {
			if (rvu_ndc_fix_locked_cacheline(rvu, BLKADDR_NDC_NPA0))
				dev_err(rvu->dev,
					"%s: Not able to unlock cachelines\n", __func__);
		}

		return -EBUSY;
	}

	return 0;
}
@@ -545,3 +554,48 @@ void rvu_npa_lf_teardown(struct rvu *rvu, u16 pcifunc, int npalf)

	npa_ctx_free(rvu, pfvf);
}

/* Due to an Hardware errata, in some corner cases, AQ context lock
 * operations can result in a NDC way getting into an illegal state
 * of not valid but locked.
 *
 * This API solves the problem by clearing the lock bit of the NDC block.
 * The operation needs to be done for each line of all the NDC banks.
 */
int rvu_ndc_fix_locked_cacheline(struct rvu *rvu, int blkaddr)
{
	int bank, max_bank, line, max_line, err;
	u64 reg, ndc_af_const;

	/* Set the ENABLE bit(63) to '0' */
	reg = rvu_read64(rvu, blkaddr, NDC_AF_CAMS_RD_INTERVAL);
	rvu_write64(rvu, blkaddr, NDC_AF_CAMS_RD_INTERVAL, reg & GENMASK_ULL(62, 0));

	/* Poll until the BUSY bits(47:32) are set to '0' */
	err = rvu_poll_reg(rvu, blkaddr, NDC_AF_CAMS_RD_INTERVAL, GENMASK_ULL(47, 32), true);
	if (err) {
		dev_err(rvu->dev, "Timed out while polling for NDC CAM busy bits.\n");
		return err;
	}

	ndc_af_const = rvu_read64(rvu, blkaddr, NDC_AF_CONST);
	max_bank = FIELD_GET(NDC_AF_BANK_MASK, ndc_af_const);
	max_line = FIELD_GET(NDC_AF_BANK_LINE_MASK, ndc_af_const);
	for (bank = 0; bank < max_bank; bank++) {
		for (line = 0; line < max_line; line++) {
			/* Check if 'cache line valid bit(63)' is not set
			 * but 'cache line lock bit(60)' is set and on
			 * success, reset the lock bit(60).
			 */
			reg = rvu_read64(rvu, blkaddr,
					 NDC_AF_BANKX_LINEX_METADATA(bank, line));
			if (!(reg & BIT_ULL(63)) && (reg & BIT_ULL(60))) {
				rvu_write64(rvu, blkaddr,
					    NDC_AF_BANKX_LINEX_METADATA(bank, line),
					    reg & ~BIT_ULL(60));
			}
		}
	}

	return 0;
}
+3 −0
Original line number Diff line number Diff line
@@ -694,6 +694,7 @@
#define NDC_AF_INTR_ENA_W1S		(0x00068)
#define NDC_AF_INTR_ENA_W1C		(0x00070)
#define NDC_AF_ACTIVE_PC		(0x00078)
#define NDC_AF_CAMS_RD_INTERVAL		(0x00080)
#define NDC_AF_BP_TEST_ENABLE		(0x001F8)
#define NDC_AF_BP_TEST(a)		(0x00200 | (a) << 3)
#define NDC_AF_BLK_RST			(0x002F0)
@@ -709,6 +710,8 @@
		(0x00F00 | (a) << 5 | (b) << 4)
#define NDC_AF_BANKX_HIT_PC(a)		(0x01000 | (a) << 3)
#define NDC_AF_BANKX_MISS_PC(a)		(0x01100 | (a) << 3)
#define NDC_AF_BANKX_LINEX_METADATA(a, b) \
		(0x10000 | (a) << 12 | (b) << 3)

/* LBK */
#define LBK_CONST			(0x10ull)