hash: fix race condition in iterate
In rte_hash_iterate, the reader lock did not protect the while loop which checks empty entry. This created a race condition that the entry may become empty when enters the lock, then a wrong key data value would be read out. This commit reads out the position in the while condition, which makes sure that the position will not be changed to empty before entering the lock. Fixes: f2e3001b53ec ("hash: support read/write concurrency") Cc: stable@dpdk.org Reported-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com> Signed-off-by: Yipeng Wang <yipeng1.wang@intel.com> Reviewed-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com> Acked-by: Dharmik Thakkar <dharmik.thakkar@arm.com> Acked-by: Bruce Richardson <bruce.richardson@intel.com>
This commit is contained in:
parent
86c1ef2090
commit
9904094344
@ -1318,7 +1318,7 @@ rte_hash_iterate(const struct rte_hash *h, const void **key, void **data, uint32
|
||||
idx = *next % RTE_HASH_BUCKET_ENTRIES;
|
||||
|
||||
/* If current position is empty, go to the next one */
|
||||
while (h->buckets[bucket_idx].key_idx[idx] == EMPTY_SLOT) {
|
||||
while ((position = h->buckets[bucket_idx].key_idx[idx]) == EMPTY_SLOT) {
|
||||
(*next)++;
|
||||
/* End of table */
|
||||
if (*next == total_entries)
|
||||
@ -1326,9 +1326,8 @@ rte_hash_iterate(const struct rte_hash *h, const void **key, void **data, uint32
|
||||
bucket_idx = *next / RTE_HASH_BUCKET_ENTRIES;
|
||||
idx = *next % RTE_HASH_BUCKET_ENTRIES;
|
||||
}
|
||||
|
||||
__hash_rw_reader_lock(h);
|
||||
/* Get position of entry in key table */
|
||||
position = h->buckets[bucket_idx].key_idx[idx];
|
||||
next_key = (struct rte_hash_key *) ((char *)h->key_store +
|
||||
position * h->key_entry_size);
|
||||
/* Return key and data */
|
||||
|
Loading…
x
Reference in New Issue
Block a user