From: Christian Babeux Date: Mon, 27 Aug 2012 18:48:19 +0000 (-0400) Subject: Fix: Filter bytecode alloc buffer size must be a power of 2 X-Git-Tag: v2.1.0-rc3~8 X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=commitdiff_plain;h=01a204f0f7a1e2070826804c142a456af21867a0 Fix: Filter bytecode alloc buffer size must be a power of 2 The current allocation policy for the filter bytecode buffer is to double the size each time the underlying buffer can no longer contain the entire bytecode plus padding. In some cases, the initial allocation length is not a multiple of 2, thus possibly leading to odd-looking allocation size each time the buffer size is doubled. Acked-by: Mathieu Desnoyers Signed-off-by: Christian Babeux Signed-off-by: David Goulet --- diff --git a/src/lib/lttng-ctl/filter/filter-visitor-generate-bytecode.c b/src/lib/lttng-ctl/filter/filter-visitor-generate-bytecode.c index 36d35c558..71da21c8a 100644 --- a/src/lib/lttng-ctl/filter/filter-visitor-generate-bytecode.c +++ b/src/lib/lttng-ctl/filter/filter-visitor-generate-bytecode.c @@ -38,6 +38,45 @@ static int recursive_visit_gen_bytecode(struct filter_parser_ctx *ctx, struct ir_op *node); +static inline int fls(unsigned int x) +{ + int r = 32; + + if (!x) + return 0; + if (!(x & 0xFFFF0000U)) { + x <<= 16; + r -= 16; + } + if (!(x & 0xFF000000U)) { + x <<= 8; + r -= 8; + } + if (!(x & 0xF0000000U)) { + x <<= 4; + r -= 4; + } + if (!(x & 0xC0000000U)) { + x <<= 2; + r -= 2; + } + if (!(x & 0x80000000U)) { + x <<= 1; + r -= 1; + } + return r; +} + +static inline int get_count_order(unsigned int count) +{ + int order; + + order = fls(count) - 1; + if (count & (count - 1)) + order++; + return order; +} + static int bytecode_init(struct lttng_filter_bytecode_alloc **fb) { @@ -58,7 +97,7 @@ int32_t bytecode_reserve(struct lttng_filter_bytecode_alloc **fb, uint32_t align if ((*fb)->b.len + padding + len > (*fb)->alloc_len) { uint32_t new_len = - max_t(uint32_t, (*fb)->b.len + padding + len, + max_t(uint32_t, 1U << get_count_order((*fb)->b.len + padding + len), (*fb)->alloc_len << 1); uint32_t old_len = (*fb)->alloc_len;