diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2020-04-01 15:18:10 +0200 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2020-07-10 10:19:09 +0200 |
commit | 74ccda8a713f707fe09f218b737865db6579f955 (patch) | |
tree | fc08bc13833e60630b6c8b503a09970002fcc2cf | |
parent | 6fcb077a98a4681af15d2431977d367256f8e667 (diff) | |
download | NetworkManager-74ccda8a713f707fe09f218b737865db6579f955.tar.gz |
device: allow queuing SR-IOV operation from a callback
Keep priv->sriov.pending set during the callback set so that it
becomes possible to insert a new operation from the callback itself.
-rw-r--r-- | src/devices/nm-device.c | 35 |
1 files changed, 17 insertions, 18 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index b320d6b4f5..3bc0f47245 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,23 +15920,28 @@ 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) { NMDevice *self; + NMDevicePrivate *priv; gpointer reason; + 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_or_disposing (error)) return; - nm_utils_user_data_unpack (user_data, &self, &reason); deactivate_ready (self, (NMDeviceStateReason) reason); } @@ -16273,6 +16271,7 @@ _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, |