mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2025-01-03 10:32:33 +01:00
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:
parent
9e18552fe7
commit
22d7a3c629
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user