summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2020-07-10 10:19:21 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2020-07-10 10:19:21 +0200
commit6ca98f5b04894a1914a3f29daff90a18eb1020a9 (patch)
treefe87a7b821974fe2993aed1fa309f5317934da19
parent3a3c436571a55997ef53d21756ad58628fd8250e (diff)
parent4d6ea18de4b170f730f71cf49461474619c00947 (diff)
downloadNetworkManager-6ca98f5b04894a1914a3f29daff90a18eb1020a9.tar.gz
merge: branch 'bg/sriov-reset-on-failure'
https://bugzilla.redhat.com/show_bug.cgi?id=1819587 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/457
-rw-r--r--src/devices/nm-device.c76
-rw-r--r--src/platform/nm-linux-platform.c24
2 files changed, 63 insertions, 37 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 15162dabd1..9c8b593993 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -614,6 +614,7 @@ typedef struct _NMDevicePrivate {
SriovOp *pending; /* SR-IOV operation currently running */
SriovOp *next; /* next SR-IOV operation scheduled */
} sriov;
+ guint sriov_reset_pending;
struct {
guint timeout_id;
@@ -4765,15 +4766,12 @@ sriov_op_cb (GError *error, gpointer user_data)
nm_assert (op == priv->sriov.pending);
- priv->sriov.pending = NULL;
-
g_clear_object (&op->cancellable);
if (op->callback)
op->callback (error, op->callback_data);
- nm_assert (!priv->sriov.pending);
-
+ priv->sriov.pending = NULL;
nm_g_slice_free (op);
if (priv->sriov.next) {
@@ -4791,6 +4789,8 @@ sriov_op_queue_op (NMDevice *self,
if (priv->sriov.next) {
SriovOp *op_next = g_steal_pointer (&priv->sriov.next);
+ priv->sriov.next = op;
+
/* Cancel the next operation immediately */
if (op_next->callback) {
gs_free_error GError *error = NULL;
@@ -4800,17 +4800,10 @@ sriov_op_queue_op (NMDevice *self,
}
nm_g_slice_free (op_next);
+ return;
+ }
- if (!priv->sriov.pending) {
- /* This (having "next" set but "pending" not) can only happen if we are
- * called from inside the callback again.
- *
- * That means we append the new request as "next" and return. Once
- * the callback returns, it will schedule the request. */
- priv->sriov.next = op;
- return;
- }
- } else if (priv->sriov.pending) {
+ if (priv->sriov.pending) {
priv->sriov.next = op;
g_cancellable_cancel (priv->sriov.pending->cancellable);
return;
@@ -15927,27 +15920,51 @@ deactivate_ready (NMDevice *self, NMDeviceStateReason reason)
if (priv->dispatcher.call_id)
return;
- if ( priv->sriov.pending
- || priv->sriov.next)
+ if (priv->sriov_reset_pending > 0)
return;
- nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, reason);
+ if (priv->state == NM_DEVICE_STATE_DEACTIVATING)
+ nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, reason);
}
static void
-sriov_deactivate_cb (GError *error, gpointer user_data)
+sriov_reset_on_deactivate_cb (GError *error, gpointer user_data)
{
NMDevice *self;
+ NMDevicePrivate *priv;
gpointer reason;
- if (nm_utils_error_is_cancelled_or_disposing (error))
+ nm_utils_user_data_unpack (user_data, &self, &reason);
+ priv = NM_DEVICE_GET_PRIVATE (self);
+ nm_assert (priv->sriov_reset_pending > 0);
+ priv->sriov_reset_pending--;
+
+ if (nm_utils_error_is_cancelled (error))
return;
- nm_utils_user_data_unpack (user_data, &self, &reason);
deactivate_ready (self, (NMDeviceStateReason) reason);
}
static void
+sriov_reset_on_failure_cb (GError *error, gpointer user_data)
+{
+ NMDevice *self = user_data;
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+
+ nm_assert (priv->sriov_reset_pending > 0);
+ priv->sriov_reset_pending--;
+
+ if (nm_utils_error_is_cancelled (error))
+ return;
+
+ if (priv->state == NM_DEVICE_STATE_FAILED) {
+ nm_device_queue_state (self,
+ NM_DEVICE_STATE_DISCONNECTED,
+ NM_DEVICE_STATE_REASON_NONE);
+ }
+}
+
+static void
deactivate_async_ready (NMDevice *self,
GError *error,
gpointer user_data)
@@ -16273,10 +16290,11 @@ _set_state_full (NMDevice *self,
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_TERNARY_TRUE,
- sriov_deactivate_cb,
+ sriov_reset_on_deactivate_cb,
nm_utils_user_data_pack (self, (gpointer) reason));
}
}
@@ -16328,6 +16346,16 @@ _set_state_full (NMDevice *self,
if (sett_conn && !nm_settings_connection_get_timestamp (sett_conn, NULL))
nm_settings_connection_update_timestamp (sett_conn, (guint64) 0);
+ 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_TERNARY_TRUE,
+ sriov_reset_on_failure_cb,
+ self);
+ break;
+ }
/* Schedule the transition to DISCONNECTED. The device can't transition
* immediately because we can't change states again from the state
* handler for a variety of reasons.
@@ -17892,6 +17920,12 @@ dispose (GObject *object)
nm_clear_g_source (&priv->concheck_x[0].p_cur_id);
nm_clear_g_source (&priv->concheck_x[1].p_cur_id);
+ nm_assert (!priv->sriov.pending);
+ if (priv->sriov.next) {
+ nm_g_slice_free (priv->sriov.next);
+ priv->sriov.next = NULL;
+ }
+
G_OBJECT_CLASS (nm_device_parent_class)->dispose (object);
if (nm_clear_g_source (&priv->queued_state.id)) {
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index b05c50de48..2ee478cdcf 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -7254,7 +7254,7 @@ link_supports_sriov (NMPlatform *platform, int ifindex)
nm_auto_pop_netns NMPNetns *netns = NULL;
nm_auto_close int dirfd = -1;
char ifname[IFNAMSIZ];
- int total = -1;
+ int num = -1;
if (!nm_platform_netns_push (platform, &netns))
return FALSE;
@@ -7263,13 +7263,13 @@ link_supports_sriov (NMPlatform *platform, int ifindex)
if (dirfd < 0)
return FALSE;
- total = nm_platform_sysctl_get_int32 (platform,
- NMP_SYSCTL_PATHID_NETDIR (dirfd,
- ifname,
- "device/sriov_totalvfs"),
- -1);
+ num = nm_platform_sysctl_get_int32 (platform,
+ NMP_SYSCTL_PATHID_NETDIR (dirfd,
+ ifname,
+ "device/sriov_numvfs"),
+ -1);
- return total > 0;
+ return num != -1;
}
static int
@@ -7412,15 +7412,7 @@ link_set_sriov_params_async (NMPlatform *platform,
ifname,
"device/sriov_totalvfs"),
10, 0, G_MAXUINT, 0);
- if (errno) {
- g_set_error (&error,
- NM_UTILS_ERROR,
- NM_UTILS_ERROR_UNKNOWN,
- "failed reading sriov_totalvfs value: %s",
- nm_strerror_native (errno));
- goto out_idle;
- }
- if (num_vfs > total) {
+ if (!errno && num_vfs > total) {
_LOGW ("link: %d only supports %u VFs (requested %u)", ifindex, total, num_vfs);
num_vfs = total;
}