util/sparse_array: don't stomp head's counter on pop operations
authorD Scott Phillips <d.scott.phillips@intel.com>
Fri, 17 Apr 2020 17:28:06 +0000 (10:28 -0700)
committerMarge Bot <eric+marge@anholt.net>
Fri, 17 Apr 2020 18:41:40 +0000 (18:41 +0000)
By temporarily storing the new_head by a uint32_t, we wipe out the
counter section of the head pointer.

Fixes: e4f01eca ("util: Add a free list structure for use with util_sparse_array")
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Rafael Antognolli <rafael.antognolli@intel.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4612>

src/util/sparse_array.c

index 61dbd2acdff99ad2e962abd28ba2a1f97e6180b8..0c04fd0d6dc76fd2920bacd5e2ddb473befa7a44 100644 (file)
@@ -270,7 +270,7 @@ util_sparse_array_free_list_pop_idx(struct util_sparse_array_free_list *fl)
       uint32_t head_idx = current_head; /* Index is the bottom 32 bits */
       void *head_elem = util_sparse_array_get(fl->arr, head_idx);
       uint32_t *head_next = (uint32_t *)((char *)head_elem + fl->next_offset);
-      uint32_t new_head = free_list_head(current_head, *head_next);
+      uint64_t new_head = free_list_head(current_head, *head_next);
       uint64_t old_head = p_atomic_cmpxchg(&fl->head, current_head, new_head);
       if (old_head == current_head)
          return head_idx;
@@ -291,7 +291,7 @@ util_sparse_array_free_list_pop_elem(struct util_sparse_array_free_list *fl)
       uint32_t head_idx = current_head; /* Index is the bottom 32 bits */
       void *head_elem = util_sparse_array_get(fl->arr, head_idx);
       uint32_t *head_next = (uint32_t *)((char *)head_elem + fl->next_offset);
-      uint32_t new_head = free_list_head(current_head, *head_next);
+      uint64_t new_head = free_list_head(current_head, *head_next);
       uint64_t old_head = p_atomic_cmpxchg(&fl->head, current_head, new_head);
       if (old_head == current_head)
          return head_elem;