udev: use an "inline" array instead of allocating for advertise mode
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sun, 18 Nov 2018 09:12:14 +0000 (10:12 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sun, 18 Nov 2018 15:14:19 +0000 (16:14 +0100)
The code is a bit shorter and we don't allocate the uint32_t[127] array.

src/udev/net/ethtool-util.c
src/udev/net/link-config.c
src/udev/net/link-config.h

index 05721c71f2cd278d00276131e95120f1080063e1..4cf6f269e32c5166fb7767c69aa530d486c54224 100644 (file)
@@ -110,6 +110,8 @@ static const char* const ethtool_link_mode_bit_table[_ETHTOOL_LINK_MODE_MAX] = {
         [ETHTOOL_LINK_MODE_FEC_RS_BIT]                 = "fec-rs",
         [ETHTOOL_LINK_MODE_FEC_BASER_BIT]              = "fec-baser",
 };
+/* Make sure the array is large enough to fit all bits */
+assert_cc((ELEMENTSOF(ethtool_link_mode_bit_table)-1) / 32 < ELEMENTSOF(((struct link_config){}).advertise));
 
 DEFINE_STRING_TABLE_LOOKUP(ethtool_link_mode_bit, enum ethtool_link_mode_bit_indices);
 
@@ -612,8 +614,11 @@ int ethtool_set_glinksettings(int *fd, const char *ifname, struct link_config *l
 
         u->base.autoneg = link->autonegotiation;
 
-        if (link->advertise)
-                memcpy(&u->link_modes.advertising, link->advertise, ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBYTES);
+        if (!eqzero(link->advertise)) {
+                memcpy(&u->link_modes.advertising, link->advertise, sizeof(link->advertise));
+                memzero((uint8_t*) &u->link_modes.advertising + sizeof(link->advertise),
+                        ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBYTES - sizeof(link->advertise));
+        }
 
         if (u->base.cmd == ETHTOOL_GLINKSETTINGS)
                 r = set_slinksettings(*fd, &ifr, u);
@@ -737,8 +742,6 @@ int config_parse_advertise(const char *unit,
                            const char *rvalue,
                            void *data,
                            void *userdata) {
-        uint32_t a[ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32] = {};
-        enum ethtool_link_mode_bit_indices mode;
         link_config *config = data;
         const char *p;
         int r;
@@ -751,12 +754,13 @@ int config_parse_advertise(const char *unit,
 
         if (isempty(rvalue)) {
                 /* Empty string resets the value. */
-                config->advertise = mfree(config->advertise);
+                zero(config->advertise);
                 return 0;
         }
 
         for (p = rvalue;;) {
                 _cleanup_free_ char *w = NULL;
+                enum ethtool_link_mode_bit_indices mode;
 
                 r = extract_first_word(&p, &w, NULL, 0);
                 if (r == -ENOMEM)
@@ -774,21 +778,7 @@ int config_parse_advertise(const char *unit,
                         continue;
                 }
 
-                a[mode / 32] |= 1UL << (mode % 32);
-        }
-
-        if (!config->advertise) {
-                config->advertise = new(uint32_t, ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32);
-                if (!config->advertise)
-                        return log_oom();
-
-                memcpy(config->advertise, a, ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBYTES);
-
-        } else {
-                unsigned i;
-
-                for (i = 0; i < ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32; i++)
-                        config->advertise[i] |= a[i];
+                config->advertise[mode / 32] |= 1UL << (mode % 32);
         }
 
         return 0;
index 161e116d720d52c1df3e140655b22fb7f87dad9c..becaffe0d6cb2911749f8579cb1700d332c2baa8 100644 (file)
@@ -69,7 +69,6 @@ static void link_config_free(link_config *link) {
         free(link->name_policy);
         free(link->name);
         free(link->alias);
-        free(link->advertise);
 
         free(link);
 }
@@ -373,7 +372,7 @@ int link_config_apply(link_config_ctx *ctx, link_config *config,
                 if (config->port != _NET_DEV_PORT_INVALID)
                         log_warning_errno(r,  "Could not set port (%s) of %s: %m", port_to_string(config->port), old_name);
 
-                if (config->advertise)
+                if (!eqzero(config->advertise))
                         log_warning_errno(r, "Could not set advertise mode: %m"); /* TODO: include modes in the log message. */
 
                 if (config->speed) {
index f2f08435554a382638ef4c5a5616200df924fc7d..820495903462d7873532658be6d890b894c0e769 100644 (file)
@@ -55,7 +55,7 @@ struct link_config {
         size_t speed;
         Duplex duplex;
         int autonegotiation;
-        uint32_t *advertise;
+        uint32_t advertise[2];
         WakeOnLan wol;
         NetDevPort port;
         int features[_NET_DEV_FEAT_MAX];