util/vector: make util_vector_init harder to misuse
authorChia-I Wu <olvaffe@gmail.com>
Tue, 5 Oct 2021 18:58:58 +0000 (11:58 -0700)
committerMarge Bot <eric+marge@anholt.net>
Fri, 8 Oct 2021 00:15:11 +0000 (00:15 +0000)
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@gmail.com>
Reviewed-by: Simon Ser <contact@emersion.fr>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Reviewed-by: Eric Engestrom <eric@engestrom.ch>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13201>

13 files changed:
src/amd/common/ac_nir_lower_ngg.c
src/amd/common/ac_surface_modifier_test.c
src/compiler/nir/nir_lower_flrp.c
src/compiler/nir/nir_opt_comparison_pre.c
src/compiler/nir/nir_worklist.h
src/egl/drivers/dri2/platform_wayland.c
src/intel/vulkan/anv_allocator.c
src/intel/vulkan/anv_batch_chain.c
src/util/tests/vector/vector_test.cpp
src/util/u_vector.c
src/util/u_vector.h
src/vulkan/wsi/wsi_common_queue.h
src/vulkan/wsi/wsi_common_wayland.c

index 2aba6a0..b2fdea1 100644 (file)
@@ -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);
index 91bdc8f..e724982 100644 (file)
@@ -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]);
index e23c3c1..9c13619 100644 (file)
@@ -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) {
index f48dbe5..19516a5 100644 (file)
@@ -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;
    }
index 0f402e0..ad45b06 100644 (file)
@@ -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;
    }
index d94e674..574ee31 100644 (file)
@@ -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;
    }
 
index f00807b..6715d29 100644 (file)
@@ -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;
    }
index bc159e2..cb29aea 100644 (file)
@@ -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;
 
index aa7ca2b..e68124a 100644 (file)
@@ -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;
index 15f8ed6..3c5593d 100644 (file)
  * 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;
 }
index dbeda5f..1283e78 100644 (file)
@@ -32,6 +32,7 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include "util/macros.h"
+#include "util/u_math.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -53,11 +54,24 @@ 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)
 {
    return (queue->head - queue->tail) / queue->element_size;
index 6d489cb..3676876 100644 (file)
@@ -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;
 
index e36a468..c27a7d2 100644 (file)
@@ -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;