summaryrefslogtreecommitdiff
path: root/src/devices
diff options
context:
space:
mode:
authorAntonio Cardace <acardace@redhat.com>2020-05-14 18:36:40 +0200
committerAntonio Cardace <acardace@redhat.com>2020-05-20 10:55:02 +0200
commit2ce0e714b60aa59b1d0a46333de29d5c95ef07a4 (patch)
tree4b09b2b5e3298823d7d4ce1c86bb305b5bb9663b /src/devices
parent2d2c111304ed34a8d004cfa6e6bdde3fd3c71fa2 (diff)
downloadNetworkManager-2ce0e714b60aa59b1d0a46333de29d5c95ef07a4.tar.gz
nm-device: apply ethtool ring settings when activating a connection
nm-device now applies ethtool ring settings during stage 2 "device config" of the connection activation. ring settings will be then restored (according to what the state was before the connection got activated on the device) when the connection is deactivated during the device cleanup. One thing to be noted is that unset ring settings (in the profile) will not be touched at all by NetworkManager so that if the NIC driver sets some default values these will be preserved unless specifically overridden by the connection profile. https://bugzilla.redhat.com/show_bug.cgi?id=1614700
Diffstat (limited to 'src/devices')
-rw-r--r--src/devices/nm-device.c131
1 files changed, 123 insertions, 8 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index c20c078002..418641358d 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -187,6 +187,7 @@ typedef struct {
NMEthtoolFeatureStates *features;
NMTernary requested[_NM_ETHTOOL_ID_FEATURE_NUM];
NMEthtoolCoalesceState *coalesce;
+ NMEthtoolRingState *ring;
} EthtoolState;
/*****************************************************************************/
@@ -890,6 +891,8 @@ _ethtool_init_coalesce (NMDevice *self,
while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &variant)) {
if (!g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT32))
continue;
+ if (!nm_ethtool_optname_is_coalesce (name))
+ continue;
if (!nm_platform_ethtool_init_coalesce (platform,
coalesce,
@@ -902,7 +905,7 @@ _ethtool_init_coalesce (NMDevice *self,
}
- return (!!n_coalesce_set);
+ return !!n_coalesce_set;
}
static void
@@ -917,18 +920,15 @@ _ethtool_coalesce_reset (NMDevice *self,
nm_assert (ethtool_state);
coalesce = g_steal_pointer (&ethtool_state->coalesce);
-
if (!coalesce)
return;
if (!nm_platform_ethtool_set_coalesce (platform,
ethtool_state->ifindex,
- coalesce)) {
+ coalesce))
_LOGW (LOGD_DEVICE, "ethtool: failure resetting one or more coalesce settings");
- return;
- }
-
- _LOGD (LOGD_DEVICE, "ethtool: coalesce settings successfully reset");
+ else
+ _LOGD (LOGD_DEVICE, "ethtool: coalesce settings successfully reset");
}
static void
@@ -972,6 +972,114 @@ _ethtool_coalesce_set (NMDevice *self,
_LOGD (LOGD_DEVICE, "ethtool: coalesce settings successfully set");
}
+static gboolean
+_ethtool_init_ring (NMDevice *self,
+ NMPlatform *platform,
+ NMSettingEthtool *s_ethtool,
+ NMEthtoolRingState *ring)
+{
+ GHashTable *hash;
+ GHashTableIter iter;
+ const char *name;
+ GVariant *variant;
+ gsize n_ring_set = 0;
+
+ nm_assert (self);
+ nm_assert (platform);
+ nm_assert (ring);
+ nm_assert (NM_IS_SETTING_ETHTOOL (s_ethtool));
+
+ hash = _nm_setting_gendata_hash (NM_SETTING (s_ethtool), FALSE);
+ if (!hash)
+ return FALSE;
+
+ g_hash_table_iter_init (&iter, hash);
+ while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &variant)) {
+ if (!g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT32))
+ continue;
+ if (!nm_ethtool_optname_is_ring (name))
+ continue;
+
+ if (!nm_platform_ethtool_init_ring (platform,
+ ring,
+ name,
+ g_variant_get_uint32(variant))) {
+ _LOGW (LOGD_DEVICE, "ethtool: invalid ring setting %s", name);
+ return FALSE;
+ }
+ ++n_ring_set;
+
+ }
+
+ return !!n_ring_set;
+}
+
+
+
+static void
+_ethtool_ring_reset (NMDevice *self,
+ NMPlatform *platform,
+ EthtoolState *ethtool_state)
+{
+ gs_free NMEthtoolRingState *ring = NULL;
+
+ nm_assert (NM_IS_DEVICE (self));
+ nm_assert (NM_IS_PLATFORM (platform));
+ nm_assert (ethtool_state);
+
+ ring = g_steal_pointer (&ethtool_state->ring);
+ if (!ring)
+ return;
+
+ if (!nm_platform_ethtool_set_ring (platform,
+ ethtool_state->ifindex,
+ ring))
+ _LOGW (LOGD_DEVICE, "ethtool: failure resetting one or more ring settings");
+ else
+ _LOGD (LOGD_DEVICE, "ethtool: ring settings successfully reset");
+}
+
+static void
+_ethtool_ring_set (NMDevice *self,
+ NMPlatform *platform,
+ EthtoolState *ethtool_state,
+ NMSettingEthtool *s_ethtool)
+{
+ NMEthtoolRingState ring_old;
+ NMEthtoolRingState ring_new;
+
+ nm_assert (ethtool_state);
+ nm_assert (NM_IS_DEVICE (self));
+ nm_assert (NM_IS_PLATFORM (platform));
+ nm_assert (NM_IS_SETTING_ETHTOOL (s_ethtool));
+
+ if (!nm_platform_ethtool_get_link_ring (platform,
+ ethtool_state->ifindex,
+ &ring_old)) {
+ _LOGW (LOGD_DEVICE, "ethtool: failure getting ring settings (cannot read)");
+ return;
+ }
+
+ ring_new = ring_old;
+
+ if (!_ethtool_init_ring (self,
+ platform,
+ s_ethtool,
+ &ring_new))
+ return;
+
+ ethtool_state->ring = nm_memdup (&ring_old, sizeof (ring_old));
+
+ if (!nm_platform_ethtool_set_ring (platform,
+ ethtool_state->ifindex,
+ &ring_new)) {
+ _LOGW (LOGD_DEVICE, "ethtool: failure setting ring settings");
+ return;
+ }
+
+ _LOGD (LOGD_DEVICE, "ethtool: ring settings successfully set");
+}
+
static void
_ethtool_state_reset (NMDevice *self)
{
@@ -986,6 +1094,8 @@ _ethtool_state_reset (NMDevice *self)
_ethtool_features_reset (self, platform, ethtool_state);
if (ethtool_state->coalesce)
_ethtool_coalesce_reset (self, platform, ethtool_state);
+ if (ethtool_state->ring)
+ _ethtool_ring_reset (self, platform, ethtool_state);
}
@@ -1026,9 +1136,14 @@ _ethtool_state_set (NMDevice *self)
platform,
ethtool_state,
s_ethtool);
+ _ethtool_ring_set (self,
+ platform,
+ ethtool_state,
+ s_ethtool);
if ( ethtool_state->features
- || ethtool_state->coalesce)
+ || ethtool_state->coalesce
+ || ethtool_state->ring)
priv->ethtool_state = g_steal_pointer (&ethtool_state);
}