From: Vladimír Čunát Date: Tue, 9 Jun 2020 06:09:32 +0000 (+0200) Subject: gc: fix integer overflow when computing how much to GC X-Git-Tag: v5.1.2~3^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=26cf29390b2acfe8c6b0547532474ae53763cf42;p=thirdparty%2Fknot-resolver.git gc: fix integer overflow when computing how much to GC On 32-bit systems the insufficient GC could commonly happen: https://lists.nic.cz/pipermail/knot-resolver-users/2020/000265.html The meaning of -f parameter got slightly changed, so that the buggy computation could be greatly simplified. GC seems to make sense when most of cache space is used, in which case the difference is small. --- diff --git a/NEWS b/NEWS index fe2ebe2a8..ffa0c5e10 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,7 @@ Bugfixes - tls: send alert to peer if handshake fails (!1007) - cache: fix interaction between LMDB locks and preallocation (!1013) - cache garbage collector: fix flushing of messages to logs (!1009) +- cache garbage collector: fix insufficient GC on 32-bit systems (!1009) Knot Resolver 5.1.1 (2020-05-19) diff --git a/utils/cache_gc/kr_cache_gc.c b/utils/cache_gc/kr_cache_gc.c index 6ba8aad68..a4c049599 100644 --- a/utils/cache_gc/kr_cache_gc.c +++ b/utils/cache_gc/kr_cache_gc.c @@ -217,8 +217,8 @@ int kr_cache_gc(kr_cache_gc_cfg_t *cfg, kr_cache_gc_state_t **state) for (int i = 0; i < CATEGORIES; ++i) { cats_sumsize += cats.categories_sizes[i]; } - ssize_t amount_tofree = knot_db_lmdb_get_mapsize(db) * cfg->cache_to_be_freed - * cats_sumsize / (100 * knot_db_lmdb_get_usage(db)); + /* use less precise variant to avoid 32-bit overflow */ + ssize_t amount_tofree = cats_sumsize / 100 * cfg->cache_to_be_freed; #ifdef DEBUG printf("tofree: %zd\n", amount_tofree); diff --git a/utils/cache_gc/kr_cache_gc.h b/utils/cache_gc/kr_cache_gc.h index 261115d00..839e553d5 100644 --- a/utils/cache_gc/kr_cache_gc.h +++ b/utils/cache_gc/kr_cache_gc.h @@ -25,7 +25,7 @@ typedef struct { unsigned long rw_txn_delay; // waiting time between two RW transactions in usecs uint8_t cache_max_usage; // maximum cache usage before triggering GC (percent) - uint8_t cache_to_be_freed; // percent of cache to be freed during GC + uint8_t cache_to_be_freed; // percent of current cache usage to be freed during GC bool dry_run; } kr_cache_gc_cfg_t; diff --git a/utils/cache_gc/main.c b/utils/cache_gc/main.c index cd868553f..41654c843 100644 --- a/utils/cache_gc/main.c +++ b/utils/cache_gc/main.c @@ -36,7 +36,7 @@ static void print_help() printf(" -l \n"); printf(" -m \n"); printf(" -u \n"); - printf(" -f \n"); + printf(" -f \n"); printf(" -w \n"); printf(" -t \n"); printf(" -n (= dry run)\n");