Commit 0b3cecb5 authored by Vladimír Čunát's avatar Vladimír Čunát

lib/generic/lru: fix alignment of struct lru

parent cd571a9f
...@@ -576,9 +576,9 @@ static int init_resolver(struct engine *engine) ...@@ -576,9 +576,9 @@ static int init_resolver(struct engine *engine)
/* Empty init; filled via ./lua/config.lua */ /* Empty init; filled via ./lua/config.lua */
kr_zonecut_init(&engine->resolver.root_hints, (const uint8_t *)"", engine->pool); kr_zonecut_init(&engine->resolver.root_hints, (const uint8_t *)"", engine->pool);
/* Open NS rtt + reputation cache */ /* Open NS rtt + reputation cache */
lru_create(&engine->resolver.cache_rtt, LRU_RTT_SIZE, engine->pool, NULL); lru_create(&engine->resolver.cache_rtt, LRU_RTT_SIZE, NULL, NULL);
lru_create(&engine->resolver.cache_rep, LRU_REP_SIZE, engine->pool, NULL); lru_create(&engine->resolver.cache_rep, LRU_REP_SIZE, NULL, NULL);
lru_create(&engine->resolver.cache_cookie, LRU_COOKIES_SIZE, engine->pool, NULL); lru_create(&engine->resolver.cache_cookie, LRU_COOKIES_SIZE, NULL, NULL);
/* Load basic modules */ /* Load basic modules */
engine_register(engine, "iterate", NULL, NULL); engine_register(engine, "iterate", NULL, NULL);
...@@ -711,7 +711,7 @@ void engine_deinit(struct engine *engine) ...@@ -711,7 +711,7 @@ void engine_deinit(struct engine *engine)
kr_zonecut_deinit(&engine->resolver.root_hints); kr_zonecut_deinit(&engine->resolver.root_hints);
kr_cache_close(&engine->resolver.cache); kr_cache_close(&engine->resolver.cache);
/* The lru keys are currently malloc-ated and need to be freed. */ /* The LRUs are currently malloc-ated and need to be freed. */
lru_free(engine->resolver.cache_rtt); lru_free(engine->resolver.cache_rtt);
lru_free(engine->resolver.cache_rep); lru_free(engine->resolver.cache_rep);
lru_free(engine->resolver.cache_cookie); lru_free(engine->resolver.cache_cookie);
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "lib/generic/lru.h" #include "lib/generic/lru.h"
#include "contrib/murmurhash3/murmurhash3.h" #include "contrib/murmurhash3/murmurhash3.h"
#include "contrib/ucw/mempool.h"
typedef struct lru_group lru_group_t; typedef struct lru_group lru_group_t;
...@@ -108,6 +109,15 @@ KR_EXPORT struct lru * lru_create_impl(uint max_slots, knot_mm_t *mm_array, knot ...@@ -108,6 +109,15 @@ KR_EXPORT struct lru * lru_create_impl(uint max_slots, knot_mm_t *mm_array, knot
group_count = 1 << log_groups; group_count = 1 << log_groups;
assert(max_slots <= group_count * LRU_ASSOC && group_count * LRU_ASSOC < 2 * max_slots); assert(max_slots <= group_count * LRU_ASSOC && group_count * LRU_ASSOC < 2 * max_slots);
/* Get a sufficiently aligning mm_array if NULL is passed. */
if (!mm_array) {
static knot_mm_t mm_array_default = { 0 };
if (!mm_array_default.ctx)
mm_ctx_init_aligned(&mm_array_default, __alignof(struct lru));
mm_array = &mm_array_default;
}
assert(mm_array->alloc != mm_malloc && mm_array->alloc != (knot_mm_alloc_t)mp_alloc);
size_t size = offsetof(struct lru, groups[group_count]); size_t size = offsetof(struct lru, groups[group_count]);
struct lru *lru = mm_alloc(mm_array, size); struct lru *lru = mm_alloc(mm_array, size);
if (unlikely(lru == NULL)) if (unlikely(lru == NULL))
......
...@@ -88,6 +88,7 @@ ...@@ -88,6 +88,7 @@
* @param ptable pointer to a pointer to the LRU * @param ptable pointer to a pointer to the LRU
* @param max_slots number of slots * @param max_slots number of slots
* @param mm_ctx_array memory context to use for the huge array, NULL for default * @param mm_ctx_array memory context to use for the huge array, NULL for default
* If you pass your own, it needs to produce CACHE_ALIGNED allocations (ubsan).
* @param mm_ctx memory context to use for individual key-value pairs, NULL for default * @param mm_ctx memory context to use for individual key-value pairs, NULL for default
* *
* @note The pointers to memory contexts need to remain valid * @note The pointers to memory contexts need to remain valid
......
...@@ -71,6 +71,18 @@ void *mm_malloc(void *ctx, size_t n) ...@@ -71,6 +71,18 @@ void *mm_malloc(void *ctx, size_t n)
(void)ctx; (void)ctx;
return malloc(n); return malloc(n);
} }
void *mm_malloc_aligned(void *ctx, size_t n)
{
size_t alignment = (size_t)ctx;
void *res;
int err = posix_memalign(&res, alignment, n);
if (err == 0) {
return res;
} else {
assert(err == -1 && errno == ENOMEM);
return NULL;
}
}
/* /*
* Macros. * Macros.
......
...@@ -135,6 +135,8 @@ void *mm_realloc(knot_mm_t *mm, void *what, size_t size, size_t prev_size); ...@@ -135,6 +135,8 @@ void *mm_realloc(knot_mm_t *mm, void *what, size_t size, size_t prev_size);
/** Trivial malloc() wrapper. */ /** Trivial malloc() wrapper. */
void *mm_malloc(void *ctx, size_t n); void *mm_malloc(void *ctx, size_t n);
/** posix_memalign() wrapper. */
void *mm_malloc_aligned(void *ctx, size_t n);
/** Initialize mm with standard malloc+free. */ /** Initialize mm with standard malloc+free. */
static inline void mm_ctx_init(knot_mm_t *mm) static inline void mm_ctx_init(knot_mm_t *mm)
...@@ -143,6 +145,20 @@ static inline void mm_ctx_init(knot_mm_t *mm) ...@@ -143,6 +145,20 @@ static inline void mm_ctx_init(knot_mm_t *mm)
mm->alloc = mm_malloc; mm->alloc = mm_malloc;
mm->free = free; mm->free = free;
} }
/** Initialize mm with malloc+free with higher alignment (a power of two). */
static inline void mm_ctx_init_aligned(knot_mm_t *mm, size_t alignment)
{
assert(__builtin_popcount(alignment) == 1);
mm->ctx = (uint8_t *)NULL + alignment; /*< roundabout to satisfy linters */
/* posix_memalign() doesn't allow alignment < sizeof(void*),
* and there's no point in using it for small values anyway,
* as plain malloc() guarantees at least max_align_t.
* Nitpick: we might use that type when assuming C11. */
mm->alloc = alignment > sizeof(void*) ? mm_malloc_aligned : mm_malloc;
mm->free = free;
}
/* @endcond */ /* @endcond */
/** A strcmp() variant directly usable for qsort() on an array of strings. */ /** A strcmp() variant directly usable for qsort() on an array of strings. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment