aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Zaborowski <andrew.zaborowski@intel.com>2020-03-18 15:45:28 +0100
committerDenis Kenzior <denkenz@gmail.com>2020-03-18 13:49:42 -0500
commit22d7a3c629e00aa7c6ecfa965d09c068eb0c17b0 (patch)
tree62d1af4fda2bb133537471ed9f7adf7ca44eda91
parent9e18552fe762b209a46c279598ed87315c23a65c (diff)
downloadiwd-22d7a3c629e00aa7c6ecfa965d09c068eb0c17b0.tar.gz
frame-xchg: Optimize frame_watch_remove_by_handler scenarios
Since frame_watch_remove_by_handler only forgets a given function + user data pointers, and doesn't remove the frame prefixes added in the kernel, we can avoid later re-registering those prefixes with the kernel by keeping them in our local watchlist, and only replacing the handler pointer with a dummy function.
-rw-r--r--src/frame-xchg.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/src/frame-xchg.c b/src/frame-xchg.c
index 992149ee8..d69fff7cd 100644
--- a/src/frame-xchg.c
+++ b/src/frame-xchg.c
@@ -472,6 +472,12 @@ static void frame_watch_register_cb(struct l_genl_msg *msg, void *user_data)
L_PTR_TO_UINT(user_data), l_genl_msg_get_error(msg));
}
+static void frame_watch_notify_empty(const struct mmpdu_header *mpdu,
+ const void *body, size_t body_len,
+ int rssi, void *user_data)
+{
+}
+
struct frame_duplicate_info {
uint64_t wdev_id;
uint16_t frame_type;
@@ -506,6 +512,17 @@ static bool frame_watch_check_duplicate(void *data, void *user_data)
*/
info->registered = true;
+ /*
+ * If we previously had a watch registered on this socket,
+ * with the same or a more specific prefix, we can now forget
+ * its entry as the new watch is going to hold enough
+ * information to keep us from registering redundant prefixes
+ * in the future.
+ */
+ if (info->prefix_len <= watch->prefix_len &&
+ watch->super.notify == frame_watch_notify_empty)
+ goto drop;
+
if (info->handler != watch->super.notify ||
info->user_data != watch->super.notify_data)
return false;
@@ -522,6 +539,7 @@ static bool frame_watch_check_duplicate(void *data, void *user_data)
return false;
}
+drop:
/* Drop the existing watch as a duplicate of the new one */
frame_watch_free(&watch->super);
return true;
@@ -665,11 +683,19 @@ static bool frame_watch_item_remove_by_handler(void *data, void *user_data)
watch->super.notify_data != info->user_data)
return false;
- if (watch->super.destroy)
+ if (watch->super.destroy) {
watch->super.destroy(watch->super.notify_data);
+ watch->super.destroy = NULL;
+ }
- frame_watch_free(&watch->super);
- return true;
+ /*
+ * Keep the entry, with a dummy callback, in order to keep us from
+ * re-registering its prefix in future frame_watch_add calls. We
+ * can drop the entry in some circumstances but checking the
+ * conditions for this costs more than it is worth right now.
+ */
+ watch->super.notify = frame_watch_notify_empty;
+ return false;
}
/*