[PATCH RFC 03/10] target/riscv: Protect the hashtable modifications with a lock

Atish Patra posted 10 patches 1 month, 2 weeks ago
[PATCH RFC 03/10] target/riscv: Protect the hashtable modifications with a lock
Posted by Atish Patra 1 month, 2 weeks ago
Add a read/write lock to protect the hashtable access operations
in multi-threaded scenario.

Signed-off-by: Atish Patra <atishp@rivosinc.com>
---
 target/riscv/cpu.h |  1 +
 target/riscv/pmu.c | 10 +++++++++-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index a63a29744c26..97e408b91219 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -496,6 +496,7 @@ struct ArchCPU {
     uint32_t pmu_avail_ctrs;
     /* Mapping of events to counters */
     GHashTable *pmu_event_ctr_map;
+    pthread_rwlock_t pmu_map_lock;
     const GPtrArray *decoders;
 };
 
diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
index a88c321a6cad..21377518f4e0 100644
--- a/target/riscv/pmu.c
+++ b/target/riscv/pmu.c
@@ -271,12 +271,15 @@ static bool riscv_pmu_htable_lookup(RISCVCPU *cpu, uint32_t key,
     GHashTable *table = cpu->pmu_event_ctr_map;
     gpointer val_ptr;
 
-    val_ptr = g_hash_table_lookup(table, GUINT_TO_POINTER(key));
+    pthread_rwlock_rdlock(&cpu->pmu_map_lock);
+    gpointer val_ptr = g_hash_table_lookup(table, GUINT_TO_POINTER(key));
     if (!val_ptr) {
+        pthread_rwlock_unlock(&cpu->pmu_map_lock);
         return false;
     }
 
     *value = GPOINTER_TO_UINT(val_ptr);
+    pthread_rwlock_unlock(&cpu->pmu_map_lock);
     return true;
 }
 
@@ -388,9 +391,11 @@ int riscv_pmu_update_event_map(CPURISCVState *env, uint64_t value,
      * mapping.
      */
     if (!value) {
+        pthread_rwlock_wrlock(&cpu->pmu_map_lock);
         g_hash_table_foreach_remove(cpu->pmu_event_ctr_map,
                                     pmu_remove_event_map,
                                     GUINT_TO_POINTER(ctr_idx));
+        pthread_rwlock_unlock(&cpu->pmu_map_lock);
         return 0;
     }
 
@@ -410,8 +415,10 @@ int riscv_pmu_update_event_map(CPURISCVState *env, uint64_t value,
         /* We don't support any raw events right now */
         return -1;
     }
+    pthread_rwlock_wrlock(&cpu->pmu_map_lock);
     g_hash_table_insert(cpu->pmu_event_ctr_map, GUINT_TO_POINTER(event_idx),
                         GUINT_TO_POINTER(ctr_idx));
+    pthread_rwlock_unlock(&cpu->pmu_map_lock);
 
     return 0;
 }
@@ -597,4 +604,5 @@ void riscv_pmu_init(RISCVCPU *cpu, Error **errp)
     }
 
     cpu->pmu_avail_ctrs = cpu->cfg.pmu_mask;
+    pthread_rwlock_init(&cpu->pmu_map_lock, NULL);
 }

-- 
2.34.1