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.
This commit is contained in:
Andrew Zaborowski 2020-03-18 15:45:28 +01:00 committed by Denis Kenzior
parent 9e18552fe7
commit 22d7a3c629
1 changed files with 29 additions and 3 deletions

View File

@ -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;
}
/*