diff options
| author | Zijun Hu <zijun.hu@oss.qualcomm.com> | 2026-08-01 23:31:41 -0700 |
|---|---|---|
| committer | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2026-08-07 15:40:27 -0400 |
| commit | 0bd606b31d40dceb718bf22e3ce7b4cff7e34bf6 (patch) | |
| tree | b4febfbb1140f0eb25d9349d1651fa1c5f63f823 /include | |
| parent | 73c4c035ae25108ad98ff03ccdd0c763a42bb08f (diff) | |
| download | linux-stable-0bd606b31d40dceb718bf22e3ce7b4cff7e34bf6.tar.gz linux-stable-0bd606b31d40dceb718bf22e3ce7b4cff7e34bf6.zip | |
Bluetooth: hci_event: Introduce handle_ev_vendor() for HCI_EV_VENDOR
Introduce the hook to solve issues below:
msft_vendor_evt(), the current handler for all VSEs, is unsuitable
since:
- many VSEs are not MSFT ones;
- it always corrupts the non-MSFT VSEs by calling skb_pull_data()
once the MSFT extension is enabled.
Several issues are caused by many transport drivers pre-processing
VSEs in their RX path, often an IRQ-disabled atomic context. Take
the two typical cases below as examples:
Case 1:
// no btmon log, no way to reach userspace
Step 1: handle and free @original_skb directly
Case 2:
// hurts performance and consumes GFP_ATOMIC memory
Step 1: cloned_skb = skb_clone(original_skb, GFP_ATOMIC);
// the VSE is handled here
Step 2: handle and free @cloned_skb
Step 3: hci_recv_frame(hdev, original_skb);
// already handled, but re-enters the stack's event-handling path
Step 4: hci_event_packet(hdev, original_skb);
Fix by introducing the hook with usage:
1) the transport driver registers the hook for VSEs of interest;
2) the stack calls it in process context, handling the VSE like any
other event:
- if interested, handle the VSE - no need to free it - and
return true;
- otherwise return false.
Signed-off-by: Zijun Hu <zijun.hu@oss.qualcomm.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Diffstat (limited to 'include')
| -rw-r--r-- | include/net/bluetooth/hci_core.h | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 6ff47f9bf758..e07418a5adce 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -646,6 +646,8 @@ struct hci_dev { int (*setup)(struct hci_dev *hdev); int (*shutdown)(struct hci_dev *hdev); int (*send)(struct hci_dev *hdev, struct sk_buff *skb); + /* Handle HCI_EV_VENDOR; return true if handled, false otherwise */ + bool (*handle_ev_vendor)(struct hci_dev *hdev, struct sk_buff *skb); void (*notify)(struct hci_dev *hdev, unsigned int evt); void (*hw_error)(struct hci_dev *hdev, u8 code); int (*post_init)(struct hci_dev *hdev); |
