Skip to content

Commit

Permalink
net/mana: handle MR cache expansion failure
Browse files Browse the repository at this point in the history
On MR cache expansion failure, the request should fail as there is no
path to get a new MR into the tree. Attempting to insert a new MR to the
cache tree will result in memory violation.

Fixes: 0f5db3c ("net/mana: implement memory registration")
Cc: stable@dpdk.org

Signed-off-by: Long Li <longli@microsoft.com>
  • Loading branch information
longlimsft authored and ferruhy committed Feb 9, 2024
1 parent 5609db3 commit 7c75d45
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 17 deletions.
6 changes: 3 additions & 3 deletions drivers/net/mana/mana.h
Original file line number Diff line number Diff line change
Expand Up @@ -523,9 +523,9 @@ void mana_del_pmd_mr(struct mana_mr_cache *mr);
void mana_mempool_chunk_cb(struct rte_mempool *mp, void *opaque,
struct rte_mempool_memhdr *memhdr, unsigned int idx);

struct mana_mr_cache *mana_mr_btree_lookup(struct mana_mr_btree *bt,
uint16_t *idx,
uintptr_t addr, size_t len);
int mana_mr_btree_lookup(struct mana_mr_btree *bt, uint16_t *idx,
uintptr_t addr, size_t len,
struct mana_mr_cache **cache);
int mana_mr_btree_insert(struct mana_mr_btree *bt, struct mana_mr_cache *entry);
int mana_mr_btree_init(struct mana_mr_btree *bt, int n, int socket);
void mana_mr_btree_free(struct mana_mr_btree *bt);
Expand Down
45 changes: 31 additions & 14 deletions drivers/net/mana/mr.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,12 @@ mana_alloc_pmd_mr(struct mana_mr_btree *local_mr_btree, struct mana_priv *priv,

try_again:
/* First try to find the MR in local queue tree */
mr = mana_mr_btree_lookup(local_mr_btree, &idx,
(uintptr_t)mbuf->buf_addr, mbuf->buf_len);
ret = mana_mr_btree_lookup(local_mr_btree, &idx,
(uintptr_t)mbuf->buf_addr, mbuf->buf_len,
&mr);
if (ret)
return NULL;

if (mr) {
DP_LOG(DEBUG, "Local mr lkey %u addr 0x%" PRIxPTR " len %zu",
mr->lkey, mr->addr, mr->len);
Expand All @@ -148,11 +152,14 @@ mana_alloc_pmd_mr(struct mana_mr_btree *local_mr_btree, struct mana_priv *priv,

/* If not found, try to find the MR in global tree */
rte_spinlock_lock(&priv->mr_btree_lock);
mr = mana_mr_btree_lookup(&priv->mr_btree, &idx,
(uintptr_t)mbuf->buf_addr,
mbuf->buf_len);
ret = mana_mr_btree_lookup(&priv->mr_btree, &idx,
(uintptr_t)mbuf->buf_addr,
mbuf->buf_len, &mr);
rte_spinlock_unlock(&priv->mr_btree_lock);

if (ret)
return NULL;

/* If found in the global tree, add it to the local tree */
if (mr) {
ret = mana_mr_btree_insert(local_mr_btree, mr);
Expand Down Expand Up @@ -228,22 +235,23 @@ mana_mr_btree_expand(struct mana_mr_btree *bt, int n)
/*
* Look for a region of memory in MR cache.
*/
struct mana_mr_cache *
mana_mr_btree_lookup(struct mana_mr_btree *bt, uint16_t *idx,
uintptr_t addr, size_t len)
int mana_mr_btree_lookup(struct mana_mr_btree *bt, uint16_t *idx,
uintptr_t addr, size_t len,
struct mana_mr_cache **cache)
{
struct mana_mr_cache *table;
uint16_t n;
uint16_t base = 0;
int ret;

n = bt->len;
*cache = NULL;

n = bt->len;
/* Try to double the cache if it's full */
if (n == bt->size) {
ret = mana_mr_btree_expand(bt, bt->size << 1);
if (ret)
return NULL;
return ret;
}

table = bt->table;
Expand All @@ -262,14 +270,16 @@ mana_mr_btree_lookup(struct mana_mr_btree *bt, uint16_t *idx,

*idx = base;

if (addr + len <= table[base].addr + table[base].len)
return &table[base];
if (addr + len <= table[base].addr + table[base].len) {
*cache = &table[base];
return 0;
}

DP_LOG(DEBUG,
"addr 0x%" PRIxPTR " len %zu idx %u sum 0x%" PRIxPTR " not found",
addr, len, *idx, addr + len);

return NULL;
return 0;
}

int
Expand Down Expand Up @@ -314,14 +324,21 @@ mana_mr_btree_insert(struct mana_mr_btree *bt, struct mana_mr_cache *entry)
struct mana_mr_cache *table;
uint16_t idx = 0;
uint16_t shift;
int ret;

ret = mana_mr_btree_lookup(bt, &idx, entry->addr, entry->len, &table);
if (ret)
return ret;

if (mana_mr_btree_lookup(bt, &idx, entry->addr, entry->len)) {
if (table) {
DP_LOG(DEBUG, "Addr 0x%" PRIxPTR " len %zu exists in btree",
entry->addr, entry->len);
return 0;
}

if (bt->len >= bt->size) {
DP_LOG(ERR, "Btree overflow detected len %u size %u",
bt->len, bt->size);
bt->overflow = 1;
return -1;
}
Expand Down

0 comments on commit 7c75d45

Please sign in to comment.