Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH BlueZ v1 1/2] shared/hci: Avoid redundant BPF filter updates on duplicate events
@ 2026-06-08 20:50 Luiz Augusto von Dentz
  2026-06-08 20:50 ` [PATCH BlueZ v1 2/2] shared/hci: Debounce SO_ATTACH_FILTER with timeout_add(0) Luiz Augusto von Dentz
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Luiz Augusto von Dentz @ 2026-06-08 20:50 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

Skip updating the BPF socket filter in bt_hci_register and
bt_hci_register_subevent when the event/subevent is already
registered, since it is already part of the filter.

Similarly, skip updating the filter in bt_hci_unregister and
bt_hci_unregister_subevent when other handlers for the same
event/subevent still remain in the queue.

This avoids unnecessary setsockopt(SO_ATTACH_FILTER) calls when
multiple handlers are registered for the same event code.
---
 src/shared/hci.c | 37 +++++++++++++++++++++++++++++++++----
 1 file changed, 33 insertions(+), 4 deletions(-)

diff --git a/src/shared/hci.c b/src/shared/hci.c
index 40326fc810e6..1aba7db1d995 100644
--- a/src/shared/hci.c
+++ b/src/shared/hci.c
@@ -765,15 +765,28 @@ static void update_evt_filter(struct bt_hci *hci)
 	free(filters);
 }
 
+static bool match_evt_event(const void *a, const void *b)
+{
+	const struct evt *evt = a;
+	uint8_t event = PTR_TO_UINT(b);
+
+	return evt->event == event;
+}
+
 unsigned int bt_hci_register(struct bt_hci *hci, uint8_t event,
 				bt_hci_callback_func_t callback,
 				void *user_data, bt_hci_destroy_func_t destroy)
 {
 	struct evt *evt;
+	bool update_filter;
 
 	if (!hci)
 		return 0;
 
+	/* Check if event already has a handler registered */
+	update_filter = !queue_find(hci->evt_list, match_evt_event,
+							UINT_TO_PTR(event));
+
 	evt = new0(struct evt, 1);
 	evt->event = event;
 
@@ -791,7 +804,8 @@ unsigned int bt_hci_register(struct bt_hci *hci, uint8_t event,
 		return 0;
 	}
 
-	update_evt_filter(hci);
+	if (update_filter)
+		update_evt_filter(hci);
 
 	return evt->id;
 }
@@ -849,6 +863,7 @@ static bool match_evt_id(const void *a, const void *b)
 bool bt_hci_unregister(struct bt_hci *hci, unsigned int id)
 {
 	struct evt *evt;
+	uint8_t event;
 
 	if (!hci || !id)
 		return false;
@@ -857,9 +872,12 @@ bool bt_hci_unregister(struct bt_hci *hci, unsigned int id)
 	if (!evt)
 		return false;
 
+	event = evt->event;
 	evt_free(evt);
 
-	update_evt_filter(hci);
+	/* Only update filter if no other handler for this event remains */
+	if (!queue_find(hci->evt_list, match_evt_event, UINT_TO_PTR(event)))
+		update_evt_filter(hci);
 
 	return true;
 }
@@ -871,10 +889,15 @@ unsigned int bt_hci_register_subevent(struct bt_hci *hci,
 				void *user_data, bt_hci_destroy_func_t destroy)
 {
 	struct evt *evt;
+	bool update_filter;
 
 	if (!hci)
 		return 0;
 
+	/* Check if subevent already has a handler registered */
+	update_filter = !queue_find(hci->subevt_list, match_evt_event,
+						UINT_TO_PTR(subevent));
+
 	evt = new0(struct evt, 1);
 	evt->event = subevent;
 
@@ -892,7 +915,8 @@ unsigned int bt_hci_register_subevent(struct bt_hci *hci,
 		return 0;
 	}
 
-	update_evt_filter(hci);
+	if (update_filter)
+		update_evt_filter(hci);
 
 	return evt->id;
 }
@@ -900,6 +924,7 @@ unsigned int bt_hci_register_subevent(struct bt_hci *hci,
 bool bt_hci_unregister_subevent(struct bt_hci *hci, unsigned int id)
 {
 	struct evt *evt;
+	uint8_t event;
 
 	if (!hci || !id)
 		return false;
@@ -909,9 +934,13 @@ bool bt_hci_unregister_subevent(struct bt_hci *hci, unsigned int id)
 	if (!evt)
 		return false;
 
+	event = evt->event;
 	evt_free(evt);
 
-	update_evt_filter(hci);
+	/* Only update filter if no other handler for this subevent remains */
+	if (!queue_find(hci->subevt_list, match_evt_event,
+							UINT_TO_PTR(event)))
+		update_evt_filter(hci);
 
 	return true;
 }
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH BlueZ v1 2/2] shared/hci: Debounce SO_ATTACH_FILTER with timeout_add(0)
  2026-06-08 20:50 [PATCH BlueZ v1 1/2] shared/hci: Avoid redundant BPF filter updates on duplicate events Luiz Augusto von Dentz
@ 2026-06-08 20:50 ` Luiz Augusto von Dentz
  2026-06-08 22:15 ` [BlueZ,v1,1/2] shared/hci: Avoid redundant BPF filter updates on duplicate events bluez.test.bot
  2026-06-09 15:20 ` [PATCH BlueZ v1 1/2] " patchwork-bot+bluetooth
  2 siblings, 0 replies; 4+ messages in thread
From: Luiz Augusto von Dentz @ 2026-06-08 20:50 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

Coalesce multiple BPF filter updates into a single SO_ATTACH_FILTER
setsockopt call by deferring the update to the next event loop
iteration using timeout_add(0, ...).

When bt_hci_register_event or bt_hci_register_subevent is called
multiple times in succession (e.g. from bt_rap_attach_hci), each call
previously triggered a full filter rebuild and setsockopt. Now,
schedule_evt_filter() simply marks a pending update which fires once
in filter_timeout() after all synchronous registrations complete.
---
 src/shared/hci.c | 34 ++++++++++++++++++++++++++++++----
 1 file changed, 30 insertions(+), 4 deletions(-)

diff --git a/src/shared/hci.c b/src/shared/hci.c
index 1aba7db1d995..e8586ab5014c 100644
--- a/src/shared/hci.c
+++ b/src/shared/hci.c
@@ -31,6 +31,7 @@
 #include "src/shared/io.h"
 #include "src/shared/util.h"
 #include "src/shared/queue.h"
+#include "src/shared/timeout.h"
 #include "src/shared/hci.h"
 
 
@@ -42,6 +43,7 @@ struct bt_hci {
 	uint8_t num_cmds;
 	unsigned int next_cmd_id;
 	unsigned int next_evt_id;
+	unsigned int filter_id;
 	struct queue *cmd_queue;
 	struct queue *rsp_queue;
 	struct queue *evt_list;
@@ -485,6 +487,9 @@ void bt_hci_unref(struct bt_hci *hci)
 	if (__sync_sub_and_fetch(&hci->ref_count, 1))
 		return;
 
+	if (hci->filter_id)
+		timeout_remove(hci->filter_id);
+
 	queue_destroy(hci->evt_list, evt_free);
 	queue_destroy(hci->subevt_list, evt_free);
 	queue_destroy(hci->cmd_queue, cmd_free);
@@ -765,6 +770,27 @@ static void update_evt_filter(struct bt_hci *hci)
 	free(filters);
 }
 
+static bool filter_timeout(void *user_data)
+{
+	struct bt_hci *hci = user_data;
+
+	hci->filter_id = 0;
+	update_evt_filter(hci);
+
+	return false;
+}
+
+static void schedule_evt_filter(struct bt_hci *hci)
+{
+	/* Coalesce multiple filter updates into a single SO_ATTACH_FILTER call
+	 * by deferring the update to the next event loop iteration.
+	 */
+	if (hci->filter_id)
+		return;
+
+	hci->filter_id = timeout_add(0, filter_timeout, hci, NULL);
+}
+
 static bool match_evt_event(const void *a, const void *b)
 {
 	const struct evt *evt = a;
@@ -805,7 +831,7 @@ unsigned int bt_hci_register(struct bt_hci *hci, uint8_t event,
 	}
 
 	if (update_filter)
-		update_evt_filter(hci);
+		schedule_evt_filter(hci);
 
 	return evt->id;
 }
@@ -877,7 +903,7 @@ bool bt_hci_unregister(struct bt_hci *hci, unsigned int id)
 
 	/* Only update filter if no other handler for this event remains */
 	if (!queue_find(hci->evt_list, match_evt_event, UINT_TO_PTR(event)))
-		update_evt_filter(hci);
+		schedule_evt_filter(hci);
 
 	return true;
 }
@@ -916,7 +942,7 @@ unsigned int bt_hci_register_subevent(struct bt_hci *hci,
 	}
 
 	if (update_filter)
-		update_evt_filter(hci);
+		schedule_evt_filter(hci);
 
 	return evt->id;
 }
@@ -940,7 +966,7 @@ bool bt_hci_unregister_subevent(struct bt_hci *hci, unsigned int id)
 	/* Only update filter if no other handler for this subevent remains */
 	if (!queue_find(hci->subevt_list, match_evt_event,
 							UINT_TO_PTR(event)))
-		update_evt_filter(hci);
+		schedule_evt_filter(hci);
 
 	return true;
 }
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* RE: [BlueZ,v1,1/2] shared/hci: Avoid redundant BPF filter updates on duplicate events
  2026-06-08 20:50 [PATCH BlueZ v1 1/2] shared/hci: Avoid redundant BPF filter updates on duplicate events Luiz Augusto von Dentz
  2026-06-08 20:50 ` [PATCH BlueZ v1 2/2] shared/hci: Debounce SO_ATTACH_FILTER with timeout_add(0) Luiz Augusto von Dentz
@ 2026-06-08 22:15 ` bluez.test.bot
  2026-06-09 15:20 ` [PATCH BlueZ v1 1/2] " patchwork-bot+bluetooth
  2 siblings, 0 replies; 4+ messages in thread
From: bluez.test.bot @ 2026-06-08 22:15 UTC (permalink / raw)
  To: linux-bluetooth, luiz.dentz

[-- Attachment #1: Type: text/plain, Size: 1118 bytes --]

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1108111

---Test result---

Test Summary:
CheckPatch                    PASS      0.99 seconds
GitLint                       FAIL      0.67 seconds
BuildEll                      PASS      20.62 seconds
BluezMake                     PASS      632.10 seconds
CheckSmatch                   PASS      331.99 seconds
bluezmakeextell               PASS      166.70 seconds
IncrementalBuild              PASS      640.51 seconds
ScanBuild                     PASS      948.65 seconds

Details
##############################
Test: GitLint - FAIL
Desc: Run gitlint
Output:
[BlueZ,v1,1/2] shared/hci: Avoid redundant BPF filter updates on duplicate events

1: T1 Title exceeds max length (81>80): "[BlueZ,v1,1/2] shared/hci: Avoid redundant BPF filter updates on duplicate events"


https://github.com/bluez/bluez/pull/2197

---
Regards,
Linux Bluetooth


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH BlueZ v1 1/2] shared/hci: Avoid redundant BPF filter updates on duplicate events
  2026-06-08 20:50 [PATCH BlueZ v1 1/2] shared/hci: Avoid redundant BPF filter updates on duplicate events Luiz Augusto von Dentz
  2026-06-08 20:50 ` [PATCH BlueZ v1 2/2] shared/hci: Debounce SO_ATTACH_FILTER with timeout_add(0) Luiz Augusto von Dentz
  2026-06-08 22:15 ` [BlueZ,v1,1/2] shared/hci: Avoid redundant BPF filter updates on duplicate events bluez.test.bot
@ 2026-06-09 15:20 ` patchwork-bot+bluetooth
  2 siblings, 0 replies; 4+ messages in thread
From: patchwork-bot+bluetooth @ 2026-06-09 15:20 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth

Hello:

This series was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:

On Mon,  8 Jun 2026 16:50:08 -0400 you wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
> 
> Skip updating the BPF socket filter in bt_hci_register and
> bt_hci_register_subevent when the event/subevent is already
> registered, since it is already part of the filter.
> 
> Similarly, skip updating the filter in bt_hci_unregister and
> bt_hci_unregister_subevent when other handlers for the same
> event/subevent still remain in the queue.
> 
> [...]

Here is the summary with links:
  - [BlueZ,v1,1/2] shared/hci: Avoid redundant BPF filter updates on duplicate events
    https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=27eb493882ae
  - [BlueZ,v1,2/2] shared/hci: Debounce SO_ATTACH_FILTER with timeout_add(0)
    https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=9320e1cb4749

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-06-09 15:20 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-08 20:50 [PATCH BlueZ v1 1/2] shared/hci: Avoid redundant BPF filter updates on duplicate events Luiz Augusto von Dentz
2026-06-08 20:50 ` [PATCH BlueZ v1 2/2] shared/hci: Debounce SO_ATTACH_FILTER with timeout_add(0) Luiz Augusto von Dentz
2026-06-08 22:15 ` [BlueZ,v1,1/2] shared/hci: Avoid redundant BPF filter updates on duplicate events bluez.test.bot
2026-06-09 15:20 ` [PATCH BlueZ v1 1/2] " patchwork-bot+bluetooth

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox