From: Pavan Nikhilesh <pbhagavat...@marvell.com>

Fix timer burst arm routine writing improper updates to
the bucket.

Fixes: 5f644e1bd14c ("event/cnxk: add timer arm timeout burst")

Signed-off-by: Pavan Nikhilesh <pbhagavat...@marvell.com>
---
 drivers/event/cnxk/cnxk_tim_worker.h | 81 ++++++++++++++--------------
 1 file changed, 42 insertions(+), 39 deletions(-)

diff --git a/drivers/event/cnxk/cnxk_tim_worker.h 
b/drivers/event/cnxk/cnxk_tim_worker.h
index eda84c6f31..6be31f6f9d 100644
--- a/drivers/event/cnxk/cnxk_tim_worker.h
+++ b/drivers/event/cnxk/cnxk_tim_worker.h
@@ -270,7 +270,8 @@ cnxk_tim_add_entry_sp(struct cnxk_tim_ring *const tim_ring,
                        } while (hbt_state & BIT_ULL(33));
 #endif
 
-                       if (!(hbt_state & BIT_ULL(34))) {
+                       if (!(hbt_state & BIT_ULL(34)) ||
+                           !(hbt_state & GENMASK(31, 0))) {
                                cnxk_tim_bkt_dec_lock(bkt);
                                goto __retry;
                        }
@@ -352,7 +353,8 @@ cnxk_tim_add_entry_mp(struct cnxk_tim_ring *const tim_ring,
                        } while (hbt_state & BIT_ULL(33));
 #endif
 
-                       if (!(hbt_state & BIT_ULL(34))) {
+                       if (!(hbt_state & BIT_ULL(34)) ||
+                           !(hbt_state & GENMASK(31, 0))) {
                                cnxk_tim_bkt_dec_lock(bkt);
                                goto __retry;
                        }
@@ -449,10 +451,10 @@ cnxk_tim_add_entry_brst(struct cnxk_tim_ring *const 
tim_ring,
        struct cnxk_tim_ent *chunk = NULL;
        struct cnxk_tim_bkt *mirr_bkt;
        struct cnxk_tim_bkt *bkt;
-       uint16_t chunk_remainder;
+       int16_t chunk_remainder;
        uint16_t index = 0;
        uint64_t lock_sema;
-       int16_t rem, crem;
+       int16_t rem;
        uint8_t lock_cnt;
 
 __retry:
@@ -460,31 +462,6 @@ cnxk_tim_add_entry_brst(struct cnxk_tim_ring *const 
tim_ring,
 
        /* Only one thread beyond this. */
        lock_sema = cnxk_tim_bkt_inc_lock(bkt);
-       lock_cnt = (uint8_t)((lock_sema >> TIM_BUCKET_W1_S_LOCK) &
-                            TIM_BUCKET_W1_M_LOCK);
-
-       if (lock_cnt) {
-               cnxk_tim_bkt_dec_lock(bkt);
-#ifdef RTE_ARCH_ARM64
-               asm volatile(PLT_CPU_FEATURE_PREAMBLE
-                            "          ldxrb %w[lock_cnt], [%[lock]]   \n"
-                            "          tst %w[lock_cnt], 255           \n"
-                            "          beq dne%=                       \n"
-                            "          sevl                            \n"
-                            "rty%=:    wfe                             \n"
-                            "          ldxrb %w[lock_cnt], [%[lock]]   \n"
-                            "          tst %w[lock_cnt], 255           \n"
-                            "          bne rty%=                       \n"
-                            "dne%=:                                    \n"
-                            : [lock_cnt] "=&r"(lock_cnt)
-                            : [lock] "r"(&bkt->lock)
-                            : "memory");
-#else
-               while (__atomic_load_n(&bkt->lock, __ATOMIC_RELAXED))
-                       ;
-#endif
-               goto __retry;
-       }
 
        /* Bucket related checks. */
        if (unlikely(cnxk_tim_bkt_get_hbt(lock_sema))) {
@@ -509,21 +486,46 @@ cnxk_tim_add_entry_brst(struct cnxk_tim_ring *const 
tim_ring,
                        } while (hbt_state & BIT_ULL(33));
 #endif
 
-                       if (!(hbt_state & BIT_ULL(34))) {
+                       if (!(hbt_state & BIT_ULL(34)) ||
+                           !(hbt_state & GENMASK(31, 0))) {
                                cnxk_tim_bkt_dec_lock(bkt);
                                goto __retry;
                        }
                }
        }
 
+       lock_cnt = (uint8_t)((lock_sema >> TIM_BUCKET_W1_S_LOCK) &
+                            TIM_BUCKET_W1_M_LOCK);
+       if (lock_cnt) {
+               cnxk_tim_bkt_dec_lock(bkt);
+#ifdef RTE_ARCH_ARM64
+               asm volatile(PLT_CPU_FEATURE_PREAMBLE
+                            "          ldxrb %w[lock_cnt], [%[lock]]   \n"
+                            "          tst %w[lock_cnt], 255           \n"
+                            "          beq dne%=                       \n"
+                            "          sevl                            \n"
+                            "rty%=:    wfe                             \n"
+                            "          ldxrb %w[lock_cnt], [%[lock]]   \n"
+                            "          tst %w[lock_cnt], 255           \n"
+                            "          bne rty%=                       \n"
+                            "dne%=:                                    \n"
+                            : [lock_cnt] "=&r"(lock_cnt)
+                            : [lock] "r"(&bkt->lock)
+                            : "memory");
+#else
+               while (__atomic_load_n(&bkt->lock, __ATOMIC_RELAXED))
+                       ;
+#endif
+               goto __retry;
+       }
+
        chunk_remainder = cnxk_tim_bkt_fetch_rem(lock_sema);
        rem = chunk_remainder - nb_timers;
        if (rem < 0) {
-               crem = tim_ring->nb_chunk_slots - chunk_remainder;
-               if (chunk_remainder && crem) {
+               if (chunk_remainder > 0) {
                        chunk = ((struct cnxk_tim_ent *)
                                         mirr_bkt->current_chunk) +
-                               crem;
+                               tim_ring->nb_chunk_slots - chunk_remainder;
 
                        index = cnxk_tim_cpy_wrk(index, chunk_remainder, chunk,
                                                 tim, ents, bkt);
@@ -537,18 +539,19 @@ cnxk_tim_add_entry_brst(struct cnxk_tim_ring *const 
tim_ring,
                        chunk = cnxk_tim_insert_chunk(bkt, mirr_bkt, tim_ring);
 
                if (unlikely(chunk == NULL)) {
-                       cnxk_tim_bkt_dec_lock(bkt);
+                       cnxk_tim_bkt_dec_lock_relaxed(bkt);
                        rte_errno = ENOMEM;
                        tim[index]->state = RTE_EVENT_TIMER_ERROR;
-                       return crem;
+                       return index;
                }
                *(uint64_t *)(chunk + tim_ring->nb_chunk_slots) = 0;
                mirr_bkt->current_chunk = (uintptr_t)chunk;
-               cnxk_tim_cpy_wrk(index, nb_timers, chunk, tim, ents, bkt);
+               index = cnxk_tim_cpy_wrk(index, nb_timers, chunk, tim, ents,
+                                        bkt) -
+                       index;
 
-               rem = nb_timers - chunk_remainder;
-               cnxk_tim_bkt_set_rem(bkt, tim_ring->nb_chunk_slots - rem);
-               cnxk_tim_bkt_add_nent(bkt, rem);
+               cnxk_tim_bkt_set_rem(bkt, tim_ring->nb_chunk_slots - index);
+               cnxk_tim_bkt_add_nent(bkt, index);
        } else {
                chunk = (struct cnxk_tim_ent *)mirr_bkt->current_chunk;
                chunk += (tim_ring->nb_chunk_slots - chunk_remainder);
-- 
2.25.1

Reply via email to