diff options
author | Andrew Zaborowski <andrew.zaborowski@intel.com> | 2020-03-18 15:45:28 +0100 |
---|---|---|
committer | Denis Kenzior <denkenz@gmail.com> | 2020-03-18 13:49:42 -0500 |
commit | 22d7a3c629e00aa7c6ecfa965d09c068eb0c17b0 (patch) | |
tree | 62d1af4fda2bb133537471ed9f7adf7ca44eda91 | |
parent | 9e18552fe762b209a46c279598ed87315c23a65c (diff) | |
download | iwd-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.c | 32 |
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; } /* |