From 27bc16fcdc67f9afefefb54ae98dfdae3a5bc1f8 Mon Sep 17 00:00:00 2001 From: Mukund Sivaraman Date: Mon, 7 Dec 2015 12:48:57 +0530 Subject: [PATCH] Lazily initialize dns_compress->table only when compression is enabled (#41189) --- CHANGES | 3 ++ lib/dns/compress.c | 58 ++++++++++++++++++++++------------ lib/dns/include/dns/compress.h | 4 ++- 3 files changed, 44 insertions(+), 21 deletions(-) diff --git a/CHANGES b/CHANGES index 0708de06fc..1f0d2cb9dd 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +4275. [performance] Lazily initialize dns_compress->table only when + compression is enabled. [RT #41189] + 4274. [performance] Speed up typemap processing from text. [RT #41196] 4273. [bug] Only call dns_test_begin() and dns_test_end() once each diff --git a/lib/dns/compress.c b/lib/dns/compress.c index d826de4fb7..7a2ad36155 100644 --- a/lib/dns/compress.c +++ b/lib/dns/compress.c @@ -36,25 +36,31 @@ #define DCTX_MAGIC ISC_MAGIC('D', 'C', 'T', 'X') #define VALID_DCTX(x) ISC_MAGIC_VALID(x, DCTX_MAGIC) +#define TABLE_READY \ + do { \ + unsigned int i; \ + \ + if ((cctx->allowed & DNS_COMPRESS_READY) == 0) { \ + cctx->allowed |= DNS_COMPRESS_READY; \ + for (i = 0; i < DNS_COMPRESS_TABLESIZE; i++) \ + cctx->table[i] = NULL; \ + } \ + } while (0) + /*** *** Compression ***/ isc_result_t dns_compress_init(dns_compress_t *cctx, int edns, isc_mem_t *mctx) { - unsigned int i; - REQUIRE(cctx != NULL); REQUIRE(mctx != NULL); /* See: rdataset.c:towiresorted(). */ - cctx->allowed = 0; cctx->edns = edns; - for (i = 0; i < DNS_COMPRESS_TABLESIZE; i++) - cctx->table[i] = NULL; cctx->mctx = mctx; cctx->count = 0; + cctx->allowed = DNS_COMPRESS_ENABLED; cctx->magic = CCTX_MAGIC; - cctx->enabled = ISC_TRUE; return (ISC_R_SUCCESS); } @@ -65,19 +71,21 @@ dns_compress_invalidate(dns_compress_t *cctx) { REQUIRE(VALID_CCTX(cctx)); - cctx->magic = 0; - for (i = 0; i < DNS_COMPRESS_TABLESIZE; i++) { - while (cctx->table[i] != NULL) { - node = cctx->table[i]; - cctx->table[i] = cctx->table[i]->next; - if ((node->offset & 0x8000) != 0) - isc_mem_put(cctx->mctx, node->r.base, - node->r.length); - if (node->count < DNS_COMPRESS_INITIALNODES) - continue; - isc_mem_put(cctx->mctx, node, sizeof(*node)); + if ((cctx->allowed & DNS_COMPRESS_READY) != 0) { + for (i = 0; i < DNS_COMPRESS_TABLESIZE; i++) { + while (cctx->table[i] != NULL) { + node = cctx->table[i]; + cctx->table[i] = cctx->table[i]->next; + if ((node->offset & 0x8000) != 0) + isc_mem_put(cctx->mctx, node->r.base, + node->r.length); + if (node->count < DNS_COMPRESS_INITIALNODES) + continue; + isc_mem_put(cctx->mctx, node, sizeof(*node)); + } } } + cctx->magic = 0; cctx->allowed = 0; cctx->edns = -1; } @@ -99,7 +107,7 @@ dns_compress_getmethods(dns_compress_t *cctx) { void dns_compress_disable(dns_compress_t *cctx) { REQUIRE(VALID_CCTX(cctx)); - cctx->enabled = ISC_FALSE; + cctx->allowed &= ~DNS_COMPRESS_ENABLED; } void @@ -150,9 +158,11 @@ dns_compress_findglobal(dns_compress_t *cctx, const dns_name_t *name, REQUIRE(dns_name_isabsolute(name) == ISC_TRUE); REQUIRE(offset != NULL); - if (cctx->enabled == ISC_FALSE) + if ((cctx->allowed & DNS_COMPRESS_ENABLED) == 0) return (ISC_FALSE); + TABLE_READY; + if (cctx->count == 0) return (ISC_FALSE); @@ -222,9 +232,11 @@ dns_compress_add(dns_compress_t *cctx, const dns_name_t *name, REQUIRE(VALID_CCTX(cctx)); REQUIRE(dns_name_isabsolute(name)); - if (cctx->enabled == ISC_FALSE) + if ((cctx->allowed & DNS_COMPRESS_ENABLED) == 0) return; + TABLE_READY; + if (offset >= 0x4000) return; dns_name_init(&tname, NULL); @@ -296,6 +308,12 @@ dns_compress_rollback(dns_compress_t *cctx, isc_uint16_t offset) { REQUIRE(VALID_CCTX(cctx)); + if ((cctx->allowed & DNS_COMPRESS_ENABLED) == 0) + return; + + if ((cctx->allowed & DNS_COMPRESS_READY) == 0) + return; + for (i = 0; i < DNS_COMPRESS_TABLESIZE; i++) { node = cctx->table[i]; /* diff --git a/lib/dns/include/dns/compress.h b/lib/dns/include/dns/compress.h index 1b9f22c6d2..97d820f78e 100644 --- a/lib/dns/include/dns/compress.h +++ b/lib/dns/include/dns/compress.h @@ -44,6 +44,9 @@ ISC_LANG_BEGINDECLS #define DNS_COMPRESS_GLOBAL14 0x01 /*%< "normal" compression. */ #define DNS_COMPRESS_ALL 0x01 /*%< all compression. */ #define DNS_COMPRESS_CASESENSITIVE 0x02 /*%< case sensitive compression. */ +#define DNS_COMPRESS_ENABLED 0x04 + +#define DNS_COMPRESS_READY 0x80000000 #define DNS_COMPRESS_TABLESIZE 64 #define DNS_COMPRESS_INITIALNODES 16 @@ -61,7 +64,6 @@ struct dns_compressnode { struct dns_compress { unsigned int magic; /*%< Magic number. */ unsigned int allowed; /*%< Allowed methods. */ - isc_boolean_t enabled; /*%< If the compression is enabled at all. */ int edns; /*%< Edns version or -1. */ /*% Global compression table. */ dns_compressnode_t *table[DNS_COMPRESS_TABLESIZE];