Mesa (main): util/vector: make util_vector_init harder to misuse

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Oct 8 00:47:12 UTC 2021


Module: Mesa
Branch: main
Commit: 8cce6281e687f8c9937641ad84e7056b8ae9a23e
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=8cce6281e687f8c9937641ad84e7056b8ae9a23e

Author: Chia-I Wu <olvaffe at gmail.com>
Date:   Tue Oct  5 11:58:58 2021 -0700

util/vector: make util_vector_init harder to misuse

Make u_vector_init a wrapper to u_vector_init_pot.  Let both take
(element_count, element_size) as parameters.

Motivated by eed0fc4caf2 ("vulkan/wsi/wayland: fix an invalid
u_vector_init call")

v2: rename u_vector_init_pot to u_vector_init_pow2

Signed-off-by: Chia-I Wu <olvaffe at gmail.com>
Reviewed-by: Simon Ser <contact at emersion.fr>
Reviewed-by: Adam Jackson <ajax at redhat.com>
Reviewed-by: Eric Engestrom <eric at engestrom.ch>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13201>

---

 src/amd/common/ac_nir_lower_ngg.c         |  2 +-
 src/amd/common/ac_surface_modifier_test.c |  2 +-
 src/compiler/nir/nir_lower_flrp.c         |  2 +-
 src/compiler/nir/nir_opt_comparison_pre.c |  4 +---
 src/compiler/nir/nir_worklist.h           |  3 +--
 src/egl/drivers/dri2/platform_wayland.c   |  2 +-
 src/intel/vulkan/anv_allocator.c          | 10 ++++------
 src/intel/vulkan/anv_batch_chain.c        | 11 ++++-------
 src/util/tests/vector/vector_test.cpp     |  2 +-
 src/util/u_vector.c                       | 15 ++++++++++-----
 src/util/u_vector.h                       | 16 +++++++++++++++-
 src/vulkan/wsi/wsi_common_queue.h         |  8 +++-----
 src/vulkan/wsi/wsi_common_wayland.c       |  6 ++----
 13 files changed, 45 insertions(+), 38 deletions(-)

diff --git a/src/amd/common/ac_nir_lower_ngg.c b/src/amd/common/ac_nir_lower_ngg.c
index 2aba6a076c6..b2fdea1633d 100644
--- a/src/amd/common/ac_nir_lower_ngg.c
+++ b/src/amd/common/ac_nir_lower_ngg.c
@@ -847,7 +847,7 @@ analyze_shader_before_culling(nir_shader *shader, lower_ngg_nogs_state *nogs_sta
 static void
 save_reusable_variables(nir_builder *b, lower_ngg_nogs_state *nogs_state)
 {
-   ASSERTED int vec_ok = u_vector_init(&nogs_state->saved_uniforms, sizeof(saved_uniform), 4 * sizeof(saved_uniform));
+   ASSERTED int vec_ok = u_vector_init(&nogs_state->saved_uniforms, 4, sizeof(saved_uniform));
    assert(vec_ok);
 
    nir_block *block = nir_start_block(b->impl);
diff --git a/src/amd/common/ac_surface_modifier_test.c b/src/amd/common/ac_surface_modifier_test.c
index 91bdc8f5bba..e7249822e5e 100644
--- a/src/amd/common/ac_surface_modifier_test.c
+++ b/src/amd/common/ac_surface_modifier_test.c
@@ -397,7 +397,7 @@ int main()
    STATIC_ASSERT(sizeof(struct test_entry) == 64);
 
    struct u_vector test_entries;
-   u_vector_init(&test_entries,  sizeof(struct test_entry), 4096);
+   u_vector_init_pow2(&test_entries, 64, sizeof(struct test_entry));
 
    for (unsigned i = 0; i < ARRAY_SIZE(testcases); ++i) {
       struct radeon_info info = get_radeon_info(&testcases[i]);
diff --git a/src/compiler/nir/nir_lower_flrp.c b/src/compiler/nir/nir_lower_flrp.c
index e23c3c189a5..9c13619462f 100644
--- a/src/compiler/nir/nir_lower_flrp.c
+++ b/src/compiler/nir/nir_lower_flrp.c
@@ -635,7 +635,7 @@ nir_lower_flrp(nir_shader *shader,
 {
    struct u_vector dead_flrp;
 
-   if (!u_vector_init(&dead_flrp, sizeof(struct nir_alu_instr *), 64))
+   if (!u_vector_init_pow2(&dead_flrp, 8, sizeof(struct nir_alu_instr *)))
       return false;
 
    nir_foreach_function(function, shader) {
diff --git a/src/compiler/nir/nir_opt_comparison_pre.c b/src/compiler/nir/nir_opt_comparison_pre.c
index f48dbe59d04..19516a5061d 100644
--- a/src/compiler/nir/nir_opt_comparison_pre.c
+++ b/src/compiler/nir/nir_opt_comparison_pre.c
@@ -105,9 +105,7 @@ push_block(struct block_queue *bq)
          return NULL;
    }
 
-   if (!u_vector_init(&bi->instructions,
-                      sizeof(nir_alu_instr *),
-                      8 * sizeof(nir_alu_instr *))) {
+   if (!u_vector_init_pow2(&bi->instructions, 8, sizeof(nir_alu_instr *))) {
       free(bi);
       return NULL;
    }
diff --git a/src/compiler/nir/nir_worklist.h b/src/compiler/nir/nir_worklist.h
index 0f402e080fd..ad45b064d5c 100644
--- a/src/compiler/nir/nir_worklist.h
+++ b/src/compiler/nir/nir_worklist.h
@@ -108,8 +108,7 @@ nir_instr_worklist_create() {
    if (!wl)
       return NULL;
 
-   if (!u_vector_init(&wl->instr_vec, sizeof(struct nir_instr *),
-                      sizeof(struct nir_instr *) * 8)) {
+   if (!u_vector_init_pow2(&wl->instr_vec, 8, sizeof(struct nir_instr *))) {
       free(wl);
       return NULL;
    }
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index d94e674653f..574ee315856 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -1506,7 +1506,7 @@ dri2_initialize_wayland_drm(_EGLDisplay *disp)
    if (!dri2_dpy->wl_modifiers)
       goto cleanup;
    for (int i = 0; i < ARRAY_SIZE(dri2_wl_visuals); i++) {
-      if (!u_vector_init(&dri2_dpy->wl_modifiers[i], sizeof(uint64_t), 32))
+      if (!u_vector_init_pow2(&dri2_dpy->wl_modifiers[i], 4, sizeof(uint64_t)))
          goto cleanup;
    }
 
diff --git a/src/intel/vulkan/anv_allocator.c b/src/intel/vulkan/anv_allocator.c
index f00807b6578..6715d294140 100644
--- a/src/intel/vulkan/anv_allocator.c
+++ b/src/intel/vulkan/anv_allocator.c
@@ -160,9 +160,8 @@ anv_state_table_init(struct anv_state_table *table,
       goto fail_fd;
    }
 
-   if (!u_vector_init(&table->cleanups,
-                      round_to_power_of_two(sizeof(struct anv_state_table_cleanup)),
-                      128)) {
+   if (!u_vector_init(&table->cleanups, 8,
+                      sizeof(struct anv_state_table_cleanup))) {
       result = vk_error(device, VK_ERROR_INITIALIZATION_FAILED);
       goto fail_fd;
    }
@@ -405,9 +404,8 @@ anv_block_pool_init(struct anv_block_pool *pool,
       pool->bo = &pool->wrapper_bo;
    }
 
-   if (!u_vector_init(&pool->mmap_cleanups,
-                      round_to_power_of_two(sizeof(struct anv_mmap_cleanup)),
-                      128)) {
+   if (!u_vector_init(&pool->mmap_cleanups, 8,
+                      sizeof(struct anv_mmap_cleanup))) {
       result = vk_error(device, VK_ERROR_INITIALIZATION_FAILED);
       goto fail_fd;
    }
diff --git a/src/intel/vulkan/anv_batch_chain.c b/src/intel/vulkan/anv_batch_chain.c
index bc159e28308..cb29aeaa58c 100644
--- a/src/intel/vulkan/anv_batch_chain.c
+++ b/src/intel/vulkan/anv_batch_chain.c
@@ -861,18 +861,15 @@ anv_cmd_buffer_init_batch_bo_chain(struct anv_cmd_buffer *cmd_buffer)
    anv_batch_bo_start(batch_bo, &cmd_buffer->batch,
                       GFX8_MI_BATCH_BUFFER_START_length * 4);
 
-   int success = u_vector_init(&cmd_buffer->seen_bbos,
-                                 sizeof(struct anv_bo *),
-                                 8 * sizeof(struct anv_bo *));
+   int success = u_vector_init_pow2(&cmd_buffer->seen_bbos, 8,
+                                    sizeof(struct anv_bo *));
    if (!success)
       goto fail_batch_bo;
 
    *(struct anv_batch_bo **)u_vector_add(&cmd_buffer->seen_bbos) = batch_bo;
 
-   /* u_vector requires power-of-two size elements */
-   unsigned pow2_state_size = util_next_power_of_two(sizeof(struct anv_state));
-   success = u_vector_init(&cmd_buffer->bt_block_states,
-                           pow2_state_size, 8 * pow2_state_size);
+   success = u_vector_init(&cmd_buffer->bt_block_states, 8,
+                           sizeof(struct anv_state));
    if (!success)
       goto fail_seen_bbos;
 
diff --git a/src/util/tests/vector/vector_test.cpp b/src/util/tests/vector/vector_test.cpp
index aa7ca2bbf94..e68124a1e51 100644
--- a/src/util/tests/vector/vector_test.cpp
+++ b/src/util/tests/vector/vector_test.cpp
@@ -30,7 +30,7 @@ static void test(uint32_t size_in_elements, uint32_t elements_to_walk, uint32_t
    uint32_t add_counter = 0;
    uint32_t remove_counter = 0;
 
-   ASSERT_TRUE(u_vector_init(&vector, sizeof(uint64_t), sizeof(uint64_t) * size_in_elements));
+   ASSERT_TRUE(u_vector_init(&vector, size_in_elements, sizeof(uint64_t)));
 
    // Override the head and tail so we can quickly test rollover
    vector.head = vector.tail = start;
diff --git a/src/util/u_vector.c b/src/util/u_vector.c
index 15f8ed6bdad..3c5593da77a 100644
--- a/src/util/u_vector.c
+++ b/src/util/u_vector.c
@@ -34,17 +34,22 @@
  * wraparound.
  */
 
+/**
+ * initial_element_count and element_size must be power-of-two.
+ */
 int
-u_vector_init(struct u_vector *vector, uint32_t element_size, uint32_t size)
+u_vector_init_pow2(struct u_vector *vector,
+                   uint32_t initial_element_count,
+                   uint32_t element_size)
 {
-   assert(util_is_power_of_two_nonzero(size));
-   assert(element_size < size && util_is_power_of_two_nonzero(element_size));
+   assert(util_is_power_of_two_nonzero(initial_element_count));
+   assert(util_is_power_of_two_nonzero(element_size));
 
    vector->head = 0;
    vector->tail = 0;
    vector->element_size = element_size;
-   vector->size = size;
-   vector->data = malloc(size);
+   vector->size = element_size * initial_element_count;
+   vector->data = malloc(vector->size);
 
    return vector->data != NULL;
 }
diff --git a/src/util/u_vector.h b/src/util/u_vector.h
index dbeda5fe337..1283e78b70c 100644
--- a/src/util/u_vector.h
+++ b/src/util/u_vector.h
@@ -32,6 +32,7 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include "util/macros.h"
+#include "util/u_math.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -53,10 +54,23 @@ struct u_vector {
    void *data;
 };
 
-int u_vector_init(struct u_vector *queue, uint32_t element_size, uint32_t size);
+int u_vector_init_pow2(struct u_vector *queue,
+                       uint32_t initial_element_count,
+                       uint32_t element_size);
+
 void *u_vector_add(struct u_vector *queue);
 void *u_vector_remove(struct u_vector *queue);
 
+static inline int
+u_vector_init(struct u_vector *queue,
+              uint32_t initial_element_count,
+              uint32_t element_size)
+{
+   initial_element_count = util_next_power_of_two(initial_element_count);
+   element_size = util_next_power_of_two(element_size);
+   return u_vector_init_pow2(queue, initial_element_count, element_size);
+}
+
 static inline int
 u_vector_length(struct u_vector *queue)
 {
diff --git a/src/vulkan/wsi/wsi_common_queue.h b/src/vulkan/wsi/wsi_common_queue.h
index 6d489cbf17e..3676876b903 100644
--- a/src/vulkan/wsi/wsi_common_queue.h
+++ b/src/vulkan/wsi/wsi_common_queue.h
@@ -39,12 +39,10 @@ wsi_queue_init(struct wsi_queue *queue, int length)
 {
    int ret;
 
-   uint32_t length_pow2 = 4;
-   while (length_pow2 < length)
-      length_pow2 *= 2;
+   if (length < 4)
+      length = 4;
 
-   ret = u_vector_init(&queue->vector, sizeof(uint32_t),
-                       sizeof(uint32_t) * length_pow2);
+   ret = u_vector_init(&queue->vector, length, sizeof(uint32_t));
    if (!ret)
       return ENOMEM;
 
diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c
index e36a4683123..c27a7d2b760 100644
--- a/src/vulkan/wsi/wsi_common_wayland.c
+++ b/src/vulkan/wsi/wsi_common_wayland.c
@@ -113,7 +113,7 @@ wsi_wl_display_add_vk_format(struct wsi_wl_display *display,
       return NULL;
 
    struct u_vector modifiers;
-   if (!u_vector_init(&modifiers, sizeof(uint64_t), 32))
+   if (!u_vector_init_pow2(&modifiers, 4, sizeof(uint64_t)))
       return NULL;
 
    f = u_vector_add(formats);
@@ -455,9 +455,7 @@ wsi_wl_display_init(struct wsi_wayland *wsi_wl,
    VkResult result = VK_SUCCESS;
    memset(display, 0, sizeof(*display));
 
-   const size_t elem_size =
-      util_next_power_of_two(sizeof(struct wsi_wl_format));
-   if (!u_vector_init(&display->formats, elem_size, 8 * elem_size))
+   if (!u_vector_init(&display->formats, 8, sizeof(struct wsi_wl_format)))
       return VK_ERROR_OUT_OF_HOST_MEMORY;
 
    display->wsi_wl = wsi_wl;



More information about the mesa-commit mailing list