From d2c3ea6166cf3ada470ee0caf652470e645445af Mon Sep 17 00:00:00 2001 From: Jan Vaclav Date: Thu, 14 Aug 2025 12:52:09 +0200 Subject: [PATCH 1/2] device: extract sriov platform vf generation to separate function (cherry picked from commit 588a69cd1b0e5bab7371f297c6450d17f5de9ab2) (cherry picked from commit b2d8f60c4970401b4e981604eceaa37520052fcf) (cherry picked from commit 8676995903564a526f882dbb05126885c3272129) --- src/core/devices/nm-device.c | 61 +++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 18 deletions(-) diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index e4249dc4e8..631f978bed 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -10329,6 +10329,43 @@ sriov_params_cb(GError *error, gpointer user_data) nm_device_activate_schedule_stage1_device_prepare(self, FALSE); } +static gboolean +sriov_gen_platform_vfs(NMDevice *self, + NMSettingSriov *s_sriov, + NMPlatformVF ***plat_vfs_out, + GError **error) +{ + nm_auto_freev NMPlatformVF **plat_vfs = NULL; + guint num; + + nm_assert(s_sriov); + nm_assert(plat_vfs_out && !*plat_vfs_out); + + num = nm_setting_sriov_get_num_vfs(s_sriov); + plat_vfs = g_new0(NMPlatformVF *, num + 1); + + for (int i = 0; i < num; i++) { + NMSriovVF *vf = nm_setting_sriov_get_vf(s_sriov, i); + gs_free_error GError *local = NULL; + + plat_vfs[i] = sriov_vf_config_to_platform(self, vf, &local); + + if (!plat_vfs[i]) { + g_set_error(error, + local->domain, + local->code, + "VF '%s' is invalid: %s", + nm_utils_sriov_vf_to_str(vf, FALSE, NULL), + local->message); + return FALSE; + } + } + + *plat_vfs_out = g_steal_pointer(&plat_vfs); + + return TRUE; +} + /* * activate_stage1_device_prepare * @@ -10375,10 +10412,7 @@ activate_stage1_device_prepare(NMDevice *self) if (s_sriov && nm_device_has_capability(self, NM_DEVICE_CAP_SRIOV)) { nm_auto_freev NMPlatformVF **plat_vfs = NULL; gs_free_error GError *error = NULL; - NMSriovVF *vf; NMTernary autoprobe; - guint num; - guint i; autoprobe = nm_setting_sriov_get_autoprobe_drivers(s_sriov); if (autoprobe == NM_TERNARY_DEFAULT) { @@ -10391,21 +10425,12 @@ activate_stage1_device_prepare(NMDevice *self) NM_OPTION_BOOL_TRUE); } - num = nm_setting_sriov_get_num_vfs(s_sriov); - plat_vfs = g_new0(NMPlatformVF *, num + 1); - for (i = 0; i < num; i++) { - vf = nm_setting_sriov_get_vf(s_sriov, i); - plat_vfs[i] = sriov_vf_config_to_platform(self, vf, &error); - if (!plat_vfs[i]) { - _LOGE(LOGD_DEVICE, - "failed to apply SR-IOV VF '%s': %s", - nm_utils_sriov_vf_to_str(vf, FALSE, NULL), - error->message); - nm_device_state_changed(self, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED); - return; - } + if (!sriov_gen_platform_vfs(self, s_sriov, &plat_vfs, &error)) { + _LOGE(LOGD_DEVICE, "cannot parse the VF list: %s", error->message); + nm_device_state_changed(self, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED); + return; } /* When changing the number of VFs the kernel can block -- 2.50.1 From a92341d549de435e69c3b66d5569d2bd98d37908 Mon Sep 17 00:00:00 2001 From: Jan Vaclav Date: Thu, 14 Aug 2025 13:00:53 +0200 Subject: [PATCH 2/2] device: add support for reapplying the `sriov.vfs` property Adds support for reapplying the `sriov.vfs` property. Note this does not include `num_vfs`, as the configuration needs to be reset and reconfigured from scratch in that case. Previously, if an existing VF is modified (e.g. if we change the `trust` flag), we reset all VF configurations, and started from scratch. But in some cases, this is unnecessarily disruptive. Resolves: https://issues.redhat.com/browse/RHEL-95844 (cherry picked from commit 4ba3ffee6788e6d8b75aff6c7aa21f92e45d5b9c) (cherry picked from commit 6f454c98a98818e96ecd4f228f1e42febd2b2b32) (cherry picked from commit 737000860ee9efcc15e8eec8d85f47afd4eca8c5) --- src/core/devices/nm-device.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index 631f978bed..b9bd3492e4 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -14028,6 +14028,13 @@ can_reapply_change(NMDevice *self, NM_SETTING_BRIDGE_PORT_VLANS); } + if (nm_streq(setting_name, NM_SETTING_SRIOV_SETTING_NAME)) { + return nm_device_hash_check_invalid_keys(diffs, + NM_SETTING_SRIOV_SETTING_NAME, + error, + NM_SETTING_SRIOV_VFS); + } + out_fail: g_set_error(error, NM_DEVICE_ERROR, @@ -14203,9 +14210,35 @@ check_and_reapply_connection(NMDevice *self, nm_device_link_properties_set(self, TRUE); - if (priv->state >= NM_DEVICE_STATE_CONFIG) + if (priv->state >= NM_DEVICE_STATE_CONFIG) { + GHashTable *sriov_diff; + lldp_setup(self, NM_TERNARY_DEFAULT); + sriov_diff = nm_g_hash_table_lookup(diffs, NM_SETTING_SRIOV_SETTING_NAME); + + if (sriov_diff && nm_g_hash_table_lookup(sriov_diff, NM_SETTING_SRIOV_VFS)) { + nm_auto_freev NMPlatformVF **plat_vfs = NULL; + NMSettingSriov *s_sriov; + + s_sriov = (NMSettingSriov *) nm_connection_get_setting(applied, NM_TYPE_SETTING_SRIOV); + + if (s_sriov) { + gs_free_error GError *local = NULL; + + if (!sriov_gen_platform_vfs(self, s_sriov, &plat_vfs, &local) + || !nm_platform_link_set_sriov_vfs(nm_device_get_platform(self), + priv->ifindex, + (const NMPlatformVF *const *) plat_vfs)) { + _LOGE(LOGD_DEVICE, + "failed to reapply SRIOV VFs%s%s", + local ? ": " : "", + local ? local->message : ""); + } + } + } + } + if (priv->state >= NM_DEVICE_STATE_IP_CONFIG) { /* Allow reapply of MTU */ priv->mtu_source = NM_DEVICE_MTU_SOURCE_NONE; -- 2.50.1