]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Optimize memory layout of core structs
authoralessio <alessio@isc.org>
Tue, 5 Nov 2024 08:36:24 +0000 (09:36 +0100)
committeralessio <alessio@isc.org>
Wed, 27 Nov 2024 15:04:25 +0000 (16:04 +0100)
Reduce memory footprint by:

 - Reordering struct fields to minimize padding.
 - Using exact-sized atomic types instead of *_least/*_fast variants
 - Downsizing integer fields where possible

Affected structs:

 - dns_name_t
 - dns_slabheader_t
 - dns_rdata_t
 - qpcnode_t
 - qpznode_t

.gitlab-ci.yml
lib/dns/dnssec.c
lib/dns/include/dns/name.h
lib/dns/include/dns/rdata.h
lib/dns/include/dns/rdataslab.h
lib/dns/journal.c
lib/dns/name.c
lib/dns/nsec3.c
lib/dns/qpcache.c
lib/dns/qpzone.c
lib/dns/zone.c

index 58d64f43250aa28268951f73b600ff469b7216c8..7cedd80e424d71a1c004a8905d7e4b8c87057eec 100644 (file)
@@ -720,6 +720,10 @@ cross-version-config-tests:
     # also from the $BIND_BASELINE_VERSION.
     - find bin/tests/system/ -mindepth 1 -maxdepth 1 -type d -exec sh -c 'test -e ../"$0" || rm -rfv -- "$0"' {} \;
     - cd bin/tests/system
+    # System tests that employ binary drivers will fail on ABI change and
+    # should not be run.
+    - rm -r dlzexternal
+    - rm -r dyndb
     # Run the setup phase of all system tests in the most recently tagged BIND 9
     # release using the binaries built for the current BIND 9 version.  This
     # intends to detect obvious backward compatibility issues with the latter.
index e5bac5257ae1d160fe969e4d7c79af77a04fb9a1..dcc418f955145006ffd50c7b4fd74537fac92203 100644 (file)
@@ -325,7 +325,6 @@ dns_dnssec_sign(const dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
                 * Digest the length of the rdata.
                 */
                isc_buffer_init(&lenbuf, &len, sizeof(len));
-               INSIST(rdatas[i].length < 65536);
                isc_buffer_putuint16(&lenbuf, (uint16_t)rdatas[i].length);
                isc_buffer_usedregion(&lenbuf, &lenr);
                ret = dst_context_adddata(ctx, &lenr);
@@ -537,7 +536,6 @@ again:
                 * Digest the rdata length.
                 */
                isc_buffer_init(&lenbuf, &len, sizeof(len));
-               INSIST(rdatas[i].length < 65536);
                isc_buffer_putuint16(&lenbuf, (uint16_t)rdatas[i].length);
                isc_buffer_usedregion(&lenbuf, &lenr);
 
index b9c4164bf9859d3d26210e652a7f4f85730ec8ea..d79fe445bd170e27338f50d147e392f1d29c05e5 100644 (file)
@@ -96,10 +96,9 @@ ISC_LANG_BEGINDECLS
  * for whatever purpose the client desires.
  */
 struct dns_name {
-       unsigned int   magic;
-       unsigned char *ndata;
-       unsigned int   length;
-       unsigned int   labels;
+       unsigned int magic;
+       uint8_t      length;
+       uint8_t      labels;
        struct dns_name_attrs {
                bool absolute     : 1; /*%< Used by name.c */
                bool readonly     : 1; /*%< Used by name.c */
@@ -116,6 +115,7 @@ struct dns_name {
                bool update       : 1; /*%< Used by client. */
                bool hasupdaterec : 1; /*%< Used by client. */
        } attributes;
+       unsigned char *ndata;
        unsigned char *offsets;
        isc_buffer_t  *buffer;
        ISC_LINK(dns_name_t) link;
index 36f79c8edd2887ad92d884a1b168e9e17717f919..02ac4eef221bd0aa5862686bfe8f22940887abcd 100644 (file)
@@ -110,16 +110,17 @@ ISC_LANG_BEGINDECLS
  */
 struct dns_rdata {
        unsigned char   *data;
-       unsigned int     length;
        dns_rdataclass_t rdclass;
        dns_rdatatype_t  type;
-       unsigned int     flags;
+       uint16_t         length;
+       uint16_t         flags;
        ISC_LINK(dns_rdata_t) link;
 };
 
-#define DNS_RDATA_INIT                                           \
-       {                                                        \
-               NULL, 0, 0, 0, 0, { (void *)(-1), (void *)(-1) } \
+#define DNS_RDATA_INIT                        \
+       {                                     \
+               .data = NULL,                 \
+               .link = ISC_LINK_INITIALIZER, \
        }
 
 #define DNS_RDATA_CHECKINITIALIZED
index 4a0d58a542e7c636007d7fcf7e2ef9d73c8c7c7b..e5ecbebf33c69b0387e7d6f985a45c95af719019 100644 (file)
@@ -68,31 +68,32 @@ struct dns_slabheader_proof {
 };
 
 struct dns_slabheader {
+       _Atomic(uint16_t) attributes;
+
        /*%
         * Locked by the owning node's lock.
         */
-       uint32_t              serial;
-       dns_ttl_t             ttl;
-       dns_typepair_t        type;
-       atomic_uint_least16_t attributes;
-       dns_trust_t           trust;
+       dns_trust_t    trust;
+       uint32_t       serial;
+       dns_ttl_t      ttl;
+       dns_typepair_t type;
 
-       unsigned int heap_index;
+       _Atomic(uint16_t) count;
        /*%<
-        * Used for TTL-based cache cleaning.
+        * Monotonically increased every time this rdataset is bound so that
+        * it is used as the base of the starting point in DNS responses
+        * when the "cyclic" rrset-order is required.
         */
 
-       isc_stdtime_t resign;
        unsigned int  resign_lsb : 1;
-
-       atomic_uint_fast16_t count;
+       isc_stdtime_t resign;
+       unsigned int  heap_index;
        /*%<
-        * Monotonically increased every time this rdataset is bound so that
-        * it is used as the base of the starting point in DNS responses
-        * when the "cyclic" rrset-order is required.
+        * Used for TTL-based cache cleaning.
         */
 
-       atomic_uint_fast32_t last_refresh_fail_ts;
+       isc_stdtime_t     last_used;
+       _Atomic(uint32_t) last_refresh_fail_ts;
 
        dns_slabheader_proof_t *noqname;
        dns_slabheader_proof_t *closest;
@@ -122,7 +123,6 @@ struct dns_slabheader {
         * this rdataset, if any.
         */
 
-       isc_stdtime_t last_used;
        ISC_LINK(struct dns_slabheader) link;
 
        /*%
index 19d5f6e34a48a03469e4883f5558f2896507191a..b6f4d1901bd349acf93706984b93aa6cd50bf2e3 100644 (file)
@@ -1255,7 +1255,6 @@ dns_journal_writediff(dns_journal_t *j, dns_diff_t *diff) {
                isc_buffer_putuint16(&buffer, t->rdata.type);
                isc_buffer_putuint16(&buffer, t->rdata.rdclass);
                isc_buffer_putuint32(&buffer, t->ttl);
-               INSIST(t->rdata.length < 65536);
                isc_buffer_putuint16(&buffer, (uint16_t)t->rdata.length);
                INSIST(isc_buffer_availablelength(&buffer) >= t->rdata.length);
                isc_buffer_putmem(&buffer, t->rdata.data, t->rdata.length);
index 2b2f1aacd87e591de8d8c9b44679d5be12d94673..4ac40ae0de05cd4bc325d04e78be41708d2f7571 100644 (file)
@@ -107,9 +107,7 @@ dns_name_isvalid(const dns_name_t *name) {
                return false;
        }
 
-       if (name->length > DNS_NAME_MAXWIRE ||
-           name->labels > DNS_NAME_MAXLABELS)
-       {
+       if (name->labels > DNS_NAME_MAXLABELS) {
                return false;
        }
 
@@ -616,7 +614,7 @@ dns_name_getlabel(const dns_name_t *name, unsigned int n, dns_label_t *label) {
        SETUP_OFFSETS(name, offsets, odata);
 
        label->base = &name->ndata[offsets[n]];
-       if (n == name->labels - 1) {
+       if (n == (unsigned int)name->labels - 1) {
                label->length = name->length - offsets[n];
        } else {
                label->length = offsets[n + 1] - offsets[n];
index e8567f7d4325237f8146b76b88af2d6e12b0bfbb..a4942b3a5b84512bd307645ebf7339317a65d233 100644 (file)
@@ -995,7 +995,7 @@ void
 dns_nsec3param_toprivate(dns_rdata_t *src, dns_rdata_t *target,
                         dns_rdatatype_t privatetype, unsigned char *buf,
                         size_t buflen) {
-       REQUIRE(buflen >= src->length + 1);
+       REQUIRE(buflen >= (unsigned int)src->length + 1);
 
        REQUIRE(DNS_RDATA_INITIALIZED(target));
 
index e2235d4a3bdee01d71f301bb254fda937464683e..aadfaf2bb832ba616c607c276a11ce3e9aefab72 100644 (file)
@@ -169,9 +169,10 @@ struct qpcnode {
        unsigned int nsec       : 2; /*%< range is 0..3 */
        uint8_t                 : 0;
 
+       uint16_t locknum;
+
        isc_refcount_t references;
        isc_refcount_t erefs;
-       uint16_t locknum;
        void *data;
 
        /*%
index 5d59f3fdc3090eb610da3c0575ad17dd0daa6973..bfff5f116a3f9917fd3f5a8f75ef20956a8c899a 100644 (file)
@@ -153,11 +153,11 @@ struct qpznode {
        isc_refcount_t references;
        isc_refcount_t erefs;
        uint16_t locknum;
-       void *data;
        atomic_uint_fast8_t nsec;
        atomic_bool wild;
        atomic_bool delegating;
        atomic_bool dirty;
+       void *data;
 };
 
 struct qpzonedb {
index 7889c259525f1992f6c0454634eeaef6b9b1ce91..ddb7ae292742a09b0b7c68b81fdf66683682aa58 100644 (file)
@@ -17203,7 +17203,8 @@ getprivate:
                        {
                                next = ISC_LIST_NEXT(nsec3p, link);
 
-                               if (nsec3p->length == rdata.length + 1 &&
+                               if (nsec3p->length ==
+                                           (unsigned int)rdata.length + 1 &&
                                    memcmp(rdata.data, nsec3p->data + 1,
                                           nsec3p->length - 1) == 0)
                                {
@@ -23774,7 +23775,7 @@ rss_post(void *arg) {
                        dns_rdata_init(&rdata);
                        dns_rdataset_current(&nrdataset, &rdata);
 
-                       if (np->length == (rdata.length + 1) &&
+                       if (np->length == ((unsigned int)rdata.length + 1) &&
                            memcmp(rdata.data, np->data + 1, np->length - 1) ==
                                    0)
                        {