From: Long Li <lon...@microsoft.com>

On MR cache expension 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.

Signed-off-by: Long Li <lon...@microsoft.com>
---
 drivers/net/mana/mana.h |  6 +++---
 drivers/net/mana/mr.c   | 45 ++++++++++++++++++++++++++++-------------
 2 files changed, 34 insertions(+), 17 deletions(-)

diff --git a/drivers/net/mana/mana.h b/drivers/net/mana/mana.h
index eadcd01858..309d553956 100644
--- a/drivers/net/mana/mana.h
+++ b/drivers/net/mana/mana.h
@@ -522,9 +522,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);
diff --git a/drivers/net/mana/mr.c b/drivers/net/mana/mr.c
index c9d0f7ef5a..c4045141bc 100644
--- a/drivers/net/mana/mr.c
+++ b/drivers/net/mana/mr.c
@@ -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);
@@ -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);
@@ -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;
@@ -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
@@ -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;
        }
-- 
2.17.1

Reply via email to