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: 4a3581cd59
("octeontx2-af: NPA AQ instruction enqueue support")
Signed-off-by: Suman Ghosh <sumang@marvell.com>
Signed-off-by: Sunil Kovvuri Goutham <sgoutham@marvell.com>
Signed-off-by: Sai Krishna <saikrishnag@marvell.com>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
ce7ca79471
commit
ea9dd2e5c6
|
@ -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);
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue