diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2018-05-23 14:11:14 +0200 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2018-07-11 16:16:22 +0200 |
commit | 7df33338797fc335c245fed65ac1186284afc357 (patch) | |
tree | 3e34ef0333908f510550f55f0cdb2982a028dbd7 | |
parent | a2f12994b7cd516adafc5b80fef574d28e9fa28e (diff) | |
download | NetworkManager-7df33338797fc335c245fed65ac1186284afc357.tar.gz |
platform: allow setting drivers-autoprobe on SR-IOV PFs
It is possible to tell kernel not to automatically autoprobe drivers
for VFs. This is useful, for example, if the VF must be used by a VM.
-rw-r--r-- | src/devices/nm-device.c | 4 | ||||
-rw-r--r-- | src/platform/nm-fake-platform.c | 7 | ||||
-rw-r--r-- | src/platform/nm-linux-platform.c | 73 | ||||
-rw-r--r-- | src/platform/nm-platform.c | 19 | ||||
-rw-r--r-- | src/platform/nm-platform.h | 4 |
5 files changed, 69 insertions, 38 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index aa2a389a5d..8844672ab5 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -3951,8 +3951,8 @@ device_init_sriov_num_vfs (NMDevice *self) NULL); num_vfs = _nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXINT32, -1); if (num_vfs >= 0) { - nm_platform_link_set_sriov_num_vfs (nm_device_get_platform (self), - priv->ifindex, num_vfs); + nm_platform_link_set_sriov_params (nm_device_get_platform (self), + priv->ifindex, num_vfs, -1); } } } diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c index f8f4627ed0..d8d192c712 100644 --- a/src/platform/nm-fake-platform.c +++ b/src/platform/nm-fake-platform.c @@ -602,12 +602,6 @@ link_set_mtu (NMPlatform *platform, int ifindex, guint32 mtu) return NM_PLATFORM_ERROR_SUCCESS; } -static gboolean -link_set_sriov_num_vfs (NMPlatform *platform, int ifindex, guint num_vfs) -{ - return TRUE; -} - static const char * link_get_udi (NMPlatform *platform, int ifindex) { @@ -1422,7 +1416,6 @@ nm_fake_platform_class_init (NMFakePlatformClass *klass) platform_class->link_set_address = link_set_address; platform_class->link_set_mtu = link_set_mtu; - platform_class->link_set_sriov_num_vfs = link_set_sriov_num_vfs; platform_class->link_get_driver_info = link_get_driver_info; diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index e02269f6eb..19821a87c3 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -5528,16 +5528,18 @@ nla_put_failure: } static gboolean -link_set_sriov_num_vfs (NMPlatform *platform, int ifindex, guint num_vfs) +link_set_sriov_params (NMPlatform *platform, + int ifindex, + guint num_vfs, + int autoprobe) { nm_auto_pop_netns NMPNetns *netns = NULL; nm_auto_close int dirfd = -1; - int total, current; + gboolean current_autoprobe; + guint total, current_num; char ifname[IFNAMSIZ]; char buf[64]; - _LOGD ("link: change %d: num VFs: %u", ifindex, num_vfs); - if (!nm_platform_netns_push (platform, &netns)) return FALSE; @@ -5545,46 +5547,69 @@ link_set_sriov_num_vfs (NMPlatform *platform, int ifindex, guint num_vfs) if (!dirfd) return FALSE; - total = nm_platform_sysctl_get_int32 (platform, - NMP_SYSCTL_PATHID_NETDIR (dirfd, - ifname, - "device/sriov_totalvfs"), - -1); - if (total < 1) + total = nm_platform_sysctl_get_int_checked (platform, + NMP_SYSCTL_PATHID_NETDIR (dirfd, + ifname, + "device/sriov_totalvfs"), + 10, 0, G_MAXUINT, 0); + if (errno) return FALSE; if (num_vfs > total) { _LOGW ("link: %d only supports %u VFs (requested %u)", ifindex, total, num_vfs); num_vfs = total; } - current = nm_platform_sysctl_get_int32 (platform, - NMP_SYSCTL_PATHID_NETDIR (dirfd, - ifname, - "device/sriov_numvfs"), - -1); - if (current == num_vfs) + /* + * Take special care when setting new values: + * - don't touch anything if the right values are already set + * - to change the number of VFs or autoprobe we need to destroy existing VFs + * - the autoprobe setting is irrelevant when numvfs is zero + */ + current_num = nm_platform_sysctl_get_int_checked (platform, + NMP_SYSCTL_PATHID_NETDIR (dirfd, + ifname, + "device/sriov_numvfs"), + 10, 0, G_MAXUINT, 0); + current_autoprobe = nm_platform_sysctl_get_int_checked (platform, + NMP_SYSCTL_PATHID_NETDIR (dirfd, + ifname, + "device/sriov_drivers_autoprobe"), + 10, 0, G_MAXUINT, 0); + if ( current_num == num_vfs + && (autoprobe == -1 || current_autoprobe == autoprobe)) return TRUE; - if (current != 0) { - /* We need to destroy all other VFs before changing the value */ + if (current_num != 0) { + /* We need to destroy all other VFs before changing any value */ if (!nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_NETDIR (dirfd, ifname, "device/sriov_numvfs"), "0")) { - _LOGW ("link: couldn't set SR-IOV num_vfs to %d: %s", 0, strerror (errno)); + _LOGW ("link: couldn't reset SR-IOV num_vfs: %s", strerror (errno)); return FALSE; } - if (num_vfs == 0) - return TRUE; } - /* Finally, set the desired value */ + if (num_vfs == 0) + return TRUE; + + if ( autoprobe >= 0 + && current_autoprobe != autoprobe + && !nm_platform_sysctl_set (NM_PLATFORM_GET, + NMP_SYSCTL_PATHID_NETDIR (dirfd, + ifname, + "device/sriov_drivers_autoprobe"), + nm_sprintf_buf (buf, "%d", autoprobe))) { + _LOGW ("link: couldn't set SR-IOV drivers-autoprobe to %d: %s", autoprobe, strerror (errno)); + return FALSE; + } + if (!nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_NETDIR (dirfd, ifname, "device/sriov_numvfs"), - nm_sprintf_buf (buf, "%d", num_vfs))) { + nm_sprintf_buf (buf, "%u", num_vfs))) { _LOGW ("link: couldn't set SR-IOV num_vfs to %d: %s", num_vfs, strerror (errno)); return FALSE; } @@ -7735,7 +7760,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass) platform_class->link_get_permanent_address = link_get_permanent_address; platform_class->link_set_mtu = link_set_mtu; platform_class->link_set_name = link_set_name; - platform_class->link_set_sriov_num_vfs = link_set_sriov_num_vfs; + platform_class->link_set_sriov_params = link_set_sriov_params; platform_class->link_get_physical_port_id = link_get_physical_port_id; platform_class->link_get_dev_id = link_get_dev_id; diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 96465e3dd5..1146a07309 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -1463,18 +1463,31 @@ nm_platform_link_supports_sriov (NMPlatform *self, int ifindex) return klass->link_supports_sriov (self, ifindex); } +/** + * nm_platform_link_set_sriov_params: + * @self: platform instance + * @ifindex: the index of the interface to change + * @num_vfs: the number of VFs to create + * @autoprobe: -1 to keep the current autoprobe-drivers value, + * or {0,1} to set a new value + */ gboolean -nm_platform_link_set_sriov_num_vfs (NMPlatform *self, int ifindex, guint num_vfs) +nm_platform_link_set_sriov_params (NMPlatform *self, + int ifindex, + guint num_vfs, + int autoprobe) { _CHECK_SELF (self, klass, FALSE); g_return_val_if_fail (ifindex > 0, FALSE); + g_return_val_if_fail (NM_IN_SET (autoprobe, -1, 0, 1), FALSE); - _LOGD ("link: setting %u VFs for %s (%d)", + _LOGD ("link: setting %u total VFs and autoprobe %d for %s (%d)", num_vfs, + autoprobe, nm_strquote_a (25, nm_platform_link_get_name (self, ifindex)), ifindex); - return klass->link_set_sriov_num_vfs (self, ifindex, num_vfs); + return klass->link_set_sriov_params (self, ifindex, num_vfs, autoprobe); } /** diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 00df7fa31d..01e13f2178 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -802,7 +802,7 @@ typedef struct { NMPlatformError (*link_set_address) (NMPlatform *, int ifindex, gconstpointer address, size_t length); NMPlatformError (*link_set_mtu) (NMPlatform *, int ifindex, guint32 mtu); gboolean (*link_set_name) (NMPlatform *, int ifindex, const char *name); - gboolean (*link_set_sriov_num_vfs) (NMPlatform *, int ifindex, guint num_vfs); + gboolean (*link_set_sriov_params) (NMPlatform *, int ifindex, guint num_vfs, int autoprobe); char * (*link_get_physical_port_id) (NMPlatform *, int ifindex); guint (*link_get_dev_id) (NMPlatform *, int ifindex); @@ -1193,7 +1193,7 @@ gboolean nm_platform_link_get_permanent_address (NMPlatform *self, int ifindex, NMPlatformError nm_platform_link_set_address (NMPlatform *self, int ifindex, const void *address, size_t length); NMPlatformError nm_platform_link_set_mtu (NMPlatform *self, int ifindex, guint32 mtu); gboolean nm_platform_link_set_name (NMPlatform *self, int ifindex, const char *name); -gboolean nm_platform_link_set_sriov_num_vfs (NMPlatform *self, int ifindex, guint num_vfs); +gboolean nm_platform_link_set_sriov_params (NMPlatform *self, int ifindex, guint num_vfs, int autoprobe); char *nm_platform_link_get_physical_port_id (NMPlatform *self, int ifindex); guint nm_platform_link_get_dev_id (NMPlatform *self, int ifindex); |