sriov: set the devlink's eswitch mode

Use the new property sriov.eswitch-mode to select between legacy SRIOV
and switchdev mode.

(cherry picked from commit 837549ea94)
This commit is contained in:
Íñigo Huguet 2024-02-08 09:46:47 +01:00
parent e9561456c9
commit 1ba2b77402
5 changed files with 55 additions and 4 deletions

View file

@ -139,6 +139,7 @@ typedef struct {
gpointer callback_data;
guint num_vfs;
NMOptionBool autoprobe;
NMSriovEswitchMode eswitch_mode;
} SriovOp;
typedef enum {
@ -7708,6 +7709,7 @@ sriov_op_start(NMDevice *self, SriovOp *op)
priv->ifindex,
op->num_vfs,
op->autoprobe,
(_NMSriovEswitchMode) op->eswitch_mode,
sriov_op_cb,
op,
op->cancellable);
@ -7771,6 +7773,7 @@ static void
sriov_op_queue(NMDevice *self,
guint num_vfs,
NMOptionBool autoprobe,
NMSriovEswitchMode eswitch_mode,
NMPlatformAsyncCallback callback,
gpointer callback_data)
{
@ -7799,6 +7802,7 @@ sriov_op_queue(NMDevice *self,
*op = (SriovOp){
.num_vfs = num_vfs,
.autoprobe = autoprobe,
.eswitch_mode = eswitch_mode,
.callback = callback,
.callback_data = callback_data,
};
@ -7823,7 +7827,12 @@ device_init_static_sriov_num_vfs(NMDevice *self)
-1,
-1);
if (num_vfs >= 0)
sriov_op_queue(self, num_vfs, NM_OPTION_BOOL_DEFAULT, NULL, NULL);
sriov_op_queue(self,
num_vfs,
NM_OPTION_BOOL_DEFAULT,
NM_SRIOV_ESWITCH_MODE_PRESERVE,
NULL,
NULL);
}
}
@ -10004,6 +10013,7 @@ activate_stage1_device_prepare(NMDevice *self)
sriov_op_queue(self,
nm_setting_sriov_get_total_vfs(s_sriov),
NM_TERNARY_TO_OPTION_BOOL(autoprobe),
nm_setting_sriov_get_eswitch_mode(s_sriov),
sriov_params_cb,
nm_utils_user_data_pack(self, g_steal_pointer(&plat_vfs)));
priv->stage1_sriov_state = NM_DEVICE_STAGE_STATE_PENDING;
@ -16720,6 +16730,7 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason,
sriov_op_queue(self,
0,
NM_OPTION_BOOL_TRUE,
NM_SRIOV_ESWITCH_MODE_PRESERVE,
sriov_reset_on_deactivate_cb,
nm_utils_user_data_pack(self, GINT_TO_POINTER(reason)));
}
@ -16769,7 +16780,12 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason,
if (priv->ifindex > 0
&& (s_sriov = nm_device_get_applied_setting(self, NM_TYPE_SETTING_SRIOV))) {
priv->sriov_reset_pending++;
sriov_op_queue(self, 0, NM_OPTION_BOOL_TRUE, sriov_reset_on_failure_cb, self);
sriov_op_queue(self,
0,
NM_OPTION_BOOL_TRUE,
NM_SRIOV_ESWITCH_MODE_PRESERVE,
sriov_reset_on_failure_cb,
self);
break;
}
/* Schedule the transition to DISCONNECTED. The device can't transition

View file

@ -277,6 +277,13 @@ typedef enum {
| _NM_VLAN_FLAG_LOOSE_BINDING | _NM_VLAN_FLAG_MVRP,
} _NMVlanFlags;
typedef enum {
/* Mirrors libnm's NMSriovEswitchMode */
_NM_SRIOV_ESWITCH_MODE_PRESERVE = -1,
_NM_SRIOV_ESWITCH_MODE_LEGACY = 0,
_NM_SRIOV_ESWITCH_MODE_SWITCHDEV = 1,
} _NMSriovEswitchMode;
/*****************************************************************************/
typedef enum {

View file

@ -41,6 +41,7 @@
#include "libnm-platform/nm-netlink.h"
#include "libnm-platform/nm-platform-utils.h"
#include "libnm-platform/nmp-netns.h"
#include "libnm-platform/devlink/nm-devlink.h"
#include "libnm-platform/wifi/nm-wifi-utils-wext.h"
#include "libnm-platform/wifi/nm-wifi-utils.h"
#include "libnm-platform/wpan/nm-wpan-utils.h"
@ -8900,10 +8901,12 @@ link_set_sriov_params_async(NMPlatform *platform,
int ifindex,
guint num_vfs,
NMOptionBool autoprobe,
_NMSriovEswitchMode eswitch_mode,
NMPlatformAsyncCallback callback,
gpointer data,
GCancellable *cancellable)
{
NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform);
nm_auto_pop_netns NMPNetns *netns = NULL;
gs_free_error GError *error = NULL;
nm_auto_close int dirfd = -1;
@ -8914,6 +8917,8 @@ link_set_sriov_params_async(NMPlatform *platform,
gpointer packed;
const char *values[3];
char buf[64];
gs_free NMDevlink *devlink = NULL;
int current_eswitch_mode;
g_return_if_fail(callback || !data);
g_return_if_fail(cancellable);
@ -8926,6 +8931,8 @@ link_set_sriov_params_async(NMPlatform *platform,
goto out_idle;
}
devlink = nm_devlink_new(platform, priv->sk_genl_sync, ifindex);
dirfd = nm_platform_sysctl_open_netdir(platform, ifindex, ifname);
if (!dirfd) {
g_set_error_literal(&error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, "couldn't open netdir");
@ -8957,6 +8964,7 @@ link_set_sriov_params_async(NMPlatform *platform,
0,
G_MAXUINT,
-1);
current_autoprobe = nm_platform_sysctl_get_int_checked(
platform,
NMP_SYSCTL_PATHID_NETDIR_A(dirfd, ifname, "device/sriov_drivers_autoprobe"),
@ -8964,15 +8972,26 @@ link_set_sriov_params_async(NMPlatform *platform,
0,
1,
-1);
if (current_autoprobe == -1 && errno == ENOENT) {
/* older kernel versions don't have this sysctl. Assume the value is
* "1". */
current_autoprobe = 1;
}
current_eswitch_mode = nm_devlink_get_eswitch_mode(devlink, &error);
if (current_eswitch_mode < 0) {
/* We can proceed if eswith-mode is "preserve", otherwise propagate the error */
if (eswitch_mode != _NM_SRIOV_ESWITCH_MODE_PRESERVE)
goto out_idle;
_LOGD("%s", error->message);
g_clear_error(&error);
}
if (current_num == num_vfs
&& (autoprobe == NM_OPTION_BOOL_DEFAULT || current_autoprobe == autoprobe))
&& (autoprobe == NM_OPTION_BOOL_DEFAULT || current_autoprobe == autoprobe)
&& (eswitch_mode == _NM_SRIOV_ESWITCH_MODE_PRESERVE
|| current_eswitch_mode == eswitch_mode))
goto out_idle;
if (NM_IN_SET(autoprobe, NM_OPTION_BOOL_TRUE, NM_OPTION_BOOL_FALSE)
@ -8990,6 +9009,11 @@ link_set_sriov_params_async(NMPlatform *platform,
goto out_idle;
}
if (eswitch_mode != _NM_SRIOV_ESWITCH_MODE_PRESERVE && current_eswitch_mode != eswitch_mode) {
if (!nm_devlink_set_eswitch_mode(devlink, (enum devlink_eswitch_mode) eswitch_mode, &error))
goto out_idle;
}
if (current_num == 0 && num_vfs == 0)
goto out_idle;

View file

@ -2024,6 +2024,7 @@ nm_platform_link_set_sriov_params_async(NMPlatform *self,
int ifindex,
guint num_vfs,
NMOptionBool autoprobe,
_NMSriovEswitchMode eswitch_mode,
NMPlatformAsyncCallback callback,
gpointer callback_data,
GCancellable *cancellable)
@ -2037,6 +2038,7 @@ nm_platform_link_set_sriov_params_async(NMPlatform *self,
ifindex,
num_vfs,
autoprobe,
eswitch_mode,
callback,
callback_data,
cancellable);

View file

@ -1174,6 +1174,7 @@ typedef struct {
int ifindex,
guint num_vfs,
NMOptionBool autoprobe,
_NMSriovEswitchMode eswitch_mode,
NMPlatformAsyncCallback callback,
gpointer callback_data,
GCancellable *cancellable);
@ -2037,6 +2038,7 @@ void nm_platform_link_set_sriov_params_async(NMPlatform *self,
int ifindex,
guint num_vfs,
NMOptionBool autoprobe,
_NMSriovEswitchMode eswitch_mode,
NMPlatformAsyncCallback callback,
gpointer callback_data,
GCancellable *cancellable);