]> git.droids-corp.org - dpdk.git/commitdiff
net/bnxt: support two-level priority for TCAMs
authorJay Ding <jay.ding@broadcom.com>
Thu, 2 Jul 2020 23:28:08 +0000 (16:28 -0700)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 7 Jul 2020 21:38:27 +0000 (23:38 +0200)
Allow TCAM indexes to be allocated from top or bottom.
If the priority is set to 0, allocate from the
lowest tcam indexes i.e. from top. Any other value,
allocate it from the highest tcam indexes i.e. from
bottom.

Signed-off-by: Jay Ding <jay.ding@broadcom.com>
Signed-off-by: Venkat Duvvuru <venkatkumar.duvvuru@broadcom.com>
Reviewed-by: Randy Schacher <stuart.schacher@broadcom.com>
Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
drivers/net/bnxt/tf_core/bitalloc.c
drivers/net/bnxt/tf_core/bitalloc.h
drivers/net/bnxt/tf_core/tf_rm_new.c
drivers/net/bnxt/tf_core/tf_rm_new.h
drivers/net/bnxt/tf_core/tf_tcam.c

index fb4df9a1995878c70860fa04411369e3fe184857..918cabf19c0415b5e79d6dbd667c5c54af0ffd0a 100644 (file)
@@ -7,6 +7,40 @@
 
 #define BITALLOC_MAX_LEVELS 6
 
+
+/* Finds the last bit set plus 1, equivalent to gcc __builtin_fls */
+static int
+ba_fls(bitalloc_word_t v)
+{
+       int c = 32;
+
+       if (!v)
+               return 0;
+
+       if (!(v & 0xFFFF0000u)) {
+               v <<= 16;
+               c -= 16;
+       }
+       if (!(v & 0xFF000000u)) {
+               v <<= 8;
+               c -= 8;
+       }
+       if (!(v & 0xF0000000u)) {
+               v <<= 4;
+               c -= 4;
+       }
+       if (!(v & 0xC0000000u)) {
+               v <<= 2;
+               c -= 2;
+       }
+       if (!(v & 0x80000000u)) {
+               v <<= 1;
+               c -= 1;
+       }
+
+       return c;
+}
+
 /* Finds the first bit set plus 1, equivalent to gcc __builtin_ffs */
 static int
 ba_ffs(bitalloc_word_t v)
@@ -120,6 +154,79 @@ ba_alloc(struct bitalloc *pool)
        return ba_alloc_helper(pool, 0, 1, 32, 0, &clear);
 }
 
+/**
+ * Help function to alloc entry from highest available index
+ *
+ * Searching the pool from highest index for the empty entry.
+ *
+ * [in] pool
+ *   Pointer to the resource pool
+ *
+ * [in] offset
+ *   Offset of the storage in the pool
+ *
+ * [in] words
+ *   Number of words in this level
+ *
+ * [in] size
+ *   Number of entries in this level
+ *
+ * [in] index
+ *   Index of words that has the entry
+ *
+ * [in] clear
+ *   Indicate if a bit needs to be clear due to the entry is allocated
+ *
+ * Returns:
+ *     0 - Success
+ *    -1 - Failure
+ */
+static int
+ba_alloc_reverse_helper(struct bitalloc *pool,
+                       int offset,
+                       int words,
+                       unsigned int size,
+                       int index,
+                       int *clear)
+{
+       bitalloc_word_t *storage = &pool->storage[offset];
+       int loc = ba_fls(storage[index]);
+       int r;
+
+       if (loc == 0)
+               return -1;
+
+       loc--;
+
+       if (pool->size > size) {
+               r = ba_alloc_reverse_helper(pool,
+                                           offset + words + 1,
+                                           storage[words],
+                                           size * 32,
+                                           index * 32 + loc,
+                                           clear);
+       } else {
+               r = index * 32 + loc;
+               *clear = 1;
+               pool->free_count--;
+       }
+
+       if (*clear) {
+               storage[index] &= ~(1 << loc);
+               *clear = (storage[index] == 0);
+       }
+
+       return r;
+}
+
+int
+ba_alloc_reverse(struct bitalloc *pool)
+{
+       int clear = 0;
+
+       return ba_alloc_reverse_helper(pool, 0, 1, 32, 0, &clear);
+}
+
 static int
 ba_alloc_index_helper(struct bitalloc *pool,
                      int              offset,
index 563c8531ae0015ef0d3d23aec5c230e45fdba8b6..2825bb37e550c838089f25b68128f1ef3089c912 100644 (file)
@@ -72,6 +72,11 @@ int ba_init(struct bitalloc *pool, int size);
 int ba_alloc(struct bitalloc *pool);
 int ba_alloc_index(struct bitalloc *pool, int index);
 
+/**
+ * Returns -1 on failure, or index of allocated entry
+ */
+int ba_alloc_reverse(struct bitalloc *pool);
+
 /**
  * Query a particular index in a pool to check if its in use.
  *
index 02b4b5c8f1530dc9db4751630bd5085a093fe8b3..de8f11955d631d66a3e2bee6b17472583de6f72d 100644 (file)
@@ -671,7 +671,14 @@ tf_rm_allocate(struct tf_rm_allocate_parms *parms)
                return rc;
        }
 
-       id = ba_alloc(rm_db->db[parms->db_index].pool);
+       /*
+        * priority  0: allocate from top of the tcam i.e. high
+        * priority !0: allocate index from bottom i.e lowest
+        */
+       if (parms->priority)
+               id = ba_alloc_reverse(rm_db->db[parms->db_index].pool);
+       else
+               id = ba_alloc(rm_db->db[parms->db_index].pool);
        if (id == BA_FAIL) {
                rc = -ENOMEM;
                TFP_DRV_LOG(ERR,
index 3a41da941fea20c1defc6223499e09debb05dde5..3b818f2af5837ca452e71a76e1b964de02077103 100644 (file)
@@ -185,6 +185,14 @@ struct tf_rm_allocate_parms {
         * i.e. Full Action Record offsets.
         */
        uint32_t *index;
+       /**
+        * [in] Priority, indicates the priority of the entry
+        * priority  0: allocate from top of the tcam (from index 0
+        *              or lowest available index)
+        * priority !0: allocate from bottom of the tcam (from highest
+        *              available index)
+        */
+       uint32_t priority;
 };
 
 /**
index 2f4441de8ebf7cd50cc3c86b55ee2da6aa3e51f2..260fb15a691c2ce8a9421aa4fc0df0afd49d1bfd 100644 (file)
@@ -157,6 +157,7 @@ tf_tcam_alloc(struct tf *tfp,
        /* Allocate requested element */
        aparms.rm_db = tcam_db[parms->dir];
        aparms.db_index = parms->type;
+       aparms.priority = parms->priority;
        aparms.index = (uint32_t *)&parms->idx;
        rc = tf_rm_allocate(&aparms);
        if (rc) {