Skip to content

Commit

Permalink
net/mana: handle MR cache expansion failure
Browse files Browse the repository at this point in the history
[ upstream commit 0c7bc26bb0b39bfe8999f422329bd52861b43a72 ]

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")

Signed-off-by: Long Li <longli@microsoft.com>
  • Loading branch information
longlimsft authored and bluca committed Mar 7, 2024
1 parent 9778949 commit 706c98e
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 @@ -517,9 +517,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 @@ -137,8 +137,12 @@ mana_find_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 @@ -147,11 +151,14 @@ mana_find_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 @@ -227,22 +234,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 @@ -261,14 +269,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 @@ -313,14 +323,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 706c98e

Please sign in to comment.