From 234e48f7ef3b49467408ae87bf3ef6e10176cb5d Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 14 Sep 2015 15:27:36 +0200 Subject: platform: cancel delayed action REFRESH_LINK when receiving an update When we receive an update for a link, cancel the scheduled REFRESH_LINK delayed-action. At the point when we scheduled refrehing the link, we only cared about receiving a notification that was newer then the current state, i.e. to resync with the actual netlink state. We don't necessarily require to sent a new link-request. This extra work can be saved if we already receive a new update for the link. --- src/platform/nm-linux-platform.c | 43 ++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index a7e0bbd938..5f3fc6aacc 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -1652,6 +1652,33 @@ delayed_action_handle_idle (gpointer user_data) return G_SOURCE_REMOVE; } +static void +delayed_action_clear_REFRESH_LINK (NMPlatform *platform, int ifindex) +{ + NMLinuxPlatformPrivate *priv; + gssize idx; + gpointer user_data; + + if (ifindex <= 0) + return; + + priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); + if (!NM_FLAGS_HAS (priv->delayed_action.flags, DELAYED_ACTION_TYPE_REFRESH_LINK)) + return; + + user_data = GINT_TO_POINTER (ifindex); + + idx = _nm_utils_ptrarray_find_first (priv->delayed_action.list_refresh_link->pdata, priv->delayed_action.list_refresh_link->len, user_data); + if (idx < 0) + return; + + _LOGT_delayed_action (DELAYED_ACTION_TYPE_REFRESH_LINK, user_data, "clear"); + + g_ptr_array_remove_index_fast (priv->delayed_action.list_refresh_link, idx); + if (priv->delayed_action.list_refresh_link->len == 0) + priv->delayed_action.flags &= ~DELAYED_ACTION_TYPE_REFRESH_LINK; +} + static void delayed_action_schedule (NMPlatform *platform, DelayedActionType action_type, gpointer user_data) { @@ -2068,9 +2095,11 @@ do_request_all (NMPlatform *platform, DelayedActionType action_type, gboolean ha /* clear any delayed action that request a refresh of this object type. */ priv->delayed_action.flags &= ~iflags; + _LOGT_delayed_action (iflags, NULL, "handle (do-request-all)"); if (obj_type == NMP_OBJECT_TYPE_LINK) { priv->delayed_action.flags &= ~DELAYED_ACTION_TYPE_REFRESH_LINK; g_ptr_array_set_size (priv->delayed_action.list_refresh_link, 0); + _LOGT_delayed_action (DELAYED_ACTION_TYPE_REFRESH_LINK, NULL, "clear (do-request-all)"); } event_handler_read_netlink_all (platform, FALSE); @@ -2381,12 +2410,14 @@ event_notification (struct nl_msg *msg, gpointer user_data) switch (msghdr->nlmsg_type) { case RTM_NEWLINK: - if ( NMP_OBJECT_GET_TYPE (obj) == NMP_OBJECT_TYPE_LINK - && g_hash_table_lookup (priv->delayed_deletion, obj) != NULL) { - /* the object is scheduled for delayed deletion. Replace that object - * by clearing the value from priv->delayed_deletion. */ - _LOGT ("delayed-deletion: clear delayed deletion of protected object %s", nmp_object_to_string (obj, NMP_OBJECT_TO_STRING_ID, NULL, 0)); - g_hash_table_insert (priv->delayed_deletion, nmp_object_ref (obj), NULL); + if (NMP_OBJECT_GET_TYPE (obj) == NMP_OBJECT_TYPE_LINK) { + if (g_hash_table_lookup (priv->delayed_deletion, obj) != NULL) { + /* the object is scheduled for delayed deletion. Replace that object + * by clearing the value from priv->delayed_deletion. */ + _LOGT ("delayed-deletion: clear delayed deletion of protected object %s", nmp_object_to_string (obj, NMP_OBJECT_TO_STRING_ID, NULL, 0)); + g_hash_table_insert (priv->delayed_deletion, nmp_object_ref (obj), NULL); + } + delayed_action_clear_REFRESH_LINK (platform, obj->link.ifindex); } /* fall-through */ case RTM_NEWADDR: -- cgit v1.2.1