From: Chris Down Date: Sun, 2 Aug 2026 22:43:20 +0000 (-0700) Subject: bus: Reduce sd_bus_message size by 9.9% by dropping offset bookkeeping X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b6fba48f0f28cc8893bd2136bba05d4c452b277d;p=thirdparty%2Fsystemd.git bus: Reduce sd_bus_message size by 9.9% by dropping offset bookkeeping sd_bus_message carries an array of header field offsets and a counter, but their only reader was part of the D-Bus v2/GVariant sealing path removed in 0dd487681505 ("sd-bus: drop D-Bus version 2 format support"). There are three remaining callers of message_extend_fields(), for SD_BUS_MESSAGE_HEADER_DESTINATION, _PATH, and _INTERFACE, and all of them pass false for add_offset. The receive path does not populate the array either, so nothing reads or writes it any more. Let's drop the two fields and the now unused add_offset argument and branch. This reduces sizeof(sd_bus_message) from 792... $ gdb -batch build-baseline/test-bus-benchmark \ -ex 'ptype /o struct sd_bus_message' ... /* 688 | 8 */ usec_t timeout; /* 696 | 80 */ size_t header_offsets[10]; /* 776 | 4 */ unsigned int n_header_offsets; /* XXX 4-byte hole */ /* 784 | 8 */ uint64_t read_counter; /* total size (bytes): 792 */ to 704 bytes: $ gdb -batch build-patched/test-bus-benchmark \ -ex 'ptype /o struct sd_bus_message' ... /* 688 | 8 */ usec_t timeout; /* 696 | 8 */ uint64_t read_counter; /* total size (bytes): 704 */ On Fedora 43 aarch64 with glibc 2.42, the usable allocation for a method-call message falls from 808 to 728 bytes, a reduction of 9.9%. In my tests, retaining 400,000 method-call messages reduces in median peak RSS from 363M to 332M. Using `test-bus-benchmark chart direct 500ms` across message sizes from 1 byte to 2 MiB one can also see things are around 1% faster, which is another nice incidental boost. --- diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c index a719253fa73..09286f43337 100644 --- a/src/libsystemd/sd-bus/bus-message.c +++ b/src/libsystemd/sd-bus/bus-message.c @@ -142,7 +142,7 @@ static sd_bus_message* message_free(sd_bus_message *m) { return mfree(m); } -static void* message_extend_fields(sd_bus_message *m, size_t sz, bool add_offset) { +static void* message_extend_fields(sd_bus_message *m, size_t sz) { void *op, *np; size_t old_size, new_size, start; @@ -195,13 +195,6 @@ static void* message_extend_fields(sd_bus_message *m, size_t sz, bool add_offset m->free_header = true; - if (add_offset) { - if (m->n_header_offsets >= ELEMENTSOF(m->header_offsets)) - goto poison; - - m->header_offsets[m->n_header_offsets++] = new_size - sizeof(BusMessageHeader); - } - return (uint8_t*) np + start; poison: @@ -233,7 +226,7 @@ static int message_append_field_string( /* Signature "(yv)" where the variant contains "s" */ /* (field id byte + (signature length + signature 's' + NUL) + (string length + string + NUL)) */ - p = message_extend_fields(m, 4 + 4 + l + 1, false); + p = message_extend_fields(m, 4 + 4 + l + 1); if (!p) return -ENOMEM; @@ -274,7 +267,7 @@ static int message_append_field_signature( /* Signature "(yv)" where the variant contains "g" */ /* (field id byte + (signature length + signature 'g' + NUL) + (string length + string + NUL)) */ - p = message_extend_fields(m, 4 + 1 + l + 1, false); + p = message_extend_fields(m, 4 + 1 + l + 1); if (!p) return -ENOMEM; @@ -301,7 +294,7 @@ static int message_append_field_uint32(sd_bus_message *m, uint64_t h, uint32_t x return -EINVAL; /* (field id byte + (signature length + signature 'u' + NUL) + value) */ - p = message_extend_fields(m, 4 + 4, false); + p = message_extend_fields(m, 4 + 4); if (!p) return -ENOMEM; diff --git a/src/libsystemd/sd-bus/bus-message.h b/src/libsystemd/sd-bus/bus-message.h index 94eff878e56..7f4dc29b8df 100644 --- a/src/libsystemd/sd-bus/bus-message.h +++ b/src/libsystemd/sd-bus/bus-message.h @@ -126,9 +126,6 @@ typedef struct sd_bus_message { usec_t timeout; - size_t header_offsets[_BUS_MESSAGE_HEADER_MAX]; - unsigned n_header_offsets; - uint64_t read_counter; } sd_bus_message;