| 0/0 |
2026/05/19 04:51 |
flow |
assessment-security |
1h18m
Results: map[DenialOfService:true Explanation:Based on the analysis of the bug report and the kernel source code, here is the
assessment of the issue:
**Root Cause Analysis:**
The bug report indicates a hung task (`syz-executor:5969`) that has been blocked
for more than 143 seconds in `__flush_work`. The call trace shows this is
happening during task exit/signal handling: `get_signal` -> `task_work_run` ->
`fput`.
In the context of Bluetooth, closing a `/dev/vhci` file descriptor triggers
`vhci_release`, which calls `hci_unregister_dev`. Inside `hci_unregister_dev`,
the kernel calls `disable_work_sync(&hdev->rx_work)` to flush and disable the
receive workqueue. This is where `syz-executor` is blocked, waiting for
`rx_work` to finish.
Looking at the lockdep output for the kworkers:
1. `kworker/u9:10/11292` is running `rx_work` and is blocked at
`hci_event_packet+0x162/0x1260 net/bluetooth/hci_event.c:7736`. This line
corresponds to `hci_dev_lock(hdev)`.
2. Lockdep shows that `kworker/u9:10/11292` actually *holds* `hdev->lock`
(acquired at line 7736). Since it releases the lock just 3 lines later at 7739,
it must be blocked between these lines.
3. The only operation between acquiring and releasing the lock is
`skb_clone(skb, GFP_KERNEL)`.
A `GFP_KERNEL` allocation can block indefinitely if the system is under severe
memory pressure (Out-Of-Memory condition). Because `rx_work` is stuck in memory
reclaim while holding `hdev->lock`, any other thread trying to acquire
`hdev->lock` or flush `rx_work` (like `syz-executor` in `hci_unregister_dev`)
will also hang.
**Conclusion:**
This is a classic OOM (Out-Of-Memory) hang. The empty reproducer provided by
syzkaller strongly supports this, as it indicates the hang occurred
spontaneously due to the accumulated state of the system (memory exhaustion)
rather than a specific sequence of syscalls.
Since this is a generic resource exhaustion issue and not a logical deadlock or
memory corruption bug, it does not pose a direct security vulnerability
(privilege escalation or memory safety issue). It can cause a Denial of Service
(system hang), but triggering it requires exhausting system memory, which is a
generic system-wide issue rather than a Bluetooth-specific flaw. Furthermore,
accessing `/dev/vhci` to trigger the specific cleanup path typically requires
root privileges or `CAP_NET_ADMIN`.
**Security Impact:**
* **Exploitable:** No. This is a resource exhaustion hang, not a memory
corruption or logic bug.
* **Denial of Service:** Yes, it results in a task hang, but it is a generic OOM
side-effect.
* **Unprivileged Access:** No. Access to `/dev/vhci` is restricted. Exploitable:false FilesystemTrigger:false NetworkTrigger:false PeripheralTrigger:false RemoteTrigger:false Unprivileged:false UserNamespace:false VMGuestTrigger:false VMHostTrigger:false]
|
| 1/1 |
2026/05/19 04:51 |
action |
syz-repro-to-c-repro |
0m
Results: map[SimplifiedCRepro:// autogenerated by syzkaller (https://github.com/google/syzkaller)
#define _GNU_SOURCE
#include <endian.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mount.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{
syscall(__NR_mmap, /*addr=*/0x1ffffffff000ul, /*len=*/0x1000ul, /*prot=*/0ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul);
syscall(__NR_mmap, /*addr=*/0x200000000000ul, /*len=*/0x1000000ul, /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/7ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul);
syscall(__NR_mmap, /*addr=*/0x200001000000ul, /*len=*/0x1000ul, /*prot=*/0ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul);
const char* reason;
(void)reason;
if (write(1, "executing program\n", sizeof("executing program\n") - 1)) {}
return 0;
}
]
|
| 2/1 |
2026/05/19 04:51 |
action |
kernel-checkouter |
2m
Results: map[KernelSrc:/app/workdir/cache/src/70e90fe09a92a5786889c00be8382dee104a5a15]
|
| 3/1 |
2026/05/19 04:53 |
action |
kernel-builder |
32m
Results: map[KernelObj:/app/workdir/cache/build/ce921a0583ea403ca1ce11c51ac7f87a8e41186b]
|
| 4/1 |
2026/05/19 05:26 |
action |
codesearch-prepare |
22m
Results: map[Index:codesearch-index]
|
| 5/1 |
2026/05/19 05:48 |
agent |
expert |
21m
Model:
Results: map[DenialOfService:true Exploitable:false FilesystemTrigger:false NetworkTrigger:false PeripheralTrigger:false RemoteTrigger:false Unprivileged:false UserNamespace:false VMGuestTrigger:false VMHostTrigger:false]
Instruction:
You are an experienced Linux kernel security engineer. Your task is to analyze given kernel bug report
and determine its security impact based on the following dimensions.
Use the provided tools to examine the source code, check for capability checks (e.g., capable(), ns_capable()),
and understand the nature of the bug. Analyze the given kernel build and configuration.
You can check the kernel config by grepping ".config" file; you can check kernel cmdline by greeping
".config" file for "CONFIG_CMDLINE=". Assume sysctl parameters have default values.
But analyze for the corresponding production build w/o debugging tools enabled (like KASAN, KMSAN, UBSAN).
Don't make assumptions; verify them with source code access. Try different strategies when analyzing the bug:
- think of ways in which the vulnerable code is unreachable
- or the other way around: try to come up with different ideas of how an unprivileged user can reach the bug
If still unsure err on the side of the bug being non-exploitable/not-accessible.
In the final reply, provide a reasoning for your assessment.
Analysis dimensions:
* Exploitable:
Determine if the bug can result in memory corruption or elevated privileges.
Memory safety issues are almost always exploitable (KASAN or UBSAN reports for use-after-free, out-of-bounds;
refcounting issues, corrupted lists, etc). When kernel is crashing on a completly wild pointer access
(e.g. user-space address, or non-canonical address, but not on NULL or address corresponding to KASAN shadow
for NULL address), including both data accesses and control tranfers, that's also usually implies possibility
of exploitation. Such reports usually say "unable to handle kernel paging request".
Uses of uninitialized values detected by KMSAN may be exploitable b/c attacker frequently can affect uninit
values with spraying techniques. However, for these exploitabability depends on how exactly the uninit value
is used in the code, and what it affects.
Think of what happens after the bug is triggered. Some bugs cause kernel panic and halt execution,
they are harder to exploit. For example, BUG reports halts the kernel. However, WARNING reports don't halt
execution in production builds. Debug bug detection tools (like KASAN, KMSAN, KCSAN, UBSAN) are also not enabled
in production builds, so attacker can freely exploit these bugs w/o being detected by these tools.
If you see an integer overflow, think how the overflowed value used later (if it's used as allocation size,
or an array index). If you see an out-of-bounds read, think if it's followed by an out-of-bounds write as well.
Some KCSAN data-races may be exploitable by skilled attackers as well. Think what data structures got corrupted
as the result of data races and how. However, note that kernel has lots of "benign" data races that don't lead
to any runtime misbehavior at all.
* Denial Of Service:
Determine if the bug can result in denial-of-service. Most bugs can, since they cause system crash,
hangs, deadlocks, or resource leaks. This is mostly applicable to WARNING bugs that won't cause system crash
in production. For these think what will be consequences of the violation of the kernel assumptions flagged
by the WARNING. In some cases the unexpected condition is also properly handled by the normal control flow
(e.g. with "if (WARN_ON(...))"), these won't cause denial-of-service. If the condition is not handled,
then it may or may not cause denial-of-service.
* Accessible From Unprivileged Processes:
Determine if the bug can be reached from a typical (non-root) user process that does NOT have any special capabilities
(like CAP_SYS_ADMIN, CAP_NET_ADMIN, CAP_NET_RAW, CAP_PERFMON) or access to device nodes restricted to root.
Assume that unprivileged_bpf_disabled=1, that is eBPF loading is not accessible. However, cBPF (classical BPF)
is still accessible to non-root processes.
Assume that user namespaces are not accessible, that is, the process cannot get the mentioned capabilities even
within a new user namespace (checked by ns_capable() function in the kernel sources).
* Accessible From User Namespaces:
Determine if the bug can be reached within a user-namespace where the process has all capabilities
(including CAP_SYS_ADMIN, CAP_NET_ADMIN, CAP_NET_RAW, CAP_PERFMON). Such capabilities are checked with ns_capable()
function in the kernel sources.
* VM Guest Trigger:
Determine if the bug can be triggered from the context of a typical KVM guest (e.g., set up by a QEMU VMM).
Consider accesses to standard Linux host paravirtualized features (virtio-blk, virtio-net, etc.),
and handling of VM exits in the KVM code.
* VM Host Trigger in The Confidetial Computing Context:
Determine if the bug can be triggered in a confidential computing guest kernel from the context of a KVM host.
Consider access to standard Linux guest paravirtualized features (virtio-blk, virtio-net, etc.).
* Ethernet Network Trigger:
Determine if the bug can be triggered by processing ingress network Ethernet traffic, either directly (network stack)
or via drivers exposed to network data.
* Other Remote Trigger:
Determine if the bug can be triggered by processing remote traffic other than Ethernet (Wifi, Bluetooth, NFC, etc).
* Peripheral Trigger:
Determine if the bug can be triggered via an untrusted peripheral device that can be physically plugged
into a system, such as a USB device or a niche hardware driver handling external hardware inputs.
This is particularly important for mobile and desktop environments where users can plug in unknown devices.
* Malicious Filesystem Trigger:
Determine if the bug can be triggered by the kernel mounting and parsing a malicious filesystem image.
This is highly critical for Desktop and Mobile environments where external media or downloaded images
might be auto-mounted.
Prefer calling several tools at the same time to save round-trips.
Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.
Prompt:
The kernel bug report is:
INFO: task syz-executor:5969 blocked for more than 143 seconds.
Not tainted syzkaller #0
task:syz-executor state:D
Call Trace:
do_wait_for_common kernel/sched/completion.c:100 [inline]
__wait_for_common kernel/sched/completion.c:121 [inline]
wait_for_common kernel/sched/completion.c:132 [inline]
wait_for_completion+0x2bf/0x5d0 kernel/sched/completion.c:153
__flush_work+0x9b9/0xbc0 kernel/workqueue.c:4281
get_signal+0x1285/0x1340 kernel/signal.c:3034
arch_do_signal_or_restart+0x9a/0x7a0 arch/x86/kernel/signal.c:337
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7fac0ed9148a
#2: ffff88807c668ec0 (&hdev->req_lock){+.+.}-{4:4}, at: hci_cmd_sync_work+0x1d3/0x400 net/bluetooth/hci_sync.c:331
3 locks held by kworker/u9:3/5978:
#0: ffff888057c3e948 ((wq_completion)hci6){+.+.}-{0:0}, at: process_one_work+0x841/0x15a0 kernel/workqueue.c:3236
#1: ffffc9000412fb80 ((work_completion)(&hdev->cmd_sync_work)){+.+.}-{0:0}, at: process_one_work+0x868/0x15a0 kernel/workqueue.c:3237
#2: ffff88807ef20ec0 (&hdev->req_lock){+.+.}-{4:4}, at: hci_cmd_sync_work+0x1d3/0x400 net/bluetooth/hci_sync.c:331
3 locks held by kworker/u9:4/5979:
#0: ffff88801e7c2148 ((wq_completion)hci4){+.+.}-{0:0}, at: process_one_work+0x841/0x15a0 kernel/workqueue.c:3236
#1: ffffc900040afb80 ((work_completion)(&hdev->cmd_sync_work)){+.+.}-{0:0}, at: process_one_work+0x868/0x15a0 kernel/workqueue.c:3237
#2: ffff888054900ec0 (&hdev->req_lock){+.+.}-{4:4}, at: hci_cmd_sync_work+0x1d3/0x400 net/bluetooth/hci_sync.c:331
3 locks held by kworker/u9:5/6113:
#0: ffff8880296d3148 ((wq_completion)hci2){+.+.}-{0:0}, at: process_one_work+0x841/0x15a0 kernel/workqueue.c:3236
#1: ffffc90002f17b80 (
(work_completion)(&hdev->cmd_sync_work)
){+.+.}-{0:0}
3 locks held by kworker/u9:9/11288:
#1: ffffc9000411fb80 ((work_completion)(&hdev->cmd_sync_work)){+.+.}-{0:0}, at: process_one_work+0x868/0x15a0 kernel/workqueue.c:3237
#2: ffff888030d98ec0 (&hdev->req_lock){+.+.}-{4:4}, at: hci_cmd_sync_work+0x1d3/0x400 net/bluetooth/hci_sync.c:331
3 locks held by kworker/u9:10/11292:
#0: ffff88801e7c1148 ((wq_completion)hci4#2){+.+.}-{0:0}, at: process_one_work+0x841/0x15a0 kernel/workqueue.c:3236
#1: ffffc9000c69fb80 ((work_completion)(&hdev->rx_work)){+.+.}-{0:0}, at: process_one_work+0x868/0x15a0 kernel/workqueue.c:3237
#2: ffff8880549000c0 (&hdev->lock){+.+.}-{4:4}, at: hci_event_packet+0x162/0x1260 net/bluetooth/hci_event.c:7736
7 locks held by kworker/u9:11/12552:
It is reproducible with the followint program.
Keep in mind that it may lack the precise threading, sandboxing, and some arguments of a working reproducer.
But it should give an idea of the involved syscalls.
// autogenerated by syzkaller (https://github.com/google/syzkaller)
#define _GNU_SOURCE
#include <endian.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mount.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{
syscall(__NR_mmap, /*addr=*/0x1ffffffff000ul, /*len=*/0x1000ul, /*prot=*/0ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul);
syscall(__NR_mmap, /*addr=*/0x200000000000ul, /*len=*/0x1000000ul, /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/7ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul);
syscall(__NR_mmap, /*addr=*/0x200001000000ul, /*len=*/0x1000ul, /*prot=*/0ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul);
const char* reason;
(void)reason;
if (write(1, "executing program\n", sizeof("executing program\n") - 1)) {}
return 0;
}
Reply: Based on the analysis of the bug report and the kernel source code, here is the assessment of the issue:
**Root Cause Analysis:**
The bug report indicates a hung task (`syz-executor:5969`) that has been blocked for more than 143 seconds in `__flush_work`. The call trace shows this is happening during task exit/signal handling: `get_signal` -> `task_work_run` -> `fput`.
In the context of Bluetooth, closing a `/dev/vhci` file descriptor triggers `vhci_release`, which calls `hci_unregister_dev`. Inside `hci_unregister_dev`, the kernel calls `disable_work_sync(&hdev->rx_work)` to flush and disable the receive workqueue. This is where `syz-executor` is blocked, waiting for `rx_work` to finish.
Looking at the lockdep output for the kworkers:
1. `kworker/u9:10/11292` is running `rx_work` and is blocked at `hci_event_packet+0x162/0x1260 net/bluetooth/hci_event.c:7736`. This line corresponds to `hci_dev_lock(hdev)`.
2. Lockdep shows that `kworker/u9:10/11292` actually *holds* `hdev->lock` (acquired at line 7736). Since it releases the lock just 3 lines later at 7739, it must be blocked between these lines.
3. The only operation between acquiring and releasing the lock is `skb_clone(skb, GFP_KERNEL)`.
A `GFP_KERNEL` allocation can block indefinitely if the system is under severe memory pressure (Out-Of-Memory condition). Because `rx_work` is stuck in memory reclaim while holding `hdev->lock`, any other thread trying to acquire `hdev->lock` or flush `rx_work` (like `syz-executor` in `hci_unregister_dev`) will also hang.
**Conclusion:**
This is a classic OOM (Out-Of-Memory) hang. The empty reproducer provided by syzkaller strongly supports this, as it indicates the hang occurred spontaneously due to the accumulated state of the system (memory exhaustion) rather than a specific sequence of syscalls.
Since this is a generic resource exhaustion issue and not a logical deadlock or memory corruption bug, it does not pose a direct security vulnerability (privilege escalation or memory safety issue). It can cause a Denial of Service (system hang), but triggering it requires exhausting system memory, which is a generic system-wide issue rather than a Bluetooth-specific flaw. Furthermore, accessing `/dev/vhci` to trigger the specific cleanup path typically requires root privileges or `CAP_NET_ADMIN`.
**Security Impact:**
* **Exploitable:** No. This is a resource exhaustion hang, not a memory corruption or logic bug.
* **Denial of Service:** Yes, it results in a task hang, but it is a generic OOM side-effect.
* **Unprivileged Access:** No. Access to `/dev/vhci` is restricted.
|
| 6/2 |
2026/05/19 05:48 |
llm |
expert |
0m
Model:
Tokens:
input: 6168
output: 45
thoughts: 594
Thoughts: **Analyzing a Bluetooth Deadlock**
Okay, so I've got this syzkaller report, a pretty clear indication of a hang, a task blocked for over two minutes. The call trace immediately jumps out at me: it's showing `wait_for_completion`, and then something deeply entangled with workqueues and signal handling. That's a classic deadlock situation, or at least a very long wait, in my experience.
Looking at the trace, and especially the lock information, the problem seems to be originating within Bluetooth, specifically `hci_cmd_sync_work`. Both the blocked task and a `kworker` thread are holding locks on `hdev->req_lock`. This strongly suggests a classic lock ordering issue or a circular dependency within that `hci_sync` path. The fact that the reproducer is empty is annoying, but hey, Bluetooth is the problem. It could be something subtly timing related, that only occurs under heavy load or specific states.
My next move is clear: I need to dig into the `hci_cmd_sync_work` function in `net/bluetooth/hci_sync.c`. I'll have to trace the lock acquisition and release patterns. I will need to look at any potential double locks, or any path that can lead to two threads waiting for each other to release the same lock. Then, I will need to understand the dependencies of this code path, specifically what the `hdev->req_lock` is protecting and how these workqueues are interacting. I would bet that a bad sequence of locking and unlocking is the cause. Let's see if we can find a race condition that leads to this block.
|
| 7/2 |
2026/05/19 05:48 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_sync.c IncludeLines:true Name:hci_cmd_sync_work]
Results: map[SourceCode: 305: static void hci_cmd_sync_work(struct work_struct *work)
306: {
307: struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_sync_work);
308:
309: bt_dev_dbg(hdev, "");
310:
311: /* Dequeue all entries and run them */
312: while (1) {
313: struct hci_cmd_sync_work_entry *entry;
314:
315: mutex_lock(&hdev->cmd_sync_work_lock);
316: entry = list_first_entry_or_null(&hdev->cmd_sync_work_list,
317: struct hci_cmd_sync_work_entry,
318: list);
319: if (entry)
320: list_del(&entry->list);
321: mutex_unlock(&hdev->cmd_sync_work_lock);
322:
323: if (!entry)
324: break;
325:
326: bt_dev_dbg(hdev, "entry %p", entry);
327:
328: if (entry->func) {
329: int err;
330:
331: hci_req_sync_lock(hdev);
332: err = entry->func(hdev, entry->data);
333: if (entry->destroy)
334: entry->destroy(hdev, entry->data, err);
335: hci_req_sync_unlock(hdev);
336: }
337:
338: kfree(entry);
339: }
340: }
SourceFile:net/bluetooth/hci_sync.c]
|
| 8/2 |
2026/05/19 05:48 |
llm |
expert |
0m
Model:
Tokens:
input: 7693
output: 37
thoughts: 75
Thoughts: Okay, let's break this down.
**Debugging a Kernel Hang: Tracing the Signal Path**
Right, so the system's hung, and the stack trace points to `__flush_work`. That's a classic sign of some sort of resource contention or deadlock, but why is it showing up here? I need to understand the call path. The immediate thought is, "Wait, how does `__flush_work` get called from `get_signal`?" That seems...odd. I need to be sure about the relationship between these two. My first inclination is to assume `get_signal` directly calls `__flush_work`, but my experience says that's likely too simplistic.
Let me thinkβ¦ `get_signal` is probably calling some intermediary function. Ah, of course β it looks like `task_work_run` is the likely candidate. *That's* the function that might eventually lead to the call to `__flush_work`. So, I need to confirm this indirect relationship. The signal handling code is, by nature, very complex, so I'm going to head to `kernel/signal.c` right away, to get a solid grasp of what's happening. I need to trace the call graph in that function, to figure out how `task_work_run` and by extension, `__flush_work` fit into the normal execution path of `get_signal`. This is the place to get to the bottom of this hang.
|
| 9/2 |
2026/05/19 05:48 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:kernel/signal.c IncludeLines:true Name:get_signal]
Results: map[SourceCode:2799: bool get_signal(struct ksignal *ksig)
2800: {
2801: struct sighand_struct *sighand = current->sighand;
2802: struct signal_struct *signal = current->signal;
2803: int signr;
2804:
2805: clear_notify_signal();
2806: if (unlikely(task_work_pending(current)))
2807: task_work_run();
2808:
2809: if (!task_sigpending(current))
2810: return false;
2811:
2812: if (unlikely(uprobe_deny_signal()))
2813: return false;
2814:
2815: /*
2816: * Do this once, we can't return to user-mode if freezing() == T.
2817: * do_signal_stop() and ptrace_stop() do freezable_schedule() and
2818: * thus do not need another check after return.
2819: */
2820: try_to_freeze();
2821:
2822: relock:
2823: spin_lock_irq(&sighand->siglock);
2824:
2825: /*
2826: * Every stopped thread goes here after wakeup. Check to see if
2827: * we should notify the parent, prepare_signal(SIGCONT) encodes
2828: * the CLD_ si_code into SIGNAL_CLD_MASK bits.
2829: */
2830: if (unlikely(signal->flags & SIGNAL_CLD_MASK)) {
2831: int why;
2832:
2833: if (signal->flags & SIGNAL_CLD_CONTINUED)
2834: why = CLD_CONTINUED;
2835: else
2836: why = CLD_STOPPED;
2837:
2838: signal->flags &= ~SIGNAL_CLD_MASK;
2839:
2840: spin_unlock_irq(&sighand->siglock);
2841:
2842: /*
2843: * Notify the parent that we're continuing. This event is
2844: * always per-process and doesn't make whole lot of sense
2845: * for ptracers, who shouldn't consume the state via
2846: * wait(2) either, but, for backward compatibility, notify
2847: * the ptracer of the group leader too unless it's gonna be
2848: * a duplicate.
2849: */
2850: read_lock(&tasklist_lock);
2851: do_notify_parent_cldstop(current, false, why);
2852:
2853: if (ptrace_reparented(current->group_leader))
2854: do_notify_parent_cldstop(current->group_leader,
2855: true, why);
2856: read_unlock(&tasklist_lock);
2857:
2858: goto relock;
2859: }
2860:
2861: for (;;) {
2862: struct k_sigaction *ka;
2863: enum pid_type type;
2864:
2865: /* Has this task already been marked for death? */
2866: if ((signal->flags & SIGNAL_GROUP_EXIT) ||
2867: signal->group_exec_task) {
2868: signr = SIGKILL;
2869: sigdelset(¤t->pending.signal, SIGKILL);
2870: trace_signal_deliver(SIGKILL, SEND_SIG_NOINFO,
2871: &sighand->action[SIGKILL-1]);
2872: recalc_sigpending();
2873: /*
2874: * implies do_group_exit() or return to PF_USER_WORKER,
2875: * no need to initialize ksig->info/etc.
2876: */
2877: goto fatal;
2878: }
2879:
2880: if (unlikely(current->jobctl & JOBCTL_STOP_PENDING) &&
2881: do_signal_stop(0))
2882: goto relock;
2883:
2884: if (unlikely(current->jobctl &
2885: (JOBCTL_TRAP_MASK | JOBCTL_TRAP_FREEZE))) {
2886: if (current->jobctl & JOBCTL_TRAP_MASK) {
2887: do_jobctl_trap();
2888: spin_unlock_irq(&sighand->siglock);
2889: } else if (current->jobctl & JOBCTL_TRAP_FREEZE)
2890: do_freezer_trap();
2891:
2892: goto relock;
2893: }
2894:
2895: /*
2896: * If the task is leaving the frozen state, let's update
2897: * cgroup counters and reset the frozen bit.
2898: */
2899: if (unlikely(cgroup_task_frozen(current))) {
2900: spin_unlock_irq(&sighand->siglock);
2901: cgroup_leave_frozen(false);
2902: goto relock;
2903: }
2904:
2905: /*
2906: * Signals generated by the execution of an instruction
2907: * need to be delivered before any other pending signals
2908: * so that the instruction pointer in the signal stack
2909: * frame points to the faulting instruction.
2910: */
2911: type = PIDTYPE_PID;
2912: signr = dequeue_synchronous_signal(&ksig->info);
2913: if (!signr)
2914: signr = dequeue_signal(¤t->blocked, &ksig->info, &type);
2915:
2916: if (!signr)
2917: break; /* will return 0 */
2918:
2919: if (unlikely(current->ptrace) && (signr != SIGKILL) &&
2920: !(sighand->action[signr -1].sa.sa_flags & SA_IMMUTABLE)) {
2921: signr = ptrace_signal(signr, &ksig->info, type);
2922: if (!signr)
2923: continue;
2924: }
2925:
2926: ka = &sighand->action[signr-1];
2927:
2928: /* Trace actually delivered signals. */
2929: trace_signal_deliver(signr, &ksig->info, ka);
2930:
2931: if (ka->sa.sa_handler == SIG_IGN) /* Do nothing. */
2932: continue;
2933: if (ka->sa.sa_handler != SIG_DFL) {
2934: /* Run the handler. */
2935: ksig->ka = *ka;
2936:
2937: if (ka->sa.sa_flags & SA_ONESHOT)
2938: ka->sa.sa_handler = SIG_DFL;
2939:
2940: break; /* will return non-zero "signr" value */
2941: }
2942:
2943: /*
2944: * Now we are doing the default action for this signal.
2945: */
2946: if (sig_kernel_ignore(signr)) /* Default is nothing. */
2947: continue;
2948:
2949: /*
2950: * Global init gets no signals it doesn't want.
2951: * Container-init gets no signals it doesn't want from same
2952: * container.
2953: *
2954: * Note that if global/container-init sees a sig_kernel_only()
2955: * signal here, the signal must have been generated internally
2956: * or must have come from an ancestor namespace. In either
2957: * case, the signal cannot be dropped.
2958: */
2959: if (unlikely(signal->flags & SIGNAL_UNKILLABLE) &&
2960: !sig_kernel_only(signr))
2961: continue;
2962:
2963: if (sig_kernel_stop(signr)) {
2964: /*
2965: * The default action is to stop all threads in
2966: * the thread group. The job control signals
2967: * do nothing in an orphaned pgrp, but SIGSTOP
2968: * always works. Note that siglock needs to be
2969: * dropped during the call to is_orphaned_pgrp()
2970: * because of lock ordering with tasklist_lock.
2971: * This allows an intervening SIGCONT to be posted.
2972: * We need to check for that and bail out if necessary.
2973: */
2974: if (signr != SIGSTOP) {
2975: spin_unlock_irq(&sighand->siglock);
2976:
2977: /* signals can be posted during this window */
2978:
2979: if (is_current_pgrp_orphaned())
2980: goto relock;
2981:
2982: spin_lock_irq(&sighand->siglock);
2983: }
2984:
2985: if (likely(do_signal_stop(signr))) {
2986: /* It released the siglock. */
2987: goto relock;
2988: }
2989:
2990: /*
2991: * We didn't actually stop, due to a race
2992: * with SIGCONT or something like that.
2993: */
2994: continue;
2995: }
2996:
2997: fatal:
2998: spin_unlock_irq(&sighand->siglock);
2999: if (unlikely(cgroup_task_frozen(current)))
3000: cgroup_leave_frozen(true);
3001:
3002: /*
3003: * Anything else is fatal, maybe with a core dump.
3004: */
3005: current->flags |= PF_SIGNALED;
3006:
3007: if (sig_kernel_coredump(signr)) {
3008: if (print_fatal_signals)
3009: print_fatal_signal(signr);
3010: proc_coredump_connector(current);
3011: /*
3012: * If it was able to dump core, this kills all
3013: * other threads in the group and synchronizes with
3014: * their demise. If we lost the race with another
3015: * thread getting here, it set group_exit_code
3016: * first and our do_group_exit call below will use
3017: * that value and ignore the one we pass it.
3018: */
3019: vfs_coredump(&ksig->info);
3020: }
3021:
3022: /*
3023: * PF_USER_WORKER threads will catch and exit on fatal signals
3024: * themselves. They have cleanup that must be performed, so we
3025: * cannot call do_exit() on their behalf. Note that ksig won't
3026: * be properly initialized, PF_USER_WORKER's shouldn't use it.
3027: */
3028: if (current->flags & PF_USER_WORKER)
3029: goto out;
3030:
3031: /*
3032: * Death signals, no core dump.
3033: */
3034: do_group_exit(signr);
3035: /* NOTREACHED */
3036: }
3037: spin_unlock_irq(&sighand->siglock);
3038:
3039: ksig->sig = signr;
3040:
3041: if (signr && !(ksig->ka.sa.sa_flags & SA_EXPOSE_TAGBITS))
3042: hide_si_addr_tag_bits(ksig);
3043: out:
3044: return signr > 0;
3045: }
SourceFile:kernel/signal.c]
|
| 10/2 |
2026/05/19 05:48 |
llm |
expert |
0m
Model:
Tokens:
input: 11687
output: 41
thoughts: 325
Thoughts: **Decoding This Trace: A Journey Through Signal Handling and Workqueues**
Okay, so I'm looking at this trace and it's pointing me to `get_signal` calling `__flush_work`. That's a bit odd. I'm seeing line 3034 in `get_signal` as `do_group_exit(signr);`. Now, I know `do_group_exit` doesn't directly call `__flush_work`. My initial thought was maybe there's a chain: `do_group_exit` -> `do_exit` -> `exit_task_work` -> `task_work_run` -> `__flush_work`. But, that seems overly convoluted.
Hold on a second... the trace data points to `get_signal+0x1285/0x1340 kernel/signal.c:3034`. Hmm, the line numbers *should* match. So, line 3034 *is* `do_group_exit(signr);` in the source I'm using, but the trace seems to indicate a more direct relationship than I initially imagined. Let me pull that trace up again...
Okay, the full call stack in the trace is:
```
wait_for_completion+0x2bf/0x5d0 kernel/sched/completion.c:153
__flush_work+0x9b9/0xbc0 kernel/workqueue.c:4281
get_signal+0x1285/0x1340 kernel/signal.c:3034
```
Okay, so the trace itself is claiming line 3034 of `get_signal` is involved. I'm wondering if something is inlined. Maybe `task_work_run` is getting inlined? Since I know the connection between signal and task work, and that `__flush_work` is a frequent part of task work. Let me check the definition of `task_work_run` in `kernel/task_work.c` and see if the compiler's optimizations have anything to do with it.
|
| 11/2 |
2026/05/19 05:49 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:kernel/task_work.c IncludeLines:true Name:task_work_run]
Results: map[SourceCode: 192: /**
193: * task_work_run - execute the works added by task_work_add()
194: *
195: * Flush the pending works. Should be used by the core kernel code.
196: * Called before the task returns to the user-mode or stops, or when
197: * it exits. In the latter case task_work_add() can no longer add the
198: * new work after task_work_run() returns.
199: */
200: void task_work_run(void)
201: {
202: struct task_struct *task = current;
203: struct callback_head *work, *head, *next;
204:
205: for (;;) {
206: /*
207: * work->func() can do task_work_add(), do not set
208: * work_exited unless the list is empty.
209: */
210: work = READ_ONCE(task->task_works);
211: do {
212: head = NULL;
213: if (!work) {
214: if (task->flags & PF_EXITING)
215: head = &work_exited;
216: else
217: break;
218: }
219: } while (!try_cmpxchg(&task->task_works, &work, head));
220:
221: if (!work)
222: break;
223: /*
224: * Synchronize with task_work_cancel_match(). It can not remove
225: * the first entry == work, cmpxchg(task_works) must fail.
226: * But it can remove another entry from the ->next list.
227: */
228: raw_spin_lock_irq(&task->pi_lock);
229: raw_spin_unlock_irq(&task->pi_lock);
230:
231: do {
232: next = work->next;
233: work->func(work);
234: work = next;
235: cond_resched();
236: } while (work);
237: }
238: }
SourceFile:kernel/task_work.c]
|
| 12/2 |
2026/05/19 05:49 |
llm |
expert |
0m
Model:
Tokens:
input: 13215
output: 39
thoughts: 86
Thoughts: Okay, here's my interpretation of that thought process, from an expert's perspective:
**Debugging a Signal/Work Queue Interaction**
Right, so I'm chasing down this issue, and the trace is suggesting something funky. I thought `__flush_work` was being called directly, but now I see it's triggered from within `get_signal`? That's a bit unexpected. I need to understand the call chain here.
Let me see... perhaps `get_signal` is calling `task_work_run`, which would explain things? The trace initially pointed me to line 2807, but the actual crash seems to happen at line 3034. That's `do_group_exit(signr)`. So, `do_group_exit` must be the root of my problem. That makes sense, now I need to dive into that function to understand how the signal is being handled and why things are going sideways. I suspect something with signal handling and the work queue might be tangled. Let's see what's actually going on in `do_group_exit`.
|
| 13/2 |
2026/05/19 05:49 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:kernel/exit.c IncludeLines:true Name:do_group_exit]
Results: map[SourceCode:1082: /*
1083: * Take down every thread in the group. This is called by fatal signals
1084: * as well as by sys_exit_group (below).
1085: */
1086: void __noreturn
1087: do_group_exit(int exit_code)
1088: {
1089: struct signal_struct *sig = current->signal;
1090:
1091: if (sig->flags & SIGNAL_GROUP_EXIT)
1092: exit_code = sig->group_exit_code;
1093: else if (sig->group_exec_task)
1094: exit_code = 0;
1095: else {
1096: struct sighand_struct *const sighand = current->sighand;
1097:
1098: spin_lock_irq(&sighand->siglock);
1099: if (sig->flags & SIGNAL_GROUP_EXIT)
1100: /* Another thread got here before we took the lock. */
1101: exit_code = sig->group_exit_code;
1102: else if (sig->group_exec_task)
1103: exit_code = 0;
1104: else {
1105: sig->group_exit_code = exit_code;
1106: sig->flags = SIGNAL_GROUP_EXIT;
1107: zap_other_threads(current);
1108: }
1109: spin_unlock_irq(&sighand->siglock);
1110: }
1111:
1112: do_exit(exit_code);
1113: /* NOTREACHED */
1114: }
SourceFile:kernel/exit.c]
|
| 14/2 |
2026/05/19 05:49 |
llm |
expert |
0m
Model:
Tokens:
input: 14084
output: 39
thoughts: 141
Thoughts: **Debugging a Mysterious Signal**
Okay, here's what's running through my mind. I'm seeing this trace, and it's pointing at `get_signal` after `do_exit`, which is strange. I thought `do_exit` would call `exit_task_work`, which then calls `task_work_run`. That seems logical, but the trace is placing the issue in `kernel/signal.c` at line 3034 within `get_signal`. Is `do_group_exit` inlined somewhere unexpectedly? No, I don't see any inline markers on it.
Hmm, could `get_signal` itself be calling `task_work_run`, maybe around line 2807, and the line number 3034 is just a side effect of some compiler optimization or something? That's plausible. Let's dig deeper. I need to understand how the work queue is interacting here. I'm going to check `__flush_work` in `kernel/workqueue.c`. I need to figure out what's causing this unexpected flow.
|
| 15/2 |
2026/05/19 05:49 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:kernel/workqueue.c IncludeLines:true Name:__flush_work]
Results: map[SourceCode:4235: static bool __flush_work(struct work_struct *work, bool from_cancel)
4236: {
4237: struct wq_barrier barr;
4238:
4239: if (WARN_ON(!wq_online))
4240: return false;
4241:
4242: if (WARN_ON(!work->func))
4243: return false;
4244:
4245: if (!start_flush_work(work, &barr, from_cancel))
4246: return false;
4247:
4248: /*
4249: * start_flush_work() returned %true. If @from_cancel is set, we know
4250: * that @work must have been executing during start_flush_work() and
4251: * can't currently be queued. Its data must contain OFFQ bits. If @work
4252: * was queued on a BH workqueue, we also know that it was running in the
4253: * BH context and thus can be busy-waited.
4254: */
4255: if (from_cancel) {
4256: unsigned long data = *work_data_bits(work);
4257:
4258: if (!WARN_ON_ONCE(data & WORK_STRUCT_PWQ) &&
4259: (data & WORK_OFFQ_BH)) {
4260: /*
4261: * On RT, prevent a live lock when %current preempted
4262: * soft interrupt processing by blocking on lock which
4263: * is owned by the thread invoking the callback.
4264: */
4265: while (!try_wait_for_completion(&barr.done)) {
4266: if (IS_ENABLED(CONFIG_PREEMPT_RT)) {
4267: struct worker_pool *pool;
4268:
4269: guard(rcu)();
4270: pool = get_work_pool(work);
4271: if (pool)
4272: workqueue_callback_cancel_wait_running(pool);
4273: } else {
4274: cpu_relax();
4275: }
4276: }
4277: goto out_destroy;
4278: }
4279: }
4280:
4281: wait_for_completion(&barr.done);
4282:
4283: out_destroy:
4284: destroy_work_on_stack(&barr.work);
4285: return true;
4286: }
SourceFile:kernel/workqueue.c]
|
| 16/2 |
2026/05/19 05:49 |
llm |
expert |
0m
Model:
Tokens:
input: 15262
output: 45
thoughts: 627
Thoughts: Here's my analysis of this situation:
**Debugging a Kernel Workqueue Block**
Okay, so I'm looking at a trace that shows `__flush_work` calling `wait_for_completion`. The weird thing is, `__flush_work` seems to be called directly from `get_signal`. But wait, `__flush_work` is normally called through `flush_work` or `cancel_work_sync`. I'd expect to see those functions in the trace if they were the direct cause.
My initial thought is to check if `flush_work` or `cancel_work_sync` are called in related Bluetooth code, specifically `net/bluetooth/hci_sync.c`. Wait, the trace is a bit misleading. Maybe `get_signal` calls `task_work_run`, and *that* calls the functions I was expecting. A tail call or unwinder issue could explain why they're missing from the trace. I need to keep that in mind.
Now, let's look at the locks. The trace shows a worker thread, `kworker/u9:3`, holding multiple locks: a `wq_completion`, `work_completion` and `hdev->req_lock`. The stack trace points to `hci_cmd_sync_work`. Okay, so `hci_cmd_sync_work` is running and blocked holding that `req_lock`. The trace suggests there are *multiple* worker threads running `hci_cmd_sync_work` for different HCI devices (hci6, hci4, hci2). And another worker, `kworker/u9:10`, is also running `hci_rx_work` and holding `hdev->lock`.
The blocked task, `syz-executor:5969`, is waiting on `__flush_work` completing. That's the crux of it. I need to figure out *what* work it's flushing. It's likely related to `task_work`.
I'll start with a hypothesis: could this be related to file descriptor cleanup? Specifically, maybe `fput` calls `__fput`, then `hci_sock_release`, and finally `hci_dev_close`? Let's verify what `hci_dev_close` does. That seems like a logical next step to narrow down the potential root cause.
|
| 17/2 |
2026/05/19 05:49 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_core.c IncludeLines:true Name:hci_dev_close_sync]
Results: map[SourceCode:5252: int hci_dev_close_sync(struct hci_dev *hdev)
5253: {
5254: bool auto_off;
5255: int err = 0;
5256:
5257: bt_dev_dbg(hdev, "");
5258:
5259: if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
5260: disable_delayed_work(&hdev->power_off);
5261: disable_delayed_work(&hdev->ncmd_timer);
5262: disable_delayed_work(&hdev->le_scan_disable);
5263: } else {
5264: cancel_delayed_work(&hdev->power_off);
5265: cancel_delayed_work(&hdev->ncmd_timer);
5266: cancel_delayed_work(&hdev->le_scan_disable);
5267: }
5268:
5269: hci_cmd_sync_cancel_sync(hdev, ENODEV);
5270:
5271: cancel_interleave_scan(hdev);
5272:
5273: if (hdev->adv_instance_timeout) {
5274: cancel_delayed_work_sync(&hdev->adv_instance_expire);
5275: hdev->adv_instance_timeout = 0;
5276: }
5277:
5278: err = hci_dev_shutdown(hdev);
5279:
5280: if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
5281: cancel_delayed_work_sync(&hdev->cmd_timer);
5282: return err;
5283: }
5284:
5285: hci_leds_update_powered(hdev, false);
5286:
5287: /* Flush RX and TX works */
5288: flush_work(&hdev->tx_work);
5289: flush_work(&hdev->rx_work);
5290:
5291: if (hdev->discov_timeout > 0) {
5292: hdev->discov_timeout = 0;
5293: hci_dev_clear_flag(hdev, HCI_DISCOVERABLE);
5294: hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
5295: }
5296:
5297: if (hci_dev_test_and_clear_flag(hdev, HCI_SERVICE_CACHE))
5298: cancel_delayed_work(&hdev->service_cache);
5299:
5300: if (hci_dev_test_flag(hdev, HCI_MGMT)) {
5301: struct adv_info *adv_instance;
5302:
5303: cancel_delayed_work_sync(&hdev->rpa_expired);
5304:
5305: list_for_each_entry(adv_instance, &hdev->adv_instances, list)
5306: cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
5307: }
5308:
5309: /* Avoid potential lockdep warnings from the *_flush() calls by
5310: * ensuring the workqueue is empty up front.
5311: */
5312: drain_workqueue(hdev->workqueue);
5313:
5314: hci_dev_lock(hdev);
5315:
5316: hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
5317:
5318: auto_off = hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF);
5319:
5320: if (!auto_off && !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
5321: hci_dev_test_flag(hdev, HCI_MGMT))
5322: __mgmt_power_off(hdev);
5323:
5324: hci_inquiry_cache_flush(hdev);
5325: hci_pend_le_actions_clear(hdev);
5326: hci_conn_hash_flush(hdev);
5327: /* Prevent data races on hdev->smp_data or hdev->smp_bredr_data */
5328: smp_unregister(hdev);
5329: hci_dev_unlock(hdev);
5330:
5331: hci_sock_dev_event(hdev, HCI_DEV_DOWN);
5332:
5333: if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
5334: aosp_do_close(hdev);
5335: msft_do_close(hdev);
5336: }
5337:
5338: if (hdev->flush)
5339: hdev->flush(hdev);
5340:
5341: /* Reset device */
5342: skb_queue_purge(&hdev->cmd_q);
5343: atomic_set(&hdev->cmd_cnt, 1);
5344: if (hci_test_quirk(hdev, HCI_QUIRK_RESET_ON_CLOSE) &&
5345: !auto_off && !hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
5346: set_bit(HCI_INIT, &hdev->flags);
5347: hci_reset_sync(hdev);
5348: clear_bit(HCI_INIT, &hdev->flags);
5349: }
5350:
5351: /* flush cmd work */
5352: flush_work(&hdev->cmd_work);
5353:
5354: /* Drop queues */
5355: skb_queue_purge(&hdev->rx_q);
5356: skb_queue_purge(&hdev->cmd_q);
5357: skb_queue_purge(&hdev->raw_q);
5358:
5359: /* Drop last sent command */
5360: if (hdev->sent_cmd) {
5361: cancel_delayed_work_sync(&hdev->cmd_timer);
5362: kfree_skb(hdev->sent_cmd);
5363: hdev->sent_cmd = NULL;
5364: }
5365:
5366: /* Drop last request */
5367: if (hdev->req_skb) {
5368: kfree_skb(hdev->req_skb);
5369: hdev->req_skb = NULL;
5370: }
5371:
5372: clear_bit(HCI_RUNNING, &hdev->flags);
5373: hci_sock_dev_event(hdev, HCI_DEV_CLOSE);
5374:
5375: /* After this point our queues are empty and no tasks are scheduled. */
5376: hdev->close(hdev);
5377:
5378: /* Clear flags */
5379: hdev->flags &= BIT(HCI_RAW);
5380: hci_dev_clear_volatile_flags(hdev);
5381:
5382: memset(hdev->eir, 0, sizeof(hdev->eir));
5383: memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
5384: bacpy(&hdev->random_addr, BDADDR_ANY);
5385: hci_codec_list_clear(&hdev->local_codecs);
5386:
5387: hci_dev_put(hdev);
5388: return err;
5389: }
SourceFile:net/bluetooth/hci_sync.c]
|
| 18/2 |
2026/05/19 05:49 |
llm |
expert |
0m
Model:
Tokens:
input: 18669
output: 47
thoughts: 55
Thoughts: **Analyzing the HCI Device Closure Procedure**
Okay, so I'm diving into this `hci_dev_close_sync` function, and something's immediately snagging my attention: on line 5269, it's calling `hci_cmd_sync_cancel_sync(hdev, ENODEV)`. Hmm, that's interesting. I need to understand what's happening within `hci_cmd_sync_cancel_sync` in this context. It seems like it's handling command synchronization cancellation, specifically when the device (`hdev`) is marked as not available (`ENODEV`). I need to determine why this call is occurring during the device closure. Is this some kind of clean-up operation, or are there other more subtle implications? I need to analyze `hci_cmd_sync_cancel_sync` to get the full picture.
|
| 19/2 |
2026/05/19 05:49 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_sync.c IncludeLines:true Name:hci_cmd_sync_cancel_sync]
Results: map[SourceCode: 677: /* Cancel ongoing command request synchronously:
678: *
679: * - Set result and mark status to HCI_REQ_CANCELED
680: * - Wakeup command sync thread
681: */
682: void hci_cmd_sync_cancel_sync(struct hci_dev *hdev, int err)
683: {
684: bt_dev_dbg(hdev, "err 0x%2.2x", err);
685:
686: if (hdev->req_status == HCI_REQ_PEND) {
687: /* req_result is __u32 so error must be positive to be properly
688: * propagated.
689: */
690: hdev->req_result = err < 0 ? -err : err;
691: hdev->req_status = HCI_REQ_CANCELED;
692:
693: wake_up_interruptible(&hdev->req_wait_q);
694: }
695: }
SourceFile:net/bluetooth/hci_sync.c]
|
| 20/2 |
2026/05/19 05:49 |
llm |
expert |
0m
Model:
Tokens:
input: 19283
output: 43
thoughts: 159
Thoughts: **A Deep Dive into Bluetooth HCI Device Closure**
Okay, so I'm tracing this `hci_dev_close_sync` function, and I just realized something significant. It's not just about cleaning up resources directly; it also calls `flush_work` on a few key workqueues: `tx_work`, `rx_work`, and `cmd_work`. That's standard practice, but it's important to keep in mind.
But then, I saw something in the trace that really grabbed my attention: `__flush_work` showing up in a `get_signal` call. Now, `get_signal` is linked with signal processing, but this got me thinking. If `get_signal` somehow leads to `task_work_run`, and `task_work_run` then ends up triggering `fput`, and `fput` in turn calls `hci_sock_release`... wait a minute... could `hci_sock_release` *also* call `hci_dev_close_sync`?
That's a potentially crucial loop to consider. If the socket release path directly or indirectly invokes the device closure, and the device closure then flushes the work queues, it means these paths are intertwined, and could potentially result in some interesting locking patterns, especially when dealing with racing threads. I'd better double-check the `hci_sock_release` function in `net/bluetooth/hci_sock.c` to see if this is indeed the case. I need to understand the relationship between socket closure and device shutdown here.
|
| 21/2 |
2026/05/19 05:49 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_sock.c IncludeLines:true Name:hci_sock_release]
Results: map[SourceCode: 901: static int hci_sock_release(struct socket *sock)
902: {
903: struct sock *sk = sock->sk;
904: struct hci_dev *hdev;
905: struct sk_buff *skb;
906:
907: BT_DBG("sock %p sk %p", sock, sk);
908:
909: if (!sk)
910: return 0;
911:
912: lock_sock(sk);
913:
914: switch (hci_pi(sk)->channel) {
915: case HCI_CHANNEL_MONITOR:
916: atomic_dec(&monitor_promisc);
917: break;
918: case HCI_CHANNEL_RAW:
919: case HCI_CHANNEL_USER:
920: case HCI_CHANNEL_CONTROL:
921: /* Send event to monitor */
922: skb = create_monitor_ctrl_close(sk);
923: if (skb) {
924: hci_send_to_channel(HCI_CHANNEL_MONITOR, skb,
925: HCI_SOCK_TRUSTED, NULL);
926: kfree_skb(skb);
927: }
928:
929: hci_sock_free_cookie(sk);
930: break;
931: }
932:
933: bt_sock_unlink(&hci_sk_list, sk);
934:
935: hdev = hci_pi(sk)->hdev;
936: if (hdev) {
937: if (hci_pi(sk)->channel == HCI_CHANNEL_USER &&
938: !hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
939: /* When releasing a user channel exclusive access,
940: * call hci_dev_do_close directly instead of calling
941: * hci_dev_close to ensure the exclusive access will
942: * be released and the controller brought back down.
943: *
944: * The checking of HCI_AUTO_OFF is not needed in this
945: * case since it will have been cleared already when
946: * opening the user channel.
947: *
948: * Make sure to also check that we haven't already
949: * unregistered since all the cleanup will have already
950: * been complete and hdev will get released when we put
951: * below.
952: */
953: hci_dev_do_close(hdev);
954: hci_dev_clear_flag(hdev, HCI_USER_CHANNEL);
955: mgmt_index_added(hdev);
956: }
957:
958: atomic_dec(&hdev->promisc);
959: hci_dev_put(hdev);
960: }
961:
962: sock_orphan(sk);
963: release_sock(sk);
964: sock_put(sk);
965: return 0;
966: }
SourceFile:net/bluetooth/hci_sock.c]
|
| 22/2 |
2026/05/19 05:49 |
llm |
expert |
0m
Model:
Tokens:
input: 20770
output: 45
thoughts: 66
Thoughts: Here's my take on the thought process:
**Diving Deep into HCI Socket Release**
Okay, so I'm tracing the execution flow of `hci_sock_release`. It looks like it's pretty clear β it calls `hci_dev_do_close`. Wait a minute, I think I need to double-check that. I need to make sure I haven't missed anything. And, more importantly, let me see if that `hci_dev_do_close` function is actually calling `hci_dev_close_sync` as I believe it does. Let's start with `hci_dev_do_close` and verify that.
|
| 23/2 |
2026/05/19 05:49 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_core.c IncludeLines:true Name:hci_dev_do_close]
Results: map[SourceCode: 493: int hci_dev_do_close(struct hci_dev *hdev)
494: {
495: int err;
496:
497: BT_DBG("%s %p", hdev->name, hdev);
498:
499: hci_req_sync_lock(hdev);
500:
501: err = hci_dev_close_sync(hdev);
502:
503: hci_req_sync_unlock(hdev);
504:
505: return err;
506: }
SourceFile:net/bluetooth/hci_core.c]
|
| 24/2 |
2026/05/19 05:49 |
llm |
expert |
0m
Model:
Tokens:
input: 21229
output: 43
thoughts: 1105
Thoughts: **Debugging a Bluetooth Device Close Race Condition**
Okay, here's what I'm seeing. It looks like `hci_dev_do_close` is the culprit, calling `hci_req_sync_lock` and then `hci_dev_close_sync`. The problem seems to stem from the locking mechanism. `hci_req_sync_lock` is trying to take `hdev->req_lock`. However, the trace shows that `hci_cmd_sync_work` already *holds* `hdev->req_lock`. Specifically:
```
#2: ffff88807c668ec0 (&hdev->req_lock){+.+.}-{4:4}, at: hci_cmd_sync_work+0x1d3/0x400 net/bluetooth/hci_sync.c:331
```
`hci_cmd_sync_work` is running on `kworker/u9:3/5978`. This function executes `entry->func(hdev, entry->data)` while holding the lock. If `entry->func` blocks, `hci_cmd_sync_work` blocks while holding the lock.
Now, the trace shows a task `syz-executor:5969` blocked in `__flush_work`. The question is, what work is it trying to flush? `hci_dev_close_sync` *doesn't* directly flush `cmd_sync_work`. It does flush `tx_work`, `rx_work`, and `cmd_work`. However, `hci_cmd_sync_cancel_sync` (which is called by `hci_dev_close_sync`) also doesn't flush `cmd_sync_work`.
Let's look more closely at the trace:
```
wait_for_completion+0x2bf/0x5d0 kernel/sched/completion.c:153
__flush_work+0x9b9/0xbc0 kernel/workqueue.c:4281
get_signal+0x1285/0x1340 kernel/signal.c:3034
```
Okay, so `get_signal` calls `task_work_run`, which calls `fput`, and that, in turn, calls `hci_sock_release`, and finally, `hci_dev_do_close` again! This also calls `hci_req_sync_lock(hdev)`.
If `syz-executor` was directly blocked in `hci_req_sync_lock(hdev)`, it would be in `mutex_lock`, not `__flush_work`, so that's a dead end. However, `__flush_work` itself can block if it's waiting for a work item to complete. So, what if `syz-executor` is blocked in `__flush_work` called from `hci_dev_close_sync`? The important lines are:
```c
/* Flush RX and TX works */
flush_work(&hdev->tx_work);
flush_work(&hdev->rx_work);
...
/* flush cmd work */
flush_work(&hdev->cmd_work);
```
Wait! I see that `kworker/u9:10/11292` is holding `hdev->lock` and running `hdev->rx_work`:
```
3 locks held by kworker/u9:10/11292:
#0: ffff88801e7c1148 ((wq_completion)hci4#2){+.+.}-{0:0}, at: process_one_work+0x841/0x15a0 kernel/workqueue.c:3236
#1: ffffc9000c69fb80 ((work_completion)(&hdev->rx_work)){+.+.}-{0:0}, at: process_one_work+0x868/0x15a0 kernel/workqueue.c:3237
#2: ffff8880549000c0 (&hdev->lock){+.+.}-{4:4}, at: hci_event_packet+0x162/0x1260 net/bluetooth/hci_event.c:7736
```
So, `rx_work` is running and holding `hdev->lock`. If `syz-executor` is trying to flush `rx_work` *while* it's holding the lock, it will block until `
|
| 25/2 |
2026/05/19 05:49 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_event.c IncludeLines:true Name:hci_event_packet]
Results: map[SourceCode:7722: void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
7723: {
7724: struct hci_event_hdr *hdr = (void *) skb->data;
7725: hci_req_complete_t req_complete = NULL;
7726: hci_req_complete_skb_t req_complete_skb = NULL;
7727: struct sk_buff *orig_skb = NULL;
7728: u8 status = 0, event, req_evt = 0;
7729: u16 opcode = HCI_OP_NOP;
7730:
7731: if (skb->len < sizeof(*hdr)) {
7732: bt_dev_err(hdev, "Malformed HCI Event");
7733: goto done;
7734: }
7735:
7736: hci_dev_lock(hdev);
7737: kfree_skb(hdev->recv_event);
7738: hdev->recv_event = skb_clone(skb, GFP_KERNEL);
7739: hci_dev_unlock(hdev);
7740:
7741: event = hdr->evt;
7742: if (!event) {
7743: bt_dev_warn(hdev, "Received unexpected HCI Event 0x%2.2x",
7744: event);
7745: goto done;
7746: }
7747:
7748: /* Only match event if command OGF is not for LE */
7749: if (hdev->req_skb &&
7750: hci_opcode_ogf(hci_skb_opcode(hdev->req_skb)) != 0x08 &&
7751: hci_skb_event(hdev->req_skb) == event) {
7752: hci_req_cmd_complete(hdev, hci_skb_opcode(hdev->req_skb),
7753: status, &req_complete, &req_complete_skb);
7754: req_evt = event;
7755: }
7756:
7757: /* If it looks like we might end up having to call
7758: * req_complete_skb, store a pristine copy of the skb since the
7759: * various handlers may modify the original one through
7760: * skb_pull() calls, etc.
7761: */
7762: if (req_complete_skb || event == HCI_EV_CMD_STATUS ||
7763: event == HCI_EV_CMD_COMPLETE)
7764: orig_skb = skb_clone(skb, GFP_KERNEL);
7765:
7766: skb_pull(skb, HCI_EVENT_HDR_SIZE);
7767:
7768: /* Store wake reason if we're suspended */
7769: hci_store_wake_reason(hdev, event, skb);
7770:
7771: bt_dev_dbg(hdev, "event 0x%2.2x", event);
7772:
7773: hci_event_func(hdev, event, skb, &opcode, &status, &req_complete,
7774: &req_complete_skb);
7775:
7776: if (req_complete) {
7777: req_complete(hdev, status, opcode);
7778: } else if (req_complete_skb) {
7779: if (!hci_get_cmd_complete(hdev, opcode, req_evt, orig_skb)) {
7780: kfree_skb(orig_skb);
7781: orig_skb = NULL;
7782: }
7783: req_complete_skb(hdev, status, opcode, orig_skb);
7784: }
7785:
7786: done:
7787: kfree_skb(orig_skb);
7788: kfree_skb(skb);
7789: hdev->stat.evt_rx++;
7790: }
SourceFile:net/bluetooth/hci_event.c]
|
| 26/2 |
2026/05/19 05:49 |
llm |
expert |
0m
Model:
Tokens:
input: 24592
output: 25
thoughts: 2344
Thoughts: **Bluetooth HCI Locking Analysis: A Deep Dive**
Okay, so I'm looking at this trace and it seems like we've got a lock contention issue in the Bluetooth HCI layer. Let's see... the `hci_event_packet` function is trying to grab `hdev->lock` but is getting blocked. The trace shows it trying to acquire the lock at line 7736. Now, who's holding it? That's the key.
My initial thought was `hci_dev_close_sync` since it flushes work queues, and I see it taking the `hdev` lock, but no, on closer inspection, it doesn't hold the lock while it flushes `rx_work`. That's not the culprit. Hmm, who else? Let's check kworkers.
Ah, there are several kworkers. I see `hci_cmd_sync_work` holding `hdev->req_lock`. The trace *doesn't* show `hdev->lock` being held by this kworker. Could `entry->func` inside `hci_cmd_sync_work` be taking `hdev->lock`? But the trace *still* wouldn't show the `hdev->lock`.
Then I see `syz-executor:5969`, the fuzzer. It's blocked in `__flush_work`. But the fuzzer doesn't explicitly show holding *any* locks in the report, which is strange. I thought that maybe `syz-executor` holds `hci_req_sync_lock` (I was right!) when calling `hci_dev_close_sync`, but not directly `hdev->lock`. But I see `hdev->req_lock` being held by kworkers for other hci devices too. So, all good.
Wait a second. The trace is truncated! It seems it has a user space RIP, but the report *also* shows the kernel holding a lock. This doesn't make sense. If the process is blocked in kernel space, it has to be in kernel space.
Okay, let's step back. Let's look at those kworkers again. There are multiple `hci_cmd_sync_work` tasks running concurrently, all holding `hdev->req_lock`. It's likely `entry->func` is the blocker, which makes sense. If it blocks holding `hdev->lock`, that would explain this. But what *is* `entry->func`? I need to analyze the code paths for those function pointers.
|
| 27/2 |
2026/05/19 05:50 |
tool |
codesearch-find-references |
0m
Args: map[Name:hci_cmd_sync_work]
Results: map[References:[map[ReferenceKind:takes-address-of ReferencingEntityKind:function ReferencingEntityName:hci_cmd_sync_init SourceFile:net/bluetooth/hci_sync.c SourceLine:628]] TruncatedOutput:false]
|
| 28/2 |
2026/05/19 05:50 |
llm |
expert |
0m
Model:
Tokens:
input: 27587
output: 45
thoughts: 15
Thoughts: Okay, here's my attempt at summarizing that thought process, keeping in mind I'm speaking to a fellow expert:
**Investigating the `cmd_sync_work` Queueing Process**
Alright, let's dive into this. My immediate concern is understanding *precisely* how `cmd_sync_work` is being enqueued. Where's it originating from? What's the triggering mechanism? Is it a timer, an interrupt, a specific event in the system, or something else entirely? I need to trace its path from inception to its eventual placement in the relevant work queue.
I'm thinking, are there any potential race conditions I should be on the lookout for, given its nature as a synchronization primitive? Also, let's identify what priorities and constraints are associated with this queue. That will tell a lot about system-level design.
I'll be looking for clues about the work queue itself: What's the underlying data structure? How is concurrency managed within that queue? Are there any potential bottlenecks? Identifying these are crucial to avoiding performance problems.
|
| 29/2 |
2026/05/19 05:50 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_sync.c IncludeLines:true Name:hci_cmd_sync_queue]
Results: map[SourceCode: 735: /* Queue HCI command:
736: *
737: * - hdev must be running
738: */
739: int hci_cmd_sync_queue(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
740: void *data, hci_cmd_sync_work_destroy_t destroy)
741: {
742: /* Only queue command if hdev is running which means it had been opened
743: * and is either on init phase or is already up.
744: */
745: if (!test_bit(HCI_RUNNING, &hdev->flags))
746: return -ENETDOWN;
747:
748: return hci_cmd_sync_submit(hdev, func, data, destroy);
749: }
SourceFile:net/bluetooth/hci_sync.c]
|
| 30/2 |
2026/05/19 05:50 |
llm |
expert |
0m
Model:
Tokens:
input: 28144
output: 18
thoughts: 1216
Thoughts: **Analyzing a Bluetooth HCI Device Lock Contention**
Okay, so I'm looking at this `hci_cmd_sync_work` function, and it calls `entry->func` with the device handle (`hdev`) and data. What could `entry->func` possibly be? I need to figure out what's causing this hang, so I start by looking at what `syz-executor:5969` is up to. It's in `__flush_work`, called from `get_signal`, which, interestingly, calls `task_work_run`. So, what task work could be involved in flushing a work queue? I trace it down: `fput` -> `hci_sock_release` -> `hci_dev_do_close` -> `hci_dev_close_sync` -> `flush_work(&hdev->rx_work)`. So, if the syz executor is flushing `rx_work`, then `rx_work` must be blocked.
Now, let's look at `kworker/u9:10/11292`, the worker thread running `rx_work`. It's showing three held locks, but the important one is the lock on `hdev->lock` at the line 7736 of `hci_event_packet` in `net/bluetooth/hci_event.c`. So, `rx_work` is blocked, waiting for `hdev->lock`. That's the key. Who holds this lock?
I need to check if `syz-executor` holds `hdev->lock`. If `syz-executor` is in `hci_dev_close_sync`, I know that it *doesn't* hold `hdev->lock` when it calls `flush_work(&hdev->rx_work)`. I check `hci_dev_close_sync` again, and that's confirmed: `flush_work` is called *before* the lock is acquired. So, it's not holding the lock then.
Could `hci_cmd_sync_work` be the culprit? Does the function passed to `cmd_sync_work` take `hdev->lock`? Let's check. The worker running `cmd_sync_work` (`kworker/u9:3/5978`) *doesn't* show `hdev->lock` as being held, only `req_lock`. However, what if `entry->func` *is* blocked trying to acquire `hdev->lock`? Then it wouldn't show as held yet. But if no one holds it, why is `rx_work` blocked? Maybe the syz-executor *does* hold `hdev->lock`.
If `syz-executor` is in `hci_sock_release`, does *that* take `hdev->lock`? No, it doesn't. Now, what if `syz-executor` isn't in `hci_sock_release`? What if it's in *another* function that takes the `hdev->lock` and *then* flushes a work? I will need to search for `flush_work` in `net/bluetooth/` to see if there are other places where that's possible.
|
| 31/2 |
2026/05/19 05:50 |
tool |
grepper |
0m
Args: map[Expression:flush_work\(]
Results: map[Output:
Full output is too long, showing 500 out of 3565 lines.
Use more precise expression if possible.
[arch/s390/kernel/topology.c=348=void topology_schedule_update(void)
--
arch/s390/kernel/topology.c-352-
arch/s390/kernel/topology.c:353:static void topology_flush_work(void)
arch/s390/kernel/topology.c-354-{
arch/s390/kernel/topology.c:355: flush_work(&topology_work);
arch/s390/kernel/topology.c-356-}
--
arch/s390/kernel/topology.c=614=static int topology_ctl_handler(const struct ctl_table *ctl, int write,
--
arch/s390/kernel/topology.c-638- mutex_unlock(&smp_cpu_state_mutex);
arch/s390/kernel/topology.c:639: topology_flush_work();
arch/s390/kernel/topology.c-640-
--
arch/sh/drivers/push-switch.c=94=static void switch_drv_remove(struct platform_device *pdev)
--
arch/sh/drivers/push-switch.c-104- timer_shutdown_sync(&psw->debounce);
arch/sh/drivers/push-switch.c:105: flush_work(&psw->work);
arch/sh/drivers/push-switch.c-106- free_irq(irq, pdev);
--
arch/x86/kvm/i8254.c=234=static void destroy_pit_timer(struct kvm_pit *pit)
--
arch/x86/kvm/i8254.c-236- hrtimer_cancel(&pit->pit_state.timer);
arch/x86/kvm/i8254.c:237: kthread_flush_work(&pit->expired);
arch/x86/kvm/i8254.c-238-}
--
arch/x86/kvm/i8254.c=322=static void create_pit_timer(struct kvm_pit *pit, u32 val, int is_period)
--
arch/x86/kvm/i8254.c-337- hrtimer_cancel(&ps->timer);
arch/x86/kvm/i8254.c:338: kthread_flush_work(&pit->expired);
arch/x86/kvm/i8254.c-339- ps->period = interval;
--
block/blk-iolatency.c=635=static void blkcg_iolatency_exit(struct rq_qos *rqos)
--
block/blk-iolatency.c-639- timer_shutdown_sync(&blkiolat->timer);
block/blk-iolatency.c:640: flush_work(&blkiolat->enable_work);
block/blk-iolatency.c-641- blkcg_deactivate_policy(rqos->disk, &blkcg_policy_iolatency);
--
crypto/algapi.c=579=void crypto_unregister_template(struct crypto_template *tmpl)
--
crypto/algapi.c-605-
crypto/algapi.c:606: flush_work(&tmpl->free_work);
crypto/algapi.c-607-}
--
crypto/scompress.c=290=static void crypto_exit_scomp_ops_async(struct crypto_tfm *tfm)
--
crypto/scompress.c-295-
crypto/scompress.c:296: flush_work(&scomp_scratch_work);
crypto/scompress.c-297- mutex_lock(&scomp_lock);
--
drivers/accel/ivpu/ivpu_debugfs.c=326=ivpu_force_recovery_fn(struct file *file, const char __user *user_buf, size_t size, loff_t *pos)
--
drivers/accel/ivpu/ivpu_debugfs.c-338- ivpu_pm_trigger_recovery(vdev, "debugfs");
drivers/accel/ivpu/ivpu_debugfs.c:339: flush_work(&vdev->pm->recovery_work);
drivers/accel/ivpu/ivpu_debugfs.c-340- ivpu_rpm_put(vdev);
--
drivers/accel/ivpu/ivpu_drv.c=428=void ivpu_prepare_for_reset(struct ivpu_device *vdev)
--
drivers/accel/ivpu/ivpu_drv.c-431- disable_irq(vdev->irq);
drivers/accel/ivpu/ivpu_drv.c:432: flush_work(&vdev->irq_ipc_work);
drivers/accel/ivpu/ivpu_drv.c:433: flush_work(&vdev->irq_dct_work);
drivers/accel/ivpu/ivpu_drv.c:434: flush_work(&vdev->context_abort_work);
drivers/accel/ivpu/ivpu_drv.c-435- ivpu_ipc_disable(vdev);
--
drivers/acpi/ec.c=528=static void acpi_ec_enable_event(struct acpi_ec *ec)
--
drivers/acpi/ec.c-542-#ifdef CONFIG_PM_SLEEP
drivers/acpi/ec.c:543:static void __acpi_ec_flush_work(void)
drivers/acpi/ec.c-544-{
--
drivers/acpi/ec.c=549=static void acpi_ec_disable_event(struct acpi_ec *ec)
--
drivers/acpi/ec.c-560- */
drivers/acpi/ec.c:561: __acpi_ec_flush_work();
drivers/acpi/ec.c-562-}
drivers/acpi/ec.c-563-
drivers/acpi/ec.c:564:void acpi_ec_flush_work(void)
drivers/acpi/ec.c-565-{
--
drivers/acpi/ec.c-569-
drivers/acpi/ec.c:570: __acpi_ec_flush_work();
drivers/acpi/ec.c-571-}
--
drivers/acpi/ec.c=2163=bool acpi_ec_dispatch_gpe(void)
--
drivers/acpi/ec.c-2208- do {
drivers/acpi/ec.c:2209: acpi_ec_flush_work();
drivers/acpi/ec.c-2210-
--
drivers/acpi/internal.h=235=void acpi_ec_register_opregions(struct acpi_device *adev);
--
drivers/acpi/internal.h-237-#ifdef CONFIG_PM_SLEEP
drivers/acpi/internal.h:238:void acpi_ec_flush_work(void);
drivers/acpi/internal.h-239-bool acpi_ec_dispatch_gpe(void);
--
drivers/acpi/internal.h=256=static inline void acpi_ec_register_opregions(struct acpi_device *adev) {}
drivers/acpi/internal.h-257-
drivers/acpi/internal.h:258:static inline void acpi_ec_flush_work(void) {}
drivers/acpi/internal.h-259-static inline bool acpi_ec_dispatch_gpe(void)
--
drivers/acpi/sleep.c=813=void acpi_s2idle_restore(void)
--
drivers/acpi/sleep.c-819- acpi_os_wait_events_complete(); /* synchronize GPE processing */
drivers/acpi/sleep.c:820: acpi_ec_flush_work(); /* flush the EC driver's workqueues */
drivers/acpi/sleep.c-821- acpi_os_wait_events_complete(); /* synchronize Notify handling */
--
drivers/base/dd.c=305=static void deferred_probe_timeout_work_func(struct work_struct *work)
--
drivers/base/dd.c-312- driver_deferred_probe_trigger();
drivers/base/dd.c:313: flush_work(&deferred_probe_work);
drivers/base/dd.c-314-
--
drivers/base/dd.c=345=static int deferred_probe_initcall(void)
--
drivers/base/dd.c-352- /* Sort as many dependencies as possible before exiting initcalls */
drivers/base/dd.c:353: flush_work(&deferred_probe_work);
drivers/base/dd.c-354- initcalls_done = true;
--
drivers/base/dd.c-363- driver_deferred_probe_trigger();
drivers/base/dd.c:364: flush_work(&deferred_probe_work);
drivers/base/dd.c-365-
--
drivers/base/dd.c=769=void wait_for_device_probe(void)
--
drivers/base/dd.c-771- /* wait for the deferred probe workqueue to finish */
drivers/base/dd.c:772: flush_work(&deferred_probe_work);
drivers/base/dd.c-773-
--
drivers/base/firmware_loader/sysfs_upload.c=388=void firmware_upload_unregister(struct fw_upload *fw_upload)
--
drivers/base/firmware_loader/sysfs_upload.c-403- /* Ensure lower-level device-driver is finished */
drivers/base/firmware_loader/sysfs_upload.c:404: flush_work(&fw_upload_priv->work);
drivers/base/firmware_loader/sysfs_upload.c-405-
--
drivers/block/sunvdc.c=1065=static void vdc_port_remove(struct vio_dev *vdev)
--
drivers/block/sunvdc.c-1071-
drivers/block/sunvdc.c:1072: flush_work(&port->ldc_reset_work);
drivers/block/sunvdc.c-1073- cancel_delayed_work_sync(&port->ldc_reset_timer_work);
--
drivers/block/virtio_blk.c=1562=static void virtblk_remove(struct virtio_device *vdev)
--
drivers/block/virtio_blk.c-1566- /* Make sure no work handler is accessing the device. */
drivers/block/virtio_blk.c:1567: flush_work(&vblk->config_work);
drivers/block/virtio_blk.c-1568-
--
drivers/block/virtio_blk.c=1588=static int virtblk_freeze_priv(struct virtio_device *vdev)
--
drivers/block/virtio_blk.c-1602- /* Make sure no work handler is accessing the device. */
drivers/block/virtio_blk.c:1603: flush_work(&vblk->config_work);
drivers/block/virtio_blk.c-1604-
--
drivers/block/xen-blkback/blkback.c=554=int xen_blkif_schedule(void *arg)
--
drivers/block/xen-blkback/blkback.c-622- /* Drain pending purge work */
drivers/block/xen-blkback/blkback.c:623: flush_work(&ring->persistent_purge_work);
drivers/block/xen-blkback/blkback.c-624-
--
drivers/block/xen-blkfront.c=1207=static void blkif_free_ring(struct blkfront_ring_info *rinfo)
--
drivers/block/xen-blkfront.c-1289- /* Flush gnttab callback work. Must be done with no locks held. */
drivers/block/xen-blkfront.c:1290: flush_work(&rinfo->work);
drivers/block/xen-blkfront.c-1291-
--
drivers/block/xen-blkfront.c=2122=static void blkfront_closing(struct blkfront_info *info)
--
drivers/block/xen-blkfront.c-2141- /* Flush gnttab callback work. Must be done with no locks held. */
drivers/block/xen-blkfront.c:2142: flush_work(&rinfo->work);
drivers/block/xen-blkfront.c-2143- }
--
drivers/block/zram/zram_drv.c=1341=static int read_from_bdev_sync(struct zram *zram, struct page *page,
--
drivers/block/zram/zram_drv.c-1351- queue_work(system_dfl_wq, &work.work);
drivers/block/zram/zram_drv.c:1352: flush_work(&work.work);
drivers/block/zram/zram_drv.c-1353- destroy_work_on_stack(&work.work);
--
drivers/bluetooth/btintel_pcie.c=2248=static void btintel_pcie_removal_work(struct work_struct *wk)
--
drivers/bluetooth/btintel_pcie.c-2265-
drivers/bluetooth/btintel_pcie.c:2266: flush_work(&data->rx_work);
drivers/bluetooth/btintel_pcie.c-2267-
--
drivers/bluetooth/btintel_pcie.c=2539=static void btintel_pcie_remove(struct pci_dev *pdev)
--
drivers/bluetooth/btintel_pcie.c-2548-
drivers/bluetooth/btintel_pcie.c:2549: flush_work(&data->rx_work);
drivers/bluetooth/btintel_pcie.c-2550-
--
drivers/bluetooth/btnxpuart.c=420=static void ps_cancel_timer(struct btnxpuart_dev *nxpdev)
--
drivers/bluetooth/btnxpuart.c-423-
drivers/bluetooth/btnxpuart.c:424: flush_work(&psdata->work);
drivers/bluetooth/btnxpuart.c-425- timer_shutdown_sync(&psdata->ps_timer);
--
drivers/bluetooth/hci_vhci.c=677=static int vhci_release(struct inode *inode, struct file *file)
--
drivers/bluetooth/hci_vhci.c-682- cancel_delayed_work_sync(&data->open_timeout);
drivers/bluetooth/hci_vhci.c:683: flush_work(&data->suspend_work);
drivers/bluetooth/hci_vhci.c-684-
--
drivers/bus/mhi/host/pci_generic.c=1685=static int __maybe_unused mhi_pci_freeze(struct device *dev)
--
drivers/bus/mhi/host/pci_generic.c-1694- */
drivers/bus/mhi/host/pci_generic.c:1695: flush_work(&mhi_pdev->recovery_work);
drivers/bus/mhi/host/pci_generic.c-1696- if (test_and_clear_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status)) {
--
drivers/bus/mhi/host/pm.c=1212=static void __mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful,
--
drivers/bus/mhi/host/pm.c-1258- /* Wait for shutdown to complete */
drivers/bus/mhi/host/pm.c:1259: flush_work(&mhi_cntrl->st_worker);
drivers/bus/mhi/host/pm.c-1260-
--
drivers/cdx/controller/cdx_rpmsg.c=149=static void cdx_rpmsg_remove(struct rpmsg_device *rpdev)
--
drivers/cdx/controller/cdx_rpmsg.c-153-
drivers/cdx/controller/cdx_rpmsg.c:154: flush_work(&cdx_mcdi->work);
drivers/cdx/controller/cdx_rpmsg.c-155- cdx_rpmsg_pre_remove(cdx_c);
--
drivers/char/sonypi.c=1411=static void sonypi_remove(struct platform_device *dev)
--
drivers/char/sonypi.c-1415- synchronize_irq(sonypi_device.irq);
drivers/char/sonypi.c:1416: flush_work(&sonypi_device.input_work);
drivers/char/sonypi.c-1417-
--
drivers/char/tpm/tpm-dev-common.c=130=ssize_t tpm_common_read(struct file *file, char __user *buf,
--
drivers/char/tpm/tpm-dev-common.c-163- timer_delete_sync(&priv->user_read_timer);
drivers/char/tpm/tpm-dev-common.c:164: flush_work(&priv->timeout_work);
drivers/char/tpm/tpm-dev-common.c-165- }
--
drivers/char/tpm/tpm-dev-common.c=267=void tpm_common_release(struct file *file, struct file_priv *priv)
drivers/char/tpm/tpm-dev-common.c-268-{
drivers/char/tpm/tpm-dev-common.c:269: flush_work(&priv->async_work);
drivers/char/tpm/tpm-dev-common.c-270- timer_delete_sync(&priv->user_read_timer);
drivers/char/tpm/tpm-dev-common.c:271: flush_work(&priv->timeout_work);
drivers/char/tpm/tpm-dev-common.c-272- file->private_data = NULL;
--
drivers/char/tpm/tpm_tis_core.c=1016=void tpm_tis_remove(struct tpm_chip *chip)
--
drivers/char/tpm/tpm_tis_core.c-1030- if (priv->free_irq_work.func)
drivers/char/tpm/tpm_tis_core.c:1031: flush_work(&priv->free_irq_work);
drivers/char/tpm/tpm_tis_core.c-1032-
--
drivers/char/tpm/tpm_vtpm_proxy.c=471=static void vtpm_proxy_work_stop(struct proxy_dev *proxy_dev)
--
drivers/char/tpm/tpm_vtpm_proxy.c-473- vtpm_proxy_fops_undo_open(proxy_dev);
drivers/char/tpm/tpm_vtpm_proxy.c:474: flush_work(&proxy_dev->work);
drivers/char/tpm/tpm_vtpm_proxy.c-475-}
--
drivers/char/virtio_console.c=1902=static void virtcons_remove(struct virtio_device *vdev)
--
drivers/char/virtio_console.c-1915- if (use_multiport(portdev))
drivers/char/virtio_console.c:1916: flush_work(&portdev->control_work);
drivers/char/virtio_console.c-1917- else
drivers/char/virtio_console.c:1918: flush_work(&portdev->config_work);
drivers/char/virtio_console.c-1919-
--
drivers/char/xillybus/xillyusb.c=636=static void safely_assign_in_fifo(struct xillyusb_channel *chan,
--
drivers/char/xillybus/xillyusb.c-642-
drivers/char/xillybus/xillyusb.c:643: flush_work(&chan->xdev->in_ep->workitem);
drivers/char/xillybus/xillyusb.c-644-}
--
drivers/char/xillybus/xillyusb.c=2001=static int xillyusb_discovery(struct usb_interface *interface)
--
drivers/char/xillybus/xillyusb.c-2117- flush_workqueue(xdev->workq);
drivers/char/xillybus/xillyusb.c:2118: flush_work(&xdev->wakeup_workitem);
drivers/char/xillybus/xillyusb.c-2119-
--
drivers/cpufreq/tegra194-cpufreq.c=320=static unsigned int tegra194_calculate_speed(u32 cpu)
--
drivers/cpufreq/tegra194-cpufreq.c-334- queue_work_on(cpu, read_counters_wq, &read_counters_work.work);
drivers/cpufreq/tegra194-cpufreq.c:335: flush_work(&read_counters_work.work);
drivers/cpufreq/tegra194-cpufreq.c-336- c = read_counters_work.c;
--
drivers/crypto/caam/caamrng.c=166=static void caam_cleanup(struct hwrng *rng)
--
drivers/crypto/caam/caamrng.c-169-
drivers/crypto/caam/caamrng.c:170: flush_work(&ctx->worker);
drivers/crypto/caam/caamrng.c-171- caam_jr_free(ctx->jrdev);
--
drivers/crypto/cavium/nitrox/nitrox_common.h=23=int nitrox_process_se_request(struct nitrox_device *ndev,
--
drivers/crypto/cavium/nitrox/nitrox_common.h-26- void *cb_arg);
drivers/crypto/cavium/nitrox/nitrox_common.h:27:void backlog_qflush_work(struct work_struct *work);
drivers/crypto/cavium/nitrox/nitrox_common.h-28-
--
drivers/crypto/cavium/nitrox/nitrox_reqmgr.c=500=static inline int cmd_timeout(unsigned long tstamp, unsigned long timeout)
--
drivers/crypto/cavium/nitrox/nitrox_reqmgr.c-504-
drivers/crypto/cavium/nitrox/nitrox_reqmgr.c:505:void backlog_qflush_work(struct work_struct *work)
drivers/crypto/cavium/nitrox/nitrox_reqmgr.c-506-{
--
drivers/crypto/hisilicon/qm.c=2901=void hisi_qm_wait_task_finish(struct hisi_qm *qm, struct hisi_qm_list *qm_list)
--
drivers/crypto/hisilicon/qm.c-2913- if (test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps))
drivers/crypto/hisilicon/qm.c:2914: flush_work(&qm->cmd_process);
drivers/crypto/hisilicon/qm.c-2915-
--
drivers/crypto/virtio/virtio_crypto_core.c=489=static void virtcrypto_remove(struct virtio_device *vdev)
--
drivers/crypto/virtio/virtio_crypto_core.c-495-
drivers/crypto/virtio/virtio_crypto_core.c:496: flush_work(&vcrypto->config_work);
drivers/crypto/virtio/virtio_crypto_core.c-497- if (virtcrypto_dev_started(vcrypto))
--
drivers/crypto/virtio/virtio_crypto_core.c=517=static int virtcrypto_freeze(struct virtio_device *vdev)
--
drivers/crypto/virtio/virtio_crypto_core.c-520-
drivers/crypto/virtio/virtio_crypto_core.c:521: flush_work(&vcrypto->config_work);
drivers/crypto/virtio/virtio_crypto_core.c-522- virtio_reset_device(vdev);
--
drivers/dma/imx-sdma.c=1228=static void sdma_channel_synchronize(struct dma_chan *chan)
--
drivers/dma/imx-sdma.c-1233-
drivers/dma/imx-sdma.c:1234: flush_work(&sdmac->terminate_worker);
drivers/dma/imx-sdma.c-1235-}
--
drivers/edac/igen6_edac.c=1545=static void igen6_remove(struct pci_dev *pdev)
--
drivers/edac/igen6_edac.c-1552- irq_work_sync(&ecclog_irq_work);
drivers/edac/igen6_edac.c:1553: flush_work(&ecclog_work);
drivers/edac/igen6_edac.c-1554- gen_pool_destroy(ecclog_pool);
--
drivers/extcon/extcon-axp288.c=363=static int axp288_extcon_probe(struct platform_device *pdev)
--
drivers/extcon/extcon-axp288.c-464- queue_work(system_long_wq, &info->role_work);
drivers/extcon/extcon-axp288.c:465: flush_work(&info->role_work);
drivers/extcon/extcon-axp288.c-466- }
--
drivers/firewire/ohci.c=2411=static void ohci_disable(struct fw_card *card)
--
drivers/firewire/ohci.c-2427-
drivers/firewire/ohci.c:2428: flush_work(&ohci->ar_request_ctx.work);
drivers/firewire/ohci.c:2429: flush_work(&ohci->ar_response_ctx.work);
drivers/firewire/ohci.c:2430: flush_work(&ohci->at_request_ctx.work);
drivers/firewire/ohci.c:2431: flush_work(&ohci->at_response_ctx.work);
drivers/firewire/ohci.c-2432-
--
drivers/firewire/ohci.c-2434- if (!(ohci->ir_context_mask & BIT(i)))
drivers/firewire/ohci.c:2435: flush_work(&ohci->ir_context_list[i].base.work);
drivers/firewire/ohci.c-2436- }
--
drivers/firewire/ohci.c-2438- if (!(ohci->it_context_mask & BIT(i)))
drivers/firewire/ohci.c:2439: flush_work(&ohci->it_context_list[i].base.work);
drivers/firewire/ohci.c-2440- }
--
drivers/gpu/drm/amd/amdgpu/aldebaran.c=152=aldebaran_mode2_perform_reset(struct amdgpu_reset_control *reset_ctl,
--
drivers/gpu/drm/amd/amdgpu/aldebaran.c-198- if (tmp_adev->gmc.xgmi.num_physical_nodes > 1) {
drivers/gpu/drm/amd/amdgpu/aldebaran.c:199: flush_work(&tmp_adev->reset_cntl->reset_work);
drivers/gpu/drm/amd/amdgpu/aldebaran.c-200- r = tmp_adev->asic_reset_res;
--
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c=6144=int amdgpu_do_asic_reset(struct list_head *device_list_handle,
--
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c-6194- if (tmp_adev->gmc.xgmi.num_physical_nodes > 1) {
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:6195: flush_work(&tmp_adev->xgmi_reset_work);
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c-6196- r = tmp_adev->asic_reset_res;
--
drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c=913=static int gpu_recover_get(void *data, u64 *val)
--
drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c-925- if (amdgpu_reset_domain_schedule(adev->reset_domain, &adev->reset_work))
drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:926: flush_work(&adev->reset_work);
drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c-927-
--
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c=3652=static int amdgpu_ras_poison_consumption_handler(struct amdgpu_device *adev,
--
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c-3693- /* Wait for gpu recovery to complete */
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c:3694: flush_work(&con->recovery_work);
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c-3695- }
--
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c=5067=int amdgpu_ras_reset_gpu(struct amdgpu_device *adev)
--
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c-5093- } else {
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c:5094: flush_work(&ras->recovery_work);
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c-5095- amdgpu_reset_domain_schedule(ras->adev->reset_domain, &ras->recovery_work);
--
drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c=99=static int amdgpu_reset_xgmi_reset_on_init_perform_reset(
--
drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c-131- list_for_each_entry(tmp_adev, reset_device_list, reset_list) {
drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c:132: flush_work(&tmp_adev->xgmi_reset_work);
drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c-133- r = tmp_adev->asic_reset_res;
--
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c=85=static void amdgpu_userq_gpu_reset(struct amdgpu_device *adev)
--
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c-90- /* Wait for the reset job to complete */
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c:91: flush_work(&adev->userq_reset_work);
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c-92- }
--
drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c=1671=int amdgpu_xgmi_reset_on_init(struct amdgpu_device *adev)
--
drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c-1692- if (reset_scheduled)
drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c:1693: flush_work(&hive->reset_on_init_work);
drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c-1694-
--
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c=1045=static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep,
--
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c-1063- */
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c:1064: svm_range_list_lock_and_flush_work(&p->svms, current->mm);
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c-1065- mutex_lock(&p->svms.lock);
--
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c=3419=int suspend_queues(struct kfd_process *p,
--
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c-3522-
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c:3523: flush_work(©_context_worker.copy_context_work);
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c-3524- destroy_work_on_stack(©_context_worker.copy_context_work);
--
drivers/gpu/drm/amd/amdkfd/kfd_process.c=328=static ssize_t kfd_procfs_show(struct kobject *kobj, struct attribute *attr,
--
drivers/gpu/drm/amd/amdkfd/kfd_process.c-349-
drivers/gpu/drm/amd/amdkfd/kfd_process.c:350: flush_work(&sdma_activity_work_handler.sdma_activity_work);
drivers/gpu/drm/amd/amdkfd/kfd_process.c-351- destroy_work_on_stack(&sdma_activity_work_handler.sdma_activity_work);
--
drivers/gpu/drm/amd/amdkfd/kfd_process.c=2266=int kfd_send_exception_to_runtime(struct kfd_process *p,
--
drivers/gpu/drm/amd/amdkfd/kfd_process.c-2278- schedule_work(&worker.work);
drivers/gpu/drm/amd/amdkfd/kfd_process.c:2279: flush_work(&worker.work);
drivers/gpu/drm/amd/amdkfd/kfd_process.c-2280- destroy_work_on_stack(&worker.work);
--
drivers/gpu/drm/amd/amdkfd/kfd_svm.c=1818=void
drivers/gpu/drm/amd/amdkfd/kfd_svm.c:1819:svm_range_list_lock_and_flush_work(struct svm_range_list *svms,
drivers/gpu/drm/amd/amdkfd/kfd_svm.c-1820- struct mm_struct *mm)
--
drivers/gpu/drm/amd/amdkfd/kfd_svm.c-1822-retry_flush_work:
drivers/gpu/drm/amd/amdkfd/kfd_svm.c:1823: flush_work(&svms->deferred_list_work);
drivers/gpu/drm/amd/amdkfd/kfd_svm.c-1824- mmap_write_lock(mm);
--
drivers/gpu/drm/amd/amdkfd/kfd_svm.c=1833=static void svm_range_restore_work(struct work_struct *work)
--
drivers/gpu/drm/amd/amdkfd/kfd_svm.c-1862- mutex_lock(&process_info->lock);
drivers/gpu/drm/amd/amdkfd/kfd_svm.c:1863: svm_range_list_lock_and_flush_work(svms, mm);
drivers/gpu/drm/amd/amdkfd/kfd_svm.c-1864- mutex_lock(&svms->lock);
--
drivers/gpu/drm/amd/amdkfd/kfd_svm.c=3264=void svm_range_list_fini(struct kfd_process *p)
--
drivers/gpu/drm/amd/amdkfd/kfd_svm.c-3274- /* Ensure list work is finished before process is destroyed */
drivers/gpu/drm/amd/amdkfd/kfd_svm.c:3275: flush_work(&p->svms.deferred_list_work);
drivers/gpu/drm/amd/amdkfd/kfd_svm.c-3276-
--
drivers/gpu/drm/amd/amdkfd/kfd_svm.c=3641=svm_range_set_attr(struct kfd_process *p, struct mm_struct *mm,
--
drivers/gpu/drm/amd/amdkfd/kfd_svm.c-3667-
drivers/gpu/drm/amd/amdkfd/kfd_svm.c:3668: svm_range_list_lock_and_flush_work(svms, mm);
drivers/gpu/drm/amd/amdkfd/kfd_svm.c-3669-
--
drivers/gpu/drm/amd/amdkfd/kfd_svm.c=3775=svm_range_get_attr(struct kfd_process *p, struct mm_struct *mm,
--
drivers/gpu/drm/amd/amdkfd/kfd_svm.c-3807- */
drivers/gpu/drm/amd/amdkfd/kfd_svm.c:3808: flush_work(&p->svms.deferred_list_work);
drivers/gpu/drm/amd/amdkfd/kfd_svm.c-3809-
--
drivers/gpu/drm/amd/amdkfd/kfd_svm.h=197=svm_range_get_pdd_by_node(struct svm_range *prange, struct kfd_node *node);
drivers/gpu/drm/amd/amdkfd/kfd_svm.h:198:void svm_range_list_lock_and_flush_work(struct svm_range_list *svms, struct mm_struct *mm);
drivers/gpu/drm/amd/amdkfd/kfd_svm.h-199-
--
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c=2225=static void amdgpu_dm_fini(struct amdgpu_device *adev)
--
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c-2236- adev->dm.idle_workqueue->enable = false;
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c:2237: flush_work(&adev->dm.idle_workqueue->work);
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c-2238- }
--
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c-2249- if (adev->dm.secure_display_ctx.crtc_ctx[i].crtc) {
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c:2250: flush_work(&adev->dm.secure_display_ctx.crtc_ctx[i].notify_ta_work);
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c:2251: flush_work(&adev->dm.secure_display_ctx.crtc_ctx[i].forward_roi_work);
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c-2252- }
--
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c=295=static void amdgpu_dm_set_crc_window_default(struct drm_crtc *crtc, struct dc_stream_state *stream)
--
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c-322- /* stop ROI update on this crtc */
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c:323: flush_work(&dm->secure_display_ctx.crtc_ctx[crtc->index].notify_ta_work);
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c:324: flush_work(&dm->secure_display_ctx.crtc_ctx[crtc->index].forward_roi_work);
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c-325- aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
--
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c=445=void amdgpu_dm_irq_fini(struct amdgpu_device *adev)
--
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c-468- list);
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c:469: flush_work(&handler->work);
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c-470- }
--
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c=477=void amdgpu_dm_irq_suspend(struct amdgpu_device *adev)
--
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c-508- list);
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c:509: flush_work(&handler->work);
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c-510- }
--
drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c=3028=static int kv_dpm_sw_fini(struct amdgpu_ip_block *ip_block)
--
drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c-3031-
drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c:3032: flush_work(&adev->pm.dpm.thermal.work);
drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c-3033-
--
drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c=7813=static int si_dpm_sw_fini(struct amdgpu_ip_block *ip_block)
--
drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c-7816-
drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c:7817: flush_work(&adev->pm.dpm.thermal.work);
drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c-7818-
--
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c=2528=static void cdns_mhdp_remove(struct platform_device *pdev)
--
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c-2561- cancel_work_sync(&mhdp->modeset_retry_work);
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c:2562: flush_work(&mhdp->hpd_work);
]
]
|
| 32/2 |
2026/05/19 05:50 |
llm |
expert |
0m
Model:
Tokens:
input: 41554
output: 22
thoughts: 321
Thoughts: **Analyzing a Potential Race Condition in HCI Device Closure**
Okay, so I'm digging into this `hci_dev_close_sync` function, and it's calling `flush_work(&hdev->rx_work)`. My immediate thought is, "Hang on, `rx_work` could be blocked on `hci_dev_lock(hdev)`." That sets off alarm bells because if the `rx_work` is waiting for a lock held elsewhere, we need to know where and how the lock is released. Who *holds* `hdev->lock` in this scenario? This smells like a potential deadlock, and I need to be thorough.
My next step is to examine `hci_cmd_sync_work` because that seems related to the work queue. The code reveals a `mutex_lock(&hdev->cmd_sync_work_lock)` around the work queue. Then I see on lines 331-332 `hci_req_sync_lock(hdev)` is called, which, as I recall, takes `hdev->req_lock`. Now, the key is the `entry->func` call. What if this `entry->func` *also* attempts to take `hdev->lock`? That's the critical piece.
I need to identify which functions are being passed to this work queue. I'll search for every instance of `entry->func` to determine functions that may also acquire `hdev->lock`, especially those within the `hci_cmd_sync_work_list`. Perhaps `hci_cmd_sync_cancel_sync` could be a culprit. No, that one isn't a work function, so that's a dead end. Okay, back to the basics: let's re-examine what functions are passed to `hci_cmd_sync_queue`.
|
| 33/2 |
2026/05/19 05:50 |
tool |
grepper |
0m
Args: map[Expression:hci_cmd_sync_queue\(]
Results: map[Output:drivers/bluetooth/btmtk.c=362=void btmtk_reset_sync(struct hci_dev *hdev)
--
drivers/bluetooth/btmtk.c-368-
drivers/bluetooth/btmtk.c:369: err = hci_cmd_sync_queue(hdev, reset_work->reset_sync, NULL, NULL);
drivers/bluetooth/btmtk.c-370- if (err)
--
drivers/bluetooth/btnxpuart.c=372=static struct sk_buff *nxp_drv_send_cmd(struct hci_dev *hdev, u16 opcode,
--
drivers/bluetooth/btnxpuart.c-381- /* set flag to prevent nxp_enqueue from parsing values from this command and
drivers/bluetooth/btnxpuart.c:382: * calling hci_cmd_sync_queue() again.
drivers/bluetooth/btnxpuart.c-383- */
--
drivers/bluetooth/btnxpuart.c=1563=static int nxp_enqueue(struct hci_dev *hdev, struct sk_buff *skb)
--
drivers/bluetooth/btnxpuart.c-1594- psdata->c2h_ps_interval = __le16_to_cpu(ps_parm.c2h_ps_interval);
drivers/bluetooth/btnxpuart.c:1595: hci_cmd_sync_queue(hdev, send_ps_cmd, NULL, NULL);
drivers/bluetooth/btnxpuart.c-1596- goto free_skb;
--
drivers/bluetooth/btnxpuart.c-1616- }
drivers/bluetooth/btnxpuart.c:1617: hci_cmd_sync_queue(hdev, send_wakeup_method_cmd, NULL, NULL);
drivers/bluetooth/btnxpuart.c-1618- goto free_skb;
--
drivers/bluetooth/btnxpuart.c-1624- nxpdev->new_baudrate = __le32_to_cpu(baudrate_parm);
drivers/bluetooth/btnxpuart.c:1625: hci_cmd_sync_queue(hdev, nxp_set_baudrate_cmd, NULL, NULL);
drivers/bluetooth/btnxpuart.c-1626- goto free_skb;
--
drivers/bluetooth/btnxpuart.c-1630- if (hdr->plen == 1) {
drivers/bluetooth/btnxpuart.c:1631: hci_cmd_sync_queue(hdev, nxp_set_ind_reset, NULL, NULL);
drivers/bluetooth/btnxpuart.c-1632- goto free_skb;
--
include/net/bluetooth/hci_sync.h=70=int hci_cmd_sync_submit(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
include/net/bluetooth/hci_sync.h-71- void *data, hci_cmd_sync_work_destroy_t destroy);
include/net/bluetooth/hci_sync.h:72:int hci_cmd_sync_queue(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
include/net/bluetooth/hci_sync.h-73- void *data, hci_cmd_sync_work_destroy_t destroy);
--
net/bluetooth/hci_conn.c=459=bool hci_setup_sync(struct hci_conn *conn, __u16 handle)
--
net/bluetooth/hci_conn.c-471- conn_handle->handle = handle;
net/bluetooth/hci_conn.c:472: result = hci_cmd_sync_queue(conn->hdev, hci_enhanced_setup_sync,
net/bluetooth/hci_conn.c-473- conn_handle, NULL);
--
net/bluetooth/hci_conn.c=721=static int hci_le_terminate_big(struct hci_dev *hdev, struct hci_conn *conn)
--
net/bluetooth/hci_conn.c-736-
net/bluetooth/hci_conn.c:737: ret = hci_cmd_sync_queue(hdev, terminate_big_sync, d,
net/bluetooth/hci_conn.c-738- terminate_big_destroy);
--
net/bluetooth/hci_conn.c=772=static int hci_le_big_terminate(struct hci_dev *hdev, struct hci_conn *conn)
--
net/bluetooth/hci_conn.c-808-
net/bluetooth/hci_conn.c:809: ret = hci_cmd_sync_queue(hdev, big_terminate_sync, d,
net/bluetooth/hci_conn.c-810- terminate_big_destroy);
--
net/bluetooth/hci_conn.c=871=static int hci_le_remove_cig(struct hci_dev *hdev, u8 handle)
--
net/bluetooth/hci_conn.c-874-
net/bluetooth/hci_conn.c:875: return hci_cmd_sync_queue(hdev, remove_cig_sync, UINT_PTR(handle),
net/bluetooth/hci_conn.c-876- NULL);
--
net/bluetooth/hci_conn.c=1889=static bool hci_le_set_cig_params(struct hci_conn *conn, struct bt_iso_qos *qos)
--
net/bluetooth/hci_conn.c-1940-done:
net/bluetooth/hci_conn.c:1941: if (hci_cmd_sync_queue(hdev, set_cig_params_sync,
net/bluetooth/hci_conn.c-1942- UINT_PTR(qos->ucast.cig), NULL) < 0)
--
net/bluetooth/hci_conn.c=2066=int hci_le_create_cis_pending(struct hci_dev *hdev)
--
net/bluetooth/hci_conn.c-2088- /* Queue Create CIS */
net/bluetooth/hci_conn.c:2089: return hci_cmd_sync_queue(hdev, hci_create_cis_sync, NULL, NULL);
net/bluetooth/hci_conn.c-2090-}
--
net/bluetooth/hci_conn.c=2287=struct hci_conn *hci_connect_bis(struct hci_dev *hdev, bdaddr_t *dst,
--
net/bluetooth/hci_conn.c-2327- /* Queue start periodic advertising and create BIG */
net/bluetooth/hci_conn.c:2328: err = hci_cmd_sync_queue(hdev, create_big_sync, conn,
net/bluetooth/hci_conn.c-2329- create_big_complete);
--
net/bluetooth/hci_event.c=7010=static void hci_le_create_big_complete_evt(struct hci_dev *hdev, void *data,
--
net/bluetooth/hci_event.c-7051- */
net/bluetooth/hci_event.c:7052: hci_cmd_sync_queue(hdev, hci_iso_term_big_sync,
net/bluetooth/hci_event.c-7053- UINT_PTR(ev->handle), NULL);
--
net/bluetooth/hci_sync.c=364=static void le_scan_disable(struct work_struct *work)
--
net/bluetooth/hci_sync.c-375-
net/bluetooth/hci_sync.c:376: status = hci_cmd_sync_queue(hdev, scan_disable_sync, NULL, NULL);
net/bluetooth/hci_sync.c-377- if (status) {
--
net/bluetooth/hci_sync.c-403-
net/bluetooth/hci_sync.c:404: status = hci_cmd_sync_queue(hdev, interleaved_inquiry_sync, NULL, NULL);
net/bluetooth/hci_sync.c-405- if (status) {
--
net/bluetooth/hci_sync.c=447=static void reenable_adv(struct work_struct *work)
--
net/bluetooth/hci_sync.c-456-
net/bluetooth/hci_sync.c:457: status = hci_cmd_sync_queue(hdev, reenable_adv_sync, NULL, NULL);
net/bluetooth/hci_sync.c-458- if (status)
--
net/bluetooth/hci_sync.c=553=static void adv_timeout_expire(struct work_struct *work)
--
net/bluetooth/hci_sync.c-572- *inst_ptr = hdev->cur_adv_instance;
net/bluetooth/hci_sync.c:573: hci_cmd_sync_queue(hdev, adv_timeout_expire_sync, inst_ptr, NULL);
net/bluetooth/hci_sync.c-574-
--
net/bluetooth/hci_sync.c=733=EXPORT_SYMBOL(hci_cmd_sync_submit);
--
net/bluetooth/hci_sync.c-738- */
net/bluetooth/hci_sync.c:739:int hci_cmd_sync_queue(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
net/bluetooth/hci_sync.c-740- void *data, hci_cmd_sync_work_destroy_t destroy)
--
net/bluetooth/hci_sync.c=779=int hci_cmd_sync_queue_once(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
--
net/bluetooth/hci_sync.c-784-
net/bluetooth/hci_sync.c:785: return hci_cmd_sync_queue(hdev, func, data, destroy);
net/bluetooth/hci_sync.c-786-}
--
net/bluetooth/hci_sync.c=1912=int hci_enable_advertising(struct hci_dev *hdev)
--
net/bluetooth/hci_sync.c-1917-
net/bluetooth/hci_sync.c:1918: return hci_cmd_sync_queue(hdev, enable_advertising_sync, NULL, NULL);
net/bluetooth/hci_sync.c-1919-}
--
net/bluetooth/hci_sync.c=3246=int hci_update_scan(struct hci_dev *hdev)
net/bluetooth/hci_sync.c-3247-{
net/bluetooth/hci_sync.c:3248: return hci_cmd_sync_queue(hdev, update_scan_sync, NULL, NULL);
net/bluetooth/hci_sync.c-3249-}
--
net/bluetooth/hci_sync.c=5881=int hci_update_discoverable(struct hci_dev *hdev)
--
net/bluetooth/hci_sync.c-5887- hci_dev_test_flag(hdev, HCI_LIMITED_PRIVACY))
net/bluetooth/hci_sync.c:5888: return hci_cmd_sync_queue(hdev, update_discoverable_sync, NULL,
net/bluetooth/hci_sync.c-5889- NULL);
--
net/bluetooth/hci_sync.c=6862=int hci_update_adv_data(struct hci_dev *hdev, u8 instance)
net/bluetooth/hci_sync.c-6863-{
net/bluetooth/hci_sync.c:6864: return hci_cmd_sync_queue(hdev, _update_adv_data_sync,
net/bluetooth/hci_sync.c-6865- UINT_PTR(instance), NULL);
--
net/bluetooth/mgmt.c=1009=static void service_cache_off(struct work_struct *work)
--
net/bluetooth/mgmt.c-1016-
net/bluetooth/mgmt.c:1017: hci_cmd_sync_queue(hdev, service_cache_sync, NULL, NULL);
net/bluetooth/mgmt.c-1018-}
--
net/bluetooth/mgmt.c=1032=static void rpa_expired(struct work_struct *work)
--
net/bluetooth/mgmt.c-1043-
net/bluetooth/mgmt.c:1044: hci_cmd_sync_queue(hdev, rpa_expired_sync, NULL, NULL);
net/bluetooth/mgmt.c-1045-}
--
net/bluetooth/mgmt.c=1049=static void discov_off(struct work_struct *work)
--
net/bluetooth/mgmt.c-1066-
net/bluetooth/mgmt.c:1067: hci_cmd_sync_queue(hdev, set_discoverable_sync, NULL, NULL);
net/bluetooth/mgmt.c-1068-
--
net/bluetooth/mgmt.c=1105=static void mesh_next(struct hci_dev *hdev, void *data, int err)
--
net/bluetooth/mgmt.c-1111-
net/bluetooth/mgmt.c:1112: err = hci_cmd_sync_queue(hdev, mesh_send_sync, mesh_tx,
net/bluetooth/mgmt.c-1113- mesh_send_start_complete);
--
net/bluetooth/mgmt.c=1121=static void mesh_send_done(struct work_struct *work)
--
net/bluetooth/mgmt.c-1128-
net/bluetooth/mgmt.c:1129: hci_cmd_sync_queue(hdev, mesh_send_done_sync, NULL, mesh_next);
net/bluetooth/mgmt.c-1130-}
--
net/bluetooth/mgmt.c=1390=static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data,
--
net/bluetooth/mgmt.c-1432- hci_cmd_sync_cancel_sync(hdev, -EHOSTDOWN);
net/bluetooth/mgmt.c:1433: err = hci_cmd_sync_queue(hdev, set_powered_sync, cmd,
net/bluetooth/mgmt.c-1434- mgmt_set_powered_complete);
--
net/bluetooth/mgmt.c=1572=static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
--
net/bluetooth/mgmt.c-1693-
net/bluetooth/mgmt.c:1694: err = hci_cmd_sync_queue(hdev, set_discoverable_sync, cmd,
net/bluetooth/mgmt.c-1695- mgmt_set_discoverable_complete);
--
net/bluetooth/mgmt.c=1772=static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data,
--
net/bluetooth/mgmt.c-1820-
net/bluetooth/mgmt.c:1821: err = hci_cmd_sync_queue(hdev, set_connectable_sync, cmd,
net/bluetooth/mgmt.c-1822- mgmt_set_connectable_complete);
--
net/bluetooth/mgmt.c=2012=static int set_ssp(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
--
net/bluetooth/mgmt.c-2070- else
net/bluetooth/mgmt.c:2071: err = hci_cmd_sync_queue(hdev, set_ssp_sync, cmd,
net/bluetooth/mgmt.c-2072- set_ssp_complete);
--
net/bluetooth/mgmt.c=2242=static int set_mesh(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
--
net/bluetooth/mgmt.c-2282- else
net/bluetooth/mgmt.c:2283: err = hci_cmd_sync_queue(hdev, set_mesh_sync, cmd,
net/bluetooth/mgmt.c-2284- set_mesh_complete);
--
net/bluetooth/mgmt.c=2437=static int mesh_send_cancel(struct sock *sk, struct hci_dev *hdev,
--
net/bluetooth/mgmt.c-2456- else
net/bluetooth/mgmt.c:2457: err = hci_cmd_sync_queue(hdev, send_cancel, cmd, NULL);
net/bluetooth/mgmt.c-2458-
--
net/bluetooth/mgmt.c=2471=static int mesh_send(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
--
net/bluetooth/mgmt.c-2507- else if (!sending)
net/bluetooth/mgmt.c:2508: err = hci_cmd_sync_queue(hdev, mesh_send_sync, mesh_tx,
net/bluetooth/mgmt.c-2509- mesh_send_start_complete);
--
net/bluetooth/mgmt.c=2532=static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
--
net/bluetooth/mgmt.c-2604- else
net/bluetooth/mgmt.c:2605: err = hci_cmd_sync_queue(hdev, set_le_sync, cmd,
net/bluetooth/mgmt.c-2606- set_le_complete);
--
net/bluetooth/mgmt.c=2649=static int mgmt_hci_cmd_sync(struct sock *sk, struct hci_dev *hdev,
--
net/bluetooth/mgmt.c-2665- else
net/bluetooth/mgmt.c:2666: err = hci_cmd_sync_queue(hdev, send_hci_cmd_sync, cmd, NULL);
net/bluetooth/mgmt.c-2667-
--
net/bluetooth/mgmt.c=3102=static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data,
--
net/bluetooth/mgmt.c-3220-
net/bluetooth/mgmt.c:3221: err = hci_cmd_sync_queue(hdev, unpair_device_sync, cmd,
net/bluetooth/mgmt.c-3222- unpair_device_complete);
--
net/bluetooth/mgmt.c=3263=static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data,
--
net/bluetooth/mgmt.c-3298-
net/bluetooth/mgmt.c:3299: err = hci_cmd_sync_queue(hdev, disconnect_sync, cmd,
net/bluetooth/mgmt.c-3300- disconnect_complete);
--
net/bluetooth/mgmt.c=3941=static void set_name_complete(struct hci_dev *hdev, void *data, int err)
--
net/bluetooth/mgmt.c-3961- if (hci_dev_test_flag(hdev, HCI_LE_ADV))
net/bluetooth/mgmt.c:3962: hci_cmd_sync_queue(hdev, name_changed_sync, NULL, NULL);
net/bluetooth/mgmt.c-3963- }
--
net/bluetooth/mgmt.c=3998=static int set_local_name(struct sock *sk, struct hci_dev *hdev, void *data,
--
net/bluetooth/mgmt.c-4040- else
net/bluetooth/mgmt.c:4041: err = hci_cmd_sync_queue(hdev, set_name_sync, cmd,
net/bluetooth/mgmt.c-4042- set_name_complete);
--
net/bluetooth/mgmt.c=4066=static int set_appearance(struct sock *sk, struct hci_dev *hdev, void *data,
--
net/bluetooth/mgmt.c-4086- if (hci_dev_test_flag(hdev, HCI_LE_ADV))
net/bluetooth/mgmt.c:4087: hci_cmd_sync_queue(hdev, appearance_changed_sync, NULL,
net/bluetooth/mgmt.c-4088- NULL);
--
net/bluetooth/mgmt.c=4211=static int set_phy_configuration(struct sock *sk, struct hci_dev *hdev,
--
net/bluetooth/mgmt.c-4321- else
net/bluetooth/mgmt.c:4322: err = hci_cmd_sync_queue(hdev, set_default_phy_sync, cmd,
net/bluetooth/mgmt.c-4323- set_default_phy_complete);
--
net/bluetooth/mgmt.c=5398=static int __add_adv_patterns_monitor(struct sock *sk, struct hci_dev *hdev,
--
net/bluetooth/mgmt.c-5423- cmd->user_data = m;
net/bluetooth/mgmt.c:5424: err = hci_cmd_sync_queue(hdev, mgmt_add_adv_patterns_monitor_sync, cmd,
net/bluetooth/mgmt.c-5425- mgmt_add_adv_patterns_monitor_complete);
--
net/bluetooth/mgmt.c=5746=static int read_local_oob_data(struct sock *sk, struct hci_dev *hdev,
--
net/bluetooth/mgmt.c-5771- else
net/bluetooth/mgmt.c:5772: err = hci_cmd_sync_queue(hdev, read_local_oob_data_sync, cmd,
net/bluetooth/mgmt.c-5773- read_local_oob_data_complete);
--
net/bluetooth/mgmt.c=5985=static int start_discovery_internal(struct sock *sk, struct hci_dev *hdev,
--
net/bluetooth/mgmt.c-6041-
net/bluetooth/mgmt.c:6042: err = hci_cmd_sync_queue(hdev, start_discovery_sync, cmd,
net/bluetooth/mgmt.c-6043- start_discovery_complete);
--
net/bluetooth/mgmt.c=6071=static int start_service_discovery(struct sock *sk, struct hci_dev *hdev,
--
net/bluetooth/mgmt.c-6168-
net/bluetooth/mgmt.c:6169: err = hci_cmd_sync_queue(hdev, start_discovery_sync, cmd,
net/bluetooth/mgmt.c-6170- start_discovery_complete);
--
net/bluetooth/mgmt.c=6208=static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
--
net/bluetooth/mgmt.c-6238-
net/bluetooth/mgmt.c:6239: err = hci_cmd_sync_queue(hdev, stop_discovery_sync, cmd,
net/bluetooth/mgmt.c-6240- stop_discovery_complete);
--
net/bluetooth/mgmt.c=6372=static int set_device_id(struct sock *sk, struct hci_dev *hdev, void *data,
--
net/bluetooth/mgmt.c-6396-
net/bluetooth/mgmt.c:6397: hci_cmd_sync_queue(hdev, set_device_id_sync, NULL, NULL);
net/bluetooth/mgmt.c-6398-
--
net/bluetooth/mgmt.c=6510=static int set_advertising(struct sock *sk, struct hci_dev *hdev, void *data,
--
net/bluetooth/mgmt.c-6583- else
net/bluetooth/mgmt.c:6584: err = hci_cmd_sync_queue(hdev, set_adv_sync, cmd,
net/bluetooth/mgmt.c-6585- set_advertising_complete);
--
net/bluetooth/mgmt.c=6721=static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev,
--
net/bluetooth/mgmt.c-6759- else
net/bluetooth/mgmt.c:6760: err = hci_cmd_sync_queue(hdev, write_fast_connectable_sync, cmd,
net/bluetooth/mgmt.c-6761- fast_connectable_complete);
--
net/bluetooth/mgmt.c=6818=static int set_bredr(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
--
net/bluetooth/mgmt.c-6895- else
net/bluetooth/mgmt.c:6896: err = hci_cmd_sync_queue(hdev, set_bredr_sync, cmd,
net/bluetooth/mgmt.c-6897- set_bredr_complete);
--
net/bluetooth/mgmt.c=6968=static int set_secure_conn(struct sock *sk, struct hci_dev *hdev,
--
net/bluetooth/mgmt.c-7033- else
net/bluetooth/mgmt.c:7034: err = hci_cmd_sync_queue(hdev, set_secure_conn_sync, cmd,
net/bluetooth/mgmt.c-7035- set_secure_conn_complete);
--
net/bluetooth/mgmt.c=7419=static int get_conn_info(struct sock *sk, struct hci_dev *hdev, void *data,
--
net/bluetooth/mgmt.c-7479- } else {
net/bluetooth/mgmt.c:7480: err = hci_cmd_sync_queue(hdev, get_conn_info_sync,
net/bluetooth/mgmt.c-7481- cmd, get_conn_info_complete);
--
net/bluetooth/mgmt.c=7563=static int get_clock_info(struct sock *sk, struct hci_dev *hdev, void *data,
--
net/bluetooth/mgmt.c-7609- else
net/bluetooth/mgmt.c:7610: err = hci_cmd_sync_queue(hdev, get_clock_info_sync, cmd,
net/bluetooth/mgmt.c-7611- get_clock_info_complete);
--
net/bluetooth/mgmt.c=7667=static int add_device(struct sock *sk, struct hci_dev *hdev,
--
net/bluetooth/mgmt.c-7752-
net/bluetooth/mgmt.c:7753: err = hci_cmd_sync_queue(hdev, add_device_sync, cmd,
net/bluetooth/mgmt.c-7754- add_device_complete);
--
net/bluetooth/mgmt.c=7795=static int remove_device(struct sock *sk, struct hci_dev *hdev,
--
net/bluetooth/mgmt.c-7907-
net/bluetooth/mgmt.c:7908: hci_cmd_sync_queue(hdev, remove_device_sync, NULL, NULL);
net/bluetooth/mgmt.c-7909-
--
net/bluetooth/mgmt.c=7931=static int load_conn_param(struct sock *sk, struct hci_dev *hdev, void *data,
--
net/bluetooth/mgmt.c-8038- conn->le_supv_timeout != timeout))
net/bluetooth/mgmt.c:8039: hci_cmd_sync_queue(hdev, conn_update_sync,
net/bluetooth/mgmt.c-8040- hci_param, NULL);
--
net/bluetooth/mgmt.c=8278=static int read_local_ssp_oob_req(struct hci_dev *hdev, struct sock *sk,
--
net/bluetooth/mgmt.c-8288-
net/bluetooth/mgmt.c:8289: err = hci_cmd_sync_queue(hdev, read_local_oob_data_sync, cmd,
net/bluetooth/mgmt.c-8290- read_local_oob_ext_data_complete);
--
net/bluetooth/mgmt.c=8734=static int add_advertising(struct sock *sk, struct hci_dev *hdev,
--
net/bluetooth/mgmt.c-8857-
net/bluetooth/mgmt.c:8858: err = hci_cmd_sync_queue(hdev, add_advertising_sync, cmd,
net/bluetooth/mgmt.c-8859- add_advertising_complete);
--
net/bluetooth/mgmt.c=8927=static int add_ext_adv_params(struct sock *sk, struct hci_dev *hdev,
--
net/bluetooth/mgmt.c-9022-
net/bluetooth/mgmt.c:9023: err = hci_cmd_sync_queue(hdev, add_ext_adv_params_sync, cmd,
net/bluetooth/mgmt.c-9024- add_ext_adv_params_complete);
--
net/bluetooth/mgmt.c=9086=static int add_ext_adv_data(struct sock *sk, struct hci_dev *hdev, void *data,
--
net/bluetooth/mgmt.c-9178-
net/bluetooth/mgmt.c:9179: err = hci_cmd_sync_queue(hdev, add_ext_adv_data_sync, cmd,
net/bluetooth/mgmt.c-9180- add_ext_adv_data_complete);
--
net/bluetooth/mgmt.c=9243=static int remove_advertising(struct sock *sk, struct hci_dev *hdev,
--
net/bluetooth/mgmt.c-9279-
net/bluetooth/mgmt.c:9280: err = hci_cmd_sync_queue(hdev, remove_advertising_sync, cmd,
net/bluetooth/mgmt.c-9281- remove_advertising_complete);
--
net/bluetooth/msft.c=927=static struct msft_monitor_addr_filter_data *msft_add_address_filter
--
net/bluetooth/msft.c-955-
net/bluetooth/msft.c:956: err = hci_cmd_sync_queue(hdev, msft_add_address_filter_sync,
net/bluetooth/msft.c-957- address_filter, NULL);
--
net/bluetooth/msft.c=972=static void msft_monitor_device_evt(struct hci_dev *hdev, struct sk_buff *skb)
--
net/bluetooth/msft.c-1058- address_filter->state = AF_STATE_REMOVING;
net/bluetooth/msft.c:1059: hci_cmd_sync_queue(hdev,
net/bluetooth/msft.c-1060- msft_cancel_address_filter_sync,
]
|
| 34/2 |
2026/05/19 05:50 |
llm |
expert |
0m
Model:
Tokens:
input: 50132
output: 23
thoughts: 1636
Thoughts: **Analyzing a Potential Bluetooth Driver Deadlock**
Okay, let's break this down. My initial observation is that `hci_cmd_sync_queue` is a key function, and if an entry's `func` blocks, it's holding `hdev->req_lock`. This is where it starts to get interesting. `hci_cmd_sync_work` also holds `hdev->req_lock`. Now, the syz-executor is blocked in `__flush_work` called from `hci_dev_close_sync`, and this implies that `hdev->req_lock` is being held somewhere. And, `hci_dev_do_close` *does* take `hci_req_sync_lock(hdev)`!
So, `hci_dev_do_close` locks `hdev->req_lock`, calls `hci_dev_close_sync`, and the sync function calls `flush_work(&hdev->rx_work)`. My immediate thought is, if `rx_work` is blocked on `hci_dev_lock(hdev)`, who holds that `hdev->lock`? But, wait, `hci_dev_close_sync` *doesn't* hold `hdev->lock` when it calls `flush_work(&hdev->rx_work)`. Instead, it first calls `drain_workqueue` and then takes `hci_dev_lock`.
If the syz-executor is stuck inside `hci_dev_do_close` during this process, it's holding `hdev->req_lock`. However, `kworker/u9:3/5978` holds `hdev->req_lock` in `hci_cmd_sync_work`, for hci6, and `kworker/u9:4/5979` holds it for hci4. `kworker/u9:9/11288` holds it for hci2, etc. Also, `kworker/u9:10/11292` holds `hdev->lock` for `hci4#2` and is running `rx_work`.
So, the syz-executor is blocked in `__flush_work`, and if it's flushing `rx_work` for `hci4#2`, it's blocked *because* `kworker/u9:10/11292` is running `rx_work` for the same device and is blocked on `hci_dev_lock(hdev)` for that device. I need to figure out who is holding `hdev->lock` for hci4#2. The syz-executor *doesn't* hold `hdev->lock` in `hci_dev_close_sync` at line 5289. Is the executor perhaps in `hci_cmd_sync_work`? But it is a user task, so probably not. If the executor had called `hci_dev_close_sync` from `hci_sock_release`, would that change things?
If `syz-executor:5969` is in `hci_dev_close_sync`, it holds `hdev->req_lock`. But `kworker/u9:4/5979` already holds it for `hci4`. Wait... `hci4#2` is just a lockdep name, meaning it's the `hdev->lock` of `hci4`. Only one thread can hold a mutex, so if the `kworker` has `hdev->req_lock`, the syz-executor *cannot*. And if the syz-executor were in `hci_dev_do_close` for `hci4`, it would be blocked on `hci_req_sync_lock(hdev)`! But the trace says it's blocked in `__flush_work`! So, it can't be holding `hdev->req_lock` for hci4.
The lockdep trace confirms that `kworker/u9:4/5979` *does* hold `hdev->req_lock` for `hci4`. Thus, the syz-executor *cannot*. If the syz-executor is blocked in `__flush_work`, it must be flushing *something*, but not the `cmd_sync_work`. Because `hci_dev_close_sync` does not flush `cmd_sync_work`, and therefore something else must. Where else is `cmd_sync_work` being flushed? This is the core issue to resolve.
|
| 35/2 |
2026/05/19 05:51 |
tool |
grepper |
0m
Error:
Args: map[Expression:flush_work.*cmd_sync_work]
Results:
|
| 36/2 |
2026/05/19 05:51 |
llm |
expert |
0m
Model:
Tokens:
input: 52789
output: 25
thoughts: 15
Thoughts: Here's my attempt at summarizing that thought process, tailored for an expert audience:
**Analyzing `cmd_sync_work` Flush Points**
Okay, so I'm thinking about `cmd_sync_work`. Specifically, I'm trying to mentally map out all the call sites and related infrastructure. The crucial question is: where are the points of *actual* flushing? I'm not interested in where it's *queued*, I'm focused on the execution. Where does the hardware get told to *go*?
I need to understand this to make any meaningful judgment of its behaviour and determine if a race condition exists. There are a couple of obvious candidates: explicit synchronization primitives, perhaps an interrupt handler, or maybe a specific point in the driver model. I'm going to have to dive into the code and start tracking the flow.
|
| 37/2 |
2026/05/19 05:51 |
tool |
grepper |
0m
Args: map[Expression:cancel_work_sync.*cmd_sync_work]
Results: map[Output:net/bluetooth/hci_sync.c=651=void hci_cmd_sync_clear(struct hci_dev *hdev)
--
net/bluetooth/hci_sync.c-654-
net/bluetooth/hci_sync.c:655: cancel_work_sync(&hdev->cmd_sync_work);
net/bluetooth/hci_sync.c-656- cancel_work_sync(&hdev->reenable_adv_work);
]
|
| 38/2 |
2026/05/19 05:51 |
llm |
expert |
0m
Model:
Tokens:
input: 53131
output: 25
thoughts: 42
Thoughts: Okay, here's my take on those thoughts, framed as an expert's internal monologue:
**Investigating the HCI Command Synchronization**
Right, so `hci_cmd_sync_clear`... that's calling `cancel_work_sync(&hdev->cmd_sync_work)`. Interesting. Essentially, it's attempting to halt or flush an asynchronous command execution. But what's triggering this function in the first place? I need to understand the call chain. Knowing *who* calls `hci_cmd_sync_clear` will give crucial context to the command sync work's lifecycle and its possible interaction points. This is likely going to reveal something about how commands are queued, executed, and, critically, how their execution is potentially interrupted or cancelled within the Bluetooth stack. Gotta trace back the callers. This seems like a potential point of contention for resource contention or a timing issue.
|
| 39/2 |
2026/05/19 05:51 |
tool |
codesearch-find-references |
0m
Args: map[Name:hci_cmd_sync_clear]
Results: map[References:[map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:hci_unregister_dev SourceFile:net/bluetooth/hci_core.c SourceLine:2711]] TruncatedOutput:false]
|
| 40/2 |
2026/05/19 05:51 |
llm |
expert |
0m
Model:
Tokens:
input: 53458
output: 43
thoughts: 29
Thoughts: Here's my take on the thought process, as if it were my own:
**Investigating `hci_unregister_dev`**
Okay, so `hci_unregister_dev` seems to be calling `hci_cmd_sync_clear`. That's interesting, and it suggests a connection between device unregistration and clearing some sort of synchronous command state. I need to understand that link. Given that my field requires intimate knowledge of the Bluetooth stack, I immediately want to dig deeper into the `hci_unregister_dev` function to understand the precise mechanism at play. Let's start there.
|
| 41/2 |
2026/05/19 05:51 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_core.c IncludeLines:true Name:hci_unregister_dev]
Results: map[SourceCode:2689: /* Unregister HCI device */
2690: void hci_unregister_dev(struct hci_dev *hdev)
2691: {
2692: BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
2693:
2694: mutex_lock(&hdev->unregister_lock);
2695: hci_dev_set_flag(hdev, HCI_UNREGISTER);
2696: mutex_unlock(&hdev->unregister_lock);
2697:
2698: write_lock(&hci_dev_list_lock);
2699: list_del(&hdev->list);
2700: write_unlock(&hci_dev_list_lock);
2701:
2702: synchronize_srcu(&hdev->srcu);
2703: cleanup_srcu_struct(&hdev->srcu);
2704:
2705: disable_work_sync(&hdev->rx_work);
2706: disable_work_sync(&hdev->cmd_work);
2707: disable_work_sync(&hdev->tx_work);
2708: disable_work_sync(&hdev->power_on);
2709: disable_work_sync(&hdev->error_reset);
2710:
2711: hci_cmd_sync_clear(hdev);
2712:
2713: hci_unregister_suspend_notifier(hdev);
2714:
2715: hci_dev_do_close(hdev);
2716:
2717: if (!test_bit(HCI_INIT, &hdev->flags) &&
2718: !hci_dev_test_flag(hdev, HCI_SETUP) &&
2719: !hci_dev_test_flag(hdev, HCI_CONFIG)) {
2720: hci_dev_lock(hdev);
2721: mgmt_index_removed(hdev);
2722: hci_dev_unlock(hdev);
2723: }
2724:
2725: /* mgmt_index_removed should take care of emptying the
2726: * pending list */
2727: BUG_ON(!list_empty(&hdev->mgmt_pending));
2728:
2729: hci_sock_dev_event(hdev, HCI_DEV_UNREG);
2730:
2731: if (hdev->rfkill) {
2732: rfkill_unregister(hdev->rfkill);
2733: rfkill_destroy(hdev->rfkill);
2734: }
2735:
2736: device_del(&hdev->dev);
2737: /* Actual cleanup is deferred until hci_release_dev(). */
2738: hci_dev_put(hdev);
2739: }
SourceFile:net/bluetooth/hci_core.c]
|
| 42/2 |
2026/05/19 05:51 |
llm |
expert |
0m
Model:
Tokens:
input: 54483
output: 43
thoughts: 167
Thoughts: **Analyzing a Potential Race Condition**
Okay, so I'm looking at this trace and trying to piece together what's going on. Line 2705 of `hci_unregister_dev` is calling `disable_work_sync(&hdev->rx_work)`. I know that `disable_work_sync` is just a wrapper, ultimately calling `__flush_work`. Right now, it looks like `syz-executor:5969` is stuck inside `hci_unregister_dev`, specifically within that `disable_work_sync` call. That's a classic sign of a blocking operation.
But I need to understand *why* `syz-executor:5969` would be in `hci_unregister_dev` in the first place. My knowledge tells me `hci_unregister_dev` gets called when a Bluetooth device is essentially being removed from the system. So, can the syz-executor even *trigger* a device removal? Thinking about it, absolutely! It's likely involved in fuzzing, so it's probably messing with the device in some way.
Now, how could this happen? Let me see... If it were closing a vhci file descriptor, I could see how that could cause the device to be removed, triggering `hci_unregister_dev`. Let me dig into `vhci_release` in `drivers/bluetooth/hci_vhci.c` and see if my hunch is correct. That's the likely culprit to investigate.
|
| 43/2 |
2026/05/19 05:51 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:drivers/bluetooth/hci_vhci.c IncludeLines:true Name:vhci_release]
Results: map[SourceCode: 677: static int vhci_release(struct inode *inode, struct file *file)
678: {
679: struct vhci_data *data = file->private_data;
680: struct hci_dev *hdev;
681:
682: cancel_delayed_work_sync(&data->open_timeout);
683: flush_work(&data->suspend_work);
684:
685: hdev = data->hdev;
686:
687: if (hdev) {
688: if (!IS_ERR_OR_NULL(hdev->debugfs))
689: vhci_debugfs_remove(hdev);
690: hci_unregister_dev(hdev);
691: hci_free_dev(hdev);
692: }
693:
694: skb_queue_purge(&data->readq);
695: file->private_data = NULL;
696: kfree(data);
697:
698: return 0;
699: }
SourceFile:drivers/bluetooth/hci_vhci.c]
|
| 44/2 |
2026/05/19 05:51 |
llm |
expert |
0m
Model:
Tokens:
input: 55363
output: 23
thoughts: 2631
Thoughts: **Analysis of a Potential Bluetooth Deadlock**
Okay, here's the breakdown of my thought process as I've been tracing this crash in the Bluetooth subsystem. My initial observation is that `vhci_release` gets called when the vhci file descriptor is closed, and that this calls `hci_unregister_dev`, which is the key. The call stack makes sense, linking `vhci_release` through `fput` to `task_work_run` and finally to `get_signal`. This explains how the syz-executor is ending up in `vhci_release` and then calling `hci_unregister_dev`.
I know that `hci_unregister_dev` is where the crash is happening, specifically when it calls `disable_work_sync` on various work queues associated with the Bluetooth device (`hdev`). My immediate thought is that if this is blocked in `disable_work_sync(&hdev->rx_work)` it means that `rx_work` is currently running, and I need to figure out what it's doing and why it's blocking.
I checked the kernel worker thread (`kworker/u9:10/11292`) associated with `rx_work`, but I see that it's blocked acquiring `hdev->lock` at the `hci_event_packet` function. Now I need to figure out who *holds* this lock.
I know `hci_unregister_dev` *doesn't* hold `hdev->lock` when it's calling `disable_work_sync`. I checked, and `hci_unregister_dev` uses `unregister_lock` while unregistering, but not `hdev->lock`. So, who *does* have it?
I then looked at the kernel worker (`kworker/u9:4/5979`) holding `hdev->req_lock`. This worker runs `cmd_sync_work`, and the worker's execution path could call a function that tries to acquire `hdev->lock`.
The critical question is, does this worker (kworker/u9:4/5979) hold `hdev->lock` *before* getting to `hdev->req_lock`? If it doesn't hold `hdev->lock`, it is *trying* to get it. The lockdep trace only shows locks that are held, not those that are *being* requested. So, if this worker is trying to get `hdev->lock` while another task (like `rx_work`) is trying as well, and there is no one currently holding it, then there is a *contention*. If `rx_work` is already running and waiting for the lock, it looks like a deadlock.
So, who is holding `hdev->lock`? If `syz-executor:5969` isn't blocked, it could be in `hci_cmd_sync_clear` waiting for `cmd_sync_work`.
I think that `syz-executor:5969` is blocked in `cancel_work_sync` which is waiting for `cmd_sync_work` to complete, which is running on `kworker/u9:4/5979`. However, kworker/u9:4/5979 might be blocked trying to acquire `hdev->lock`, while the other kworker is running `rx_work`, and `rx_work` is blocked *trying* to acquire `hdev->lock`. Since both threads are blocked on the same resource, `hdev->lock`, the crash makes sense, and it seems like a deadlock.
The output shows that there are multiple other kworkers running. And the stack trace is truncated with one worker holding 7 locks. If `syz-executor:5969` is blocked in `disable_work_sync(&hdev->rx_work)` or `cancel_work_sync(&hdev->cmd_sync_work)` then it means the respective work is currently running. Thus, `rx_work` is running, but blocked on `hdev->lock`.
If there is a deadlock, this means one worker *holds* `hdev->lock` and is waiting for `hdev->req_lock`. And another worker *holds* `hdev->req_lock` and is waiting for `hdev->lock`.
Could `kworker/u9:11/12552` hold `hdev->lock`? If `kworker/u9:11/12552` is doing something that uses the `hdev->lock` it could be a classic AB-BA deadlock situation. I need to investigate the functions called by `kworker/u9:11/1
|
| 45/2 |
2026/05/19 05:51 |
tool |
grepper |
0m
Args: map[Expression:hci_dev_lock\(hdev\)]
Results: map[Output:
Full output is too long, showing 500 out of 1837 lines.
Use more precise expression if possible.
[drivers/bluetooth/btmtk.c=362=void btmtk_reset_sync(struct hci_dev *hdev)
--
drivers/bluetooth/btmtk.c-366-
drivers/bluetooth/btmtk.c:367: hci_dev_lock(hdev);
drivers/bluetooth/btmtk.c-368-
--
net/bluetooth/6lowpan.c=968=static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
--
net/bluetooth/6lowpan.c-1007-
net/bluetooth/6lowpan.c:1008: hci_dev_lock(hdev);
net/bluetooth/6lowpan.c-1009- hcon = hci_conn_hash_lookup_le(hdev, addr, le_addr_type);
--
net/bluetooth/coredump.c=331=void hci_devcd_rx(struct work_struct *work)
--
net/bluetooth/coredump.c-345-
net/bluetooth/coredump.c:346: hci_dev_lock(hdev);
net/bluetooth/coredump.c-347- start_state = hdev->dump.state;
--
net/bluetooth/coredump.c-385- /* Reset the state machine if the devcoredump is complete */
net/bluetooth/coredump.c:386: hci_dev_lock(hdev);
net/bluetooth/coredump.c-387- if (hdev->dump.state == HCI_DEVCOREDUMP_DONE ||
--
net/bluetooth/coredump.c=395=void hci_devcd_timeout(struct work_struct *work)
--
net/bluetooth/coredump.c-402-
net/bluetooth/coredump.c:403: hci_dev_lock(hdev);
net/bluetooth/coredump.c-404-
--
net/bluetooth/coredump.c=421=int hci_devcd_register(struct hci_dev *hdev, coredump_t coredump,
--
net/bluetooth/coredump.c-432-
net/bluetooth/coredump.c:433: hci_dev_lock(hdev);
net/bluetooth/coredump.c-434- hdev->dump.coredump = coredump;
--
net/bluetooth/hci_codec.c=48=static void hci_read_codec_capabilities(struct hci_dev *hdev, __u8 transport,
--
net/bluetooth/hci_codec.c-67- if (!(hdev->commands[45] & 0x08)) {
net/bluetooth/hci_codec.c:68: hci_dev_lock(hdev);
net/bluetooth/hci_codec.c-69- hci_codec_list_add(&hdev->local_codecs, cmd,
--
net/bluetooth/hci_codec.c-109-skip_caps_parse:
net/bluetooth/hci_codec.c:110: hci_dev_lock(hdev);
net/bluetooth/hci_codec.c-111- hci_codec_list_add(&hdev->local_codecs, cmd, rp,
--
net/bluetooth/hci_conn.c=483=u8 hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency,
--
net/bluetooth/hci_conn.c-489-
net/bluetooth/hci_conn.c:490: hci_dev_lock(hdev);
net/bluetooth/hci_conn.c-491-
--
net/bluetooth/hci_conn.c=643=static void le_conn_timeout(struct work_struct *work)
--
net/bluetooth/hci_conn.c-658- le_disable_advertising(hdev);
net/bluetooth/hci_conn.c:659: hci_dev_lock(hdev);
net/bluetooth/hci_conn.c-660- hci_conn_failed(conn, HCI_ERROR_ADVERTISING_TIMEOUT);
--
net/bluetooth/hci_conn.c=2664=int hci_get_conn_list(void __user *arg)
--
net/bluetooth/hci_conn.c-2691-
net/bluetooth/hci_conn.c:2692: hci_dev_lock(hdev);
net/bluetooth/hci_conn.c-2693- list_for_each_entry(c, &hdev->conn_hash.list, list) {
--
net/bluetooth/hci_conn.c=2717=int hci_get_conn_info(struct hci_dev *hdev, void __user *arg)
--
net/bluetooth/hci_conn.c-2726-
net/bluetooth/hci_conn.c:2727: hci_dev_lock(hdev);
net/bluetooth/hci_conn.c-2728- conn = hci_conn_hash_lookup_ba(hdev, req.type, &req.bdaddr);
--
net/bluetooth/hci_conn.c=2745=int hci_get_auth_info(struct hci_dev *hdev, void __user *arg)
--
net/bluetooth/hci_conn.c-2752-
net/bluetooth/hci_conn.c:2753: hci_dev_lock(hdev);
net/bluetooth/hci_conn.c-2754- conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &req.bdaddr);
--
net/bluetooth/hci_core.c=325=int hci_inquiry(void __user *arg)
--
net/bluetooth/hci_core.c-360-
net/bluetooth/hci_core.c:361: hci_dev_lock(hdev);
net/bluetooth/hci_core.c-362- if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
--
net/bluetooth/hci_core.c-400-
net/bluetooth/hci_core.c:401: hci_dev_lock(hdev);
net/bluetooth/hci_core.c-402- ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
--
net/bluetooth/hci_core.c=533=static int hci_dev_do_reset(struct hci_dev *hdev)
--
net/bluetooth/hci_core.c-563-
net/bluetooth/hci_core.c:564: hci_dev_lock(hdev);
net/bluetooth/hci_core.c-565- hci_inquiry_cache_flush(hdev);
--
net/bluetooth/hci_core.c=943=static void hci_power_on(struct work_struct *work)
--
net/bluetooth/hci_core.c-960- if (err < 0) {
net/bluetooth/hci_core.c:961: hci_dev_lock(hdev);
net/bluetooth/hci_core.c-962- mgmt_set_powered_failed(hdev, err);
--
net/bluetooth/hci_core.c=1920=int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor)
--
net/bluetooth/hci_core.c-1927-
net/bluetooth/hci_core.c:1928: hci_dev_lock(hdev);
net/bluetooth/hci_core.c-1929-
--
net/bluetooth/hci_core.c=2392=static void hci_clear_wake_reason(struct hci_dev *hdev)
net/bluetooth/hci_core.c-2393-{
net/bluetooth/hci_core.c:2394: hci_dev_lock(hdev);
net/bluetooth/hci_core.c-2395-
--
net/bluetooth/hci_core.c=2690=void hci_unregister_dev(struct hci_dev *hdev)
--
net/bluetooth/hci_core.c-2719- !hci_dev_test_flag(hdev, HCI_CONFIG)) {
net/bluetooth/hci_core.c:2720: hci_dev_lock(hdev);
net/bluetooth/hci_core.c-2721- mgmt_index_removed(hdev);
--
net/bluetooth/hci_core.c=2743=void hci_release_dev(struct hci_dev *hdev)
--
net/bluetooth/hci_core.c-2751-
net/bluetooth/hci_core.c:2752: hci_dev_lock(hdev);
net/bluetooth/hci_core.c-2753- hci_bdaddr_list_clear(&hdev->reject_list);
--
net/bluetooth/hci_core.c=3464=static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
--
net/bluetooth/hci_core.c-3470-
net/bluetooth/hci_core.c:3471: hci_dev_lock(hdev);
net/bluetooth/hci_core.c-3472-
--
net/bluetooth/hci_debugfs.c=78=static int __name ## _show(struct seq_file *f, void *ptr) \
--
net/bluetooth/hci_debugfs.c-81- \
net/bluetooth/hci_debugfs.c:82: hci_dev_lock(hdev); \
net/bluetooth/hci_debugfs.c-83- seq_printf(f, "%s\n", hdev->__field ? : ""); \
--
net/bluetooth/hci_debugfs.c=91=static int features_show(struct seq_file *f, void *ptr)
--
net/bluetooth/hci_debugfs.c-95-
net/bluetooth/hci_debugfs.c:96: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-97- for (p = 0; p < HCI_MAX_PAGES && p <= hdev->max_page; p++)
--
net/bluetooth/hci_debugfs.c=108=static int device_id_show(struct seq_file *f, void *ptr)
--
net/bluetooth/hci_debugfs.c-111-
net/bluetooth/hci_debugfs.c:112: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-113- seq_printf(f, "%4.4x:%4.4x:%4.4x:%4.4x\n", hdev->devid_source,
--
net/bluetooth/hci_debugfs.c=122=static int device_list_show(struct seq_file *f, void *ptr)
--
net/bluetooth/hci_debugfs.c-127-
net/bluetooth/hci_debugfs.c:128: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-129- list_for_each_entry(b, &hdev->accept_list, list)
--
net/bluetooth/hci_debugfs.c=142=static int blacklist_show(struct seq_file *f, void *p)
--
net/bluetooth/hci_debugfs.c-146-
net/bluetooth/hci_debugfs.c:147: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-148- list_for_each_entry(b, &hdev->reject_list, list)
--
net/bluetooth/hci_debugfs.c=172=static int uuids_show(struct seq_file *f, void *p)
--
net/bluetooth/hci_debugfs.c-176-
net/bluetooth/hci_debugfs.c:177: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-178- list_for_each_entry(uuid, &hdev->uuids, list) {
--
net/bluetooth/hci_debugfs.c=197=static int remote_oob_show(struct seq_file *f, void *ptr)
--
net/bluetooth/hci_debugfs.c-201-
net/bluetooth/hci_debugfs.c:202: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-203- list_for_each_entry(data, &hdev->remote_oob_data, list) {
--
net/bluetooth/hci_debugfs.c=216=static int conn_info_min_age_set(void *data, u64 val)
--
net/bluetooth/hci_debugfs.c-219-
net/bluetooth/hci_debugfs.c:220: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-221- if (val == 0 || val > hdev->conn_info_max_age) {
--
net/bluetooth/hci_debugfs.c=232=static int conn_info_min_age_get(void *data, u64 *val)
--
net/bluetooth/hci_debugfs.c-235-
net/bluetooth/hci_debugfs.c:236: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-237- *val = hdev->conn_info_min_age;
--
net/bluetooth/hci_debugfs.c=246=static int conn_info_max_age_set(void *data, u64 val)
--
net/bluetooth/hci_debugfs.c-249-
net/bluetooth/hci_debugfs.c:250: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-251- if (val == 0 || val < hdev->conn_info_min_age) {
--
net/bluetooth/hci_debugfs.c=262=static int conn_info_max_age_get(void *data, u64 *val)
--
net/bluetooth/hci_debugfs.c-265-
net/bluetooth/hci_debugfs.c:266: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-267- *val = hdev->conn_info_max_age;
--
net/bluetooth/hci_debugfs.c=360=static int inquiry_cache_show(struct seq_file *f, void *p)
--
net/bluetooth/hci_debugfs.c-365-
net/bluetooth/hci_debugfs.c:366: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-367-
--
net/bluetooth/hci_debugfs.c=402=static int dev_class_show(struct seq_file *f, void *ptr)
--
net/bluetooth/hci_debugfs.c-405-
net/bluetooth/hci_debugfs.c:406: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-407- seq_printf(f, "0x%.2x%.2x%.2x\n", hdev->dev_class[2],
--
net/bluetooth/hci_debugfs.c=416=static int voice_setting_get(void *data, u64 *val)
--
net/bluetooth/hci_debugfs.c-419-
net/bluetooth/hci_debugfs.c:420: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-421- *val = hdev->voice_setting;
--
net/bluetooth/hci_debugfs.c=448=static int auto_accept_delay_set(void *data, u64 val)
--
net/bluetooth/hci_debugfs.c-451-
net/bluetooth/hci_debugfs.c:452: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-453- hdev->auto_accept_delay = val;
--
net/bluetooth/hci_debugfs.c=459=static int min_encrypt_key_size_set(void *data, u64 val)
--
net/bluetooth/hci_debugfs.c-465-
net/bluetooth/hci_debugfs.c:466: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-467- hdev->min_enc_key_size = val;
--
net/bluetooth/hci_debugfs.c=473=static int min_encrypt_key_size_get(void *data, u64 *val)
--
net/bluetooth/hci_debugfs.c-476-
net/bluetooth/hci_debugfs.c:477: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-478- *val = hdev->min_enc_key_size;
--
net/bluetooth/hci_debugfs.c=488=static int auto_accept_delay_get(void *data, u64 *val)
--
net/bluetooth/hci_debugfs.c-491-
net/bluetooth/hci_debugfs.c:492: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-493- *val = hdev->auto_accept_delay;
--
net/bluetooth/hci_debugfs.c=541=static int idle_timeout_set(void *data, u64 val)
--
net/bluetooth/hci_debugfs.c-547-
net/bluetooth/hci_debugfs.c:548: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-549- hdev->idle_timeout = val;
--
net/bluetooth/hci_debugfs.c=555=static int idle_timeout_get(void *data, u64 *val)
--
net/bluetooth/hci_debugfs.c-558-
net/bluetooth/hci_debugfs.c:559: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-560- *val = hdev->idle_timeout;
--
net/bluetooth/hci_debugfs.c=569=static int sniff_min_interval_set(void *data, u64 val)
--
net/bluetooth/hci_debugfs.c-572-
net/bluetooth/hci_debugfs.c:573: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-574- if (val == 0 || val % 2 || val > hdev->sniff_max_interval) {
--
net/bluetooth/hci_debugfs.c=585=static int sniff_min_interval_get(void *data, u64 *val)
--
net/bluetooth/hci_debugfs.c-588-
net/bluetooth/hci_debugfs.c:589: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-590- *val = hdev->sniff_min_interval;
--
net/bluetooth/hci_debugfs.c=599=static int sniff_max_interval_set(void *data, u64 val)
--
net/bluetooth/hci_debugfs.c-602-
net/bluetooth/hci_debugfs.c:603: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-604- if (val == 0 || val % 2 || val < hdev->sniff_min_interval) {
--
net/bluetooth/hci_debugfs.c=615=static int sniff_max_interval_get(void *data, u64 *val)
--
net/bluetooth/hci_debugfs.c-618-
net/bluetooth/hci_debugfs.c:619: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-620- *val = hdev->sniff_max_interval;
--
net/bluetooth/hci_debugfs.c=670=static int identity_show(struct seq_file *f, void *p)
--
net/bluetooth/hci_debugfs.c-675-
net/bluetooth/hci_debugfs.c:676: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-677-
--
net/bluetooth/hci_debugfs.c=690=static int rpa_timeout_set(void *data, u64 val)
--
net/bluetooth/hci_debugfs.c-699-
net/bluetooth/hci_debugfs.c:700: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-701- hdev->rpa_timeout = val;
--
net/bluetooth/hci_debugfs.c=707=static int rpa_timeout_get(void *data, u64 *val)
--
net/bluetooth/hci_debugfs.c-710-
net/bluetooth/hci_debugfs.c:711: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-712- *val = hdev->rpa_timeout;
--
net/bluetooth/hci_debugfs.c=721=static int random_address_show(struct seq_file *f, void *p)
--
net/bluetooth/hci_debugfs.c-724-
net/bluetooth/hci_debugfs.c:725: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-726- seq_printf(f, "%pMR\n", &hdev->random_addr);
--
net/bluetooth/hci_debugfs.c=734=static int static_address_show(struct seq_file *f, void *p)
--
net/bluetooth/hci_debugfs.c-737-
net/bluetooth/hci_debugfs.c:738: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-739- seq_printf(f, "%pMR\n", &hdev->static_addr);
--
net/bluetooth/hci_debugfs.c=790=static int white_list_show(struct seq_file *f, void *ptr)
--
net/bluetooth/hci_debugfs.c-794-
net/bluetooth/hci_debugfs.c:795: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-796- list_for_each_entry(b, &hdev->le_accept_list, list)
--
net/bluetooth/hci_debugfs.c=805=static int resolv_list_show(struct seq_file *f, void *ptr)
--
net/bluetooth/hci_debugfs.c-809-
net/bluetooth/hci_debugfs.c:810: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-811- list_for_each_entry(b, &hdev->le_resolv_list, list)
--
net/bluetooth/hci_debugfs.c=856=static int conn_min_interval_set(void *data, u64 val)
--
net/bluetooth/hci_debugfs.c-859-
net/bluetooth/hci_debugfs.c:860: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-861- if (val < 0x0006 || val > 0x0c80 || val > hdev->le_conn_max_interval) {
--
net/bluetooth/hci_debugfs.c=872=static int conn_min_interval_get(void *data, u64 *val)
--
net/bluetooth/hci_debugfs.c-875-
net/bluetooth/hci_debugfs.c:876: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-877- *val = hdev->le_conn_min_interval;
--
net/bluetooth/hci_debugfs.c=886=static int conn_max_interval_set(void *data, u64 val)
--
net/bluetooth/hci_debugfs.c-889-
net/bluetooth/hci_debugfs.c:890: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-891- if (val < 0x0006 || val > 0x0c80 || val < hdev->le_conn_min_interval) {
--
net/bluetooth/hci_debugfs.c=902=static int conn_max_interval_get(void *data, u64 *val)
--
net/bluetooth/hci_debugfs.c-905-
net/bluetooth/hci_debugfs.c:906: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-907- *val = hdev->le_conn_max_interval;
--
net/bluetooth/hci_debugfs.c=916=static int conn_latency_set(void *data, u64 val)
--
net/bluetooth/hci_debugfs.c-922-
net/bluetooth/hci_debugfs.c:923: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-924- hdev->le_conn_latency = val;
--
net/bluetooth/hci_debugfs.c=930=static int conn_latency_get(void *data, u64 *val)
--
net/bluetooth/hci_debugfs.c-933-
net/bluetooth/hci_debugfs.c:934: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-935- *val = hdev->le_conn_latency;
--
net/bluetooth/hci_debugfs.c=944=static int supervision_timeout_set(void *data, u64 val)
--
net/bluetooth/hci_debugfs.c-950-
net/bluetooth/hci_debugfs.c:951: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-952- hdev->le_supv_timeout = val;
--
net/bluetooth/hci_debugfs.c=958=static int supervision_timeout_get(void *data, u64 *val)
--
net/bluetooth/hci_debugfs.c-961-
net/bluetooth/hci_debugfs.c:962: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-963- *val = hdev->le_supv_timeout;
--
net/bluetooth/hci_debugfs.c=972=static int adv_channel_map_set(void *data, u64 val)
--
net/bluetooth/hci_debugfs.c-978-
net/bluetooth/hci_debugfs.c:979: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-980- hdev->le_adv_channel_map = val;
--
net/bluetooth/hci_debugfs.c=986=static int adv_channel_map_get(void *data, u64 *val)
--
net/bluetooth/hci_debugfs.c-989-
net/bluetooth/hci_debugfs.c:990: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-991- *val = hdev->le_adv_channel_map;
--
net/bluetooth/hci_debugfs.c=1000=static int adv_min_interval_set(void *data, u64 val)
--
net/bluetooth/hci_debugfs.c-1003-
net/bluetooth/hci_debugfs.c:1004: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-1005- if (val < 0x0020 || val > 0x4000 || val > hdev->le_adv_max_interval) {
--
net/bluetooth/hci_debugfs.c=1016=static int adv_min_interval_get(void *data, u64 *val)
--
net/bluetooth/hci_debugfs.c-1019-
net/bluetooth/hci_debugfs.c:1020: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-1021- *val = hdev->le_adv_min_interval;
--
net/bluetooth/hci_debugfs.c=1030=static int adv_max_interval_set(void *data, u64 val)
--
net/bluetooth/hci_debugfs.c-1033-
net/bluetooth/hci_debugfs.c:1034: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-1035- if (val < 0x0020 || val > 0x4000 || val < hdev->le_adv_min_interval) {
--
net/bluetooth/hci_debugfs.c=1046=static int adv_max_interval_get(void *data, u64 *val)
--
net/bluetooth/hci_debugfs.c-1049-
net/bluetooth/hci_debugfs.c:1050: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-1051- *val = hdev->le_adv_max_interval;
--
net/bluetooth/hci_debugfs.c=1060=static int min_key_size_set(void *data, u64 val)
--
net/bluetooth/hci_debugfs.c-1063-
net/bluetooth/hci_debugfs.c:1064: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-1065- if (val > hdev->le_max_key_size || val < SMP_MIN_ENC_KEY_SIZE) {
--
net/bluetooth/hci_debugfs.c=1076=static int min_key_size_get(void *data, u64 *val)
--
net/bluetooth/hci_debugfs.c-1079-
net/bluetooth/hci_debugfs.c:1080: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-1081- *val = hdev->le_min_key_size;
--
net/bluetooth/hci_debugfs.c=1090=static int max_key_size_set(void *data, u64 val)
--
net/bluetooth/hci_debugfs.c-1093-
net/bluetooth/hci_debugfs.c:1094: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-1095- if (val > SMP_MAX_ENC_KEY_SIZE || val < hdev->le_min_key_size) {
--
net/bluetooth/hci_debugfs.c=1106=static int max_key_size_get(void *data, u64 *val)
--
net/bluetooth/hci_debugfs.c-1109-
net/bluetooth/hci_debugfs.c:1110: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-1111- *val = hdev->le_max_key_size;
--
net/bluetooth/hci_debugfs.c=1120=static int auth_payload_timeout_set(void *data, u64 val)
--
net/bluetooth/hci_debugfs.c-1126-
net/bluetooth/hci_debugfs.c:1127: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-1128- hdev->auth_payload_timeout = val;
--
net/bluetooth/hci_debugfs.c=1134=static int auth_payload_timeout_get(void *data, u64 *val)
--
net/bluetooth/hci_debugfs.c-1137-
net/bluetooth/hci_debugfs.c:1138: hci_dev_lock(hdev);
net/bluetooth/hci_debugfs.c-1139- *val = hdev->auth_payload_timeout;
--
net/bluetooth/hci_event.c=83=static u8 hci_cc_inquiry_cancel(struct hci_dev *hdev, void *data,
--
net/bluetooth/hci_event.c-108-
net/bluetooth/hci_event.c:109: hci_dev_lock(hdev);
net/bluetooth/hci_event.c-110- /* Set discovery state to stopped if we're not doing LE active
--
net/bluetooth/hci_event.c=161=static u8 hci_cc_role_discovery(struct hci_dev *hdev, void *data,
--
net/bluetooth/hci_event.c-171-
net/bluetooth/hci_event.c:172: hci_dev_lock(hdev);
net/bluetooth/hci_event.c-173-
--
net/bluetooth/hci_event.c=183=static u8 hci_cc_read_link_policy(struct hci_dev *hdev, void *data,
--
net/bluetooth/hci_event.c-193-
net/bluetooth/hci_event.c:194: hci_dev_lock(hdev);
net/bluetooth/hci_event.c-195-
--
net/bluetooth/hci_event.c=205=static u8 hci_cc_write_link_policy(struct hci_dev *hdev, void *data,
--
net/bluetooth/hci_event.c-220-
net/bluetooth/hci_event.c:221: hci_dev_lock(hdev);
net/bluetooth/hci_event.c-222-
--
net/bluetooth/hci_event.c=343=static u8 hci_cc_write_local_name(struct hci_dev *hdev, void *data,
--
net/bluetooth/hci_event.c-354-
net/bluetooth/hci_event.c:355: hci_dev_lock(hdev);
net/bluetooth/hci_event.c-356-
--
net/bluetooth/hci_event.c=384=static u8 hci_cc_write_auth_enable(struct hci_dev *hdev, void *data,
--
net/bluetooth/hci_event.c-395-
net/bluetooth/hci_event.c:396: hci_dev_lock(hdev);
net/bluetooth/hci_event.c-397-
--
net/bluetooth/hci_event.c=441=static u8 hci_cc_write_scan_enable(struct hci_dev *hdev, void *data,
--
net/bluetooth/hci_event.c-455-
net/bluetooth/hci_event.c:456: hci_dev_lock(hdev);
net/bluetooth/hci_event.c-457-
--
net/bluetooth/hci_event.c=526=static u8 hci_cc_write_class_of_dev(struct hci_dev *hdev, void *data,
--
net/bluetooth/hci_event.c-537-
net/bluetooth/hci_event.c:538: hci_dev_lock(hdev);
net/bluetooth/hci_event.c-539-
--
net/bluetooth/hci_event.c=625=static u8 hci_cc_write_ssp_mode(struct hci_dev *hdev, void *data,
--
net/bluetooth/hci_event.c-636-
net/bluetooth/hci_event.c:637: hci_dev_lock(hdev);
net/bluetooth/hci_event.c-638-
--
net/bluetooth/hci_event.c=658=static u8 hci_cc_write_sc_support(struct hci_dev *hdev, void *data,
--
net/bluetooth/hci_event.c-669-
net/bluetooth/hci_event.c:670: hci_dev_lock(hdev);
net/bluetooth/hci_event.c-671-
--
net/bluetooth/hci_event.c=713=static u8 hci_cc_read_enc_key_size(struct hci_dev *hdev, void *data,
--
net/bluetooth/hci_event.c-724-
net/bluetooth/hci_event.c:725: hci_dev_lock(hdev);
net/bluetooth/hci_event.c-726-
--
net/bluetooth/hci_event.c=796=static u8 hci_cc_read_auth_payload_timeout(struct hci_dev *hdev, void *data,
--
net/bluetooth/hci_event.c-806-
]
]
|
| 46/2 |
2026/05/19 05:51 |
llm |
expert |
0m
Model:
Tokens:
input: 68551
output: 45
thoughts: 1456
Thoughts: **Analyzing a Bluetooth Device Lock Contention**
Okay, here's the breakdown of what I'm seeing. It looks like we've got a lock contention issue in the Bluetooth stack, specifically with the `hdev` (HCI device) lock.
First off, I'm observing that `hci_event_packet` at line 7736 is taking `hci_dev_lock(hdev)`. This implies that the `rx_work` is blocked on this lock acquisition. The question now is, who's holding this lock?
Let's trace it down. `hci_cmd_sync_work` acquires *two* locks: `hdev->req_lock` and then *potentially* `hdev->lock`. If `entry->func` inside `hci_cmd_sync_work` tries to take the `hdev->lock`, `hci_cmd_sync_work` would be holding both. However, the trace doesn't show the expected lock held by the worker, specifically `kworker/u9:4/5979`.
If, however, `entry->func` is blocked *trying* to acquire `hdev->lock`, the picture changes. In this scenario, `kworker/u9:4/5979` is blocked on `hdev->lock` while holding `hdev->req_lock`, and another worker, `kworker/u9:10/11292`, is also blocked on the *same* `hdev->lock`. This seems like a likely candidate for the deadlock.
Now, who's the prime suspect for holding `hdev->lock`? It looks like `syz-executor:5969`, which is related to fuzzing. It's blocked in `__flush_work`, which is a bit strange, but it's *in* `hci_unregister_dev`. The relevant code snippet at line 2705 shows that `hci_unregister_dev` calls `disable_work_sync(&hdev->rx_work)` *before* the lock is taken, but the code later acquires the lock at line 2720, but only after it checks whether the device is initialized and set up.
Okay, let's explore another possibility. If `syz-executor:5969` isn't in `hci_unregister_dev`, it could be inside `hci_dev_do_close` as called from `hci_sock_release`.
`hci_sock_release` calls `hci_dev_do_close(hdev)`. `hci_dev_do_close` then calls `hci_req_sync_lock(hdev)`. So, if `syz-executor:5969` were blocked in `hci_dev_do_close`, it *should* be blocked on `hci_req_sync_lock(hdev)` because `kworker/u9:4/5979` has that lock! The trace says it's in `__flush_work`, meaning it's not.
Then `hci_dev_do_close` calls `hci_req_sync_lock(hdev)`, then `hci_dev_close_sync(hdev)`. If `syz-executor:5969` *did* acquire `hci_req_sync_lock(hdev)`, `kworker/u9:4/5979` would *not* be able to hold `hdev->req_lock` for the *same* `hdev`.
Aha! Now things are becoming clear. `kworker/u9:4/5979` holds `hdev->req_lock` *for* `hci4`. `kworker/u9:10/11292` is running `rx_work` *for* `hci4#2`. This looks like *different* workqueues, even though they operate on the *same* `hdev`.
Let's look more closely at the workqueue names. `hci4` seems to be the workqueue name, but `hci4#2` must mean it's a second *instance* or a different lockdep class of a workqueue with the same name. It is the same device, but it looks like the *workqueues* are distinct.
The workqueue is allocated with `alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | WQ_MEM_RECLAIM, 1, hdev->name)`, where `hdev->name` is "hci4". If multiple workqueues are allocated with the same name, lockdep appends `#2`, etc.
Wait, `
|
| 47/2 |
2026/05/19 05:52 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_core.c IncludeLines:true Name:hci_alloc_dev_priv]
Results: map[SourceCode:2436: /* Alloc HCI device */
2437: struct hci_dev *hci_alloc_dev_priv(int sizeof_priv)
2438: {
2439: struct hci_dev *hdev;
2440: unsigned int alloc_size;
2441:
2442: alloc_size = sizeof(*hdev);
2443: if (sizeof_priv) {
2444: /* Fixme: May need ALIGN-ment? */
2445: alloc_size += sizeof_priv;
2446: }
2447:
2448: hdev = kzalloc(alloc_size, GFP_KERNEL);
2449: if (!hdev)
2450: return NULL;
2451:
2452: if (init_srcu_struct(&hdev->srcu)) {
2453: kfree(hdev);
2454: return NULL;
2455: }
2456:
2457: hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1);
2458: hdev->esco_type = (ESCO_HV1);
2459: hdev->link_mode = (HCI_LM_ACCEPT);
2460: hdev->num_iac = 0x01; /* One IAC support is mandatory */
2461: hdev->io_capability = 0x03; /* No Input No Output */
2462: hdev->manufacturer = 0xffff; /* Default to internal use */
2463: hdev->inq_tx_power = HCI_TX_POWER_INVALID;
2464: hdev->adv_tx_power = HCI_TX_POWER_INVALID;
2465: hdev->adv_instance_cnt = 0;
2466: hdev->cur_adv_instance = 0x00;
2467: hdev->adv_instance_timeout = 0;
2468:
2469: hdev->advmon_allowlist_duration = 300;
2470: hdev->advmon_no_filter_duration = 500;
2471: hdev->enable_advmon_interleave_scan = 0x00; /* Default to disable */
2472:
2473: hdev->sniff_max_interval = 800;
2474: hdev->sniff_min_interval = 80;
2475:
2476: hdev->le_adv_channel_map = 0x07;
2477: hdev->le_adv_min_interval = 0x0800;
2478: hdev->le_adv_max_interval = 0x0800;
2479: hdev->le_scan_interval = DISCOV_LE_SCAN_INT_FAST;
2480: hdev->le_scan_window = DISCOV_LE_SCAN_WIN_FAST;
2481: hdev->le_scan_int_suspend = DISCOV_LE_SCAN_INT_SLOW1;
2482: hdev->le_scan_window_suspend = DISCOV_LE_SCAN_WIN_SLOW1;
2483: hdev->le_scan_int_discovery = DISCOV_LE_SCAN_INT;
2484: hdev->le_scan_window_discovery = DISCOV_LE_SCAN_WIN;
2485: hdev->le_scan_int_adv_monitor = DISCOV_LE_SCAN_INT_FAST;
2486: hdev->le_scan_window_adv_monitor = DISCOV_LE_SCAN_WIN_FAST;
2487: hdev->le_scan_int_connect = DISCOV_LE_SCAN_INT_CONN;
2488: hdev->le_scan_window_connect = DISCOV_LE_SCAN_WIN_CONN;
2489: hdev->le_conn_min_interval = 0x0018;
2490: hdev->le_conn_max_interval = 0x0028;
2491: hdev->le_conn_latency = 0x0000;
2492: hdev->le_supv_timeout = 0x002a;
2493: hdev->le_def_tx_len = 0x001b;
2494: hdev->le_def_tx_time = 0x0148;
2495: hdev->le_max_tx_len = 0x001b;
2496: hdev->le_max_tx_time = 0x0148;
2497: hdev->le_max_rx_len = 0x001b;
2498: hdev->le_max_rx_time = 0x0148;
2499: hdev->le_max_key_size = SMP_MAX_ENC_KEY_SIZE;
2500: hdev->le_min_key_size = SMP_MIN_ENC_KEY_SIZE;
2501: hdev->le_tx_def_phys = HCI_LE_SET_PHY_1M;
2502: hdev->le_rx_def_phys = HCI_LE_SET_PHY_1M;
2503: hdev->le_num_of_adv_sets = HCI_MAX_ADV_INSTANCES;
2504: hdev->def_multi_adv_rotation_duration = HCI_DEFAULT_ADV_DURATION;
2505: hdev->def_le_autoconnect_timeout = HCI_LE_CONN_TIMEOUT;
2506: hdev->min_le_tx_power = HCI_TX_POWER_INVALID;
2507: hdev->max_le_tx_power = HCI_TX_POWER_INVALID;
2508:
2509: hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT;
2510: hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT;
2511: hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE;
2512: hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE;
2513: hdev->auth_payload_timeout = DEFAULT_AUTH_PAYLOAD_TIMEOUT;
2514: hdev->min_enc_key_size = HCI_MIN_ENC_KEY_SIZE;
2515:
2516: /* default 1.28 sec page scan */
2517: hdev->def_page_scan_type = PAGE_SCAN_TYPE_STANDARD;
2518: hdev->def_page_scan_int = 0x0800;
2519: hdev->def_page_scan_window = 0x0012;
2520:
2521: mutex_init(&hdev->lock);
2522: mutex_init(&hdev->req_lock);
2523: mutex_init(&hdev->mgmt_pending_lock);
2524:
2525: ida_init(&hdev->unset_handle_ida);
2526:
2527: INIT_LIST_HEAD(&hdev->mesh_pending);
2528: INIT_LIST_HEAD(&hdev->mgmt_pending);
2529: INIT_LIST_HEAD(&hdev->reject_list);
2530: INIT_LIST_HEAD(&hdev->accept_list);
2531: INIT_LIST_HEAD(&hdev->uuids);
2532: INIT_LIST_HEAD(&hdev->link_keys);
2533: INIT_LIST_HEAD(&hdev->long_term_keys);
2534: INIT_LIST_HEAD(&hdev->identity_resolving_keys);
2535: INIT_LIST_HEAD(&hdev->remote_oob_data);
2536: INIT_LIST_HEAD(&hdev->le_accept_list);
2537: INIT_LIST_HEAD(&hdev->le_resolv_list);
2538: INIT_LIST_HEAD(&hdev->le_conn_params);
2539: INIT_LIST_HEAD(&hdev->pend_le_conns);
2540: INIT_LIST_HEAD(&hdev->pend_le_reports);
2541: INIT_LIST_HEAD(&hdev->conn_hash.list);
2542: INIT_LIST_HEAD(&hdev->adv_instances);
2543: INIT_LIST_HEAD(&hdev->blocked_keys);
2544: INIT_LIST_HEAD(&hdev->monitored_devices);
2545:
2546: INIT_LIST_HEAD(&hdev->local_codecs);
2547: INIT_WORK(&hdev->rx_work, hci_rx_work);
2548: INIT_WORK(&hdev->cmd_work, hci_cmd_work);
2549: INIT_WORK(&hdev->tx_work, hci_tx_work);
2550: INIT_WORK(&hdev->power_on, hci_power_on);
2551: INIT_WORK(&hdev->error_reset, hci_error_reset);
2552:
2553: hci_cmd_sync_init(hdev);
2554:
2555: INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
2556:
2557: skb_queue_head_init(&hdev->rx_q);
2558: skb_queue_head_init(&hdev->cmd_q);
2559: skb_queue_head_init(&hdev->raw_q);
2560:
2561: init_waitqueue_head(&hdev->req_wait_q);
2562:
2563: INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout);
2564: INIT_DELAYED_WORK(&hdev->ncmd_timer, hci_ncmd_timeout);
2565:
2566: hci_devcd_setup(hdev);
2567:
2568: hci_init_sysfs(hdev);
2569: discovery_init(hdev);
2570:
2571: return hdev;
2572: }
SourceFile:net/bluetooth/hci_core.c]
|
| 48/2 |
2026/05/19 05:52 |
llm |
expert |
0m
Model:
Tokens:
input: 73880
output: 43
thoughts: 29
Thoughts: Okay, here's my interpretation of those thoughts, summarized from an expert's perspective, presented as a personal thought process:
**Diving Deep into HCI Device Registration**
Alright, I'm tracing through this `hci_register_dev` function again, trying to solidify my understanding of the device initialization. And, it hits me: I need to explicitly acknowledge the memory allocation for `hdev->workqueue` and `hdev->req_workqueue`. I was just about to gloss over it, but those are *crucial*. They're the work queues that handle asynchronous operations for the HCI device. I'm digging into where they are allocated, because I know that is very important to track how those queues are used. It's a key part of the device setup. Now, I have a firm handle on the critical allocation points in the register function.
|
| 49/2 |
2026/05/19 05:52 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_core.c IncludeLines:true Name:hci_register_dev]
Results: map[SourceCode:2583: /* Register HCI device */
2584: int hci_register_dev(struct hci_dev *hdev)
2585: {
2586: int id, error;
2587:
2588: if (!hdev->open || !hdev->close || !hdev->send)
2589: return -EINVAL;
2590:
2591: id = ida_alloc_max(&hci_index_ida, HCI_MAX_ID - 1, GFP_KERNEL);
2592: if (id < 0)
2593: return id;
2594:
2595: error = dev_set_name(&hdev->dev, "hci%u", id);
2596: if (error)
2597: return error;
2598:
2599: hdev->name = dev_name(&hdev->dev);
2600: hdev->id = id;
2601:
2602: BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
2603:
2604: hdev->workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI, hdev->name);
2605: if (!hdev->workqueue) {
2606: error = -ENOMEM;
2607: goto err;
2608: }
2609:
2610: hdev->req_workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI,
2611: hdev->name);
2612: if (!hdev->req_workqueue) {
2613: destroy_workqueue(hdev->workqueue);
2614: error = -ENOMEM;
2615: goto err;
2616: }
2617:
2618: if (!IS_ERR_OR_NULL(bt_debugfs))
2619: hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs);
2620:
2621: error = device_add(&hdev->dev);
2622: if (error < 0)
2623: goto err_wqueue;
2624:
2625: hci_leds_init(hdev);
2626:
2627: hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
2628: RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
2629: hdev);
2630: if (hdev->rfkill) {
2631: if (rfkill_register(hdev->rfkill) < 0) {
2632: rfkill_destroy(hdev->rfkill);
2633: hdev->rfkill = NULL;
2634: }
2635: }
2636:
2637: if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
2638: hci_dev_set_flag(hdev, HCI_RFKILLED);
2639:
2640: hci_dev_set_flag(hdev, HCI_SETUP);
2641: hci_dev_set_flag(hdev, HCI_AUTO_OFF);
2642:
2643: /* Assume BR/EDR support until proven otherwise (such as
2644: * through reading supported features during init.
2645: */
2646: hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
2647:
2648: write_lock(&hci_dev_list_lock);
2649: list_add(&hdev->list, &hci_dev_list);
2650: write_unlock(&hci_dev_list_lock);
2651:
2652: /* Devices that are marked for raw-only usage are unconfigured
2653: * and should not be included in normal operation.
2654: */
2655: if (hci_test_quirk(hdev, HCI_QUIRK_RAW_DEVICE))
2656: hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
2657:
2658: /* Mark Remote Wakeup connection flag as supported if driver has wakeup
2659: * callback.
2660: */
2661: if (hdev->wakeup)
2662: hdev->conn_flags |= HCI_CONN_FLAG_REMOTE_WAKEUP;
2663:
2664: hci_sock_dev_event(hdev, HCI_DEV_REG);
2665: hci_dev_hold(hdev);
2666:
2667: error = hci_register_suspend_notifier(hdev);
2668: if (error)
2669: BT_WARN("register suspend notifier failed error:%d\n", error);
2670:
2671: queue_work(hdev->req_workqueue, &hdev->power_on);
2672:
2673: idr_init(&hdev->adv_monitors_idr);
2674: msft_register(hdev);
2675:
2676: return id;
2677:
2678: err_wqueue:
2679: debugfs_remove_recursive(hdev->debugfs);
2680: destroy_workqueue(hdev->workqueue);
2681: destroy_workqueue(hdev->req_workqueue);
2682: err:
2683: ida_free(&hci_index_ida, hdev->id);
2684:
2685: return error;
2686: }
SourceFile:net/bluetooth/hci_core.c]
|
| 50/2 |
2026/05/19 05:52 |
llm |
expert |
0m
Model:
Tokens:
input: 75755
output: 43
thoughts: 2954
Thoughts: **Analysis of a Potential Bluetooth Deadlock**
Okay, here's the breakdown of my thinking. I've got this scenario where a Bluetooth device (`hci4`, specifically, although the issue seems to span multiple devices: `hci2`, `hci4`, and `hci6`) might be deadlocked, and I'm using the provided trace to piece together what's going on.
First, I established the connections: `hdev->workqueue` and `hdev->req_workqueue` are both named after the device (`hci4` or its equivalent), and work items are queued on each. `cmd_sync_work` goes to `req_workqueue`, and `rx_work` to the `workqueue`. This confirms the workers in question are tied to the same device instance. I can see a worker (`kworker/u9:4/5979`) executing `cmd_sync_work` and another (`kworker/u9:10/11292`) handling `rx_work`, both apparently for `hci4`.
The key part is that the `cmd_sync_work` worker holds `hdev->req_lock`. The other worker, `rx_work`, is blocked trying to get the `hdev->lock`. There's also this other process, `syz-executor:5969`, stuck in `__flush_work`. My thinking is that if `syz-executor` is in `hci_unregister_dev`, it will call `disable_work_sync(&hdev->rx_work)`. So, `syz-executor` seems to be waiting for `rx_work` to finish, but `rx_work` is blocked on a lock. This is where it gets interesting...
If `kworker/u9:4/5979` is holding `hdev->req_lock`, and `rx_work` is blocked on `hdev->lock`, this could suggest a deadlock. However, if that worker also held `hdev->lock`, lockdep *should* have shown it, but it doesn't. So, that worker is *not* the one holding `hdev->lock`. This tells me the current state of locks held is this:
* `kworker/u9:4/5979`: Holds `hdev->req_lock` *but* not `hdev->lock`.
* `kworker/u9:10/11292`: Blocked, trying to get `hdev->lock`.
* `syz-executor:5969`: Blocked, in a flush operation, which is related to `rx_work`.
Since the trace says only 3 locks are held, this doesn't tell us who's holding the lock we care about.
Now, my attention shifted to the other worker, `kworker/u9:11/12552`. It has 7 locks held. It *could* be involved in another hdev. I considered what this worker might be doing: could it be `power_on`, which *does* take both `hdev->req_lock` and `hdev->lock`? However, `power_on` is queued on the `req_workqueue`. The `req_workqueue` is ordered, so only one task can run at a time. The other workers also handle hdevs and their respective `cmd_sync_work` function so I have to analyze if they're involved.
I reviewed code paths to see if the device unregistration (`vhci_release`, `hci_sock_release`) could be holding `hdev->lock`. The trace suggests `syz-executor` might be in `hci_unregister_dev`. `vhci_release` doesn't hold `hdev->lock`. `hci_sock_release` calls `hci_dev_do_close` which has a path that takes `hdev->req_lock` and calls `flush_work(&hdev->rx_work)`. I concluded that `syz-executor:5969` *cannot* be stuck in `hci_dev_do_close`.
So, `syz-executor` must be in `hci_unregister_dev`. But, `hci_unregister_dev` calls `disable_work_sync(&hdev->rx_work)` *before* it gets `hdev->req_lock`. This means `syz-executor` could indeed be stuck in the `__flush_work` if `rx_work` is indeed blocked. So, I have to find out who's holding `hdev->lock`. The workqueue setup also confirms that one `cmd_sync_work` can
|
| 51/2 |
2026/05/19 05:52 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_core.c IncludeLines:true Name:hci_error_reset]
Results: map[SourceCode:1022: static void hci_error_reset(struct work_struct *work)
1023: {
1024: struct hci_dev *hdev = container_of(work, struct hci_dev, error_reset);
1025:
1026: hci_dev_hold(hdev);
1027: BT_DBG("%s", hdev->name);
1028:
1029: if (hdev->hw_error)
1030: hdev->hw_error(hdev, hdev->hw_error_code);
1031: else
1032: bt_dev_err(hdev, "hardware error 0x%2.2x", hdev->hw_error_code);
1033:
1034: if (!hci_dev_do_close(hdev))
1035: hci_dev_do_open(hdev);
1036:
1037: hci_dev_put(hdev);
1038: }
SourceFile:net/bluetooth/hci_core.c]
|
| 52/2 |
2026/05/19 05:52 |
llm |
expert |
0m
Model:
Tokens:
input: 80080
output: 43
thoughts: 220
Thoughts: **Analyzing a Potential Race Condition**
Okay, so I'm looking at this `hci_error_reset` function. It seems it calls `hci_dev_do_close` which then, crucially, attempts to acquire the `hci_req_sync_lock` on the `hdev` device. I see that if `kworker/u9:11/12552` is running `hci_error_reset`, it could potentially get blocked waiting for that lock. My immediate concern is, what process is already *holding* that lock?
Now, if `kworker/u9:4/5979` has a lock on it, it would cause `kworker/u9:11/12552` to stall! But wait a second, if `kworker/u9:11/12552` *is* blocked on `hci_req_sync_lock`, it *wouldn't* be holding the device's main `hdev->lock` at that moment, because `hci_dev_do_close` grabs the request lock *before* the main device lock (though, thinking about it, `hci_dev_close_sync` *does* acquire the device lock later).
I need to back up and think this through more clearly. What about another case? Let's say `kworker/u9:11/12552` is running `hci_power_on`?
|
| 53/2 |
2026/05/19 05:52 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_core.c IncludeLines:true Name:hci_power_on]
Results: map[SourceCode: 943: static void hci_power_on(struct work_struct *work)
944: {
945: struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
946: int err;
947:
948: BT_DBG("%s", hdev->name);
949:
950: if (test_bit(HCI_UP, &hdev->flags) &&
951: hci_dev_test_flag(hdev, HCI_MGMT) &&
952: hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) {
953: cancel_delayed_work(&hdev->power_off);
954: err = hci_powered_update_sync(hdev);
955: mgmt_power_on(hdev, err);
956: return;
957: }
958:
959: err = hci_dev_do_open(hdev);
960: if (err < 0) {
961: hci_dev_lock(hdev);
962: mgmt_set_powered_failed(hdev, err);
963: hci_dev_unlock(hdev);
964: return;
965: }
966:
967: /* During the HCI setup phase, a few error conditions are
968: * ignored and they need to be checked now. If they are still
969: * valid, it is important to turn the device back off.
970: */
971: if (hci_dev_test_flag(hdev, HCI_RFKILLED) ||
972: hci_dev_test_flag(hdev, HCI_UNCONFIGURED) ||
973: (!bacmp(&hdev->bdaddr, BDADDR_ANY) &&
974: !bacmp(&hdev->static_addr, BDADDR_ANY))) {
975: hci_dev_clear_flag(hdev, HCI_AUTO_OFF);
976: hci_dev_do_close(hdev);
977: } else if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) {
978: queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
979: HCI_AUTO_OFF_TIMEOUT);
980: }
981:
982: if (hci_dev_test_and_clear_flag(hdev, HCI_SETUP)) {
983: /* For unconfigured devices, set the HCI_RAW flag
984: * so that userspace can easily identify them.
985: */
986: if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
987: set_bit(HCI_RAW, &hdev->flags);
988:
989: /* For fully configured devices, this will send
990: * the Index Added event. For unconfigured devices,
991: * it will send Unconfigued Index Added event.
992: *
993: * Devices with HCI_QUIRK_RAW_DEVICE are ignored
994: * and no event will be send.
995: */
996: mgmt_index_added(hdev);
997: } else if (hci_dev_test_and_clear_flag(hdev, HCI_CONFIG)) {
998: /* When the controller is now configured, then it
999: * is important to clear the HCI_RAW flag.
1000: */
1001: if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
1002: clear_bit(HCI_RAW, &hdev->flags);
1003:
1004: /* Powering on the controller with HCI_CONFIG set only
1005: * happens with the transition from unconfigured to
1006: * configured. This will send the Index Added event.
1007: */
1008: mgmt_index_added(hdev);
1009: }
1010: }
SourceFile:net/bluetooth/hci_core.c]
|
| 54/2 |
2026/05/19 05:52 |
llm |
expert |
0m
Model:
Tokens:
input: 81842
output: 45
thoughts: 35
Thoughts: Here's my summary, as the thought process unfolds:
**Digging into the Bluetooth Device Power-On Sequence**
Alright, so `hci_power_on` is the function that's responsible for, well, powering on the Bluetooth device. Makes sense. Now, let's see what happens within that function. Ah, here it is: `hci_dev_do_open(hdev)`. Okay, so that's the next logical step β `hci_dev_do_open` is the function that's likely the core logic for the device's initialization and bringing it online. Seems like a critical spot to investigate further. Time to dive into the implementation of `hci_dev_do_open` and figure out what exactly it's doing with that `hdev` handle. I expect there'll be resource allocation, hardware initialization, and likely some sort of connection setup or state machine transition happening in there. Let's get to it.
|
| 55/2 |
2026/05/19 05:52 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_core.c IncludeLines:true Name:hci_dev_do_open]
Results: map[SourceCode: 422: static int hci_dev_do_open(struct hci_dev *hdev)
423: {
424: int ret = 0;
425:
426: BT_DBG("%s %p", hdev->name, hdev);
427:
428: hci_req_sync_lock(hdev);
429:
430: ret = hci_dev_open_sync(hdev);
431:
432: hci_req_sync_unlock(hdev);
433: return ret;
434: }
SourceFile:net/bluetooth/hci_core.c]
|
| 56/2 |
2026/05/19 05:52 |
llm |
expert |
0m
Model:
Tokens:
input: 82330
output: 44
thoughts: 1341
Thoughts: **Analyzing a Potential Deadlock in Bluetooth Device Unregistration**
Okay, here's what's running through my head. I'm looking at a potential deadlock scenario related to Bluetooth device unregistration. Let's break it down.
First, I see that `hci_dev_do_open` takes `hdev->req_lock`, and so does `hci_power_on`. If the kernel worker thread `kworker/u9:4/5979` holds `hdev->req_lock`, then `hci_power_on` could be blocked waiting for that lock. This is the starting point.
Now, this `kworker` thread is running `cmd_sync_work`. What if `cmd_sync_work` itself is blocked on `hdev->lock`? This complicates things. If that's true, who's holding `hdev->lock`? Could it be `syz-executor:5969` which is running inside `hci_unregister_dev`?
Looking at the code for `hci_unregister_dev`, specifically lines like 2705 where `disable_work_sync(&hdev->rx_work)` is called. Aha! `hci_unregister_dev` is calling `disable_work_sync` on various workqueues. If `rx_work` is blocked on `hdev->lock`, this `disable_work_sync` will block indefinitely if the thread holding `hdev->lock` is waiting for `rx_work` to complete. That's a textbook deadlock.
So the question becomes: is there a thread that is currently holding `hdev->lock` *and* waiting for `rx_work`? `hci_unregister_dev` itself, it doesn't hold `hdev->lock` at line 2705, so that's not it. However, if `kworker/u9:4/5979` (running `cmd_sync_work`) holds `hdev->lock`, and `cmd_sync_work` then waits for `rx_work`, we have a deadlock.
Let me think. Is there any situation where `cmd_sync_work` would be blocked on something inside `rx_work`? Looking at the `entry->func` code path within `cmd_sync_work`, is it taking `hdev->lock`, and then waiting for `rx_work`? I don't see `flush_work` being called. What is the blocking function of the work queue?
Wait! What if `entry->func` is blocked on something else, but that "something else" involves waiting for `hdev->lock`, and at the same time `rx_work` is also waiting for `hdev->lock`? Who is holding `hdev->lock` in this scenario? I need to check if there are *any* other threads holding the lock right now. There's `kworker/u9:11/12552`... but is that even on the same device?
Now I see `syz-executor:5969` is blocked in `__flush_work`. If it's in `hci_unregister_dev`, it might be blocked in `disable_work_sync` called on the `rx_work`, `cmd_work`, `tx_work`, `power_on`, or `error_reset` workqueues. Or perhaps `cancel_work_sync` in `hci_cmd_sync_clear`. If blocked in `cancel_work_sync` then it's waiting for `cmd_sync_work` to finish. But why is `cmd_sync_work` blocked? `cmd_sync_work` in turn calls `entry->func`. I've got to understand what `entry->func` does.
Is `entry->func` itself blocking? Is it `hci_cmd_sync_cancel_sync`? No, that's not a work func. Is it `hci_dev_close_sync`? Nope. Is it blocked on something within `hci_unregister_dev`? Does it try to acquire `hdev->unregister_lock`? No. What if `entry->func` is blocked on `hdev->lock`, and `hdev->lock` is held by `rx_work`? Let me see... `rx_work` is running on `kworker/u9:10/11292`. I see that it IS blocked on `hdev->lock`! But it does NOT hold the lock.
Okay, so if `rx_work` is *waiting* for `hdev->lock`, and `cmd_sync_work` is trying to run on
|
| 57/2 |
2026/05/19 05:53 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_sock.c IncludeLines:true Name:hci_sock_sendmsg]
Results: map[SourceCode:1800: static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg,
1801: size_t len)
1802: {
1803: struct sock *sk = sock->sk;
1804: struct hci_mgmt_chan *chan;
1805: struct hci_dev *hdev;
1806: struct sk_buff *skb;
1807: int err;
1808: const unsigned int flags = msg->msg_flags;
1809:
1810: BT_DBG("sock %p sk %p", sock, sk);
1811:
1812: if (flags & MSG_OOB)
1813: return -EOPNOTSUPP;
1814:
1815: if (flags & ~(MSG_DONTWAIT | MSG_NOSIGNAL | MSG_ERRQUEUE | MSG_CMSG_COMPAT))
1816: return -EINVAL;
1817:
1818: if (len < 4 || len > hci_pi(sk)->mtu)
1819: return -EINVAL;
1820:
1821: skb = bt_skb_sendmsg(sk, msg, len, len, 0, 0);
1822: if (IS_ERR(skb))
1823: return PTR_ERR(skb);
1824:
1825: lock_sock(sk);
1826:
1827: switch (hci_pi(sk)->channel) {
1828: case HCI_CHANNEL_RAW:
1829: case HCI_CHANNEL_USER:
1830: break;
1831: case HCI_CHANNEL_MONITOR:
1832: err = -EOPNOTSUPP;
1833: goto drop;
1834: case HCI_CHANNEL_LOGGING:
1835: err = hci_logging_frame(sk, skb, flags);
1836: goto drop;
1837: default:
1838: mutex_lock(&mgmt_chan_list_lock);
1839: chan = __hci_mgmt_chan_find(hci_pi(sk)->channel);
1840: if (chan)
1841: err = hci_mgmt_cmd(chan, sk, skb);
1842: else
1843: err = -EINVAL;
1844:
1845: mutex_unlock(&mgmt_chan_list_lock);
1846: goto drop;
1847: }
1848:
1849: hdev = hci_hdev_from_sock(sk);
1850: if (IS_ERR(hdev)) {
1851: err = PTR_ERR(hdev);
1852: goto drop;
1853: }
1854:
1855: if (!test_bit(HCI_UP, &hdev->flags)) {
1856: err = -ENETDOWN;
1857: goto drop;
1858: }
1859:
1860: hci_skb_pkt_type(skb) = skb->data[0];
1861: skb_pull(skb, 1);
1862:
1863: if (hci_pi(sk)->channel == HCI_CHANNEL_USER) {
1864: /* No permission check is needed for user channel
1865: * since that gets enforced when binding the socket.
1866: *
1867: * However check that the packet type is valid.
1868: */
1869: if (hci_skb_pkt_type(skb) != HCI_COMMAND_PKT &&
1870: hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT &&
1871: hci_skb_pkt_type(skb) != HCI_SCODATA_PKT &&
1872: hci_skb_pkt_type(skb) != HCI_ISODATA_PKT &&
1873: hci_skb_pkt_type(skb) != HCI_DRV_PKT) {
1874: err = -EINVAL;
1875: goto drop;
1876: }
1877:
1878: skb_queue_tail(&hdev->raw_q, skb);
1879: queue_work(hdev->workqueue, &hdev->tx_work);
1880: } else if (hci_skb_pkt_type(skb) == HCI_COMMAND_PKT) {
1881: u16 opcode = get_unaligned_le16(skb->data);
1882: u16 ogf = hci_opcode_ogf(opcode);
1883: u16 ocf = hci_opcode_ocf(opcode);
1884:
1885: if (((ogf > HCI_SFLT_MAX_OGF) ||
1886: !hci_test_bit(ocf & HCI_FLT_OCF_BITS,
1887: &hci_sec_filter.ocf_mask[ogf])) &&
1888: !capable(CAP_NET_RAW)) {
1889: err = -EPERM;
1890: goto drop;
1891: }
1892:
1893: /* Since the opcode has already been extracted here, store
1894: * a copy of the value for later use by the drivers.
1895: */
1896: hci_skb_opcode(skb) = opcode;
1897:
1898: if (ogf == 0x3f) {
1899: skb_queue_tail(&hdev->raw_q, skb);
1900: queue_work(hdev->workqueue, &hdev->tx_work);
1901: } else {
1902: /* Stand-alone HCI commands must be flagged as
1903: * single-command requests.
1904: */
1905: bt_cb(skb)->hci.req_flags |= HCI_REQ_START;
1906:
1907: skb_queue_tail(&hdev->cmd_q, skb);
1908: queue_work(hdev->workqueue, &hdev->cmd_work);
1909: }
1910: } else {
1911: if (!capable(CAP_NET_RAW)) {
1912: err = -EPERM;
1913: goto drop;
1914: }
1915:
1916: if (hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT &&
1917: hci_skb_pkt_type(skb) != HCI_SCODATA_PKT &&
1918: hci_skb_pkt_type(skb) != HCI_ISODATA_PKT) {
1919: err = -EINVAL;
1920: goto drop;
1921: }
1922:
1923: skb_queue_tail(&hdev->raw_q, skb);
1924: queue_work(hdev->workqueue, &hdev->tx_work);
1925: }
1926:
1927: err = len;
1928:
1929: done:
1930: release_sock(sk);
1931: return err;
1932:
1933: drop:
1934: kfree_skb(skb);
1935: goto done;
1936: }
SourceFile:net/bluetooth/hci_sock.c]
|
| 58/2 |
2026/05/19 05:53 |
llm |
expert |
0m
Model:
Tokens:
input: 86870
output: 43
thoughts: 737
Thoughts: **Debugging a Bluetooth Locking Issue**
Okay, so I'm trying to figure out a deadlock in the Bluetooth stack. It looks like `syz-executor:5969` is blocked in `__flush_work`, and I need to figure out why. First, I need to understand the lock hierarchy around the `hdev->lock`. I know `hci_sock_sendmsg` *doesn't* take `hdev->lock`, so that's not the issue. I need to consider what functions do. I wonder, what about `hci_mgmt_cmd`? That's a good place to start. It calls the handler for the management command, and a lot of those handlers *do* take `hdev->lock`, like `set_powered` which calls `hci_dev_lock(hdev)`.
Alright, I see. Since it's blocked in `__flush_work`, it *can't* be in `hci_sock_sendmsg`. Could it be in `hci_unregister_dev`? Yes, `vhci_release` calls `hci_unregister_dev`, which calls `disable_work_sync(&hdev->rx_work)`. Bingo. That's a clue because `rx_work` is blocked on `hdev->lock`.
Now, who *holds* `hdev->lock`? I checked `hci_unregister_dev` and `vhci_release`, and neither do. Could `hci_cmd_sync_work` be doing it? If `hci_cmd_sync_work` is running `entry->func`, and `entry->func` takes the lock, then it could be holding it, right? But the stack trace for `kworker/u9:4/5979` doesn't show `hdev->lock` as held. Weird.
Could the `entry->func` be `hci_dev_close_sync`? No, it's not queued via `hci_cmd_sync_queue`. Or `hci_cmd_sync_cancel_sync`? Nope. Or `hci_power_on`? No, that's a work function, not the direct function. What if `kworker/u9:4/5979` is *blocked* trying to acquire the lock?
Okay, who actually *has* it? Maybe `kworker/u9:11/12552`? Let me see what that worker is doing... It's holding *seven* locks! Could it be running `hci_rx_work` for another device? Now that's interesting. If it's running `hci_rx_work` for `hci4`, it could be holding `hdev->lock`. Wait, isn't `kworker/u9:10/11292` already running `hci_rx_work` for `hci4#2`?
Can there be *two* `hci_rx_work` running for the *same* device? No, `rx_work` is a single `work_struct`; it can't run concurrently. What if `kworker/u9:11/12552` is running `hci_cmd_work` for `hci4`? Does *that* take `hdev->lock`? I need to check `hci_cmd_work`. I have a feeling I'm getting close.
|
| 59/2 |
2026/05/19 05:53 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_core.c IncludeLines:true Name:hci_cmd_work]
Results: map[SourceCode:4137: static void hci_cmd_work(struct work_struct *work)
4138: {
4139: struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
4140: struct sk_buff *skb;
4141: int err;
4142:
4143: BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
4144: atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
4145:
4146: /* Send queued commands */
4147: if (atomic_read(&hdev->cmd_cnt)) {
4148: skb = skb_dequeue(&hdev->cmd_q);
4149: if (!skb)
4150: return;
4151:
4152: err = hci_send_cmd_sync(hdev, skb);
4153: if (err)
4154: return;
4155:
4156: rcu_read_lock();
4157: if (test_bit(HCI_RESET, &hdev->flags) ||
4158: hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
4159: cancel_delayed_work(&hdev->cmd_timer);
4160: else
4161: queue_delayed_work(hdev->workqueue, &hdev->cmd_timer,
4162: HCI_CMD_TIMEOUT);
4163: rcu_read_unlock();
4164: }
4165: }
SourceFile:net/bluetooth/hci_core.c]
|
| 60/2 |
2026/05/19 05:53 |
llm |
expert |
0m
Model:
Tokens:
input: 88881
output: 45
thoughts: 50
Thoughts: Okay, let's break this down.
**Investigating the HCI Command Transmission Path**
Right, so `hci_cmd_work` is calling `hci_send_cmd_sync`. I need to figure out the locking situation within this flow. Specifically, I need to know if `hci_send_cmd_sync` itself takes `hdev->lock`. This is critical for understanding potential race conditions and concurrency issues in the Bluetooth HCI driver. I'm going to jump into the `hci_send_cmd_sync` function definition and examine the code directly.
|
| 61/2 |
2026/05/19 05:53 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_sync.c IncludeLines:true Name:hci_send_cmd_sync]
Results: map[SourceCode:4101: static int hci_send_cmd_sync(struct hci_dev *hdev, struct sk_buff *skb)
4102: {
4103: int err;
4104:
4105: bt_dev_dbg(hdev, "skb %p", skb);
4106:
4107: kfree_skb(hdev->sent_cmd);
4108:
4109: hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
4110: if (!hdev->sent_cmd) {
4111: skb_queue_head(&hdev->cmd_q, skb);
4112: queue_work(hdev->workqueue, &hdev->cmd_work);
4113: return -EINVAL;
4114: }
4115:
4116: if (hci_skb_opcode(skb) != HCI_OP_NOP) {
4117: err = hci_send_frame(hdev, skb);
4118: if (err < 0) {
4119: hci_cmd_sync_cancel_sync(hdev, -err);
4120: return err;
4121: }
4122: atomic_dec(&hdev->cmd_cnt);
4123: } else {
4124: err = -ENODATA;
4125: kfree_skb(skb);
4126: }
4127:
4128: if (hdev->req_status == HCI_REQ_PEND &&
4129: !hci_dev_test_and_set_flag(hdev, HCI_CMD_PENDING)) {
4130: kfree_skb(hdev->req_skb);
4131: hdev->req_skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
4132: }
4133:
4134: return err;
4135: }
SourceFile:net/bluetooth/hci_core.c]
|
| 62/2 |
2026/05/19 05:53 |
llm |
expert |
0m
Model:
Tokens:
input: 89680
output: 43
thoughts: 118
Thoughts: Okay, let me think this through.
**Debugging Bluetooth HCI Command Synchronization**
Hmm, so `hci_send_cmd_sync` is apparently defined within `net/bluetooth/hci_core.c` according to the tool, but the line number seems off; it's 4101. That's a little strange. Maybe a version mismatch or something. Regardless, I need to get to the bottom of this.
Wait a second...I'm double-checking the code, and I see that `hci_send_cmd_sync` doesn't actually grab `hdev->lock`! That's interesting. I was assuming it would be protected by the device lock, but apparently not. This changes things.
Now, could `kworker/u9:11/12552` be the culprit? Is it running `hci_tx_work`? That worker process is a likely suspect. I need to figure out if that particular kernel worker is handling the transmit work. That could explain what I'm seeing.
And that leads me to my next question: Does `hci_tx_work` itself *take* `hdev->lock`? If it does, and `hci_send_cmd_sync` doesn't, we've got a potential race condition on our hands. I need to confirm the locking strategy in `hci_tx_work` ASAP. That's where I need to look now.
|
| 63/2 |
2026/05/19 05:53 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_core.c IncludeLines:true Name:hci_tx_work]
Results: map[SourceCode:3805: static void hci_tx_work(struct work_struct *work)
3806: {
3807: struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
3808: struct sk_buff *skb;
3809:
3810: BT_DBG("%s acl %d sco %d le %d iso %d", hdev->name, hdev->acl_cnt,
3811: hdev->sco_cnt, hdev->le_cnt, hdev->iso_cnt);
3812:
3813: if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
3814: /* Schedule queues and send stuff to HCI driver */
3815: hci_sched_sco(hdev, SCO_LINK);
3816: hci_sched_sco(hdev, ESCO_LINK);
3817: hci_sched_iso(hdev, CIS_LINK);
3818: hci_sched_iso(hdev, BIS_LINK);
3819: hci_sched_iso(hdev, PA_LINK);
3820: hci_sched_acl(hdev);
3821: hci_sched_le(hdev);
3822: }
3823:
3824: /* Send next queued raw (unknown type) packet */
3825: while ((skb = skb_dequeue(&hdev->raw_q)))
3826: hci_send_frame(hdev, skb);
3827: }
SourceFile:net/bluetooth/hci_core.c]
|
| 64/2 |
2026/05/19 05:53 |
llm |
expert |
0m
Model:
Tokens:
input: 90599
output: 40
thoughts: 4206
Thoughts: **Analysis of a Bluetooth HCI Lock Contention Deadlock**
Alright, let's break this down systematically. My initial thought process revolves around a potential deadlock scenario within the Bluetooth HCI (Host Controller Interface) driver, specifically involving workqueues and mutexes. The key threads involved appear to be `syz-executor`, a syzkaller fuzzing process, and a few kernel worker threads (`kworker`).
Initially, I see that `hci_tx_work` doesn't take `hdev->lock`, which seems normal. However, I'm concerned about the possibility of `kworker/u9:11/12552` running `hci_rx_work` and holding `hdev->lock` simultaneously. Then, I observe that `syz-executor:5969` is blocked in `disable_work_sync(&hdev->rx_work)` for `hci4`. This suggests `rx_work` on `hci4` is stalled, most likely waiting for `hdev->lock` on `hci4`. The question is, who has the lock?
My first inclination is to re-examine the `hci_unregister_dev` function, since device unregistration can involve resource cleanup and lock management. I note that it calls `hci_dev_do_close` which in turn calls `hci_req_sync_lock(hdev)`. If `syz-executor` is in `hci_unregister_dev`, I realize it would *not* be holding `hdev->lock` when it calls `disable_work_sync`. I then consider if `syz-executor` could be in `hci_dev_close_sync`, which *does* take `hdev->lock`. However, `hci_dev_close_sync` flushes the `rx_work` before taking the lock. So this seems unlikely, as `syz-executor` is waiting for `rx_work` to complete.
I also check the lockdep trace and note `kworker/u9:4/5979` for `hci4` holds `hdev->req_lock`, this is a very important fact. I conclude that `syz-executor` *cannot* be in `hci_dev_close_sync` because it doesn't hold `hdev->req_lock` if `kworker/u9:4/5979` is already holding it.
Back to `hci_unregister_dev`: I realize that `syz-executor` could call `hci_unregister_dev`, as it doesn't hold `hdev->req_lock`. Now, it is clear that `syz-executor` should be in `hci_unregister_dev`, blocked trying to disable `rx_work` on `hci4`. This blocking action is waiting on `hdev->lock`, so who holds this lock is still the issue. If `kworker/u9:4/5979` holds `hdev->lock`, then `syz-executor` will block forever. However, the lockdep trace does *not* show that thread holding `hdev->lock`. This seems very strange, as lockdep is *supposed* to list all held locks.
The lockdep trace for `kworker/u9:4/5979` explicitly lists three locks and *not* `hdev->lock`. So it doesn't hold `hdev->lock`, which leads me to look at `syz-executor` again. `syz-executor` may hold `hdev->lock` *before* calling `hci_unregister_dev`? No, since it does not acquire the lock in `vhci_release`.
If `syz-executor` is *not* in `hci_unregister_dev`, maybe it's in `hci_dev_close_sync`. However, that function flushes `rx_work` before acquiring `hdev->lock`. Another possibility is `syz-executor` is in `hci_cmd_sync_clear`, which could call `cancel_work_sync(&hdev->cmd_sync_work)`. If `kworker/u9:4/5979` holds `hdev->req_lock` and blocks during that call, it would cause `syz-executor` to block. That would imply `kworker/u9:4/5979` holds `hdev->req_lock` and is trying to acquire `hdev->lock`.
However, that does not make sense! I need to ensure if a thread is blocked trying to acquire a lock, then it shows up as *trying* to acquire it. Let me confirm the lockdep rules for showing locks that have been acquired, or are blocked.
|
| 65/2 |
2026/05/19 05:54 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:kernel/locking/mutex.c IncludeLines:true Name:__mutex_lock]
Results: map[SourceCode: 766: static int __sched
767: __mutex_lock(struct mutex *lock, unsigned int state, unsigned int subclass,
768: struct lockdep_map *nest_lock, unsigned long ip)
769: {
770: return __mutex_lock_common(lock, state, subclass, nest_lock, ip, NULL, false);
771: }
SourceFile:kernel/locking/mutex.c]
|
| 66/2 |
2026/05/19 05:54 |
llm |
expert |
0m
Model:
Tokens:
input: 96005
output: 42
thoughts: 12
Thoughts: Here's a summary of my immediate thought process:
**Diving into `__mutex_lock_common`**
Alright, time to dig into `__mutex_lock_common`. This is the core locking primitive, so understanding its behavior is crucial for any deeper debugging or performance analysis related to mutexes. I need to refresh my understanding of how this handles contention, potential race conditions, and any subtleties of the implementation specific to the current architecture. I'll be looking for things like how it interacts with the scheduler, atomic operations used, potential spin-waiting mechanisms (if any), and how it deals with recursive locking. My focus is going to be to identify the specific logic flow and look for the parts of the code that will lead to performance bottlenecks. Specifically, I'll be looking for any indications of possible lock convoys or priority inversion. Let's see what's actually going on in there!
|
| 67/2 |
2026/05/19 05:54 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:kernel/locking/mutex.c IncludeLines:true Name:__mutex_lock_common]
Results: map[SourceCode: 568: /*
569: * Lock a mutex (possibly interruptible), slowpath:
570: */
571: static __always_inline int __sched
572: __mutex_lock_common(struct mutex *lock, unsigned int state, unsigned int subclass,
573: struct lockdep_map *nest_lock, unsigned long ip,
574: struct ww_acquire_ctx *ww_ctx, const bool use_ww_ctx)
575: {
576: DEFINE_WAKE_Q(wake_q);
577: struct mutex_waiter waiter;
578: struct ww_mutex *ww;
579: unsigned long flags;
580: int ret;
581:
582: if (!use_ww_ctx)
583: ww_ctx = NULL;
584:
585: might_sleep();
586:
587: MUTEX_WARN_ON(lock->magic != lock);
588:
589: ww = container_of(lock, struct ww_mutex, base);
590: if (ww_ctx) {
591: if (unlikely(ww_ctx == READ_ONCE(ww->ctx)))
592: return -EALREADY;
593:
594: /*
595: * Reset the wounded flag after a kill. No other process can
596: * race and wound us here since they can't have a valid owner
597: * pointer if we don't have any locks held.
598: */
599: if (ww_ctx->acquired == 0)
600: ww_ctx->wounded = 0;
601:
602: #ifdef CONFIG_DEBUG_LOCK_ALLOC
603: nest_lock = &ww_ctx->dep_map;
604: #endif
605: }
606:
607: preempt_disable();
608: mutex_acquire_nest(&lock->dep_map, subclass, 0, nest_lock, ip);
609:
610: trace_contention_begin(lock, LCB_F_MUTEX | LCB_F_SPIN);
611: if (__mutex_trylock(lock) ||
612: mutex_optimistic_spin(lock, ww_ctx, NULL)) {
613: /* got the lock, yay! */
614: lock_acquired(&lock->dep_map, ip);
615: if (ww_ctx)
616: ww_mutex_set_context_fastpath(ww, ww_ctx);
617: trace_contention_end(lock, 0);
618: preempt_enable();
619: return 0;
620: }
621:
622: raw_spin_lock_irqsave(&lock->wait_lock, flags);
623: /*
624: * After waiting to acquire the wait_lock, try again.
625: */
626: if (__mutex_trylock(lock)) {
627: if (ww_ctx)
628: __ww_mutex_check_waiters(lock, ww_ctx, &wake_q);
629:
630: goto skip_wait;
631: }
632:
633: debug_mutex_lock_common(lock, &waiter);
634: waiter.task = current;
635: if (use_ww_ctx)
636: waiter.ww_ctx = ww_ctx;
637:
638: lock_contended(&lock->dep_map, ip);
639:
640: if (!use_ww_ctx) {
641: /* add waiting tasks to the end of the waitqueue (FIFO): */
642: __mutex_add_waiter(lock, &waiter, &lock->wait_list);
643: } else {
644: /*
645: * Add in stamp order, waking up waiters that must kill
646: * themselves.
647: */
648: ret = __ww_mutex_add_waiter(&waiter, lock, ww_ctx, &wake_q);
649: if (ret)
650: goto err_early_kill;
651: }
652:
653: __set_task_blocked_on(current, lock);
654: set_current_state(state);
655: trace_contention_begin(lock, LCB_F_MUTEX);
656: for (;;) {
657: bool first;
658:
659: /*
660: * Once we hold wait_lock, we're serialized against
661: * mutex_unlock() handing the lock off to us, do a trylock
662: * before testing the error conditions to make sure we pick up
663: * the handoff.
664: */
665: if (__mutex_trylock(lock))
666: goto acquired;
667:
668: /*
669: * Check for signals and kill conditions while holding
670: * wait_lock. This ensures the lock cancellation is ordered
671: * against mutex_unlock() and wake-ups do not go missing.
672: */
673: if (signal_pending_state(state, current)) {
674: ret = -EINTR;
675: goto err;
676: }
677:
678: if (ww_ctx) {
679: ret = __ww_mutex_check_kill(lock, &waiter, ww_ctx);
680: if (ret)
681: goto err;
682: }
683:
684: raw_spin_unlock_irqrestore_wake(&lock->wait_lock, flags, &wake_q);
685:
686: schedule_preempt_disabled();
687:
688: first = __mutex_waiter_is_first(lock, &waiter);
689:
690: /*
691: * As we likely have been woken up by task
692: * that has cleared our blocked_on state, re-set
693: * it to the lock we are trying to acquire.
694: */
695: set_task_blocked_on(current, lock);
696: set_current_state(state);
697: /*
698: * Here we order against unlock; we must either see it change
699: * state back to RUNNING and fall through the next schedule(),
700: * or we must see its unlock and acquire.
701: */
702: if (__mutex_trylock_or_handoff(lock, first))
703: break;
704:
705: if (first) {
706: trace_contention_begin(lock, LCB_F_MUTEX | LCB_F_SPIN);
707: /*
708: * mutex_optimistic_spin() can call schedule(), so
709: * clear blocked on so we don't become unselectable
710: * to run.
711: */
712: clear_task_blocked_on(current, lock);
713: if (mutex_optimistic_spin(lock, ww_ctx, &waiter))
714: break;
715: set_task_blocked_on(current, lock);
716: trace_contention_begin(lock, LCB_F_MUTEX);
717: }
718:
719: raw_spin_lock_irqsave(&lock->wait_lock, flags);
720: }
721: raw_spin_lock_irqsave(&lock->wait_lock, flags);
722: acquired:
723: __clear_task_blocked_on(current, lock);
724: __set_current_state(TASK_RUNNING);
725:
726: if (ww_ctx) {
727: /*
728: * Wound-Wait; we stole the lock (!first_waiter), check the
729: * waiters as anyone might want to wound us.
730: */
731: if (!ww_ctx->is_wait_die &&
732: !__mutex_waiter_is_first(lock, &waiter))
733: __ww_mutex_check_waiters(lock, ww_ctx, &wake_q);
734: }
735:
736: __mutex_remove_waiter(lock, &waiter);
737:
738: debug_mutex_free_waiter(&waiter);
739:
740: skip_wait:
741: /* got the lock - cleanup and rejoice! */
742: lock_acquired(&lock->dep_map, ip);
743: trace_contention_end(lock, 0);
744:
745: if (ww_ctx)
746: ww_mutex_lock_acquired(ww, ww_ctx);
747:
748: raw_spin_unlock_irqrestore_wake(&lock->wait_lock, flags, &wake_q);
749: preempt_enable();
750: return 0;
751:
752: err:
753: __clear_task_blocked_on(current, lock);
754: __set_current_state(TASK_RUNNING);
755: __mutex_remove_waiter(lock, &waiter);
756: err_early_kill:
757: WARN_ON(__get_task_blocked_on(current));
758: trace_contention_end(lock, ret);
759: raw_spin_unlock_irqrestore_wake(&lock->wait_lock, flags, &wake_q);
760: debug_mutex_free_waiter(&waiter);
761: mutex_release(&lock->dep_map, ip);
762: preempt_enable();
763: return ret;
764: }
SourceFile:kernel/locking/mutex.c]
|
| 68/2 |
2026/05/19 05:54 |
llm |
expert |
0m
Model:
Tokens:
input: 99197
output: 45
thoughts: 1435
Thoughts: **Deadlock Analysis in Bluetooth HCI Subsystem**
Alright, let's break this down. Line 608 calls `mutex_acquire_nest`, which is the key here. This tells lockdep that a lock is being acquired, even *before* it's actually acquired. That's crucial. This means that lockdep will mark the lock as "held" even if the thread is blocked waiting for it. The immediate implication is that a thread can be blocked attempting to acquire a lock and be reported as holding it, according to lockdep.
So, first, `kworker/u9:10/11292` is blocked, trying to acquire `hdev->lock` at line 7736. Lockdep has recorded that it is trying to acquire the lock and is, therefore, listed as holding it. `kworker/u9:4/5979` is *also* blocked trying to acquire `hdev->req_lock`, but it's not holding it, despite also being reported as such. Specifically, `kworker/u9:4/5979` calls `hci_req_sync_lock(hdev)` at line 331, within `hci_cmd_sync_work`. So, `kworker/u9:4/5979` is BLOCKED trying to acquire `hdev->req_lock`, and lockdep is showing it as holding it, due to the mutex_acquire call.
Now, who holds `hdev->req_lock`? Ah, `syz-executor:5969` does, acquired within `hci_dev_do_close`. Specifically, `syz-executor:5969` calls `hci_req_sync_lock(hdev)` in `hci_dev_do_close` at line 499, and is, therefore, currently holding the lock. Then, `hci_dev_close_sync` is called, which then attempts to flush `hdev->rx_work` via `flush_work(&hdev->rx_work)`. I was concerned that `syz-executor:5969` might be blocked in `flush_work`, but no. Since it is in `hci_dev_close_sync`, I need to keep looking at `hci_dev_close_sync`. In fact, `syz-executor:5969` is not necessarily in `hci_dev_close_sync`, but in `hci_unregister_dev`. `hci_unregister_dev` calls `disable_work_sync(&hdev->rx_work)`. I need to figure out who has the locks.
So, `syz-executor:5969` is blocked in `disable_work_sync(&hdev->rx_work)`. The main key here is who holds the locks. What if another thread is holding the locks? `kworker/u9:11/12552` might be running `hci_power_on`. `hci_power_on` calls `hci_dev_do_open`, which takes `hdev->req_lock`. Then, `hci_dev_open_sync` takes `hdev->lock`.
Therefore, if `kworker/u9:11/12552` is running `hci_power_on`, it holds BOTH `hdev->req_lock` AND `hdev->lock`. Now we can see the full picture:
* `kworker/u9:4/5979` (running `cmd_sync_work`) is blocked on `hdev->req_lock`.
* `kworker/u9:10/11292` (running `rx_work`) is blocked on `hdev->lock`.
* `syz-executor:5969` (in `hci_unregister_dev`) is blocked in `disable_work_sync(&hdev->rx_work)`.
So, the likely deadlock scenario is that `kworker/u9:11/12552`, which is running `hci_power_on`, has both locks. It's probably waiting for `rx_work` to finish within `hci_dev_open_sync`, and `rx_work` is `kworker/u9:10/11292` which is blocked, waiting for the lock that `kworker/u9:11/12552` has!
|
| 69/2 |
2026/05/19 05:54 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_sync.c IncludeLines:true Name:hci_dev_open_sync]
Results: map[SourceCode:5102: int hci_dev_open_sync(struct hci_dev *hdev)
5103: {
5104: int ret;
5105:
5106: bt_dev_dbg(hdev, "");
5107:
5108: if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
5109: ret = -ENODEV;
5110: goto done;
5111: }
5112:
5113: if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
5114: !hci_dev_test_flag(hdev, HCI_CONFIG)) {
5115: /* Check for rfkill but allow the HCI setup stage to
5116: * proceed (which in itself doesn't cause any RF activity).
5117: */
5118: if (hci_dev_test_flag(hdev, HCI_RFKILLED)) {
5119: ret = -ERFKILL;
5120: goto done;
5121: }
5122:
5123: /* Check for valid public address or a configured static
5124: * random address, but let the HCI setup proceed to
5125: * be able to determine if there is a public address
5126: * or not.
5127: *
5128: * In case of user channel usage, it is not important
5129: * if a public address or static random address is
5130: * available.
5131: */
5132: if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
5133: !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
5134: !bacmp(&hdev->static_addr, BDADDR_ANY)) {
5135: ret = -EADDRNOTAVAIL;
5136: goto done;
5137: }
5138: }
5139:
5140: if (test_bit(HCI_UP, &hdev->flags)) {
5141: ret = -EALREADY;
5142: goto done;
5143: }
5144:
5145: if (hdev->open(hdev)) {
5146: ret = -EIO;
5147: goto done;
5148: }
5149:
5150: hci_devcd_reset(hdev);
5151:
5152: set_bit(HCI_RUNNING, &hdev->flags);
5153: hci_sock_dev_event(hdev, HCI_DEV_OPEN);
5154:
5155: ret = hci_dev_init_sync(hdev);
5156: if (!ret) {
5157: hci_dev_hold(hdev);
5158: hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
5159: hci_adv_instances_set_rpa_expired(hdev, true);
5160: set_bit(HCI_UP, &hdev->flags);
5161: hci_sock_dev_event(hdev, HCI_DEV_UP);
5162: hci_leds_update_powered(hdev, true);
5163: if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
5164: !hci_dev_test_flag(hdev, HCI_CONFIG) &&
5165: !hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
5166: !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
5167: hci_dev_test_flag(hdev, HCI_MGMT)) {
5168: ret = hci_powered_update_sync(hdev);
5169: mgmt_power_on(hdev, ret);
5170: }
5171: } else {
5172: /* Init failed, cleanup */
5173: flush_work(&hdev->tx_work);
5174:
5175: /* Since hci_rx_work() is possible to awake new cmd_work
5176: * it should be flushed first to avoid unexpected call of
5177: * hci_cmd_work()
5178: */
5179: flush_work(&hdev->rx_work);
5180: flush_work(&hdev->cmd_work);
5181:
5182: skb_queue_purge(&hdev->cmd_q);
5183: skb_queue_purge(&hdev->rx_q);
5184:
5185: if (hdev->flush)
5186: hdev->flush(hdev);
5187:
5188: if (hdev->sent_cmd) {
5189: cancel_delayed_work_sync(&hdev->cmd_timer);
5190: kfree_skb(hdev->sent_cmd);
5191: hdev->sent_cmd = NULL;
5192: }
5193:
5194: if (hdev->req_skb) {
5195: kfree_skb(hdev->req_skb);
5196: hdev->req_skb = NULL;
5197: }
5198:
5199: clear_bit(HCI_RUNNING, &hdev->flags);
5200: hci_sock_dev_event(hdev, HCI_DEV_CLOSE);
5201:
5202: hdev->close(hdev);
5203: hdev->flags &= BIT(HCI_RAW);
5204: }
5205:
5206: done:
5207: return ret;
5208: }
SourceFile:net/bluetooth/hci_sync.c]
|
| 70/2 |
2026/05/19 05:54 |
llm |
expert |
0m
Model:
Tokens:
input: 103309
output: 25
thoughts: 1551
Thoughts: **Debugging a Potential Bluetooth Deadlock**
Okay, let's break this down. I see that `hci_dev_open_sync` calls `flush_work(&hdev->rx_work)` if `hci_dev_init_sync` fails. The critical question here is, does `hci_dev_open_sync` hold `hdev->lock`? It appears not directly; it uses `hci_req_sync_lock(hdev)` which is `hdev->req_lock`, but *not* `hdev->lock`. This is important. `hci_power_on` calls `hci_dev_do_open`, which also takes `hdev->req_lock`. So, if `hci_dev_init_sync` fails and calls `flush_work(&hdev->rx_work)`, and `rx_work` is blocked on `hdev->lock`, who *does* hold `hdev->lock`?
`hci_dev_init_sync` doesn't seem to hold `hdev->lock`, nor does `hci_power_on`. If *no one* holds `hdev->lock`, then why is `rx_work` blocked? I need to check `hci_dev_init_sync` for a lock leak, even though it's a large function, to be thorough. It doesn't appear that `hci_dev_init_sync` leaks a lock.
Could another process be holding it? Let's check `syz-executor:5969`. It's associated with `hci_unregister_dev`. But, `hci_unregister_dev` *does not* hold `hdev->lock` at the relevant point (line 2705). Maybe `syz-executor:5969` is running `hci_dev_close_sync`? Yes, it takes `hdev->lock` at line 5314. But, it flushes `rx_work` *before* releasing the lock, so it's not holding the lock when the flush happens.
Wait, back up. What if `hci_dev_close_sync` flushes `rx_work` and *then* the `rx_work` is blocked on the lock and no one holds the lock? Who *is* holding `hdev->lock`? Let's look at `hci_cmd_sync_work`, `kworker/u9:4/5979` is running this. If `entry->func` takes `hdev->lock`, then `kworker/u9:4/5979` would hold it. However, the lockdep trace does *not* show `hdev->lock` for this work queue. The trace only lists three locks.
Lockdep only reports the first three locks? It appears so. `kworker/u9:11/12552` is interesting. The output states that it holds seven locks. The output is truncated! This worker *could* be holding `hdev->lock`! What is this worker doing? Maybe it is running `hci_cmd_sync_work` for `hci4#2`? But, `hci4#2` is just a lockdep class. Maybe it is running an event handler that takes `hdev->lock` and then blocks?
If `kworker/u9:11/12552` *does* hold `hdev->lock` and is blocked, what is it blocked on? Potentially, `hdev->req_lock`? If `kworker/u9:11/12552` holds `hdev->lock` and is blocked on `hdev->req_lock` *and* `kworker/u9:4/5979` holds `hdev->req_lock` and is blocked on `hdev->lock`, then this is a deadlock! The trace for `kworker/u9:4/5979` wouldn't list the lock, because it isn't holding it when it's blocked.
So, this is likely a deadlock. Let me check the code for any path that takes `hdev->lock` and then `hdev->req_lock`. Bingo! `hci_event_packet` takes `hdev->lock` at line 7736, *but* unlocks it at line 7739. But it calls `hci_event_func` immediately afterward. Does `hci_event_func` take `hdev->lock`? Yes, many event handlers take `hdev->lock`. And could any event handlers take `hdev->req_lock`? Let me check if they are calling `hci_req_
|
| 71/2 |
2026/05/19 05:54 |
tool |
grepper |
0m
Args: map[Expression:hci_req_sync_lock\(hdev\)]
Results: map[Output:include/net/bluetooth/hci_sync.h-14-
include/net/bluetooth/hci_sync.h:15:#define hci_req_sync_lock(hdev) mutex_lock(&hdev->req_lock)
include/net/bluetooth/hci_sync.h-16-#define hci_req_sync_unlock(hdev) mutex_unlock(&hdev->req_lock)
--
net/bluetooth/hci_core.c=325=int hci_inquiry(void __user *arg)
--
net/bluetooth/hci_core.c-369- if (do_inquiry) {
net/bluetooth/hci_core.c:370: hci_req_sync_lock(hdev);
net/bluetooth/hci_core.c-371- err = hci_inquiry_sync(hdev, ir.length, ir.num_rsp);
--
net/bluetooth/hci_core.c=422=static int hci_dev_do_open(struct hci_dev *hdev)
--
net/bluetooth/hci_core.c-427-
net/bluetooth/hci_core.c:428: hci_req_sync_lock(hdev);
net/bluetooth/hci_core.c-429-
--
net/bluetooth/hci_core.c=493=int hci_dev_do_close(struct hci_dev *hdev)
--
net/bluetooth/hci_core.c-498-
net/bluetooth/hci_core.c:499: hci_req_sync_lock(hdev);
net/bluetooth/hci_core.c-500-
--
net/bluetooth/hci_core.c=533=static int hci_dev_do_reset(struct hci_dev *hdev)
--
net/bluetooth/hci_core.c-538-
net/bluetooth/hci_core.c:539: hci_req_sync_lock(hdev);
net/bluetooth/hci_core.c-540-
--
net/bluetooth/hci_core.c=887=static int hci_dev_do_poweroff(struct hci_dev *hdev)
--
net/bluetooth/hci_core.c-892-
net/bluetooth/hci_core.c:893: hci_req_sync_lock(hdev);
net/bluetooth/hci_core.c-894-
--
net/bluetooth/hci_core.c=2830=int hci_suspend_dev(struct hci_dev *hdev)
--
net/bluetooth/hci_core.c-2847-
net/bluetooth/hci_core.c:2848: hci_req_sync_lock(hdev);
net/bluetooth/hci_core.c-2849- ret = hci_suspend_sync(hdev);
--
net/bluetooth/hci_core.c=2861=int hci_resume_dev(struct hci_dev *hdev)
--
net/bluetooth/hci_core.c-2875-
net/bluetooth/hci_core.c:2876: hci_req_sync_lock(hdev);
net/bluetooth/hci_core.c-2877- ret = hci_resume_sync(hdev);
--
net/bluetooth/hci_debugfs.c=1287=static ssize_t dut_mode_write(struct file *file, const char __user *user_buf,
--
net/bluetooth/hci_debugfs.c-1304-
net/bluetooth/hci_debugfs.c:1305: hci_req_sync_lock(hdev);
net/bluetooth/hci_debugfs.c-1306- if (enable)
--
net/bluetooth/hci_debugfs.c=1343=static ssize_t vendor_diag_write(struct file *file, const char __user *user_buf,
--
net/bluetooth/hci_debugfs.c-1363-
net/bluetooth/hci_debugfs.c:1364: hci_req_sync_lock(hdev);
net/bluetooth/hci_debugfs.c-1365- err = hdev->set_diag(hdev, enable);
--
net/bluetooth/hci_sync.c=228=struct sk_buff *hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
--
net/bluetooth/hci_sync.c-237-
net/bluetooth/hci_sync.c:238: hci_req_sync_lock(hdev);
net/bluetooth/hci_sync.c-239- skb = __hci_cmd_sync(hdev, opcode, plen, param, timeout);
--
net/bluetooth/hci_sync.c=292=int hci_cmd_sync_status(struct hci_dev *hdev, u16 opcode, u32 plen,
--
net/bluetooth/hci_sync.c-296-
net/bluetooth/hci_sync.c:297: hci_req_sync_lock(hdev);
net/bluetooth/hci_sync.c-298- err = __hci_cmd_sync_status(hdev, opcode, plen, param, timeout);
--
net/bluetooth/hci_sync.c=305=static void hci_cmd_sync_work(struct work_struct *work)
--
net/bluetooth/hci_sync.c-330-
net/bluetooth/hci_sync.c:331: hci_req_sync_lock(hdev);
net/bluetooth/hci_sync.c-332- err = entry->func(hdev, entry->data);
--
net/bluetooth/mgmt.c=4780=static int set_quality_report_func(struct sock *sk, struct hci_dev *hdev,
--
net/bluetooth/mgmt.c-4805-
net/bluetooth/mgmt.c:4806: hci_req_sync_lock(hdev);
net/bluetooth/mgmt.c-4807-
]
|
| 72/2 |
2026/05/19 05:54 |
llm |
expert |
0m
Model:
Tokens:
input: 107420
output: 20
thoughts: 64
Thoughts: **Analyzing the HCI Command Synchronization**
Okay, so I'm digging into this code and something's immediately snagging my attention. Specifically, the `hci_cmd_sync` function. It seems to utilize `hci_req_sync_lock(hdev)`, which signals a critical section needing synchronization around the `hdev` structure. My immediate question is: *who's calling this thing?*
I need to understand the potential concurrency issues here. Is `hci_cmd_sync` being invoked from an event handler context? I need to know if an event handler, and particularly if `hci_event_func` or its child functions, are making the call. This is key to evaluating potential race conditions or deadlocks. I need to trace the call paths to be sure. This warrants a deep dive into the code.
|
| 73/2 |
2026/05/19 05:54 |
tool |
grepper |
0m
Args: map[Expression:hci_cmd_sync\(]
Results: map[Output:
Full output is too long, showing 500 out of 692 lines.
Use more precise expression if possible.
[drivers/bluetooth/bpa10x.c=246=static int bpa10x_setup(struct hci_dev *hdev)
--
drivers/bluetooth/bpa10x.c-253- /* Read revision string */
drivers/bluetooth/bpa10x.c:254: skb = __hci_cmd_sync(hdev, 0xfc0e, sizeof(req), req, HCI_INIT_TIMEOUT);
drivers/bluetooth/bpa10x.c-255- if (IS_ERR(skb))
--
drivers/bluetooth/bpa10x.c=344=static int bpa10x_set_diag(struct hci_dev *hdev, bool enable)
--
drivers/bluetooth/bpa10x.c-354- /* Enable sniffer operation */
drivers/bluetooth/bpa10x.c:355: skb = __hci_cmd_sync(hdev, 0xfc0e, sizeof(req), req, HCI_INIT_TIMEOUT);
drivers/bluetooth/bpa10x.c-356- if (IS_ERR(skb))
--
drivers/bluetooth/btbcm.c=77=int btbcm_check_bdaddr(struct hci_dev *hdev)
--
drivers/bluetooth/btbcm.c-81-
drivers/bluetooth/btbcm.c:82: skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
drivers/bluetooth/btbcm.c-83- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btbcm.c=148=int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
--
drivers/bluetooth/btbcm.c-152-
drivers/bluetooth/btbcm.c:153: skb = __hci_cmd_sync(hdev, 0xfc01, 6, bdaddr, HCI_INIT_TIMEOUT);
drivers/bluetooth/btbcm.c-154- if (IS_ERR(skb)) {
--
drivers/bluetooth/btbcm.c=165=int btbcm_read_pcm_int_params(struct hci_dev *hdev,
--
drivers/bluetooth/btbcm.c-170-
drivers/bluetooth/btbcm.c:171: skb = __hci_cmd_sync(hdev, 0xfc1d, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btbcm.c-172- if (IS_ERR(skb)) {
--
drivers/bluetooth/btbcm.c=193=int btbcm_write_pcm_int_params(struct hci_dev *hdev,
--
drivers/bluetooth/btbcm.c-198-
drivers/bluetooth/btbcm.c:199: skb = __hci_cmd_sync(hdev, 0xfc1c, 5, params, HCI_INIT_TIMEOUT);
drivers/bluetooth/btbcm.c-200- if (IS_ERR(skb)) {
--
drivers/bluetooth/btbcm.c=211=int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw)
--
drivers/bluetooth/btbcm.c-220- /* Start Download */
drivers/bluetooth/btbcm.c:221: skb = __hci_cmd_sync(hdev, 0xfc2e, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btbcm.c-222- if (IS_ERR(skb)) {
--
drivers/bluetooth/btbcm.c-254-
drivers/bluetooth/btbcm.c:255: skb = __hci_cmd_sync(hdev, opcode, cmd->plen, cmd_param,
drivers/bluetooth/btbcm.c-256- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btbcm.c=274=static int btbcm_reset(struct hci_dev *hdev)
--
drivers/bluetooth/btbcm.c-277-
drivers/bluetooth/btbcm.c:278: skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btbcm.c-279- if (IS_ERR(skb)) {
--
drivers/bluetooth/btbcm.c=293=static struct sk_buff *btbcm_read_local_name(struct hci_dev *hdev)
--
drivers/bluetooth/btbcm.c-296-
drivers/bluetooth/btbcm.c:297: skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL,
drivers/bluetooth/btbcm.c-298- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btbcm.c=314=static struct sk_buff *btbcm_read_local_version(struct hci_dev *hdev)
--
drivers/bluetooth/btbcm.c-317-
drivers/bluetooth/btbcm.c:318: skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL,
drivers/bluetooth/btbcm.c-319- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btbcm.c=335=static struct sk_buff *btbcm_read_verbose_config(struct hci_dev *hdev)
--
drivers/bluetooth/btbcm.c-338-
drivers/bluetooth/btbcm.c:339: skb = __hci_cmd_sync(hdev, 0xfc79, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btbcm.c-340- if (IS_ERR(skb)) {
--
drivers/bluetooth/btbcm.c=355=static struct sk_buff *btbcm_read_controller_features(struct hci_dev *hdev)
--
drivers/bluetooth/btbcm.c-358-
drivers/bluetooth/btbcm.c:359: skb = __hci_cmd_sync(hdev, 0xfc6e, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btbcm.c-360- if (IS_ERR(skb)) {
--
drivers/bluetooth/btbcm.c=375=static struct sk_buff *btbcm_read_usb_product(struct hci_dev *hdev)
--
drivers/bluetooth/btbcm.c-378-
drivers/bluetooth/btbcm.c:379: skb = __hci_cmd_sync(hdev, 0xfc5a, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btbcm.c-380- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=61=int btintel_check_bdaddr(struct hci_dev *hdev)
--
drivers/bluetooth/btintel.c-65-
drivers/bluetooth/btintel.c:66: skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
drivers/bluetooth/btintel.c-67- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btintel.c=100=int btintel_enter_mfg(struct hci_dev *hdev)
--
drivers/bluetooth/btintel.c-104-
drivers/bluetooth/btintel.c:105: skb = __hci_cmd_sync(hdev, 0xfc11, 2, param, HCI_CMD_TIMEOUT);
drivers/bluetooth/btintel.c-106- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=117=int btintel_exit_mfg(struct hci_dev *hdev, bool reset, bool patched)
--
drivers/bluetooth/btintel.c-129-
drivers/bluetooth/btintel.c:130: skb = __hci_cmd_sync(hdev, 0xfc11, 2, param, HCI_CMD_TIMEOUT);
drivers/bluetooth/btintel.c-131- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=142=int btintel_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
--
drivers/bluetooth/btintel.c-146-
drivers/bluetooth/btintel.c:147: skb = __hci_cmd_sync(hdev, 0xfc31, 6, bdaddr, HCI_INIT_TIMEOUT);
drivers/bluetooth/btintel.c-148- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=160=static int btintel_set_event_mask(struct hci_dev *hdev, bool debug)
--
drivers/bluetooth/btintel.c-168-
drivers/bluetooth/btintel.c:169: skb = __hci_cmd_sync(hdev, 0xfc52, 8, mask, HCI_INIT_TIMEOUT);
drivers/bluetooth/btintel.c-170- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=180=int btintel_set_diag(struct hci_dev *hdev, bool enable)
--
drivers/bluetooth/btintel.c-195-
drivers/bluetooth/btintel.c:196: skb = __hci_cmd_sync(hdev, 0xfc43, 3, param, HCI_INIT_TIMEOUT);
drivers/bluetooth/btintel.c-197- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=247=void btintel_hw_error(struct hci_dev *hdev, u8 code)
--
drivers/bluetooth/btintel.c-253-
drivers/bluetooth/btintel.c:254: skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btintel.c-255- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c-261-
drivers/bluetooth/btintel.c:262: skb = __hci_cmd_sync(hdev, 0xfc22, 1, &type, HCI_INIT_TIMEOUT);
drivers/bluetooth/btintel.c-263- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=346=static int btintel_secure_send(struct hci_dev *hdev, u8 fragment_type, u32 plen,
--
drivers/bluetooth/btintel.c-355-
drivers/bluetooth/btintel.c:356: skb = __hci_cmd_sync(hdev, 0xfc09, fragment_len + 1,
drivers/bluetooth/btintel.c-357- cmd_param, HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btintel.c=370=int btintel_load_ddc_config(struct hci_dev *hdev, const char *ddc_name)
--
drivers/bluetooth/btintel.c-393-
drivers/bluetooth/btintel.c:394: skb = __hci_cmd_sync(hdev, 0xfc8b, cmd_plen, fw_ptr,
drivers/bluetooth/btintel.c-395- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btintel.c=433=int btintel_read_version(struct hci_dev *hdev, struct intel_version *ver)
--
drivers/bluetooth/btintel.c-436-
drivers/bluetooth/btintel.c:437: skb = __hci_cmd_sync(hdev, 0xfc05, 0, NULL, HCI_CMD_TIMEOUT);
drivers/bluetooth/btintel.c-438- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=662=static int btintel_read_version_tlv(struct hci_dev *hdev,
--
drivers/bluetooth/btintel.c-670-
drivers/bluetooth/btintel.c:671: skb = __hci_cmd_sync(hdev, 0xfc05, 1, param, HCI_CMD_TIMEOUT);
drivers/bluetooth/btintel.c-672- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=716=static int regmap_ibt_read(void *context, const void *addr, size_t reg_size,
--
drivers/bluetooth/btintel.c-747-
drivers/bluetooth/btintel.c:748: skb = hci_cmd_sync(ctx->hdev, ctx->op_read, sizeof(cp), &cp,
drivers/bluetooth/btintel.c-749- HCI_CMD_TIMEOUT);
--
drivers/bluetooth/btintel.c=780=static int regmap_ibt_gather_write(void *context,
--
drivers/bluetooth/btintel.c-819-
drivers/bluetooth/btintel.c:820: skb = hci_cmd_sync(ctx->hdev, ctx->op_write, plen, cp, HCI_CMD_TIMEOUT);
drivers/bluetooth/btintel.c-821- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=886=int btintel_send_intel_reset(struct hci_dev *hdev, u32 boot_param)
--
drivers/bluetooth/btintel.c-892-
drivers/bluetooth/btintel.c:893: skb = __hci_cmd_sync(hdev, BTINTEL_HCI_OP_RESET, sizeof(params), ¶ms,
drivers/bluetooth/btintel.c-894- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btintel.c=906=int btintel_read_boot_params(struct hci_dev *hdev,
--
drivers/bluetooth/btintel.c-910-
drivers/bluetooth/btintel.c:911: skb = __hci_cmd_sync(hdev, 0xfc0d, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btintel.c-912- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=1258=static void btintel_reset_to_bootloader(struct hci_dev *hdev)
--
drivers/bluetooth/btintel.c-1290-
drivers/bluetooth/btintel.c:1291: skb = __hci_cmd_sync(hdev, BTINTEL_HCI_OP_RESET, sizeof(params),
drivers/bluetooth/btintel.c-1292- ¶ms, HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btintel.c=1309=static int btintel_read_debug_features(struct hci_dev *hdev,
--
drivers/bluetooth/btintel.c-1317- */
drivers/bluetooth/btintel.c:1318: skb = __hci_cmd_sync(hdev, 0xfca6, sizeof(page_no), &page_no,
drivers/bluetooth/btintel.c-1319- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btintel.c=1340=static int btintel_set_debug_features(struct hci_dev *hdev,
--
drivers/bluetooth/btintel.c-1358-
drivers/bluetooth/btintel.c:1359: skb = __hci_cmd_sync(hdev, 0xfc8b, 11, mask, HCI_INIT_TIMEOUT);
drivers/bluetooth/btintel.c-1360- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c-1366-
drivers/bluetooth/btintel.c:1367: skb = __hci_cmd_sync(hdev, 0xfc8b, 5, period, HCI_INIT_TIMEOUT);
drivers/bluetooth/btintel.c-1368- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c-1374-
drivers/bluetooth/btintel.c:1375: skb = __hci_cmd_sync(hdev, 0xfca1, 1, &trace_enable, HCI_INIT_TIMEOUT);
drivers/bluetooth/btintel.c-1376- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=1389=static int btintel_reset_debug_features(struct hci_dev *hdev,
--
drivers/bluetooth/btintel.c-1407- /* Should stop the trace before writing ddc event mask. */
drivers/bluetooth/btintel.c:1408: skb = __hci_cmd_sync(hdev, 0xfca1, 1, &trace_enable, HCI_INIT_TIMEOUT);
drivers/bluetooth/btintel.c-1409- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c-1415-
drivers/bluetooth/btintel.c:1416: skb = __hci_cmd_sync(hdev, 0xfc8b, 11, mask, HCI_INIT_TIMEOUT);
drivers/bluetooth/btintel.c-1417- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=1454=static void btintel_coredump(struct hci_dev *hdev)
--
drivers/bluetooth/btintel.c-1457-
drivers/bluetooth/btintel.c:1458: skb = __hci_cmd_sync(hdev, 0xfc4e, 0, NULL, HCI_CMD_TIMEOUT);
drivers/bluetooth/btintel.c-1459- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=2439=static int btintel_configure_offload(struct hci_dev *hdev)
--
drivers/bluetooth/btintel.c-2444-
drivers/bluetooth/btintel.c:2445: skb = __hci_cmd_sync(hdev, 0xfc86, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btintel.c-2446- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=2473=static void btintel_set_ppag(struct hci_dev *hdev, struct intel_version_tlv *ver)
--
drivers/bluetooth/btintel.c-2545-
drivers/bluetooth/btintel.c:2546: skb = __hci_cmd_sync(hdev, INTEL_OP_PPAG_CMD, sizeof(ppag_cmd),
drivers/bluetooth/btintel.c-2547- &ppag_cmd, HCI_CMD_TIMEOUT);
--
drivers/bluetooth/btintel.c=2743=static int btintel_set_dsbr(struct hci_dev *hdev, struct intel_version_tlv *ver)
--
drivers/bluetooth/btintel.c-2795-
drivers/bluetooth/btintel.c:2796: skb = __hci_cmd_sync(hdev, 0xfc0a, sizeof(cmd), &cmd, HCI_CMD_TIMEOUT);
drivers/bluetooth/btintel.c-2797- if (IS_ERR(skb))
--
drivers/bluetooth/btintel.c=2862=static int btintel_send_sar_ddc(struct hci_dev *hdev, struct btintel_cp_ddc_write *data, u8 len)
--
drivers/bluetooth/btintel.c-2865-
drivers/bluetooth/btintel.c:2866: skb = __hci_cmd_sync(hdev, 0xfc8b, len, data, HCI_CMD_TIMEOUT);
drivers/bluetooth/btintel.c-2867- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=2968=static int btintel_set_mutual_sar(struct hci_dev *hdev, struct btintel_sar_inc_pwr *sar)
--
drivers/bluetooth/btintel.c-3018- enable = true;
drivers/bluetooth/btintel.c:3019: skb = __hci_cmd_sync(hdev, 0xfe25, 1, &enable, HCI_CMD_TIMEOUT);
drivers/bluetooth/btintel.c-3020- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=3267=void btintel_print_fseq_info(struct hci_dev *hdev)
--
drivers/bluetooth/btintel.c-3273-
drivers/bluetooth/btintel.c:3274: skb = __hci_cmd_sync(hdev, 0xfcb3, 0, NULL, HCI_CMD_TIMEOUT);
drivers/bluetooth/btintel.c-3275- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=3381=static int btintel_setup_combined(struct hci_dev *hdev)
--
drivers/bluetooth/btintel.c-3406- btintel_test_flag(hdev, INTEL_BROKEN_SHUTDOWN_LED)) {
drivers/bluetooth/btintel.c:3407: skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL,
drivers/bluetooth/btintel.c-3408- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btintel.c-3423- */
drivers/bluetooth/btintel.c:3424: skb = __hci_cmd_sync(hdev, 0xfc05, 1, param, HCI_CMD_TIMEOUT);
drivers/bluetooth/btintel.c-3425- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=3637=int btintel_shutdown_combined(struct hci_dev *hdev)
--
drivers/bluetooth/btintel.c-3645- */
drivers/bluetooth/btintel.c:3646: skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btintel.c-3647- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c-3659- if (btintel_test_flag(hdev, INTEL_BROKEN_SHUTDOWN_LED)) {
drivers/bluetooth/btintel.c:3660: skb = __hci_cmd_sync(hdev, 0xfc3f, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btintel.c-3661- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel_pcie.c=2041=static int btintel_pcie_setup_internal(struct hci_dev *hdev)
--
drivers/bluetooth/btintel_pcie.c-2050-
drivers/bluetooth/btintel_pcie.c:2051: skb = __hci_cmd_sync(hdev, 0xfc05, 1, param, HCI_CMD_TIMEOUT);
drivers/bluetooth/btintel_pcie.c-2052- if (IS_ERR(skb)) {
--
drivers/bluetooth/btmrvl_main.c=548=static int btmrvl_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
--
drivers/bluetooth/btmrvl_main.c-557-
drivers/bluetooth/btmrvl_main.c:558: skb = __hci_cmd_sync(hdev, BT_CMD_SET_BDADDR, sizeof(buf), buf,
drivers/bluetooth/btmrvl_main.c-559- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btmtk.c=344=int btmtk_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
--
drivers/bluetooth/btmtk.c-348-
drivers/bluetooth/btmtk.c:349: skb = __hci_cmd_sync(hdev, 0xfc1a, 6, bdaddr, HCI_INIT_TIMEOUT);
drivers/bluetooth/btmtk.c-350- if (IS_ERR(skb)) {
--
drivers/bluetooth/btmtk.c=1210=static int btmtk_usb_isointf_init(struct hci_dev *hdev)
--
drivers/bluetooth/btmtk.c-1227-
drivers/bluetooth/btmtk.c:1228: skb = __hci_cmd_sync(hdev, 0xfd98, sizeof(iso_param), iso_param,
drivers/bluetooth/btmtk.c-1229- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btmtk.c=1271=int btmtk_usb_setup(struct hci_dev *hdev)
--
drivers/bluetooth/btmtk.c-1437-
drivers/bluetooth/btmtk.c:1438: skb = __hci_cmd_sync(hdev, 0xfc7a, sizeof(tci_sleep), &tci_sleep,
drivers/bluetooth/btmtk.c-1439- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btmtksdio.c=781=static int mt76xx_setup(struct hci_dev *hdev, const char *fwname)
--
drivers/bluetooth/btmtksdio.c-853-
drivers/bluetooth/btmtksdio.c:854: skb = __hci_cmd_sync(hdev, 0xfc7a, sizeof(tci_sleep), &tci_sleep,
drivers/bluetooth/btmtksdio.c-855- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btmtksdio.c=1016=static int btmtksdio_sco_setting(struct hci_dev *hdev)
--
drivers/bluetooth/btmtksdio.c-1026- /* Enable SCO over I2S/PCM for MediaTek chipset */
drivers/bluetooth/btmtksdio.c:1027: skb = __hci_cmd_sync(hdev, 0xfc72, sizeof(sco_setting),
drivers/bluetooth/btmtksdio.c-1028- &sco_setting, HCI_CMD_TIMEOUT);
--
drivers/bluetooth/btmtksdio.c=1316=static bool btmtksdio_sdio_wakeup(struct hci_dev *hdev)
--
drivers/bluetooth/btmtksdio.c-1330-
drivers/bluetooth/btmtksdio.c:1331: skb = __hci_cmd_sync(hdev, 0xfc27, sizeof(bt_awake),
drivers/bluetooth/btmtksdio.c-1332- &bt_awake, HCI_CMD_TIMEOUT);
--
drivers/bluetooth/btmtkuart.c=589=static int btmtkuart_setup(struct hci_dev *hdev)
--
drivers/bluetooth/btmtkuart.c-685-
drivers/bluetooth/btmtkuart.c:686: skb = __hci_cmd_sync(hdev, 0xfc7a, sizeof(tci_sleep), &tci_sleep,
drivers/bluetooth/btmtkuart.c-687- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btnxpuart.c=372=static struct sk_buff *nxp_drv_send_cmd(struct hci_dev *hdev, u16 opcode,
--
drivers/bluetooth/btnxpuart.c-385- if (resp) {
drivers/bluetooth/btnxpuart.c:386: skb = __hci_cmd_sync(hdev, opcode, plen, param, HCI_CMD_TIMEOUT);
drivers/bluetooth/btnxpuart.c-387- } else {
--
drivers/bluetooth/btqca.c=191=static int qca_send_reset(struct hci_dev *hdev)
--
drivers/bluetooth/btqca.c-197-
drivers/bluetooth/btqca.c:198: skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btqca.c-199- if (IS_ERR(skb)) {
--
drivers/bluetooth/btqca.c=717=static int qca_check_bdaddr(struct hci_dev *hdev, const struct qca_fw_config *config)
--
drivers/bluetooth/btqca.c-725-
drivers/bluetooth/btqca.c:726: skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
drivers/bluetooth/btqca.c-727- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btqcomsmd.c=108=static int btqcomsmd_setup(struct hci_dev *hdev)
--
drivers/bluetooth/btqcomsmd.c-111-
drivers/bluetooth/btqcomsmd.c:112: skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btqcomsmd.c-113- if (IS_ERR(skb))
--
drivers/bluetooth/btrtl.c=374=static struct sk_buff *btrtl_read_local_version(struct hci_dev *hdev)
--
drivers/bluetooth/btrtl.c-377-
drivers/bluetooth/btrtl.c:378: skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL,
drivers/bluetooth/btrtl.c-379- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btrtl.c=395=static int rtl_read_rom_version(struct hci_dev *hdev, u8 *version)
--
drivers/bluetooth/btrtl.c-400- /* Read RTL ROM version command */
drivers/bluetooth/btrtl.c:401: skb = __hci_cmd_sync(hdev, 0xfc6d, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btrtl.c-402- if (IS_ERR(skb)) {
--
drivers/bluetooth/btrtl.c=424=static int btrtl_vendor_read_reg16(struct hci_dev *hdev,
--
drivers/bluetooth/btrtl.c-429-
drivers/bluetooth/btrtl.c:430: skb = __hci_cmd_sync(hdev, 0xfc61, sizeof(*cmd), cmd,
drivers/bluetooth/btrtl.c-431- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btrtl.c=819=static int rtl_download_firmware(struct hci_dev *hdev,
--
drivers/bluetooth/btrtl.c-850- /* Send download command */
drivers/bluetooth/btrtl.c:851: skb = __hci_cmd_sync(hdev, 0xfc20, frag_len + 1, dl_cmd,
drivers/bluetooth/btrtl.c-852- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btrtl.c=1017=static int rtl_read_chip_type(struct hci_dev *hdev, u8 *type)
--
drivers/bluetooth/btrtl.c-1023- /* Read RTL chip type command */
drivers/bluetooth/btrtl.c:1024: skb = __hci_cmd_sync(hdev, 0xfc61, 5, cmd_buf, HCI_INIT_TIMEOUT);
drivers/bluetooth/btrtl.c-1025- if (IS_ERR(skb)) {
--
drivers/bluetooth/btrtl.c=1386=int btrtl_shutdown_realtek(struct hci_dev *hdev)
--
drivers/bluetooth/btrtl.c-1393- */
drivers/bluetooth/btrtl.c:1394: skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_CMD_TIMEOUT);
drivers/bluetooth/btrtl.c-1395- if (IS_ERR(skb)) {
--
drivers/bluetooth/btusb.c=2431=static int btusb_setup_bcm92035(struct hci_dev *hdev)
--
drivers/bluetooth/btusb.c-2437-
drivers/bluetooth/btusb.c:2438: skb = __hci_cmd_sync(hdev, 0xfc3b, 1, &val, HCI_INIT_TIMEOUT);
drivers/bluetooth/btusb.c-2439- if (IS_ERR(skb))
--
drivers/bluetooth/btusb.c=2447=static int btusb_setup_csr(struct hci_dev *hdev)
--
drivers/bluetooth/btusb.c-2457-
drivers/bluetooth/btusb.c:2458: skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL,
drivers/bluetooth/btusb.c-2459- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btusb.c=2958=static int btusb_set_bdaddr_marvell(struct hci_dev *hdev,
--
drivers/bluetooth/btusb.c-2968-
drivers/bluetooth/btusb.c:2969: skb = __hci_cmd_sync(hdev, 0xfc22, sizeof(buf), buf, HCI_INIT_TIMEOUT);
drivers/bluetooth/btusb.c-2970- if (IS_ERR(skb)) {
--
drivers/bluetooth/btusb.c=2981=static int btusb_set_bdaddr_ath3012(struct hci_dev *hdev,
--
drivers/bluetooth/btusb.c-2993-
drivers/bluetooth/btusb.c:2994: skb = __hci_cmd_sync(hdev, 0xfc0b, sizeof(buf), buf, HCI_INIT_TIMEOUT);
drivers/bluetooth/btusb.c-2995- if (IS_ERR(skb)) {
--
drivers/bluetooth/btusb.c=3824=static int btusb_shutdown_qca(struct hci_dev *hdev)
--
drivers/bluetooth/btusb.c-3827-
drivers/bluetooth/btusb.c:3828: skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btusb.c-3829- if (IS_ERR(skb)) {
--
drivers/bluetooth/hci_ag6xx.c=121=static int intel_mem_write(struct hci_dev *hdev, u32 addr, u32 plen,
--
drivers/bluetooth/hci_ag6xx.c-136-
drivers/bluetooth/hci_ag6xx.c:137: skb = __hci_cmd_sync(hdev, 0xfc8e, fragment_len + 6, cmd_param,
drivers/bluetooth/hci_ag6xx.c-138- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/hci_aml.c=404=static int aml_check_bdaddr(struct hci_dev *hdev)
--
drivers/bluetooth/hci_aml.c-412-
drivers/bluetooth/hci_aml.c:413: skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
drivers/bluetooth/hci_aml.c-414- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/hci_ath.c=147=static int ath_vendor_cmd(struct hci_dev *hdev, uint8_t opcode, uint16_t index,
--
drivers/bluetooth/hci_ath.c-160-
drivers/bluetooth/hci_ath.c:161: skb = __hci_cmd_sync(hdev, 0xfc0b, dlen + 4, &cmd, HCI_INIT_TIMEOUT);
drivers/bluetooth/hci_ath.c-162- if (IS_ERR(skb))
--
drivers/bluetooth/hci_bcm.c=178=static int bcm_set_baudrate(struct hci_uart *hu, unsigned int speed)
--
drivers/bluetooth/hci_bcm.c-194- */
drivers/bluetooth/hci_bcm.c:195: skb = __hci_cmd_sync(hdev, 0xfc45, 1, &clock, HCI_INIT_TIMEOUT);
drivers/bluetooth/hci_bcm.c-196- if (IS_ERR(skb)) {
--
drivers/bluetooth/hci_bcm.c-213- */
drivers/bluetooth/hci_bcm.c:214: skb = __hci_cmd_sync(hdev, 0xfc18, sizeof(param), ¶m,
drivers/bluetooth/hci_bcm.c-215- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/hci_bcm.c=391=static int bcm_setup_sleep(struct hci_uart *hu)
--
drivers/bluetooth/hci_bcm.c-398-
drivers/bluetooth/hci_bcm.c:399: skb = __hci_cmd_sync(hu->hdev, 0xfc27, sizeof(sleep_params),
drivers/bluetooth/hci_bcm.c-400- &sleep_params, HCI_INIT_TIMEOUT);
--
drivers/bluetooth/hci_bcm4377.c=1124=static int __bcm4378_send_calibration_chunk(struct bcm4377_data *bcm4377,
--
drivers/bluetooth/hci_bcm4377.c-1138-
drivers/bluetooth/hci_bcm4377.c:1139: skb = __hci_cmd_sync(bcm4377->hdev, 0xfd97, sizeof(cmd), &cmd,
drivers/bluetooth/hci_bcm4377.c-1140- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/hci_bcm4377.c=1240=static int bcm4377_send_ptb(struct bcm4377_data *bcm4377,
--
drivers/bluetooth/hci_bcm4377.c-1244-
drivers/bluetooth/hci_bcm4377.c:1245: skb = __hci_cmd_sync(bcm4377->hdev, 0xfd98, fw->size, fw->data,
drivers/bluetooth/hci_bcm4377.c-1246- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/hci_bcm4377.c=1259=static int bcm4378_send_ptb_chunk(struct bcm4377_data *bcm4377,
--
drivers/bluetooth/hci_bcm4377.c-1272-
drivers/bluetooth/hci_bcm4377.c:1273: skb = __hci_cmd_sync(bcm4377->hdev, 0xfe0d, sizeof(cmd), &cmd,
drivers/bluetooth/hci_bcm4377.c-1274- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/hci_bcm4377.c=1414=static int bcm4377_check_bdaddr(struct bcm4377_data *bcm4377)
--
drivers/bluetooth/hci_bcm4377.c-1418-
drivers/bluetooth/hci_bcm4377.c:1419: skb = __hci_cmd_sync(bcm4377->hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
drivers/bluetooth/hci_bcm4377.c-1420- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/hci_bcm4377.c=1507=static int bcm4377_hci_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
--
drivers/bluetooth/hci_bcm4377.c-1512-
drivers/bluetooth/hci_bcm4377.c:1513: skb = __hci_cmd_sync(hdev, 0xfc01, 6, bdaddr, HCI_INIT_TIMEOUT);
drivers/bluetooth/hci_bcm4377.c-1514- if (IS_ERR(skb)) {
--
drivers/bluetooth/hci_h5.c=934=static int h5_btrtl_setup(struct h5 *h5)
--
drivers/bluetooth/hci_h5.c-954- baudrate_data = cpu_to_le32(device_baudrate);
drivers/bluetooth/hci_h5.c:955: skb = __hci_cmd_sync(h5->hu->hdev, 0xfc17, sizeof(baudrate_data),
drivers/bluetooth/hci_h5.c-956- &baudrate_data, HCI_INIT_TIMEOUT);
--
drivers/bluetooth/hci_intel.c=460=static int intel_set_baudrate(struct hci_uart *hu, unsigned int speed)
--
drivers/bluetooth/hci_intel.c-489- */
drivers/bluetooth/hci_intel.c:490: skb = __hci_cmd_sync(hdev, 0xfc05, 0, NULL, HCI_CMD_TIMEOUT);
drivers/bluetooth/hci_intel.c-491- if (IS_ERR(skb)) {
--
drivers/bluetooth/hci_intel.c=521=static int intel_setup(struct hci_uart *hu)
--
drivers/bluetooth/hci_intel.c-846-
drivers/bluetooth/hci_intel.c:847: skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_CMD_TIMEOUT);
drivers/bluetooth/hci_intel.c-848- if (IS_ERR(skb))
--
]
]
|
| 74/2 |
2026/05/19 05:54 |
llm |
expert |
0m
Model:
Tokens:
input: 118753
output: 20
thoughts: 183
Thoughts: **Analyzing Potential Concurrency Issues with `hci_cmd_sync`**
Okay, I need to understand how `__hci_cmd_sync` is being used, specifically in relation to potential locking conflicts. My initial thought is that `__hci_cmd_sync` is called from many parts of the code base, so that immediately raises a red flag. The key question is whether it directly interacts with any locks.
Ah, I see. My initial thought was wrong. Itβs `hci_cmd_sync` that takes the `hdev->req_lock`, not `__hci_cmd_sync` directly. `__hci_cmd_sync` is then called by `hci_cmd_sync`. Okay, let me rephrase that for clarity: `hci_cmd_sync` grabs the lock, and then *calls* `__hci_cmd_sync`.
Right, `hci_cmd_sync` definitely grabs `hdev->req_lock`. Now, the crucial scenario to consider is concurrency. If a `kworker` thread, specifically `kworker/u9:11/12552` in this example, is actively running an event handler, and that event handler then calls `hci_cmd_sync`, then we have a potential locking issue. The event handler would attempt to acquire `hdev->req_lock` when it's already held!
Okay, so I need to understand the connection between event handlers and `hci_cmd_sync`. Let's step back and consider how event handlers are triggered. `hci_event_func` calls those handlers. Now, the critical question: Do any of these event handlers *themselves* call `hci_cmd_sync`? That would be the critical link in this potential deadlock chain.
My next step is to examine the `hci_event.c` file and specifically search for any calls to `hci_cmd_sync`. That's where I need to focus to confirm this hypothesis.
|
| 75/2 |
2026/05/19 05:55 |
tool |
grepper |
0m
Args: map[Expression:hci_cmd_sync\(]
Results: map[Output:
Full output is too long, showing 500 out of 692 lines.
Use more precise expression if possible.
[drivers/bluetooth/bpa10x.c=246=static int bpa10x_setup(struct hci_dev *hdev)
--
drivers/bluetooth/bpa10x.c-253- /* Read revision string */
drivers/bluetooth/bpa10x.c:254: skb = __hci_cmd_sync(hdev, 0xfc0e, sizeof(req), req, HCI_INIT_TIMEOUT);
drivers/bluetooth/bpa10x.c-255- if (IS_ERR(skb))
--
drivers/bluetooth/bpa10x.c=344=static int bpa10x_set_diag(struct hci_dev *hdev, bool enable)
--
drivers/bluetooth/bpa10x.c-354- /* Enable sniffer operation */
drivers/bluetooth/bpa10x.c:355: skb = __hci_cmd_sync(hdev, 0xfc0e, sizeof(req), req, HCI_INIT_TIMEOUT);
drivers/bluetooth/bpa10x.c-356- if (IS_ERR(skb))
--
drivers/bluetooth/btbcm.c=77=int btbcm_check_bdaddr(struct hci_dev *hdev)
--
drivers/bluetooth/btbcm.c-81-
drivers/bluetooth/btbcm.c:82: skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
drivers/bluetooth/btbcm.c-83- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btbcm.c=148=int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
--
drivers/bluetooth/btbcm.c-152-
drivers/bluetooth/btbcm.c:153: skb = __hci_cmd_sync(hdev, 0xfc01, 6, bdaddr, HCI_INIT_TIMEOUT);
drivers/bluetooth/btbcm.c-154- if (IS_ERR(skb)) {
--
drivers/bluetooth/btbcm.c=165=int btbcm_read_pcm_int_params(struct hci_dev *hdev,
--
drivers/bluetooth/btbcm.c-170-
drivers/bluetooth/btbcm.c:171: skb = __hci_cmd_sync(hdev, 0xfc1d, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btbcm.c-172- if (IS_ERR(skb)) {
--
drivers/bluetooth/btbcm.c=193=int btbcm_write_pcm_int_params(struct hci_dev *hdev,
--
drivers/bluetooth/btbcm.c-198-
drivers/bluetooth/btbcm.c:199: skb = __hci_cmd_sync(hdev, 0xfc1c, 5, params, HCI_INIT_TIMEOUT);
drivers/bluetooth/btbcm.c-200- if (IS_ERR(skb)) {
--
drivers/bluetooth/btbcm.c=211=int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw)
--
drivers/bluetooth/btbcm.c-220- /* Start Download */
drivers/bluetooth/btbcm.c:221: skb = __hci_cmd_sync(hdev, 0xfc2e, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btbcm.c-222- if (IS_ERR(skb)) {
--
drivers/bluetooth/btbcm.c-254-
drivers/bluetooth/btbcm.c:255: skb = __hci_cmd_sync(hdev, opcode, cmd->plen, cmd_param,
drivers/bluetooth/btbcm.c-256- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btbcm.c=274=static int btbcm_reset(struct hci_dev *hdev)
--
drivers/bluetooth/btbcm.c-277-
drivers/bluetooth/btbcm.c:278: skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btbcm.c-279- if (IS_ERR(skb)) {
--
drivers/bluetooth/btbcm.c=293=static struct sk_buff *btbcm_read_local_name(struct hci_dev *hdev)
--
drivers/bluetooth/btbcm.c-296-
drivers/bluetooth/btbcm.c:297: skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL,
drivers/bluetooth/btbcm.c-298- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btbcm.c=314=static struct sk_buff *btbcm_read_local_version(struct hci_dev *hdev)
--
drivers/bluetooth/btbcm.c-317-
drivers/bluetooth/btbcm.c:318: skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL,
drivers/bluetooth/btbcm.c-319- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btbcm.c=335=static struct sk_buff *btbcm_read_verbose_config(struct hci_dev *hdev)
--
drivers/bluetooth/btbcm.c-338-
drivers/bluetooth/btbcm.c:339: skb = __hci_cmd_sync(hdev, 0xfc79, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btbcm.c-340- if (IS_ERR(skb)) {
--
drivers/bluetooth/btbcm.c=355=static struct sk_buff *btbcm_read_controller_features(struct hci_dev *hdev)
--
drivers/bluetooth/btbcm.c-358-
drivers/bluetooth/btbcm.c:359: skb = __hci_cmd_sync(hdev, 0xfc6e, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btbcm.c-360- if (IS_ERR(skb)) {
--
drivers/bluetooth/btbcm.c=375=static struct sk_buff *btbcm_read_usb_product(struct hci_dev *hdev)
--
drivers/bluetooth/btbcm.c-378-
drivers/bluetooth/btbcm.c:379: skb = __hci_cmd_sync(hdev, 0xfc5a, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btbcm.c-380- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=61=int btintel_check_bdaddr(struct hci_dev *hdev)
--
drivers/bluetooth/btintel.c-65-
drivers/bluetooth/btintel.c:66: skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
drivers/bluetooth/btintel.c-67- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btintel.c=100=int btintel_enter_mfg(struct hci_dev *hdev)
--
drivers/bluetooth/btintel.c-104-
drivers/bluetooth/btintel.c:105: skb = __hci_cmd_sync(hdev, 0xfc11, 2, param, HCI_CMD_TIMEOUT);
drivers/bluetooth/btintel.c-106- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=117=int btintel_exit_mfg(struct hci_dev *hdev, bool reset, bool patched)
--
drivers/bluetooth/btintel.c-129-
drivers/bluetooth/btintel.c:130: skb = __hci_cmd_sync(hdev, 0xfc11, 2, param, HCI_CMD_TIMEOUT);
drivers/bluetooth/btintel.c-131- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=142=int btintel_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
--
drivers/bluetooth/btintel.c-146-
drivers/bluetooth/btintel.c:147: skb = __hci_cmd_sync(hdev, 0xfc31, 6, bdaddr, HCI_INIT_TIMEOUT);
drivers/bluetooth/btintel.c-148- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=160=static int btintel_set_event_mask(struct hci_dev *hdev, bool debug)
--
drivers/bluetooth/btintel.c-168-
drivers/bluetooth/btintel.c:169: skb = __hci_cmd_sync(hdev, 0xfc52, 8, mask, HCI_INIT_TIMEOUT);
drivers/bluetooth/btintel.c-170- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=180=int btintel_set_diag(struct hci_dev *hdev, bool enable)
--
drivers/bluetooth/btintel.c-195-
drivers/bluetooth/btintel.c:196: skb = __hci_cmd_sync(hdev, 0xfc43, 3, param, HCI_INIT_TIMEOUT);
drivers/bluetooth/btintel.c-197- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=247=void btintel_hw_error(struct hci_dev *hdev, u8 code)
--
drivers/bluetooth/btintel.c-253-
drivers/bluetooth/btintel.c:254: skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btintel.c-255- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c-261-
drivers/bluetooth/btintel.c:262: skb = __hci_cmd_sync(hdev, 0xfc22, 1, &type, HCI_INIT_TIMEOUT);
drivers/bluetooth/btintel.c-263- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=346=static int btintel_secure_send(struct hci_dev *hdev, u8 fragment_type, u32 plen,
--
drivers/bluetooth/btintel.c-355-
drivers/bluetooth/btintel.c:356: skb = __hci_cmd_sync(hdev, 0xfc09, fragment_len + 1,
drivers/bluetooth/btintel.c-357- cmd_param, HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btintel.c=370=int btintel_load_ddc_config(struct hci_dev *hdev, const char *ddc_name)
--
drivers/bluetooth/btintel.c-393-
drivers/bluetooth/btintel.c:394: skb = __hci_cmd_sync(hdev, 0xfc8b, cmd_plen, fw_ptr,
drivers/bluetooth/btintel.c-395- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btintel.c=433=int btintel_read_version(struct hci_dev *hdev, struct intel_version *ver)
--
drivers/bluetooth/btintel.c-436-
drivers/bluetooth/btintel.c:437: skb = __hci_cmd_sync(hdev, 0xfc05, 0, NULL, HCI_CMD_TIMEOUT);
drivers/bluetooth/btintel.c-438- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=662=static int btintel_read_version_tlv(struct hci_dev *hdev,
--
drivers/bluetooth/btintel.c-670-
drivers/bluetooth/btintel.c:671: skb = __hci_cmd_sync(hdev, 0xfc05, 1, param, HCI_CMD_TIMEOUT);
drivers/bluetooth/btintel.c-672- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=716=static int regmap_ibt_read(void *context, const void *addr, size_t reg_size,
--
drivers/bluetooth/btintel.c-747-
drivers/bluetooth/btintel.c:748: skb = hci_cmd_sync(ctx->hdev, ctx->op_read, sizeof(cp), &cp,
drivers/bluetooth/btintel.c-749- HCI_CMD_TIMEOUT);
--
drivers/bluetooth/btintel.c=780=static int regmap_ibt_gather_write(void *context,
--
drivers/bluetooth/btintel.c-819-
drivers/bluetooth/btintel.c:820: skb = hci_cmd_sync(ctx->hdev, ctx->op_write, plen, cp, HCI_CMD_TIMEOUT);
drivers/bluetooth/btintel.c-821- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=886=int btintel_send_intel_reset(struct hci_dev *hdev, u32 boot_param)
--
drivers/bluetooth/btintel.c-892-
drivers/bluetooth/btintel.c:893: skb = __hci_cmd_sync(hdev, BTINTEL_HCI_OP_RESET, sizeof(params), ¶ms,
drivers/bluetooth/btintel.c-894- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btintel.c=906=int btintel_read_boot_params(struct hci_dev *hdev,
--
drivers/bluetooth/btintel.c-910-
drivers/bluetooth/btintel.c:911: skb = __hci_cmd_sync(hdev, 0xfc0d, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btintel.c-912- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=1258=static void btintel_reset_to_bootloader(struct hci_dev *hdev)
--
drivers/bluetooth/btintel.c-1290-
drivers/bluetooth/btintel.c:1291: skb = __hci_cmd_sync(hdev, BTINTEL_HCI_OP_RESET, sizeof(params),
drivers/bluetooth/btintel.c-1292- ¶ms, HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btintel.c=1309=static int btintel_read_debug_features(struct hci_dev *hdev,
--
drivers/bluetooth/btintel.c-1317- */
drivers/bluetooth/btintel.c:1318: skb = __hci_cmd_sync(hdev, 0xfca6, sizeof(page_no), &page_no,
drivers/bluetooth/btintel.c-1319- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btintel.c=1340=static int btintel_set_debug_features(struct hci_dev *hdev,
--
drivers/bluetooth/btintel.c-1358-
drivers/bluetooth/btintel.c:1359: skb = __hci_cmd_sync(hdev, 0xfc8b, 11, mask, HCI_INIT_TIMEOUT);
drivers/bluetooth/btintel.c-1360- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c-1366-
drivers/bluetooth/btintel.c:1367: skb = __hci_cmd_sync(hdev, 0xfc8b, 5, period, HCI_INIT_TIMEOUT);
drivers/bluetooth/btintel.c-1368- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c-1374-
drivers/bluetooth/btintel.c:1375: skb = __hci_cmd_sync(hdev, 0xfca1, 1, &trace_enable, HCI_INIT_TIMEOUT);
drivers/bluetooth/btintel.c-1376- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=1389=static int btintel_reset_debug_features(struct hci_dev *hdev,
--
drivers/bluetooth/btintel.c-1407- /* Should stop the trace before writing ddc event mask. */
drivers/bluetooth/btintel.c:1408: skb = __hci_cmd_sync(hdev, 0xfca1, 1, &trace_enable, HCI_INIT_TIMEOUT);
drivers/bluetooth/btintel.c-1409- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c-1415-
drivers/bluetooth/btintel.c:1416: skb = __hci_cmd_sync(hdev, 0xfc8b, 11, mask, HCI_INIT_TIMEOUT);
drivers/bluetooth/btintel.c-1417- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=1454=static void btintel_coredump(struct hci_dev *hdev)
--
drivers/bluetooth/btintel.c-1457-
drivers/bluetooth/btintel.c:1458: skb = __hci_cmd_sync(hdev, 0xfc4e, 0, NULL, HCI_CMD_TIMEOUT);
drivers/bluetooth/btintel.c-1459- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=2439=static int btintel_configure_offload(struct hci_dev *hdev)
--
drivers/bluetooth/btintel.c-2444-
drivers/bluetooth/btintel.c:2445: skb = __hci_cmd_sync(hdev, 0xfc86, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btintel.c-2446- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=2473=static void btintel_set_ppag(struct hci_dev *hdev, struct intel_version_tlv *ver)
--
drivers/bluetooth/btintel.c-2545-
drivers/bluetooth/btintel.c:2546: skb = __hci_cmd_sync(hdev, INTEL_OP_PPAG_CMD, sizeof(ppag_cmd),
drivers/bluetooth/btintel.c-2547- &ppag_cmd, HCI_CMD_TIMEOUT);
--
drivers/bluetooth/btintel.c=2743=static int btintel_set_dsbr(struct hci_dev *hdev, struct intel_version_tlv *ver)
--
drivers/bluetooth/btintel.c-2795-
drivers/bluetooth/btintel.c:2796: skb = __hci_cmd_sync(hdev, 0xfc0a, sizeof(cmd), &cmd, HCI_CMD_TIMEOUT);
drivers/bluetooth/btintel.c-2797- if (IS_ERR(skb))
--
drivers/bluetooth/btintel.c=2862=static int btintel_send_sar_ddc(struct hci_dev *hdev, struct btintel_cp_ddc_write *data, u8 len)
--
drivers/bluetooth/btintel.c-2865-
drivers/bluetooth/btintel.c:2866: skb = __hci_cmd_sync(hdev, 0xfc8b, len, data, HCI_CMD_TIMEOUT);
drivers/bluetooth/btintel.c-2867- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=2968=static int btintel_set_mutual_sar(struct hci_dev *hdev, struct btintel_sar_inc_pwr *sar)
--
drivers/bluetooth/btintel.c-3018- enable = true;
drivers/bluetooth/btintel.c:3019: skb = __hci_cmd_sync(hdev, 0xfe25, 1, &enable, HCI_CMD_TIMEOUT);
drivers/bluetooth/btintel.c-3020- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=3267=void btintel_print_fseq_info(struct hci_dev *hdev)
--
drivers/bluetooth/btintel.c-3273-
drivers/bluetooth/btintel.c:3274: skb = __hci_cmd_sync(hdev, 0xfcb3, 0, NULL, HCI_CMD_TIMEOUT);
drivers/bluetooth/btintel.c-3275- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=3381=static int btintel_setup_combined(struct hci_dev *hdev)
--
drivers/bluetooth/btintel.c-3406- btintel_test_flag(hdev, INTEL_BROKEN_SHUTDOWN_LED)) {
drivers/bluetooth/btintel.c:3407: skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL,
drivers/bluetooth/btintel.c-3408- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btintel.c-3423- */
drivers/bluetooth/btintel.c:3424: skb = __hci_cmd_sync(hdev, 0xfc05, 1, param, HCI_CMD_TIMEOUT);
drivers/bluetooth/btintel.c-3425- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c=3637=int btintel_shutdown_combined(struct hci_dev *hdev)
--
drivers/bluetooth/btintel.c-3645- */
drivers/bluetooth/btintel.c:3646: skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btintel.c-3647- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel.c-3659- if (btintel_test_flag(hdev, INTEL_BROKEN_SHUTDOWN_LED)) {
drivers/bluetooth/btintel.c:3660: skb = __hci_cmd_sync(hdev, 0xfc3f, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btintel.c-3661- if (IS_ERR(skb)) {
--
drivers/bluetooth/btintel_pcie.c=2041=static int btintel_pcie_setup_internal(struct hci_dev *hdev)
--
drivers/bluetooth/btintel_pcie.c-2050-
drivers/bluetooth/btintel_pcie.c:2051: skb = __hci_cmd_sync(hdev, 0xfc05, 1, param, HCI_CMD_TIMEOUT);
drivers/bluetooth/btintel_pcie.c-2052- if (IS_ERR(skb)) {
--
drivers/bluetooth/btmrvl_main.c=548=static int btmrvl_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
--
drivers/bluetooth/btmrvl_main.c-557-
drivers/bluetooth/btmrvl_main.c:558: skb = __hci_cmd_sync(hdev, BT_CMD_SET_BDADDR, sizeof(buf), buf,
drivers/bluetooth/btmrvl_main.c-559- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btmtk.c=344=int btmtk_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
--
drivers/bluetooth/btmtk.c-348-
drivers/bluetooth/btmtk.c:349: skb = __hci_cmd_sync(hdev, 0xfc1a, 6, bdaddr, HCI_INIT_TIMEOUT);
drivers/bluetooth/btmtk.c-350- if (IS_ERR(skb)) {
--
drivers/bluetooth/btmtk.c=1210=static int btmtk_usb_isointf_init(struct hci_dev *hdev)
--
drivers/bluetooth/btmtk.c-1227-
drivers/bluetooth/btmtk.c:1228: skb = __hci_cmd_sync(hdev, 0xfd98, sizeof(iso_param), iso_param,
drivers/bluetooth/btmtk.c-1229- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btmtk.c=1271=int btmtk_usb_setup(struct hci_dev *hdev)
--
drivers/bluetooth/btmtk.c-1437-
drivers/bluetooth/btmtk.c:1438: skb = __hci_cmd_sync(hdev, 0xfc7a, sizeof(tci_sleep), &tci_sleep,
drivers/bluetooth/btmtk.c-1439- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btmtksdio.c=781=static int mt76xx_setup(struct hci_dev *hdev, const char *fwname)
--
drivers/bluetooth/btmtksdio.c-853-
drivers/bluetooth/btmtksdio.c:854: skb = __hci_cmd_sync(hdev, 0xfc7a, sizeof(tci_sleep), &tci_sleep,
drivers/bluetooth/btmtksdio.c-855- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btmtksdio.c=1016=static int btmtksdio_sco_setting(struct hci_dev *hdev)
--
drivers/bluetooth/btmtksdio.c-1026- /* Enable SCO over I2S/PCM for MediaTek chipset */
drivers/bluetooth/btmtksdio.c:1027: skb = __hci_cmd_sync(hdev, 0xfc72, sizeof(sco_setting),
drivers/bluetooth/btmtksdio.c-1028- &sco_setting, HCI_CMD_TIMEOUT);
--
drivers/bluetooth/btmtksdio.c=1316=static bool btmtksdio_sdio_wakeup(struct hci_dev *hdev)
--
drivers/bluetooth/btmtksdio.c-1330-
drivers/bluetooth/btmtksdio.c:1331: skb = __hci_cmd_sync(hdev, 0xfc27, sizeof(bt_awake),
drivers/bluetooth/btmtksdio.c-1332- &bt_awake, HCI_CMD_TIMEOUT);
--
drivers/bluetooth/btmtkuart.c=589=static int btmtkuart_setup(struct hci_dev *hdev)
--
drivers/bluetooth/btmtkuart.c-685-
drivers/bluetooth/btmtkuart.c:686: skb = __hci_cmd_sync(hdev, 0xfc7a, sizeof(tci_sleep), &tci_sleep,
drivers/bluetooth/btmtkuart.c-687- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btnxpuart.c=372=static struct sk_buff *nxp_drv_send_cmd(struct hci_dev *hdev, u16 opcode,
--
drivers/bluetooth/btnxpuart.c-385- if (resp) {
drivers/bluetooth/btnxpuart.c:386: skb = __hci_cmd_sync(hdev, opcode, plen, param, HCI_CMD_TIMEOUT);
drivers/bluetooth/btnxpuart.c-387- } else {
--
drivers/bluetooth/btqca.c=191=static int qca_send_reset(struct hci_dev *hdev)
--
drivers/bluetooth/btqca.c-197-
drivers/bluetooth/btqca.c:198: skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btqca.c-199- if (IS_ERR(skb)) {
--
drivers/bluetooth/btqca.c=717=static int qca_check_bdaddr(struct hci_dev *hdev, const struct qca_fw_config *config)
--
drivers/bluetooth/btqca.c-725-
drivers/bluetooth/btqca.c:726: skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
drivers/bluetooth/btqca.c-727- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btqcomsmd.c=108=static int btqcomsmd_setup(struct hci_dev *hdev)
--
drivers/bluetooth/btqcomsmd.c-111-
drivers/bluetooth/btqcomsmd.c:112: skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btqcomsmd.c-113- if (IS_ERR(skb))
--
drivers/bluetooth/btrtl.c=374=static struct sk_buff *btrtl_read_local_version(struct hci_dev *hdev)
--
drivers/bluetooth/btrtl.c-377-
drivers/bluetooth/btrtl.c:378: skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL,
drivers/bluetooth/btrtl.c-379- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btrtl.c=395=static int rtl_read_rom_version(struct hci_dev *hdev, u8 *version)
--
drivers/bluetooth/btrtl.c-400- /* Read RTL ROM version command */
drivers/bluetooth/btrtl.c:401: skb = __hci_cmd_sync(hdev, 0xfc6d, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btrtl.c-402- if (IS_ERR(skb)) {
--
drivers/bluetooth/btrtl.c=424=static int btrtl_vendor_read_reg16(struct hci_dev *hdev,
--
drivers/bluetooth/btrtl.c-429-
drivers/bluetooth/btrtl.c:430: skb = __hci_cmd_sync(hdev, 0xfc61, sizeof(*cmd), cmd,
drivers/bluetooth/btrtl.c-431- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btrtl.c=819=static int rtl_download_firmware(struct hci_dev *hdev,
--
drivers/bluetooth/btrtl.c-850- /* Send download command */
drivers/bluetooth/btrtl.c:851: skb = __hci_cmd_sync(hdev, 0xfc20, frag_len + 1, dl_cmd,
drivers/bluetooth/btrtl.c-852- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btrtl.c=1017=static int rtl_read_chip_type(struct hci_dev *hdev, u8 *type)
--
drivers/bluetooth/btrtl.c-1023- /* Read RTL chip type command */
drivers/bluetooth/btrtl.c:1024: skb = __hci_cmd_sync(hdev, 0xfc61, 5, cmd_buf, HCI_INIT_TIMEOUT);
drivers/bluetooth/btrtl.c-1025- if (IS_ERR(skb)) {
--
drivers/bluetooth/btrtl.c=1386=int btrtl_shutdown_realtek(struct hci_dev *hdev)
--
drivers/bluetooth/btrtl.c-1393- */
drivers/bluetooth/btrtl.c:1394: skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_CMD_TIMEOUT);
drivers/bluetooth/btrtl.c-1395- if (IS_ERR(skb)) {
--
drivers/bluetooth/btusb.c=2431=static int btusb_setup_bcm92035(struct hci_dev *hdev)
--
drivers/bluetooth/btusb.c-2437-
drivers/bluetooth/btusb.c:2438: skb = __hci_cmd_sync(hdev, 0xfc3b, 1, &val, HCI_INIT_TIMEOUT);
drivers/bluetooth/btusb.c-2439- if (IS_ERR(skb))
--
drivers/bluetooth/btusb.c=2447=static int btusb_setup_csr(struct hci_dev *hdev)
--
drivers/bluetooth/btusb.c-2457-
drivers/bluetooth/btusb.c:2458: skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL,
drivers/bluetooth/btusb.c-2459- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/btusb.c=2958=static int btusb_set_bdaddr_marvell(struct hci_dev *hdev,
--
drivers/bluetooth/btusb.c-2968-
drivers/bluetooth/btusb.c:2969: skb = __hci_cmd_sync(hdev, 0xfc22, sizeof(buf), buf, HCI_INIT_TIMEOUT);
drivers/bluetooth/btusb.c-2970- if (IS_ERR(skb)) {
--
drivers/bluetooth/btusb.c=2981=static int btusb_set_bdaddr_ath3012(struct hci_dev *hdev,
--
drivers/bluetooth/btusb.c-2993-
drivers/bluetooth/btusb.c:2994: skb = __hci_cmd_sync(hdev, 0xfc0b, sizeof(buf), buf, HCI_INIT_TIMEOUT);
drivers/bluetooth/btusb.c-2995- if (IS_ERR(skb)) {
--
drivers/bluetooth/btusb.c=3824=static int btusb_shutdown_qca(struct hci_dev *hdev)
--
drivers/bluetooth/btusb.c-3827-
drivers/bluetooth/btusb.c:3828: skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
drivers/bluetooth/btusb.c-3829- if (IS_ERR(skb)) {
--
drivers/bluetooth/hci_ag6xx.c=121=static int intel_mem_write(struct hci_dev *hdev, u32 addr, u32 plen,
--
drivers/bluetooth/hci_ag6xx.c-136-
drivers/bluetooth/hci_ag6xx.c:137: skb = __hci_cmd_sync(hdev, 0xfc8e, fragment_len + 6, cmd_param,
drivers/bluetooth/hci_ag6xx.c-138- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/hci_aml.c=404=static int aml_check_bdaddr(struct hci_dev *hdev)
--
drivers/bluetooth/hci_aml.c-412-
drivers/bluetooth/hci_aml.c:413: skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
drivers/bluetooth/hci_aml.c-414- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/hci_ath.c=147=static int ath_vendor_cmd(struct hci_dev *hdev, uint8_t opcode, uint16_t index,
--
drivers/bluetooth/hci_ath.c-160-
drivers/bluetooth/hci_ath.c:161: skb = __hci_cmd_sync(hdev, 0xfc0b, dlen + 4, &cmd, HCI_INIT_TIMEOUT);
drivers/bluetooth/hci_ath.c-162- if (IS_ERR(skb))
--
drivers/bluetooth/hci_bcm.c=178=static int bcm_set_baudrate(struct hci_uart *hu, unsigned int speed)
--
drivers/bluetooth/hci_bcm.c-194- */
drivers/bluetooth/hci_bcm.c:195: skb = __hci_cmd_sync(hdev, 0xfc45, 1, &clock, HCI_INIT_TIMEOUT);
drivers/bluetooth/hci_bcm.c-196- if (IS_ERR(skb)) {
--
drivers/bluetooth/hci_bcm.c-213- */
drivers/bluetooth/hci_bcm.c:214: skb = __hci_cmd_sync(hdev, 0xfc18, sizeof(param), ¶m,
drivers/bluetooth/hci_bcm.c-215- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/hci_bcm.c=391=static int bcm_setup_sleep(struct hci_uart *hu)
--
drivers/bluetooth/hci_bcm.c-398-
drivers/bluetooth/hci_bcm.c:399: skb = __hci_cmd_sync(hu->hdev, 0xfc27, sizeof(sleep_params),
drivers/bluetooth/hci_bcm.c-400- &sleep_params, HCI_INIT_TIMEOUT);
--
drivers/bluetooth/hci_bcm4377.c=1124=static int __bcm4378_send_calibration_chunk(struct bcm4377_data *bcm4377,
--
drivers/bluetooth/hci_bcm4377.c-1138-
drivers/bluetooth/hci_bcm4377.c:1139: skb = __hci_cmd_sync(bcm4377->hdev, 0xfd97, sizeof(cmd), &cmd,
drivers/bluetooth/hci_bcm4377.c-1140- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/hci_bcm4377.c=1240=static int bcm4377_send_ptb(struct bcm4377_data *bcm4377,
--
drivers/bluetooth/hci_bcm4377.c-1244-
drivers/bluetooth/hci_bcm4377.c:1245: skb = __hci_cmd_sync(bcm4377->hdev, 0xfd98, fw->size, fw->data,
drivers/bluetooth/hci_bcm4377.c-1246- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/hci_bcm4377.c=1259=static int bcm4378_send_ptb_chunk(struct bcm4377_data *bcm4377,
--
drivers/bluetooth/hci_bcm4377.c-1272-
drivers/bluetooth/hci_bcm4377.c:1273: skb = __hci_cmd_sync(bcm4377->hdev, 0xfe0d, sizeof(cmd), &cmd,
drivers/bluetooth/hci_bcm4377.c-1274- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/hci_bcm4377.c=1414=static int bcm4377_check_bdaddr(struct bcm4377_data *bcm4377)
--
drivers/bluetooth/hci_bcm4377.c-1418-
drivers/bluetooth/hci_bcm4377.c:1419: skb = __hci_cmd_sync(bcm4377->hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
drivers/bluetooth/hci_bcm4377.c-1420- HCI_INIT_TIMEOUT);
--
drivers/bluetooth/hci_bcm4377.c=1507=static int bcm4377_hci_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
--
drivers/bluetooth/hci_bcm4377.c-1512-
drivers/bluetooth/hci_bcm4377.c:1513: skb = __hci_cmd_sync(hdev, 0xfc01, 6, bdaddr, HCI_INIT_TIMEOUT);
drivers/bluetooth/hci_bcm4377.c-1514- if (IS_ERR(skb)) {
--
drivers/bluetooth/hci_h5.c=934=static int h5_btrtl_setup(struct h5 *h5)
--
drivers/bluetooth/hci_h5.c-954- baudrate_data = cpu_to_le32(device_baudrate);
drivers/bluetooth/hci_h5.c:955: skb = __hci_cmd_sync(h5->hu->hdev, 0xfc17, sizeof(baudrate_data),
drivers/bluetooth/hci_h5.c-956- &baudrate_data, HCI_INIT_TIMEOUT);
--
drivers/bluetooth/hci_intel.c=460=static int intel_set_baudrate(struct hci_uart *hu, unsigned int speed)
--
drivers/bluetooth/hci_intel.c-489- */
drivers/bluetooth/hci_intel.c:490: skb = __hci_cmd_sync(hdev, 0xfc05, 0, NULL, HCI_CMD_TIMEOUT);
drivers/bluetooth/hci_intel.c-491- if (IS_ERR(skb)) {
--
drivers/bluetooth/hci_intel.c=521=static int intel_setup(struct hci_uart *hu)
--
drivers/bluetooth/hci_intel.c-846-
drivers/bluetooth/hci_intel.c:847: skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_CMD_TIMEOUT);
drivers/bluetooth/hci_intel.c-848- if (IS_ERR(skb))
--
]
]
|
| 76/2 |
2026/05/19 05:55 |
llm |
expert |
0m
Model:
Tokens:
input: 130449
output: 43
thoughts: 5573
Thoughts: **A Deep Dive into a Bluetooth Deadlock**
Alright, let's break this down. It seems we have a nasty deadlock in the Bluetooth stack, specifically revolving around the `hci_cmd_sync` mechanism and the device lock (`hdev->lock`). I'm seeing `hci_cmd_sync` is primarily used during driver setup, but also within the event processing flow via `hci_event_packet` and subsequent calls to `hci_event_func`. My initial concern was a potential direct call from an event handler to `hci_cmd_sync`, which would be a surefire deadlock, but it's clear event handlers are offloading work and are not *directly* calling the blocking `hci_cmd_sync`.
The stack trace reveals `kworker/u9:10/11292` is blocked at `hci_event_packet` trying to acquire `hdev->lock`. Importantly, it *isn't* holding the lock. The trace is pointing fingers at another culprit, likely `syz-executor:5969`, which is in `hci_unregister_dev`, and is possibly trying to release this device. My first instinct would be to follow this path, but the trace suggests the lock is *not* held during unregistering.
Then my gaze shifts to `kworker/u9:4/5979` running `cmd_sync_work`, as it's holding `hdev->req_lock`. This is interesting because the worker thread holds `hdev->req_lock`, and this worker thread's purpose is to call `entry->func` which may take `hdev->lock`. My investigation focuses on this thread's operation, because it looks like it may be the source of the deadlock. This thread will run `entry->func` on `hdev->lock`.
However, the lockdep trace for `kworker/u9:4/5979` doesn't list `hdev->lock`. This should be impossible, as lockdep *should* identify this lock. So my intuition is that it may be blocked trying to acquire it. This means the kworker has called `entry->func` which is blocked, and this, in turn, may block `hdev->lock`. So who holds it?
I start chasing possibilities: Could `kworker/u9:11/12552` have it? What is it even *doing*? It's holding multiple locks, but the trace isn't entirely clear. It might be running `hci_rx_work` for a different device (like `hci6`) but this would still not explain the deadlock for `hci4`. My hypothesis is that, somehow, the lock acquisition order between these threads is causing the deadlock.
Next, I revisit `syz-executor:5969`. I review `vhci_release` and then `hci_sock_release`. Could `vhci_debugfs_remove` be the culprit? No. Could the blocking happen within the socket release path? `hci_dev_do_close` grabs `hdev->req_lock`. Now, it can call `hci_dev_close_sync`, which could then block trying to grab `hdev->lock`, but in the stack trace `hci_dev_close_sync` releases it.
I keep reviewing, and it's looking increasingly likely that `kworker/u9:4/5979` (running `cmd_sync_work`), might be blocked, waiting for some other thread to release `hdev->lock`. But if that's the case, then this would show that `kworker/u9:4/5979` has a pending `entry->func`. I start running through the possibilities, but I have a strong hunch we are blocked on the worker thread.
Then I note the lockdep output. It seems that multiple kworkers are actually running `hci_cmd_sync_work` on various devices. This means that if we are blocked on a worker, this deadlock happens more than one time.
In the bug report, `syz-executor` is blocked in `__flush_work`, meaning it's waiting for a work item to complete. If it's `hci_unregister_dev` it could be blocked on `cmd_sync_work`. This all points back to a problem in the `cmd_sync_work` path for `hci4`. I start focusing on this particular thread, because it is more directly associated with the problematic device. If so, `syz-executor` is blocked waiting for that work to complete, potentially due to a lock contention.
So I am back to square one: Who has `hdev->lock`? It appears the thread holding the lock is also blocked on something:
|
| 77/2 |
2026/05/19 05:55 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_sync.c IncludeLines:true Name:update_scan_sync]
Results: map[SourceCode:3241: static int update_scan_sync(struct hci_dev *hdev, void *data)
3242: {
3243: return hci_update_scan_sync(hdev);
3244: }
SourceFile:net/bluetooth/hci_sync.c]
|
| 78/2 |
2026/05/19 05:55 |
llm |
expert |
0m
Model:
Tokens:
input: 137184
output: 45
thoughts: 13
Thoughts: Okay, let's dive into this. Here's my thought process on this:
**Analyzing `hci_update_scan_sync`**
Alright, the first thing that pops into my head is to zero in on `hci_update_scan_sync`. Given my background in [insert your field, e.g., Bluetooth protocol design, embedded systems, etc.], I immediately start to consider what this function likely does. The name itself suggests it's related to updating or synchronizing scan parameters within the HCI (Host Controller Interface) layer.
I'm thinking about the implications β is it related to active scanning, passive scanning, or both? Are we talking about scan intervals, window sizes, or maybe even filter settings? And the "sync" part... that implies some sort of coordination, possibly between the host and controller. Is this function responsible for ensuring the parameters are consistent across both sides? Is there a state machine involved, perhaps, to manage the transition and synchronization process? I need to look deeper.
|
| 79/2 |
2026/05/19 05:55 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_sync.c IncludeLines:true Name:hci_update_scan_sync]
Results: map[SourceCode:3466: int hci_update_scan_sync(struct hci_dev *hdev)
3467: {
3468: u8 scan;
3469:
3470: if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
3471: return 0;
3472:
3473: if (!hdev_is_powered(hdev))
3474: return 0;
3475:
3476: if (mgmt_powering_down(hdev))
3477: return 0;
3478:
3479: if (hdev->scanning_paused)
3480: return 0;
3481:
3482: if (hci_dev_test_flag(hdev, HCI_CONNECTABLE) ||
3483: disconnected_accept_list_entries(hdev))
3484: scan = SCAN_PAGE;
3485: else
3486: scan = SCAN_DISABLED;
3487:
3488: if (hci_dev_test_flag(hdev, HCI_DISCOVERABLE))
3489: scan |= SCAN_INQUIRY;
3490:
3491: if (test_bit(HCI_PSCAN, &hdev->flags) == !!(scan & SCAN_PAGE) &&
3492: test_bit(HCI_ISCAN, &hdev->flags) == !!(scan & SCAN_INQUIRY))
3493: return 0;
3494:
3495: return hci_write_scan_enable_sync(hdev, scan);
3496: }
SourceFile:net/bluetooth/hci_sync.c]
|
| 80/2 |
2026/05/19 05:55 |
llm |
expert |
0m
Model:
Tokens:
input: 137942
output: 41
thoughts: 31
Thoughts: Okay, here's my take on those thoughts, framed as an expert's internal monologue:
**Checking Synchronization & Locking in the HCI Driver**
Alright, let's see, I'm thinking about the low-level Bluetooth HCI driver code. Specifically, I need to be sure about the locking strategy used around critical functions. My immediate question is: does `hci_update_scan_sync` take the `hdev->lock`? I don't *think* so... no, I'm pretty sure it doesn't. We'd have to look at the actual source to be absolutely certain, but my gut feeling is that scan updates are handled differently. Now, what about the `set_powered_sync` function? Does *that* grab the lock? That's a key piece of the puzzle because if it *does* take `hdev->lock`, it could potentially introduce a deadlock scenario if `hci_update_scan_sync` is called from within a locked context and `set_powered_sync` depends on the same lock. Gotta investigate to ensure we avoid any race conditions there, as it seems we need to make sure power related changes are thread safe.
|
| 81/2 |
2026/05/19 05:55 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/mgmt.c IncludeLines:true Name:set_powered_sync]
Results: map[SourceCode:1368: static int set_powered_sync(struct hci_dev *hdev, void *data)
1369: {
1370: struct mgmt_pending_cmd *cmd = data;
1371: struct mgmt_mode cp;
1372:
1373: mutex_lock(&hdev->mgmt_pending_lock);
1374:
1375: /* Make sure cmd still outstanding. */
1376: if (!__mgmt_pending_listed(hdev, cmd)) {
1377: mutex_unlock(&hdev->mgmt_pending_lock);
1378: return -ECANCELED;
1379: }
1380:
1381: memcpy(&cp, cmd->param, sizeof(cp));
1382:
1383: mutex_unlock(&hdev->mgmt_pending_lock);
1384:
1385: BT_DBG("%s", hdev->name);
1386:
1387: return hci_set_powered_sync(hdev, cp.val);
1388: }
SourceFile:net/bluetooth/mgmt.c]
|
| 82/2 |
2026/05/19 05:55 |
llm |
expert |
0m
Model:
Tokens:
input: 138590
output: 45
thoughts: 18
Thoughts: Okay, here's my take on those thoughts, framed as an expert's internal monologue:
**Investigating `hci_set_powered_sync` Locking**
Right, so I'm looking at `hci_set_powered_sync`. My immediate question, and it's a critical one in kernel development, is: does this function properly handle its locking? Specifically, does it acquire and release `hdev->lock` appropriately? I need to know this intimately. Concurrency bugs in Bluetooth can be a nightmare to debug, and incorrect locking is often at the root of them. I've seen it happen. If it doesn't take the lock, we're asking for trouble, potential race conditions that could lead to data corruption, unexpected behavior, or even a system crash under the right (or wrong!) conditions. I can't even *begin* to assess this function's safety or efficiency without understanding its locking strategy. This is fundamental. This is *the* question I'm starting with.
|
| 83/2 |
2026/05/19 05:56 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_sync.c IncludeLines:true Name:hci_set_powered_sync]
Results: map[SourceCode:5797: int hci_set_powered_sync(struct hci_dev *hdev, u8 val)
5798: {
5799: if (val)
5800: return hci_power_on_sync(hdev);
5801:
5802: return hci_power_off_sync(hdev);
5803: }
SourceFile:net/bluetooth/hci_sync.c]
|
| 84/2 |
2026/05/19 05:56 |
llm |
expert |
0m
Model:
Tokens:
input: 138998
output: 45
thoughts: 18
Thoughts: Okay, here's my attempt at summarizing that thought process, assuming I'm a seasoned embedded systems/Bluetooth expert:
**Investigating a Potential Race Condition in HCI Power-Up**
Right, so I'm looking at this `hci_power_on_sync` function. My immediate question is, does this function handle its own locking mechanism, specifically around the `hdev->lock` mutex? This is crucial. If it *doesn't* take that lock, or if it doesn't take it correctly at the right time, we've got a potential race condition on our hands. We could be dealing with concurrent access to the `hdev` structure during a critical power-up sequence, which is a recipe for disaster. Data corruption, unexpected states⦠the usual suspects.
I need to quickly understand if this function is responsible for the necessary synchronization. If it assumes the caller has taken the lock, or if it *should* be grabbing it internally, I need to verify that interaction. This is foundational to ensuring the integrity of the Bluetooth controller initialization. Gotta drill down into the code and determine the locking strategy here. A subtle locking bug in this critical path can lead to really intermittent, difficult-to-debug failures. Gotta get this right.
|
| 85/2 |
2026/05/19 05:56 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_sync.c IncludeLines:true Name:hci_power_on_sync]
Results: map[SourceCode:5391: /* This function perform power on HCI command sequence as follows:
5392: *
5393: * If controller is already up (HCI_UP) performs hci_powered_update_sync
5394: * sequence otherwise run hci_dev_open_sync which will follow with
5395: * hci_powered_update_sync after the init sequence is completed.
5396: */
5397: static int hci_power_on_sync(struct hci_dev *hdev)
5398: {
5399: int err;
5400:
5401: if (test_bit(HCI_UP, &hdev->flags) &&
5402: hci_dev_test_flag(hdev, HCI_MGMT) &&
5403: hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) {
5404: cancel_delayed_work(&hdev->power_off);
5405: return hci_powered_update_sync(hdev);
5406: }
5407:
5408: err = hci_dev_open_sync(hdev);
5409: if (err < 0)
5410: return err;
5411:
5412: /* During the HCI setup phase, a few error conditions are
5413: * ignored and they need to be checked now. If they are still
5414: * valid, it is important to return the device back off.
5415: */
5416: if (hci_dev_test_flag(hdev, HCI_RFKILLED) ||
5417: hci_dev_test_flag(hdev, HCI_UNCONFIGURED) ||
5418: (!bacmp(&hdev->bdaddr, BDADDR_ANY) &&
5419: !bacmp(&hdev->static_addr, BDADDR_ANY))) {
5420: hci_dev_clear_flag(hdev, HCI_AUTO_OFF);
5421: hci_dev_close_sync(hdev);
5422: } else if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) {
5423: queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
5424: HCI_AUTO_OFF_TIMEOUT);
5425: }
5426:
5427: if (hci_dev_test_and_clear_flag(hdev, HCI_SETUP)) {
5428: /* For unconfigured devices, set the HCI_RAW flag
5429: * so that userspace can easily identify them.
5430: */
5431: if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
5432: set_bit(HCI_RAW, &hdev->flags);
5433:
5434: /* For fully configured devices, this will send
5435: * the Index Added event. For unconfigured devices,
5436: * it will send Unconfigued Index Added event.
5437: *
5438: * Devices with HCI_QUIRK_RAW_DEVICE are ignored
5439: * and no event will be send.
5440: */
5441: mgmt_index_added(hdev);
5442: } else if (hci_dev_test_and_clear_flag(hdev, HCI_CONFIG)) {
5443: /* When the controller is now configured, then it
5444: * is important to clear the HCI_RAW flag.
5445: */
5446: if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
5447: clear_bit(HCI_RAW, &hdev->flags);
5448:
5449: /* Powering on the controller with HCI_CONFIG set only
5450: * happens with the transition from unconfigured to
5451: * configured. This will send the Index Added event.
5452: */
5453: mgmt_index_added(hdev);
5454: }
5455:
5456: return 0;
5457: }
SourceFile:net/bluetooth/hci_sync.c]
|
| 86/2 |
2026/05/19 05:56 |
llm |
expert |
1m
Model:
Tokens:
input: 140486
output: 43
thoughts: 6547
Thoughts: **Analyzing a Bluetooth HCI Lockup**
Okay, so I'm diving into this lockdep output to figure out what's causing this 143-second hang. The initial thought process was: `hci_power_on_sync` calls `hci_dev_close_sync`, which takes `hdev->lock`. If `kworker/u9:4/5979` is running `set_powered_sync` (which calls `hci_power_on_sync`), it takes `hdev->lock`. But then, `hci_dev_close_sync` flushes `rx_work` *before* taking the lock. So if that worker flushes `rx_work` it's blocked. And `rx_work` is blocked, on `hdev->lock`. But who owns it?
My initial suspicion was `syz-executor:5969`, which is in `hci_unregister_dev`. `hci_unregister_dev` calls `hci_dev_do_close`, and I realized it calls `disable_work_sync(&hdev->rx_work)` before the close. If `syz-executor:5969` is blocked in that, it does *not* hold `hdev->lock`. If it's blocked in `hci_cmd_sync_clear`, it calls `cancel_work_sync`, and that blocks. It appears `syz-executor:5969` is blocked in `__flush_work`. `kworker/u9:4/5979` is blocked in `flush_work(&hdev->rx_work)`! The lock is not taken!
The next thought was maybe `kworker/u9:11/12552`, which may be running `hci_error_reset` or `hci_power_off` or a event handler. But those threads also don't hold `hdev->lock`.
Then I realized a critical detail: *event handlers* run in `rx_work`. But there's only one `rx_work` per `hdev`. So, two threads can't run `rx_work` on the same `hdev` at the same time. This is key. The current lockdep trace shows `kworker/u9:10/11292` holds `hdev->lock`. Then I got confused. This means `rx_work` acquired it at line 7736, where the event is processed. However, it *should* release it at 7739.
So, who's blocked on what? The lockdep trace shows three locks held by `kworker/u9:10/11292`, which is `rx_work`. It lists `hdev->lock` as held. And that acquisition is at `hci_event_packet+0x162/0x1260 net/bluetooth/hci_event.c:7736`. Lockdep only lists locks that are currently HELD. It says that `rx_work` is blocked in the event handler in the Bluetooth stack while holding the lock. And it acquired it at line 7736, meaning somewhere between 7736 and 7739. And the code is `kfree_skb` and `skb_clone`. Does `kfree_skb` block? No. Does `skb_clone`? It uses `GFP_KERNEL`, which can block for memory reclaim.
Aha! This is probably an OOM situation, perhaps triggered by syzkaller.
Now, wait, if `kworker/u9:10/11292` has the lock *and* is blocked, it means the `GFP_KERNEL` allocation *can* block indefinitely. But it can take a long time and the executor is blocked. This means if `rx_work` is indeed processing an event in `hci_event_packet`, and it calls `skb_clone`, it could be blocked in memory reclaim! If it does block in `kmem_cache_alloc` with `GFP_KERNEL`, it can call shrinkers which call many tasks.
Here's the key: lockdep shows a lock as *held* even if the task is blocked while trying to acquire it. It means it has executed `mutex_acquire_nest`, and the lock is in the task's `held_locks`.
So, `kworker/u9:10/11292` (the rx workqueue) is BLOCKED *trying to acquire* `hdev->lock` at line 7736. It does not own it. `kworker/u9:4/5
|
| 87/2 |
2026/05/19 05:57 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_sock.c IncludeLines:true Name:hci_sock_ioctl]
Results: map[SourceCode:1043: static int hci_sock_ioctl(struct socket *sock, unsigned int cmd,
1044: unsigned long arg)
1045: {
1046: void __user *argp = (void __user *)arg;
1047: struct sock *sk = sock->sk;
1048: int err;
1049:
1050: BT_DBG("cmd %x arg %lx", cmd, arg);
1051:
1052: /* Make sure the cmd is valid before doing anything */
1053: switch (cmd) {
1054: case HCIGETDEVLIST:
1055: case HCIGETDEVINFO:
1056: case HCIGETCONNLIST:
1057: case HCIDEVUP:
1058: case HCIDEVDOWN:
1059: case HCIDEVRESET:
1060: case HCIDEVRESTAT:
1061: case HCISETSCAN:
1062: case HCISETAUTH:
1063: case HCISETENCRYPT:
1064: case HCISETPTYPE:
1065: case HCISETLINKPOL:
1066: case HCISETLINKMODE:
1067: case HCISETACLMTU:
1068: case HCISETSCOMTU:
1069: case HCIINQUIRY:
1070: case HCISETRAW:
1071: case HCIGETCONNINFO:
1072: case HCIGETAUTHINFO:
1073: case HCIBLOCKADDR:
1074: case HCIUNBLOCKADDR:
1075: break;
1076: default:
1077: return -ENOIOCTLCMD;
1078: }
1079:
1080: lock_sock(sk);
1081:
1082: if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
1083: err = -EBADFD;
1084: goto done;
1085: }
1086:
1087: /* When calling an ioctl on an unbound raw socket, then ensure
1088: * that the monitor gets informed. Ensure that the resulting event
1089: * is only send once by checking if the cookie exists or not. The
1090: * socket cookie will be only ever generated once for the lifetime
1091: * of a given socket.
1092: */
1093: if (hci_sock_gen_cookie(sk)) {
1094: struct sk_buff *skb;
1095:
1096: /* Perform careful checks before setting the HCI_SOCK_TRUSTED
1097: * flag. Make sure that not only the current task but also
1098: * the socket opener has the required capability, since
1099: * privileged programs can be tricked into making ioctl calls
1100: * on HCI sockets, and the socket should not be marked as
1101: * trusted simply because the ioctl caller is privileged.
1102: */
1103: if (sk_capable(sk, CAP_NET_ADMIN))
1104: hci_sock_set_flag(sk, HCI_SOCK_TRUSTED);
1105:
1106: /* Send event to monitor */
1107: skb = create_monitor_ctrl_open(sk);
1108: if (skb) {
1109: hci_send_to_channel(HCI_CHANNEL_MONITOR, skb,
1110: HCI_SOCK_TRUSTED, NULL);
1111: kfree_skb(skb);
1112: }
1113: }
1114:
1115: release_sock(sk);
1116:
1117: switch (cmd) {
1118: case HCIGETDEVLIST:
1119: return hci_get_dev_list(argp);
1120:
1121: case HCIGETDEVINFO:
1122: return hci_get_dev_info(argp);
1123:
1124: case HCIGETCONNLIST:
1125: return hci_get_conn_list(argp);
1126:
1127: case HCIDEVUP:
1128: if (!capable(CAP_NET_ADMIN))
1129: return -EPERM;
1130: return hci_dev_open(arg);
1131:
1132: case HCIDEVDOWN:
1133: if (!capable(CAP_NET_ADMIN))
1134: return -EPERM;
1135: return hci_dev_close(arg);
1136:
1137: case HCIDEVRESET:
1138: if (!capable(CAP_NET_ADMIN))
1139: return -EPERM;
1140: return hci_dev_reset(arg);
1141:
1142: case HCIDEVRESTAT:
1143: if (!capable(CAP_NET_ADMIN))
1144: return -EPERM;
1145: return hci_dev_reset_stat(arg);
1146:
1147: case HCISETSCAN:
1148: case HCISETAUTH:
1149: case HCISETENCRYPT:
1150: case HCISETPTYPE:
1151: case HCISETLINKPOL:
1152: case HCISETLINKMODE:
1153: case HCISETACLMTU:
1154: case HCISETSCOMTU:
1155: if (!capable(CAP_NET_ADMIN))
1156: return -EPERM;
1157: return hci_dev_cmd(cmd, argp);
1158:
1159: case HCIINQUIRY:
1160: return hci_inquiry(argp);
1161: }
1162:
1163: lock_sock(sk);
1164:
1165: err = hci_sock_bound_ioctl(sk, cmd, arg);
1166:
1167: done:
1168: release_sock(sk);
1169: return err;
1170: }
SourceFile:net/bluetooth/hci_sock.c]
|
| 88/2 |
2026/05/19 05:57 |
llm |
expert |
0m
Model:
Tokens:
input: 149859
output: 42
thoughts: 190
Thoughts: Here's my analysis of this code sequence:
**Potential Deadlock in Bluetooth HCI Device Handling**
Okay, so I'm looking at this `hci_sock_ioctl` function, and it seems to be the central point for managing HCI device operations. It calls a bunch of device-specific functions like `hci_dev_open`, `hci_dev_close`, `hci_dev_reset`, `hci_dev_cmd`, and `hci_inquiry`. That's standard enough.
Now, things get interesting when I look at the locking mechanisms. `hci_dev_open`, `hci_dev_close`, and `hci_dev_reset` all call their respective "do" functions, which all seem to be grabbing `hdev->req_lock`. Makes sense, they're likely protecting critical sections of device request handling.
But then I see `hci_inquiry`. It first grabs `hdev->lock` *and then* `hdev->req_lock`. Wait a minute... that's a potential problem! If another thread is currently in `hci_dev_do_open`, `hci_dev_do_close`, or `hci_dev_do_reset` (or any of the other "do" functions) and *already has* `hdev->req_lock`, and *then* tries to call `hci_inquiry`, there will be a classic deadlock. The second thread is trying to acquire the first, while the first is trying to acquire the second! The order of lock acquisition isn't consistent, and that's a recipe for disaster.
I need to re-examine the `hci_inquiry` function very carefully. This is a critical point that needs immediate attention.
|
| 89/2 |
2026/05/19 05:57 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_core.c IncludeLines:true Name:hci_inquiry]
Results: map[SourceCode: 325: int hci_inquiry(void __user *arg)
326: {
327: __u8 __user *ptr = arg;
328: struct hci_inquiry_req ir;
329: struct hci_dev *hdev;
330: int err = 0, do_inquiry = 0, max_rsp;
331: __u8 *buf;
332:
333: if (copy_from_user(&ir, ptr, sizeof(ir)))
334: return -EFAULT;
335:
336: hdev = hci_dev_get(ir.dev_id);
337: if (!hdev)
338: return -ENODEV;
339:
340: if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
341: err = -EBUSY;
342: goto done;
343: }
344:
345: if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
346: err = -EOPNOTSUPP;
347: goto done;
348: }
349:
350: if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
351: err = -EOPNOTSUPP;
352: goto done;
353: }
354:
355: /* Restrict maximum inquiry length to 60 seconds */
356: if (ir.length > 60) {
357: err = -EINVAL;
358: goto done;
359: }
360:
361: hci_dev_lock(hdev);
362: if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
363: inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
364: hci_inquiry_cache_flush(hdev);
365: do_inquiry = 1;
366: }
367: hci_dev_unlock(hdev);
368:
369: if (do_inquiry) {
370: hci_req_sync_lock(hdev);
371: err = hci_inquiry_sync(hdev, ir.length, ir.num_rsp);
372: hci_req_sync_unlock(hdev);
373:
374: if (err < 0)
375: goto done;
376:
377: /* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
378: * cleared). If it is interrupted by a signal, return -EINTR.
379: */
380: if (wait_on_bit(&hdev->flags, HCI_INQUIRY,
381: TASK_INTERRUPTIBLE)) {
382: err = -EINTR;
383: goto done;
384: }
385: }
386:
387: /* for unlimited number of responses we will use buffer with
388: * 255 entries
389: */
390: max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
391:
392: /* cache_dump can't sleep. Therefore we allocate temp buffer and then
393: * copy it to the user space.
394: */
395: buf = kmalloc_array(max_rsp, sizeof(struct inquiry_info), GFP_KERNEL);
396: if (!buf) {
397: err = -ENOMEM;
398: goto done;
399: }
400:
401: hci_dev_lock(hdev);
402: ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
403: hci_dev_unlock(hdev);
404:
405: BT_DBG("num_rsp %d", ir.num_rsp);
406:
407: if (!copy_to_user(ptr, &ir, sizeof(ir))) {
408: ptr += sizeof(ir);
409: if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
410: ir.num_rsp))
411: err = -EFAULT;
412: } else
413: err = -EFAULT;
414:
415: kfree(buf);
416:
417: done:
418: hci_dev_put(hdev);
419: return err;
420: }
SourceFile:net/bluetooth/hci_core.c]
|
| 90/2 |
2026/05/19 05:57 |
llm |
expert |
0m
Model:
Tokens:
input: 151870
output: 44
thoughts: 239
Thoughts: **Analyzing Potential Deadlock in HCI Inquiry**
Okay, let me think this through. `hci_inquiry` grabs `hdev->lock` here (line 361), then releases it (367). After that, it takes `hdev->req_lock` (370) and releases it again (372). Then, it grabs `hdev->lock` again (401), and finally releases it (403). It looks like it never holds both locks simultaneously. So, based on that sequence, there's no obvious AB-BA deadlock situation here. That's good.
But hang on⦠there's a potential wrinkle. What if `hci_inquiry` is blocked at line 380? It's waiting on a bit, specifically `HCI_INQUIRY`. Okay, let's see... it's a `wait_on_bit` call. Crucially, it's *not* holding either `hdev->lock` or `hdev->req_lock` during that wait. That means, while waiting, `hci_inquiry` isn't blocking anything else which has the lock! That's a relief.
Alright, but I need to make sure I haven't missed anything. What about `hci_inquiry_sync`? It takes `hdev->lock`, doesn't it? Let me just quickly check that function's code to be absolutely certain...I need to make sure there's no possibility of a conflicting lock order. Let's see...
|
| 91/2 |
2026/05/19 05:57 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_sync.c IncludeLines:true Name:hci_inquiry_sync]
Results: map[SourceCode:5925: int hci_inquiry_sync(struct hci_dev *hdev, u8 length, u8 num_rsp)
5926: {
5927: const u8 giac[3] = { 0x33, 0x8b, 0x9e };
5928: const u8 liac[3] = { 0x00, 0x8b, 0x9e };
5929: struct hci_cp_inquiry cp;
5930:
5931: bt_dev_dbg(hdev, "");
5932:
5933: if (test_bit(HCI_INQUIRY, &hdev->flags))
5934: return 0;
5935:
5936: hci_dev_lock(hdev);
5937: hci_inquiry_cache_flush(hdev);
5938: hci_dev_unlock(hdev);
5939:
5940: memset(&cp, 0, sizeof(cp));
5941:
5942: if (hdev->discovery.limited)
5943: memcpy(&cp.lap, liac, sizeof(cp.lap));
5944: else
5945: memcpy(&cp.lap, giac, sizeof(cp.lap));
5946:
5947: cp.length = length;
5948: cp.num_rsp = num_rsp;
5949:
5950: return __hci_cmd_sync_status(hdev, HCI_OP_INQUIRY,
5951: sizeof(cp), &cp, HCI_CMD_TIMEOUT);
5952: }
SourceFile:net/bluetooth/hci_sync.c]
|
| 92/2 |
2026/05/19 05:57 |
llm |
expert |
0m
Model:
Tokens:
input: 152974
output: 45
thoughts: 650
Thoughts: **Debugging a Potential Bluetooth Deadlock**
Okay, let's break this down. I'm looking at `hci_inquiry_sync` and trying to understand a possible blocking issue. It's taking `hdev->lock` briefly, unlocking it, and *then* calling `__hci_cmd_sync_status`. The key thing is that it *doesn't* hold `hdev->lock` while waiting for the command to complete. This means there's *no* direct AB-BA deadlock scenario between `hdev->lock` and `hdev->req_lock` within this function's immediate logic.
So, if `rx_work` is blocked on `hdev->lock`, the question becomes: *who* is holding that lock and what are *they* blocked on? We know it's not the simple sequence within `hci_inquiry_sync`. My initial thought was `hdev->req_lock`, but we ruled that out already.
Could it be `skb_clone` causing the block, due to OOM? It's possible, and a plausible explanation, if resources are constrained. We should keep that in mind as a potential root cause.
But are there other locks, or functions that are called, that could be the source?
Let's consider `hci_dev_close_sync`. I'm seeing that function taking `hdev->lock`. I'm going to look at that code snippet closely to see what it does *while* holding that lock. Specifically, I need to know if it can be blocked in its own right. Does it call anything that could be blocked on another lock?
Looking at the code, at the lines following `hci_dev_lock(hdev)` I see:
* `hci_discovery_set_state(hdev, DISCOVERY_STOPPED)`
* `__mgmt_power_off(hdev)`
* `hci_inquiry_cache_flush(hdev)`
* `hci_pend_le_actions_clear(hdev)`
* `hci_conn_hash_flush(hdev)`
* `smp_unregister(hdev)`
I need to dig into these functions to see if any of them are blocking. I'll need to research if `__mgmt_power_off`, `hci_conn_hash_flush` and `smp_unregister` can block. Let's start with `hci_conn_hash_flush`.
|
| 93/2 |
2026/05/19 05:57 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_conn.c IncludeLines:true Name:hci_conn_hash_flush]
Results: map[SourceCode:2621: /* Drop all connection on the device */
2622: void hci_conn_hash_flush(struct hci_dev *hdev)
2623: {
2624: struct list_head *head = &hdev->conn_hash.list;
2625: struct hci_conn *conn;
2626:
2627: BT_DBG("hdev %s", hdev->name);
2628:
2629: /* We should not traverse the list here, because hci_conn_del
2630: * can remove extra links, which may cause the list traversal
2631: * to hit items that have already been released.
2632: */
2633: while ((conn = list_first_entry_or_null(head,
2634: struct hci_conn,
2635: list)) != NULL) {
2636: conn->state = BT_CLOSED;
2637: hci_disconn_cfm(conn, HCI_ERROR_LOCAL_HOST_TERM);
2638: hci_conn_del(conn);
2639: }
2640: }
SourceFile:net/bluetooth/hci_conn.c]
|
| 94/2 |
2026/05/19 05:57 |
llm |
expert |
1m
Model:
Tokens:
input: 154543
output: 43
thoughts: 28
Thoughts: Okay, here's my interpretation of that thought process, tailored for an expert audience, and written in the first person:
**Flushing Connection Hashes: Potential Blocking in the HCI Layer**
Alright, so `hci_conn_hash_flush` is calling `hci_conn_del`. That's standard practice, clearing out stale connections from the hash table, but it immediately raises a critical question for performance. I need to be sure about this - does `hci_conn_del` block? Specifically, at any point within that function, is there a spinlock, mutex, or other synchronization mechanism that could potentially lead to delays, especially under heavy load? The concern is, if `hci_conn_del` does block, `hci_conn_hash_flush` could become a bottleneck. We all know how quickly these connection tables can grow, and a blocking `hci_conn_del` means the flush operation, and therefore potential connection cleanup can be substantially delayed. I'll need to dig into the implementation of `hci_conn_del` to confirm it and assess what's happening internally β is there contention, and if so, how is it managed? Is it using a read-copy-update technique? Or some other non-blocking pattern? Or is this a potential performance issue, especially when dealing with a high volume of connections. Time to go spelunking in the code.
|
| 95/2 |
2026/05/19 05:58 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_conn.c IncludeLines:true Name:hci_conn_del]
Results: map[SourceCode:1164: void hci_conn_del(struct hci_conn *conn)
1165: {
1166: struct hci_dev *hdev = conn->hdev;
1167:
1168: BT_DBG("%s hcon %p handle %d", hdev->name, conn, conn->handle);
1169:
1170: hci_conn_unlink(conn);
1171:
1172: disable_delayed_work_sync(&conn->disc_work);
1173: disable_delayed_work_sync(&conn->auto_accept_work);
1174: disable_delayed_work_sync(&conn->idle_work);
1175:
1176: /* Remove the connection from the list so unacked logic can detect when
1177: * a certain pool is not being utilized.
1178: */
1179: hci_conn_hash_del(hdev, conn);
1180:
1181: /* Handle unacked frames:
1182: *
1183: * - In case there are no connection, or if restoring the buffers
1184: * considered in transist would overflow, restore all buffers to the
1185: * pool.
1186: * - Otherwise restore just the buffers considered in transit for the
1187: * hci_conn
1188: */
1189: switch (conn->type) {
1190: case ACL_LINK:
1191: if (!hci_conn_num(hdev, ACL_LINK) ||
1192: hdev->acl_cnt + conn->sent > hdev->acl_pkts)
1193: hdev->acl_cnt = hdev->acl_pkts;
1194: else
1195: hdev->acl_cnt += conn->sent;
1196: break;
1197: case LE_LINK:
1198: cancel_delayed_work(&conn->le_conn_timeout);
1199:
1200: if (hdev->le_pkts) {
1201: if (!hci_conn_num(hdev, LE_LINK) ||
1202: hdev->le_cnt + conn->sent > hdev->le_pkts)
1203: hdev->le_cnt = hdev->le_pkts;
1204: else
1205: hdev->le_cnt += conn->sent;
1206: } else {
1207: if ((!hci_conn_num(hdev, LE_LINK) &&
1208: !hci_conn_num(hdev, ACL_LINK)) ||
1209: hdev->acl_cnt + conn->sent > hdev->acl_pkts)
1210: hdev->acl_cnt = hdev->acl_pkts;
1211: else
1212: hdev->acl_cnt += conn->sent;
1213: }
1214: break;
1215: case CIS_LINK:
1216: case BIS_LINK:
1217: case PA_LINK:
1218: if (!hci_iso_count(hdev) ||
1219: hdev->iso_cnt + conn->sent > hdev->iso_pkts)
1220: hdev->iso_cnt = hdev->iso_pkts;
1221: else
1222: hdev->iso_cnt += conn->sent;
1223: break;
1224: }
1225:
1226: skb_queue_purge(&conn->data_q);
1227: skb_queue_purge(&conn->tx_q.queue);
1228:
1229: /* Remove the connection from the list and cleanup its remaining
1230: * state. This is a separate function since for some cases like
1231: * BT_CONNECT_SCAN we *only* want the cleanup part without the
1232: * rest of hci_conn_del.
1233: */
1234: hci_conn_cleanup(conn);
1235:
1236: /* Dequeue callbacks using connection pointer as data */
1237: hci_cmd_sync_dequeue(hdev, NULL, conn, NULL);
1238: }
SourceFile:net/bluetooth/hci_conn.c]
|
| 96/2 |
2026/05/19 05:58 |
llm |
expert |
0m
Model:
Tokens:
input: 156108
output: 43
thoughts: 61
Thoughts: Here's my summary, as though I'm thinking through this code:
**Analyzing a Potential Blocking Point in HCI Connection Deletion**
Okay, so `hci_conn_del` is the function that handles deleting a HCI connection. The first thing that jumps out is that it calls `disable_delayed_work_sync(&conn->disc_work)`. I know that `disable_delayed_work_sync` *can* be a blocking operation. That's a red flag. Specifically, it'll block if the `disc_work` work item is currently running. So, the question is: what *is* `disc_work` doing? I need to understand what this work item is responsible for to gauge the likelihood of a block and, critically, how long that block might be. Is it a quick cleanup? A lengthy procedure? This detail is crucial for assessing potential latency in the connection teardown path. I need to dive deeper into the code and figure out the exact function of that `disc_work` work item. Gotta trace that definition and see.
|
| 97/2 |
2026/05/19 05:59 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_conn.c IncludeLines:true Name:hci_conn_timeout]
Results: map[SourceCode: 559: static void hci_conn_timeout(struct work_struct *work)
560: {
561: struct hci_conn *conn = container_of(work, struct hci_conn,
562: disc_work.work);
563: int refcnt = atomic_read(&conn->refcnt);
564:
565: BT_DBG("hcon %p state %s", conn, state_to_string(conn->state));
566:
567: WARN_ON(refcnt < 0);
568:
569: /* FIXME: It was observed that in pairing failed scenario, refcnt
570: * drops below 0. Probably this is because l2cap_conn_del calls
571: * l2cap_chan_del for each channel, and inside l2cap_chan_del conn is
572: * dropped. After that loop hci_chan_del is called which also drops
573: * conn. For now make sure that ACL is alive if refcnt is higher then 0,
574: * otherwise drop it.
575: */
576: if (refcnt > 0)
577: return;
578:
579: hci_abort_conn(conn, hci_proto_disconn_ind(conn));
580: }
SourceFile:net/bluetooth/hci_conn.c]
|
| 98/2 |
2026/05/19 05:59 |
llm |
expert |
0m
Model:
Tokens:
input: 156838
output: 43
thoughts: 65
Thoughts: Okay, let's break this down.
**Diving into the Connection Timeout Logic**
Alright, so `hci_conn_timeout` calls `hci_abort_conn`. No surprises there. That makes sense for handling a connection timeout event. But wait a second... `hci_abort_conn` is grabbing `hdev->req_lock`! That's interesting, and I need to be sure I understand the locking order here. I'm going to double-check that. Let me quickly refresh my memory of the details within `hci_abort_conn`. This requires further investigation.
|
| 99/2 |
2026/05/19 05:59 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_conn.c IncludeLines:true Name:hci_abort_conn]
Results: map[SourceCode:2965: int hci_abort_conn(struct hci_conn *conn, u8 reason)
2966: {
2967: struct hci_dev *hdev = conn->hdev;
2968:
2969: /* If abort_reason has already been set it means the connection is
2970: * already being aborted so don't attempt to overwrite it.
2971: */
2972: if (conn->abort_reason)
2973: return 0;
2974:
2975: bt_dev_dbg(hdev, "handle 0x%2.2x reason 0x%2.2x", conn->handle, reason);
2976:
2977: conn->abort_reason = reason;
2978:
2979: /* If the connection is pending check the command opcode since that
2980: * might be blocking on hci_cmd_sync_work while waiting its respective
2981: * event so we need to hci_cmd_sync_cancel to cancel it.
2982: *
2983: * hci_connect_le serializes the connection attempts so only one
2984: * connection can be in BT_CONNECT at time.
2985: */
2986: if (conn->state == BT_CONNECT && hdev->req_status == HCI_REQ_PEND) {
2987: switch (hci_skb_event(hdev->sent_cmd)) {
2988: case HCI_EV_CONN_COMPLETE:
2989: case HCI_EV_LE_CONN_COMPLETE:
2990: case HCI_EV_LE_ENHANCED_CONN_COMPLETE:
2991: case HCI_EVT_LE_CIS_ESTABLISHED:
2992: hci_cmd_sync_cancel(hdev, ECANCELED);
2993: break;
2994: }
2995: /* Cancel connect attempt if still queued/pending */
2996: } else if (!hci_cancel_connect_sync(hdev, conn)) {
2997: return 0;
2998: }
2999:
3000: /* Run immediately if on cmd_sync_work since this may be called
3001: * as a result to MGMT_OP_DISCONNECT/MGMT_OP_UNPAIR which does
3002: * already queue its callback on cmd_sync_work.
3003: */
3004: return hci_cmd_sync_run_once(hdev, abort_conn_sync, conn, NULL);
3005: }
SourceFile:net/bluetooth/hci_conn.c]
|
| 100/2 |
2026/05/19 05:59 |
llm |
expert |
1m
Model:
Tokens:
input: 157792
output: 47
thoughts: 42
Thoughts: Okay, here's my interpretation of that thought process, tailored for an expert audience, and written in the first person:
**Analyzing the Locking Behavior in hci_abort_conn**
Right, so `hci_abort_conn` is calling `hci_cmd_sync_run_once`. My immediate question, the one that jumps out, is whether `hci_cmd_sync_run_once` *acquires* the `hdev->req_lock`. That's the crux of it, isn't it? Understanding the locking strategy is paramount, particularly when dealing with command execution and potential concurrency issues. I need to quickly establish if there's an implicit lock taken within `hci_cmd_sync_run_once`, or if this function expects the caller to handle that. If it *does* take the lock, I need to know the scope and duration of that lock. If it doesn't, that means `hci_abort_conn` *should* be handling the locking itself, and I need to verify that. This is fundamental for avoiding race conditions and ensuring that we're properly synchronizing access to shared resources within the Bluetooth stack. Otherwise, any potential command execution or data manipulation risks leading to data corruption and system instability. I'm going to have to dive into that function's implementation immediately.
|
| 101/2 |
2026/05/19 06:00 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_sync.c IncludeLines:true Name:hci_cmd_sync_run_once]
Results: map[SourceCode: 811: /* Run HCI command entry once:
812: *
813: * - Lookup if an entry already exist and only if it doesn't creates a new entry
814: * and run it.
815: * - if on cmd_sync_work then run immediately otherwise queue
816: */
817: int hci_cmd_sync_run_once(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
818: void *data, hci_cmd_sync_work_destroy_t destroy)
819: {
820: if (hci_cmd_sync_lookup_entry(hdev, func, data, destroy))
821: return 0;
822:
823: return hci_cmd_sync_run(hdev, func, data, destroy);
824: }
SourceFile:net/bluetooth/hci_sync.c]
|
| 102/2 |
2026/05/19 06:00 |
llm |
expert |
0m
Model:
Tokens:
input: 158431
output: 45
thoughts: 515
Thoughts: **Analyzing a Potential Deadlock in Bluetooth Connection Handling**
Okay, let's break this down. My initial observation is that `hci_cmd_sync_run` can end up calling `hci_cmd_sync_queue` if we're not already on the `cmd_sync_work` context. Now, here's where things get interesting. I'm seeing a connection between `hci_conn_del`, which is called from `hci_conn_hash_flush`, and `hci_conn_hash_flush` called by `hci_dev_close_sync`. Ah, and `hci_dev_close_sync` *holds* `hdev->lock`! Lines 5314-5326 confirm this; the code explicitly locks the device before calling `hci_conn_hash_flush`.
So, `hci_dev_close_sync` acquires and holds `hdev->lock`, then calls `hci_conn_hash_flush`. That function, in turn, calls `hci_conn_del`. The critical point here is that `hci_conn_del` then calls `disable_delayed_work_sync(&conn->disc_work)`. If `disc_work` is currently running, that `disable_delayed_work_sync` call *will* block `hci_dev_close_sync`. And remember, `hci_dev_close_sync` is *holding* `hdev->lock`!
Therefore, we have `hdev->lock` held by `hci_dev_close_sync`, which is potentially blocked within `disable_delayed_work_sync(&conn->disc_work)`. Let's clarify what `disc_work` is: it's actually `hci_conn_timeout`. And `hci_conn_timeout` calls `hci_abort_conn`. The plot thickens because `hci_abort_conn` calls `hci_cmd_sync_run_once`, which calls `hci_cmd_sync_run`. That ultimately leads us back to `hci_cmd_sync_queue`.
Now, the key to avoiding a deadlock lies in how `hci_cmd_sync_queue` operates. Fortunately, it *doesn't* block. It just queues work on `hdev->req_workqueue`. So, `hci_conn_timeout` itself isn't blocked within the queueing mechanism, which is good. But the problem still looks possible.
However, the question then becomes: does `hci_abort_conn` block? Particularly, there's a conditional call to `hci_cancel_connect_sync` (line 2996). If that blocks, that's another potential deadlock point. I need to investigate `hci_cancel_connect_sync` to see if it could be a blocking point, as that will be the culprit.
|
| 103/2 |
2026/05/19 06:01 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_sync.c IncludeLines:true Name:hci_cancel_connect_sync]
Results: map[SourceCode:6972: int hci_cancel_connect_sync(struct hci_dev *hdev, struct hci_conn *conn)
6973: {
6974: if (conn->state != BT_OPEN)
6975: return -EINVAL;
6976:
6977: switch (conn->type) {
6978: case ACL_LINK:
6979: return !hci_cmd_sync_dequeue_once(hdev,
6980: hci_acl_create_conn_sync,
6981: conn, NULL);
6982: case LE_LINK:
6983: return !hci_cmd_sync_dequeue_once(hdev, hci_le_create_conn_sync,
6984: conn, create_le_conn_complete);
6985: }
6986:
6987: return -ENOENT;
6988: }
SourceFile:net/bluetooth/hci_sync.c]
|
| 104/2 |
2026/05/19 06:01 |
llm |
expert |
0m
Model:
Tokens:
input: 159880
output: 45
thoughts: 308
Thoughts: **Analyzing Potential Blocking in HCI Connection Timeout**
Okay, let me walk through this. I see that `hci_cancel_connect_sync` calls `hci_cmd_sync_dequeue_once`. My initial thought is, does this `dequeue_once` function block? No, it looks like it just acquires `cmd_sync_work_lock`, which is a mutex, and then removes an entry from a work queue. Okay, a mutex. So if `hci_cmd_sync_work` has the lock, it *could* potentially block. But `hci_cmd_sync_work` only holds it briefly to dequeue an entry. That should be quick. So, based on this, `hci_conn_timeout` *shouldn't* block indefinitely.
Alright, but let's not jump to conclusions. What else could cause a hang? What if `hci_conn_timeout` is blocked on `hdev->req_lock`? I'm pretty sure `hci_abort_conn` is not involved here... No, wait, `hci_abort_conn` does not take that lock. Fine, what about `hdev->lock`? Does `hci_conn_timeout` take `hdev->lock`? No, that's not it either.
Hold on, what about this line: `hci_cmd_sync_cancel(hdev, ECANCELED);`. So, the potential hang must be within this call to `hci_cmd_sync_cancel`. Does `hci_cmd_sync_cancel` itself block? I need to dig deeper into its implementation.
|
| 105/2 |
2026/05/19 06:01 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_sync.c IncludeLines:true Name:hci_cmd_sync_cancel]
Results: map[SourceCode: 664: void hci_cmd_sync_cancel(struct hci_dev *hdev, int err)
665: {
666: bt_dev_dbg(hdev, "err 0x%2.2x", err);
667:
668: if (hdev->req_status == HCI_REQ_PEND) {
669: hdev->req_result = err;
670: hdev->req_status = HCI_REQ_CANCELED;
671:
672: queue_work(hdev->workqueue, &hdev->cmd_sync_cancel_work);
673: }
674: }
SourceFile:net/bluetooth/hci_sync.c]
|
| 106/2 |
2026/05/19 06:01 |
llm |
expert |
0m
Model:
Tokens:
input: 160790
output: 41
thoughts: 115
Thoughts: **Analyzing Potential Blocking Issues in Bluetooth Connection Termination**
Okay, so the `hci_conn_timeout` function just *queues* work, right? It doesn't actually block execution. This means that if `hci_conn_timeout` isn't blocking, then the call to `disable_delayed_work_sync(&conn->disc_work)` also won't block indefinitely. Consequently, `hci_dev_close_sync` shouldn't hang within `hci_conn_hash_flush`.
But hold on, there's a potential snag! What if `hci_dev_close_sync` *itself* gets blocked deeper down the call stack, specifically within `smp_unregister`? I need to quickly refresh my memory of that function. Let's delve into the `smp_unregister` code to verify this hypothesis.
|
| 107/2 |
2026/05/19 06:01 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/smp.c IncludeLines:true Name:smp_unregister]
Results: map[SourceCode:3454: void smp_unregister(struct hci_dev *hdev)
3455: {
3456: struct l2cap_chan *chan;
3457:
3458: if (hdev->smp_bredr_data) {
3459: chan = hdev->smp_bredr_data;
3460: hdev->smp_bredr_data = NULL;
3461: smp_del_chan(chan);
3462: }
3463:
3464: if (hdev->smp_data) {
3465: chan = hdev->smp_data;
3466: hdev->smp_data = NULL;
3467: smp_del_chan(chan);
3468: }
3469: }
SourceFile:net/bluetooth/smp.c]
|
| 108/2 |
2026/05/19 06:01 |
llm |
expert |
1m
Model:
Tokens:
input: 161386
output: 43
thoughts: 930
Thoughts: **Analyzing Potential Deadlocks in Bluetooth HCI Device Shutdown**
Okay, so I'm digging into this `smp_del_chan` function, and it calls `l2cap_chan_put`, which shouldn't block, so that's good. But I need to make absolutely sure there aren't any potential deadlocks creeping in during HCI device shutdown, especially with `hci_dev_close_sync`.
First, let's consider the call to `cancel_delayed_work_sync(&hdev->rpa_expired)` *before* `hci_dev_lock(hdev)`. That's critical. Because the lock isn't held here, if that call blocks, it won't be on `hdev->lock`.
Now, the potential for blocking in `drain_workqueue(hdev->workqueue)` is a serious point of concern. `drain_workqueue` needs all the work on the queue to finish. The queue in question, `hdev->workqueue`, is `hci4#2`. Since `rx_work` is queued on that, and `rx_work` is going to block on `hdev->lock`, this implies that `drain_workqueue` could be blocked waiting for it to finish. But, and here's the key, `hci_dev_close_sync` *doesn't* yet hold `hdev->lock` at that point, because the lock acquisition comes *after* the `drain_workqueue` call. So, `hci_dev_close_sync` isn't holding the lock.
Next, I need to consider `syz-executor:5969` in `hci_unregister_dev`. `hci_unregister_dev` calls `disable_work_sync(&hdev->rx_work)`. This also waits for `rx_work` to complete. I know that `rx_work` blocks on `hdev->lock`. Who *could* be holding the lock? I had to rule out possibilities: `kworker/u9:4/5979`, that runs `cmd_sync_work`, is *not* holding the lock. Also, `kworker/u9:11/12552` running `hci_cmd_sync_work` for `hci4` is incorrect. It also seems that, the workers running `hci_rx_work` and `hci_power_on` are not possibilities for holding the lock. I see that `kworker/u9:11/12552` is blocked on `hdev->req_lock` if it runs `hci_power_on`. The same goes for `hci_error_reset` and `hci_power_off` because these calls take `hdev->req_lock` *before* `hdev->lock`. So `kworker/u9:11/12552` is likely not the cause. The problem lies if `kworker/u9:11/12552` were running `hci_cmd_timeout` for `hci4`. I need to figure out, does `hci_cmd_timeout` even take `hdev->lock`? That's the critical question at the moment.
|
| 109/2 |
2026/05/19 06:02 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_core.c IncludeLines:true Name:hci_cmd_timeout]
Results: map[SourceCode:1460: /* HCI command timer function */
1461: static void hci_cmd_timeout(struct work_struct *work)
1462: {
1463: struct hci_dev *hdev = container_of(work, struct hci_dev,
1464: cmd_timer.work);
1465:
1466: if (hdev->req_skb) {
1467: u16 opcode = hci_skb_opcode(hdev->req_skb);
1468:
1469: bt_dev_err(hdev, "command 0x%4.4x tx timeout", opcode);
1470:
1471: hci_cmd_sync_cancel_sync(hdev, ETIMEDOUT);
1472: } else {
1473: bt_dev_err(hdev, "command tx timeout");
1474: }
1475:
1476: if (hdev->reset)
1477: hdev->reset(hdev);
1478:
1479: atomic_set(&hdev->cmd_cnt, 1);
1480: queue_work(hdev->workqueue, &hdev->cmd_work);
1481: }
SourceFile:net/bluetooth/hci_core.c]
|
| 110/2 |
2026/05/19 06:02 |
llm |
expert |
0m
Model:
Tokens:
input: 163441
output: 45
thoughts: 770
Thoughts: **Analyzing a Potential Bluetooth Device Lock Contention**
Okay, so I'm looking at this `hci_cmd_timeout` function, and it doesn't seem to take `hdev->lock`. That's the baseline. But what if this `kworker` thread, specifically `kworker/u9:11/12552`, is running another function *that* does take the lock? My mind jumps to possibilities.
First, is it running `hci_devcd_timeout`? Let me see⦠yes, that function *does* grab `hdev->lock`. It's setting some state, but then it unlocks right after, so that shouldn't be the issue.
What about `hci_devcd_rx`? Nope, that also takes the lock, but also unlocks quickly after.
Alright, is there *any* other work function that takes `hdev->lock`? Let's quickly search the Bluetooth networking code for `hci_dev_lock`. We've already checked the typical suspects: `hci_inquiry_cache_flush`, `hci_conn_hash_flush`, `hci_pend_le_actions_clear`, and `hci_discovery_set_state`. No luck.
Hold on, what if this `kworker` thread is running a timer callback? Like, `le_conn_timeout`? *Yes*, it does. And what does `le_conn_timeout` do? It locks `hdev`, then calls `hci_conn_failed`. That is interesting. `hci_conn_failed` then calls `hci_conn_del`. `hci_conn_del` calls `disable_delayed_work_sync(&conn->disc_work)`. Bingo! If `disc_work` is running, it could potentially block. And `le_conn_timeout` is holding `hdev->lock`!
Now, what is `disc_work`? Looking further, `disc_work` turns out to be `hci_conn_timeout`, which calls `hci_abort_conn`. `hci_abort_conn` in turn calls `hci_cmd_sync_run_once`, which calls `hci_cmd_sync_run`, which calls `hci_cmd_sync_queue`. Okay, but `hci_cmd_sync_queue` just *queues* the work; it doesn't block. So, `hci_conn_timeout` itself isn't blocking. Therefore, `le_conn_timeout` won't be blocking either.
Still, what about a call back to `hci_cmd_sync_dequeue` from `hci_conn_del`? Does *that* block? I'm going to have to investigate that function to be sure.
|
| 111/2 |
2026/05/19 06:03 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_sync.c IncludeLines:true Name:hci_cmd_sync_dequeue]
Results: map[SourceCode: 882: /* Dequeue HCI command entry:
883: *
884: * - Lookup and cancel any entry that matches by function callback or data or
885: * destroy callback.
886: */
887: bool hci_cmd_sync_dequeue(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
888: void *data, hci_cmd_sync_work_destroy_t destroy)
889: {
890: struct hci_cmd_sync_work_entry *entry;
891: bool ret = false;
892:
893: mutex_lock(&hdev->cmd_sync_work_lock);
894: while ((entry = _hci_cmd_sync_lookup_entry(hdev, func, data,
895: destroy))) {
896: _hci_cmd_sync_cancel_entry(hdev, entry, -ECANCELED);
897: ret = true;
898: }
899: mutex_unlock(&hdev->cmd_sync_work_lock);
900:
901: return ret;
902: }
SourceFile:net/bluetooth/hci_sync.c]
|
| 112/2 |
2026/05/19 06:03 |
llm |
expert |
0m
Model:
Tokens:
input: 165207
output: 43
thoughts: 2467
Thoughts: **Deadlock Investigation in Bluetooth HCI Subsystem**
Alright, let's break this down. First, I see that `hci_cmd_sync_dequeue` grabs `hdev->cmd_sync_work_lock`. Okay, no big deal, it's held briefly to dequeue. It doesn't block indefinitely. Good. However, `hci_conn_del` can call `disable_delayed_work_sync` on a couple of work items: `auto_accept_work` which calls `hci_send_cmd` and `idle_work` which calls `hci_req_sync_lock`. Wait a minute, `hci_conn_idle` takes `hdev->req_lock`!
So, if `hci_conn_idle` is running and holds `hdev->req_lock`, `hci_conn_del` could get blocked trying to disable `idle_work`. Further, `hci_conn_del` is called from `le_conn_timeout`, which holds `hdev->lock`. Or, `hci_conn_del` is called from `hci_conn_hash_flush`, which is called from `hci_dev_close_sync`, which holds `hdev->lock`! Here's where it gets interesting...
If `hci_dev_close_sync` holds `hdev->lock`, calls `hci_conn_hash_flush`, calls `hci_conn_del`, calls `disable_delayed_work_sync(&conn->idle_work)`, and `idle_work` (that's `hci_conn_idle`) is running and is blocked on `hdev->req_lock`, and this `hdev->req_lock` is held by something like `kworker/u9:4/5979` running `cmd_sync_work`. And `kworker/u9:4/5979` is blocked on `hdev->lock`. This is a DEADLOCK!
Let me verify this. `syz-executor:5969` is in `hci_dev_do_close` which takes `hdev->req_lock`. That means `kworker/u9:4/5979` can't be holding `hdev->req_lock`. But wait, the lockdep trace says `kworker/u9:4/5979` does hold `hdev->req_lock`. So, `syz-executor:5969` *can't* be in `hci_dev_do_close` holding `hdev->req_lock`. Now, I'm pretty sure `kworker/u9:4/5979` is the one holding `hdev->req_lock` in `hci_cmd_sync_work`. If the function called by `entry->func` inside `cmd_sync_work` takes `hdev->lock`, then `kworker/u9:4/5979` would be blocked! And who holds `hdev->lock`? Maybe `kworker/u9:11/12552`! Maybe it's in `le_conn_timeout`. Aha! `le_conn_timeout` takes `hdev->lock` and then calls `hci_conn_failed` which calls `hci_conn_del` which calls `disable_delayed_work_sync(&conn->idle_work)`. And that `idle_work` is `hci_conn_idle`. And `hci_conn_idle` is running on a *different* kworker, like `kworker/u9:5/6113`!
Yes, `kworker/u9:5/6113` is indeed in the lockdep trace! Wait, it is running `cmd_sync_work` for `hci2`. What about `idle_work`? If it's running, it's blocked on `hdev->req_lock`. And `hdev->req_lock` is held by `kworker/u9:4/5979`. So, `le_conn_timeout` (in `kworker/u9:11/12552`) is blocked waiting for `idle_work`, which is blocked on `hdev->req_lock`. And `kworker/u9:4/5979` holds `hdev->req_lock` and is blocked waiting for `hdev->lock`. And `hdev->lock` is held by `le_conn_timeout` (`kworker/u9:11/12552`). PERFECT! A three-way deadlock!
1. `kworker/u9:11/125
|
| 113/2 |
2026/05/19 06:04 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_conn.c IncludeLines:true Name:hci_conn_idle]
Results: map[SourceCode: 582: /* Enter sniff mode */
583: static void hci_conn_idle(struct work_struct *work)
584: {
585: struct hci_conn *conn = container_of(work, struct hci_conn,
586: idle_work.work);
587: struct hci_dev *hdev = conn->hdev;
588:
589: BT_DBG("hcon %p mode %d", conn, conn->mode);
590:
591: if (!lmp_sniff_capable(hdev) || !lmp_sniff_capable(conn))
592: return;
593:
594: if (conn->mode != HCI_CM_ACTIVE || !(conn->link_policy & HCI_LP_SNIFF))
595: return;
596:
597: if (lmp_sniffsubr_capable(hdev) && lmp_sniffsubr_capable(conn)) {
598: struct hci_cp_sniff_subrate cp;
599: cp.handle = cpu_to_le16(conn->handle);
600: cp.max_latency = cpu_to_le16(0);
601: cp.min_remote_timeout = cpu_to_le16(0);
602: cp.min_local_timeout = cpu_to_le16(0);
603: hci_send_cmd(hdev, HCI_OP_SNIFF_SUBRATE, sizeof(cp), &cp);
604: }
605:
606: if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
607: struct hci_cp_sniff_mode cp;
608: cp.handle = cpu_to_le16(conn->handle);
609: cp.max_interval = cpu_to_le16(hdev->sniff_max_interval);
610: cp.min_interval = cpu_to_le16(hdev->sniff_min_interval);
611: cp.attempt = cpu_to_le16(4);
612: cp.timeout = cpu_to_le16(1);
613: hci_send_cmd(hdev, HCI_OP_SNIFF_MODE, sizeof(cp), &cp);
614: }
615: }
SourceFile:net/bluetooth/hci_conn.c]
|
| 114/2 |
2026/05/19 06:04 |
llm |
expert |
0m
Model:
Tokens:
input: 169440
output: 43
thoughts: 189
Thoughts: **Realization Regarding `hci_conn_idle` and Lock Management**
Okay, hold on a second. I completely missed something earlier. Looking at `hci_conn_idle`, specifically the code snippet from lines 591 to 615, I see now that it *doesn't* actually acquire `hdev->req_lock`. I was certain it did, but I clearly misread that earlier. It's calling `hci_send_cmd` directly, which means the lock handling is potentially happening within that function. So, the critical question is: Does `hci_send_cmd` itself take the `hdev->req_lock`? I need to verify how `hci_send_cmd` handles the locking mechanism. Let's dive into the `hci_send_cmd` implementation to understand its behavior in detail.
|
| 115/2 |
2026/05/19 06:04 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_core.c IncludeLines:true Name:hci_send_cmd]
Results: map[SourceCode:3090: /* Send HCI command */
3091: int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
3092: const void *param)
3093: {
3094: struct sk_buff *skb;
3095:
3096: BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
3097:
3098: skb = hci_cmd_sync_alloc(hdev, opcode, plen, param, NULL);
3099: if (!skb) {
3100: bt_dev_err(hdev, "no memory for command");
3101: return -ENOMEM;
3102: }
3103:
3104: /* Stand-alone HCI commands must be flagged as
3105: * single-command requests.
3106: */
3107: bt_cb(skb)->hci.req_flags |= HCI_REQ_START;
3108:
3109: skb_queue_tail(&hdev->cmd_q, skb);
3110: queue_work(hdev->workqueue, &hdev->cmd_work);
3111:
3112: return 0;
3113: }
SourceFile:net/bluetooth/hci_core.c]
|
| 116/2 |
2026/05/19 06:04 |
llm |
expert |
0m
Model:
Tokens:
input: 170250
output: 21
thoughts: 3388
Thoughts: **Analyzing Potential Deadlocks in Bluetooth HCI Device Closure**
Okay, let's break this down. My primary concern is a potential deadlock during Bluetooth device closure (`hci_dev_close_sync`), specifically related to work queue flushing and lock contention. The initial focus was on `le_conn_timeout` and `hci_conn_del`, but I quickly realized those weren't the direct culprits. The key is understanding when and where `hdev->lock` is held, and which tasks are blocked on it.
1. **Initial Suspects Ruled Out:** It's clear that neither `hci_conn_idle` nor `le_conn_timeout` directly block on `hdev->req_lock` or hold `hdev->lock` in a way that would cause indefinite blocking during connection deletion. The various uses of `hci_cmd_sync_` functions are also not blocking the process.
2. **`drain_workqueue` and the Critical Sequence:** The crucial realization is that `drain_workqueue` in `hci_dev_close_sync` is called *before* `hci_dev_lock(hdev)`. This means that if any work items in the queue are blocked on `hdev->lock`, the `drain_workqueue` call will itself block, *before* the lock is acquired. This sets up a potential circular dependency. Specifically, `drain_workqueue` waits for the `rx_work` to finish. If `rx_work` is blocked on `hdev->lock`, the entire `hci_dev_close_sync` procedure will block.
3. **Identifying the Lock Holder:** If `rx_work` is blocked on `hdev->lock`, somebody MUST hold it. The lockdep trace reveals that `kworker/u9:10/11292` is blocked on `hdev->lock`, but it's not the owner. The trace merely indicates the tasks attempting to acquire it. The real lock owner isn't visible in the truncated output.
4. **Tracing the Paths of Lock Contention:** I then systematically checked various functions called during device closure, initialization, and reset (`hci_dev_close_sync`, `hci_dev_do_reset`, `hci_dev_open_sync`, `hci_dev_do_reset`) to see if they hold the `hdev->lock` while flushing workqueues. These include the potential blocking of the `syz-executor`. It appears that no other process is holding `hdev->lock` while flushing. All other processes call `flush_work` and `drain_workqueue` without holding the lock.
5. **The Deadlock Scenario:** The deadlock scenario is now clear: `hci_dev_close_sync` calls `drain_workqueue` and that waits for `rx_work`, but `rx_work` is blocked on the `hdev->lock`, and `hdev->lock` is held by some other task, not any task I could identify with certainty. The lockdep trace does not show any of the tasks examined as the lock owner, but the lockdep output is truncated. This is a very likely cause for a deadlock if the work items are blocked on `hdev->lock` and no other code releases it. This must be the source of the hang I'm trying to identify.
Therefore, the investigation has narrowed down the potential deadlock situation to a circular dependency where `hci_dev_close_sync` is blocked in `drain_workqueue` which is waiting for `rx_work` to complete, which is blocked because someone else holds the `hdev->lock`, and this other task is not listed in my lockdep output.
|
| 117/2 |
2026/05/19 06:05 |
tool |
grepper |
0m
Args: map[Expression:flush_work.*hdev->]
Results: map[Output:drivers/accel/habanalabs/common/command_submission.c=1064=void hl_cs_rollback_all(struct hl_device *hdev, bool skip_wq_flush)
--
drivers/accel/habanalabs/common/command_submission.c-1069- if (!skip_wq_flush) {
drivers/accel/habanalabs/common/command_submission.c:1070: flush_workqueue(hdev->ts_free_obj_wq);
drivers/accel/habanalabs/common/command_submission.c-1071-
--
drivers/accel/habanalabs/common/command_submission.c-1075- for (i = 0 ; i < hdev->asic_prop.completion_queues_count ; i++)
drivers/accel/habanalabs/common/command_submission.c:1076: flush_workqueue(hdev->cq_wq[i]);
drivers/accel/habanalabs/common/command_submission.c-1077-
drivers/accel/habanalabs/common/command_submission.c:1078: flush_workqueue(hdev->cs_cmplt_wq);
drivers/accel/habanalabs/common/command_submission.c-1079- }
--
drivers/accel/habanalabs/common/device.c=1284=static void cleanup_resources(struct hl_device *hdev, bool hard_reset, bool fw_reset,
--
drivers/accel/habanalabs/common/device.c-1304- /* flush the MMU prefetch workqueue */
drivers/accel/habanalabs/common/device.c:1305: flush_workqueue(hdev->prefetch_wq);
drivers/accel/habanalabs/common/device.c-1306-
--
drivers/accel/habanalabs/common/device.c=1612=int hl_device_reset(struct hl_device *hdev, u32 flags)
--
drivers/accel/habanalabs/common/device.c-1781- */
drivers/accel/habanalabs/common/device.c:1782: flush_workqueue(hdev->eq_wq);
drivers/accel/habanalabs/common/device.c-1783- }
--
drivers/accel/habanalabs/common/irq.c=679=void hl_eq_fini(struct hl_device *hdev, struct hl_eq *q)
drivers/accel/habanalabs/common/irq.c-680-{
drivers/accel/habanalabs/common/irq.c:681: flush_workqueue(hdev->eq_wq);
drivers/accel/habanalabs/common/irq.c-682-
--
net/bluetooth/hci_core.c=438=int hci_dev_open(__u16 dev)
--
net/bluetooth/hci_core.c-473- */
net/bluetooth/hci_core.c:474: flush_workqueue(hdev->req_workqueue);
net/bluetooth/hci_core.c-475-
--
net/bluetooth/hci_sync.c=5102=int hci_dev_open_sync(struct hci_dev *hdev)
--
net/bluetooth/hci_sync.c-5172- /* Init failed, cleanup */
net/bluetooth/hci_sync.c:5173: flush_work(&hdev->tx_work);
net/bluetooth/hci_sync.c-5174-
--
net/bluetooth/hci_sync.c-5178- */
net/bluetooth/hci_sync.c:5179: flush_work(&hdev->rx_work);
net/bluetooth/hci_sync.c:5180: flush_work(&hdev->cmd_work);
net/bluetooth/hci_sync.c-5181-
--
net/bluetooth/hci_sync.c=5252=int hci_dev_close_sync(struct hci_dev *hdev)
--
net/bluetooth/hci_sync.c-5287- /* Flush RX and TX works */
net/bluetooth/hci_sync.c:5288: flush_work(&hdev->tx_work);
net/bluetooth/hci_sync.c:5289: flush_work(&hdev->rx_work);
net/bluetooth/hci_sync.c-5290-
--
net/bluetooth/hci_sync.c-5351- /* flush cmd work */
net/bluetooth/hci_sync.c:5352: flush_work(&hdev->cmd_work);
net/bluetooth/hci_sync.c-5353-
]
|
| 118/2 |
2026/05/19 06:05 |
llm |
expert |
0m
Model:
Tokens:
input: 175656
output: 43
thoughts: 2481
Thoughts: **Debugging a Bluetooth Deadlock**
Okay, so I'm trying to figure out why this Bluetooth device is deadlocked. The initial thought was that a process (`syz-executor:5969`) was directly holding `hdev->lock` while calling `flush_work`, but that's not the case. Then it clicked: `syz-executor:5969` might be blocked on `cancel_work_sync(&hdev->cmd_sync_work)`. I started following the call stack. `cmd_sync_work` is run by a `kworker` thread (`kworker/u9:4/5979`). This thread eventually ends up in `hci_dev_close_sync` (through a power-on/off sequence), and that calls `flush_work(&hdev->rx_work)`.
So, `kworker/u9:4/5979` is waiting for `rx_work`. Another `kworker` (`kworker/u9:10/11292`) is running `rx_work`. The problem? `rx_work` is blocked on `hdev->lock`! The question is: *who* holds `hdev->lock`?
I started tracing execution. `kworker/u9:4/5979` does NOT hold the lock when calling `flush_work`. So, I started hypothesizing about other contenders. What if `kworker/u9:11/12552` has the lock? What's *it* doing? Maybe it's in `le_conn_timeout`! `le_conn_timeout` does take the lock. It calls a few things, `hci_conn_failed` which calls `hci_conn_del` and so on, but nothing in there appears to be holding up the lock for an extended period.
I checked if `hci_conn_idle` (from a different function call) might be taking the lock. Nope. It also calls `hci_send_cmd`, which queues a work, but doesn't block. This means `le_conn_timeout` *should* release the lock. So `rx_work` should acquire it and finish, and everything should unblock. But that's not happening within the expected timeout. This is frustrating!
Then I started considering other functions that may be called from `hci_conn_del`. What if `hci_conn_del` calls `disable_delayed_work_sync(&conn->disc_work)`? `disc_work` calls `hci_abort_conn` which calls `hci_cancel_connect_sync` and eventually calls `hci_cmd_sync_dequeue_once`. This does take a lock, `hdev->cmd_sync_work_lock`. However, after reviewing the code, it looks like it releases the lock before calling the function that could be blocking.
I also checked other functions called during `le_conn_timeout`. Nothing stood out. Next I went through the `hci_conn_failed` path. `hci_disconn_cfm` is called but it does not appear to block.
I considered other contenders for the lock, what if it was being held by `kworker/u9:11/12552` when running `hci_devcd_rx`, but that does not block. Or `hci_cmd_sync_work`, but other threads have a higher priority to the command queue.
Finally, I considered that `kworker/u9:4/5979` could be running `hci_cmd_sync_work` and calls `hci_dev_close_sync`. This would then call `drain_workqueue` on `hdev->workqueue`. `rx_work` is also on this workqueue. But the execution stack does not show a lock being held for a long time.
After reviewing the code in `hci_cmd_sync_work` again, the lock acquisition happens before the work function is called and then it is released after it is done. *Aha!* `hci_req_sync_lock` and `hci_req_sync_unlock` *surround* the call to `entry->func` AND `entry->destroy`. What if `entry->destroy` is the problem? The `entry->destroy` function could be the one that's holding `hdev->lock` and causing the deadlock! That's the next avenue to explore. For example `mgmt_set_powered_complete` could be holding the lock.
|
| 119/2 |
2026/05/19 06:05 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/mgmt.c IncludeLines:true Name:mgmt_set_powered_complete]
Results: map[SourceCode:1332: static void mgmt_set_powered_complete(struct hci_dev *hdev, void *data, int err)
1333: {
1334: struct mgmt_pending_cmd *cmd = data;
1335: struct mgmt_mode *cp;
1336:
1337: /* Make sure cmd still outstanding. */
1338: if (err == -ECANCELED || !mgmt_pending_valid(hdev, cmd))
1339: return;
1340:
1341: cp = cmd->param;
1342:
1343: bt_dev_dbg(hdev, "err %d", err);
1344:
1345: if (!err) {
1346: if (cp->val) {
1347: hci_dev_lock(hdev);
1348: restart_le_actions(hdev);
1349: hci_update_passive_scan(hdev);
1350: hci_dev_unlock(hdev);
1351: }
1352:
1353: send_settings_rsp(cmd->sk, cmd->opcode, hdev);
1354:
1355: /* Only call new_setting for power on as power off is deferred
1356: * to hdev->power_off work which does call hci_dev_do_close.
1357: */
1358: if (cp->val)
1359: new_settings(hdev, cmd->sk);
1360: } else {
1361: mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_POWERED,
1362: mgmt_status(err));
1363: }
1364:
1365: mgmt_pending_free(cmd);
1366: }
SourceFile:net/bluetooth/mgmt.c]
|
| 120/2 |
2026/05/19 06:05 |
llm |
expert |
0m
Model:
Tokens:
input: 179703
output: 43
thoughts: 287
Thoughts: **Analyzing a Bluetooth Concurrency Issue**
Okay, so I'm looking at this trace and it's starting to make sense. Right, `mgmt_set_powered_complete` is locking `hdev->lock` at line 1347. That's the key. If `kworker/u9:4/5979` is executing that function, it's holding *that* lock. And from what I see, itβs also holding `hdev->req_lock`! So, we have a clear double lock situation: `kworker/u9:4/5979` has a grip on *both* `hdev->req_lock` AND `hdev->lock`.
Now it clicks: If it has `hdev->lock`, the `rx_work` is blocked, isn't it? And *that* is what's blocking `syz-executor:5969`, because that process is stuck in `disable_work_sync(&hdev->rx_work)`, waiting for that very `rx_work`! But what's holding up `kworker/u9:4/5979`? It *should* finish up the `restart_le_actions` and `hci_update_passive_scan` functions and then release the lock! Are either of those functions blocking? I need to check `restart_le_actions` now.
|
| 121/2 |
2026/05/19 06:06 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_core.c IncludeLines:true Name:restart_le_actions]
Results: map[SourceCode:1299: /* This function requires the caller holds hdev->lock */
1300: static void restart_le_actions(struct hci_dev *hdev)
1301: {
1302: struct hci_conn_params *p;
1303:
1304: list_for_each_entry(p, &hdev->le_conn_params, list) {
1305: /* Needed for AUTO_OFF case where might not "really"
1306: * have been powered off.
1307: */
1308: hci_pend_le_list_del_init(p);
1309:
1310: switch (p->auto_connect) {
1311: case HCI_AUTO_CONN_DIRECT:
1312: case HCI_AUTO_CONN_ALWAYS:
1313: hci_pend_le_list_add(p, &hdev->pend_le_conns);
1314: break;
1315: case HCI_AUTO_CONN_REPORT:
1316: hci_pend_le_list_add(p, &hdev->pend_le_reports);
1317: break;
1318: default:
1319: break;
1320: }
1321: }
1322: }
SourceFile:net/bluetooth/mgmt.c]
|
| 122/2 |
2026/05/19 06:06 |
llm |
expert |
0m
Model:
Tokens:
input: 180725
output: 45
thoughts: 24
Thoughts: Okay, here's my take on those thoughts, tailored for an expert audience like yourself:
**Non-Blocking Considerations for LE Actions**
Right, so `restart_le_actions` is designed to be non-blocking, that's clear. We need to consider how this impacts overall system behaviour and synchronization, especially in high-throughput or resource-constrained environments. Makes perfect sense.
But then, the follow up question hits me: What about `hci_update_passive_scan`? Is *that* also non-blocking? If it *is* non-blocking, we have some interesting implications on how we handle potential race conditions or sequencing issues related to the passive scanning state. If it *is* blocking, or uses any kind of internal locks, that changes the whole game. The potential for deadlock, or other concurrency issues, immediately pops into my mind. I need to understand the interaction between `restart_le_actions` and `hci_update_passive_scan`, and confirm how these function relative to the overall system's event loop and threading model. Are there any internal states they depend on? Are there any potential for conflict?
|
| 123/2 |
2026/05/19 06:06 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_core.c IncludeLines:true Name:hci_update_passive_scan]
Results: map[SourceCode:3256: int hci_update_passive_scan(struct hci_dev *hdev)
3257: {
3258: /* Only queue if it would have any effect */
3259: if (!test_bit(HCI_UP, &hdev->flags) ||
3260: test_bit(HCI_INIT, &hdev->flags) ||
3261: hci_dev_test_flag(hdev, HCI_SETUP) ||
3262: hci_dev_test_flag(hdev, HCI_CONFIG) ||
3263: hci_dev_test_flag(hdev, HCI_AUTO_OFF) ||
3264: hci_dev_test_flag(hdev, HCI_UNREGISTER))
3265: return 0;
3266:
3267: return hci_cmd_sync_queue_once(hdev, update_passive_scan_sync, NULL,
3268: NULL);
3269: }
SourceFile:net/bluetooth/hci_sync.c]
|
| 124/2 |
2026/05/19 06:06 |
llm |
expert |
0m
Model:
Tokens:
input: 181329
output: 29
thoughts: 1194
Thoughts: **Analyzing a Potential Bluetooth Hang**
Okay, let's break this down. My initial thought was that `mgmt_set_powered_complete` might be the culprit. I saw that `hci_update_passive_scan` is called by it, which, in turn, calls `hci_cmd_sync_queue_once`. But since `hci_cmd_sync_queue_once` is non-blocking, the assumption was that `mgmt_set_powered_complete` wouldn't block, and so `hdev->lock` would be released quickly. This would then allow `rx_work` to complete and the problematic `disable_work_sync` wouldn't be blocked. Therefore, that wasn't the issue.
Now, let's explore if any of the `entry->destroy` functions that call `hci_update_passive_scan` block when taking `hdev->lock`. I systematically went through a series of possibilities: `mgmt_set_discoverable_complete`, `mgmt_set_connectable_complete`, `set_ssp_complete`, and all the other completion callbacks. For each one, I checked if it takes `hdev->lock` and then calls `hci_update_passive_scan`. Each time, the function is non-blocking. I was looking for a function that could potentially lock `hdev->lock` and then somehow cause a stall.
Then I shifted gears to consider the blocking behavior directly: Is there *any* `entry->func` or `entry->destroy` that blocks after taking `hdev->lock`? If so, what could it be waiting on? Maybe it calls `flush_work`, which could introduce a stall? Let's check the call sites for `flush_work`. No, that isn't it.
Now, wait a second. Didn't I rule out that `hci_dev_close_sync` is called via `hci_cmd_sync_queue` earlier? We had better verify this!
|
| 125/2 |
2026/05/19 06:06 |
tool |
grepper |
0m
Error:
Args: map[Expression:hci_cmd_sync_queue.*hci_dev_close_sync]
Results:
|
| 126/2 |
2026/05/19 06:06 |
llm |
expert |
0m
Model:
Tokens:
input: 182991
output: 29
thoughts: 20
Thoughts: Okay, here's my take on those thoughts, framed as an expert's internal monologue:
**Syncing Up HCI Command Submission and Device Closure**
Hmm, so I'm thinking about the interaction between `hci_cmd_sync_submit` and the `hci_dev_close_sync` functions, aren't I? Specifically, how do these processes handle synchronization? When closing the HCI device in sync mode, does it properly wait for all submitted commands β likely still in flight β to complete before releasing resources? Or are there potential race conditions I need to worry about? I need to consider whether there's a possibility of the closure happening prematurely, potentially leading to dangling command acknowledgements or even data corruption. I have to think about the locking mechanisms employed. Are they sufficient, or do I need to explicitly add more to ensure that the command submission and device closure are atomic with respect to each other? Let me see how the existing code handles the command queue flushing during the closing procedure, there must be a clean way to ensure those commands finish.
|
| 127/2 |
2026/05/19 06:06 |
tool |
grepper |
0m
Error:
Args: map[Expression:hci_cmd_sync_submit.*hci_dev_close_sync]
Results:
|
| 128/2 |
2026/05/19 06:06 |
llm |
expert |
0m
Model:
Tokens:
input: 183273
output: 29
thoughts: 20
Thoughts: Okay, here's my interpretation of that thought process, tailored for an expert audience, and presented as if it were my own internal monologue:
**Investigating a Potential Bluetooth HCI Device Closure Issue**
Hmm, so I'm looking at a potential issue related to closing a Bluetooth HCI device, and my mind immediately jumps to `hci_cmd_sync_run.*hci_dev_close_sync`. This combination of functions is a real point of interest in any system where Bluetooth device management is critical. The use of sync run here really highlights a critical area of concern. It can be a potential bottleneck, especially in highly concurrent environments, or in conditions where errors can cause blocking operations. I need to keep in mind, specifically, that `hci_dev_close_sync` implies a synchronous call, which means we are waiting for something to happen. What are the potential consequences of that waiting? What kind of situations can cause it to stall? I want to determine if this is the root cause, or contributing factor, to the issue at hand.
|
| 129/2 |
2026/05/19 06:07 |
tool |
grepper |
0m
Error:
Args: map[Expression:hci_cmd_sync_run.*hci_dev_close_sync]
Results:
|
| 130/2 |
2026/05/19 06:07 |
llm |
expert |
0m
Model:
Tokens:
input: 183552
output: 27
thoughts: 18
Thoughts: Okay, here's my attempt at summarizing that thought process, keeping in mind I'm speaking to a fellow expert:
**Investigating a Potential Bluetooth Driver Issue**
Right, let me think this through. The phrase "hci_cmd_sync_queue.*hci_dev_close"... That's got my attention. It's pointing me directly towards the command synchronization queue and the Bluetooth device closing process. I'm immediately thinking this could be a race condition, a deadlock, or perhaps some improper handling of commands when a device is being closed. The fact it's referencing synchronization is making me lean towards it being a critical point. My initial thought is it is worth investigating, as it could be a simple code correction or deeper issue.
|
| 131/2 |
2026/05/19 06:07 |
tool |
grepper |
0m
Error:
Args: map[Expression:hci_cmd_sync_queue.*hci_dev_close]
Results:
|
| 132/2 |
2026/05/19 06:07 |
llm |
expert |
0m
Model:
Tokens:
input: 183766
output: 45
thoughts: 64
Thoughts: Okay, let me think this through.
**Analyzing the Bluetooth HCI Device Closure Sequence**
Right, so I'm digging into this `hci_dev_close_sync` function, and it seems like it's *not* being directly called by `cmd_sync_work`. That's the initial observation, and it's a key point to understand the overall architecture.
But then, the gears start turning. What if the `entry->func` pointer, within that `cmd_sync_work` context, is pointing to `hci_power_off_sync`? That's the real question. *Does* `hci_power_off_sync` itself, internally, make a call to `hci_dev_close_sync`? If it does, then the indirect dependency is there, even if it's not a direct invocation. I need to trace the code path of `hci_power_off_sync` to confirm how the device close is actually triggered. The relationship between those two functions is the critical piece of this puzzle.
|
| 133/2 |
2026/05/19 06:07 |
tool |
codesearch-definition-source |
0m
Args: map[ContextFile:net/bluetooth/hci_sync.c IncludeLines:true Name:hci_power_off_sync]
Results: map[SourceCode:5753: /* This function perform power off HCI command sequence as follows:
5754: *
5755: * Clear Advertising
5756: * Stop Discovery
5757: * Disconnect all connections
5758: * hci_dev_close_sync
5759: */
5760: static int hci_power_off_sync(struct hci_dev *hdev)
5761: {
5762: int err;
5763:
5764: /* If controller is already down there is nothing to do */
5765: if (!test_bit(HCI_UP, &hdev->flags))
5766: return 0;
5767:
5768: hci_dev_set_flag(hdev, HCI_POWERING_DOWN);
5769:
5770: if (test_bit(HCI_ISCAN, &hdev->flags) ||
5771: test_bit(HCI_PSCAN, &hdev->flags)) {
5772: err = hci_write_scan_enable_sync(hdev, 0x00);
5773: if (err)
5774: goto out;
5775: }
5776:
5777: err = hci_clear_adv_sync(hdev, NULL, false);
5778: if (err)
5779: goto out;
5780:
5781: err = hci_stop_discovery_sync(hdev);
5782: if (err)
5783: goto out;
5784:
5785: /* Terminated due to Power Off */
5786: err = hci_disconnect_all_sync(hdev, HCI_ERROR_REMOTE_POWER_OFF);
5787: if (err)
5788: goto out;
5789:
5790: err = hci_dev_close_sync(hdev);
5791:
5792: out:
5793: hci_dev_clear_flag(hdev, HCI_POWERING_DOWN);
5794: return err;
5795: }
SourceFile:net/bluetooth/hci_sync.c]
|
| 134/2 |
2026/05/19 06:07 |
llm |
expert |
0m
Model:
Tokens:
input: 184723
output: 23
thoughts: 6096
Thoughts: **Analysis of a Bluetooth Driver Deadlock**
Alright, after meticulously tracing the execution flow and lock dependencies, I've managed to pinpoint the likely cause of this reported "task blocked" situation. It seems the problem stems from a potential OOM scenario, manifesting as a deadlock within the Bluetooth driver.
My investigation began by correlating the functions and their respective call chains, focusing on those involved in power-off sequences. I identified that `hci_dev_close_sync`, triggered during power-off, eventually calls `flush_work(&hdev->rx_work)`. This `rx_work` is run by a kworker thread that, critically, needs to acquire `hdev->lock` at line 7736, where events are processed in the kernel code.
I then identified that the `rx_work` thread is blocked, and I determined that it is blocked in `skb_clone`, a memory allocation function called inside the `hci_event_packet` handler. Crucially, while this allocation is performed, the mutex `hdev->lock` has already been acquired.
Further, I determined there are no other functions that can take `hdev->lock` and then block, therefore `rx_work` is blocked on memory allocation.
It appears the `rx_work` thread is blocked, and since it holds `hdev->lock` while blocked, other routines, like the device unregistration (`hci_unregister_dev`) or the power-off sequence, get stuck trying to flush or disable `rx_work`, leading to the deadlock.
The root cause then, is an allocation inside the `skb_clone` that is blocking due to OOM, likely triggered by syzkaller.
Ultimately, this appears to be a known characteristic of syzkaller, where the system is placed in such a state that memory allocation and subsequent lock dependencies are exposed, with these dependencies then blocking indefinitely.
|
| 135/2 |
2026/05/19 06:08 |
tool |
codesearch-find-references |
0m
Args: map[Name:hci_event_packet]
Results: map[References:[map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:hci_rx_work SourceFile:net/bluetooth/hci_core.c SourceLine:4076]] TruncatedOutput:false]
|
| 136/2 |
2026/05/19 06:08 |
llm |
expert |
1m
Model:
Tokens:
input: 191316
output: 19
thoughts: 4525
Thoughts: **Analyzing a Bluetooth HCI Deadlock: An OOM-Induced Hang**
Okay, so here's the situation. I'm staring at a kernel deadlock in a Bluetooth HCI stack, and the pieces are starting to fall into place. Initially, I thought this was a straightforward recursive lock issue with `hci_event_packet`, but that's a dead end. I quickly realized `hci_rx_work` is the only caller of `hci_event_packet`, and `hci_rx_work` doesn't hold the `hdev->lock`, so it *shouldn't* be recursive.
But then... wait, what if another thread *holds* `hdev->lock`? Lockdep showed `kworker/u9:10/11292` blocked trying to acquire it. That's the key. I had to figure out *who* was the lock holder. I started going through all the threads, specifically `kworker/u9:11/12552` who has 7 locks. My immediate suspicion was `le_conn_timeout` because it takes `hdev->lock`. That spawns a series of function calls which will not block.
However, `hci_conn_del` might call `disable_delayed_work_sync`, possibly on `idle_work` or `disc_work`. I had to analyze all possible blocking scenarios for both `idle_work` and `disc_work`, but they all appear not to block.
So it's not a direct deadlock in the typical sense. It *must* be an OOM issue. I zeroed in on the `kworker/u9:10/11292` thread because it's the one blocked on the `hdev->lock`. And then the light bulb moment: It's blocked in `skb_clone`, and the error report is pretty clear that OOM is the root cause. It's blocked allocating memory, holding the lock. And since OOM blocks that thread, it prevents other threads from continuing, specifically `syz-executor:5969` that is blocked in `disable_work_sync(&hdev->rx_work)`.
I went back and checked every possible function for a lock ordering violation, but it keeps pointing back to memory allocation in `skb_clone` in `kworker/u9:10/11292` being the root cause. There's no way to trigger a true deadlock in the traditional sense, but it is a "hang" from OOM!
The lockdep output, I realized, was probably truncated, so `kworker/u9:11/12552` *could* have been holding the `hdev->lock`. But I'm still coming back to OOM.
|
| 137/2 |
2026/05/19 06:09 |
tool |
grepper |
0m
Error:
Args: map[Expression:hdev->notify =]
Results:
|
| 138/2 |
2026/05/19 06:09 |
llm |
expert |
0m
Model:
Tokens:
input: 196480
output: 17
thoughts: 15
Thoughts: Okay, here's my interpretation of those thoughts, crafted with the understanding that I'm speaking to a fellow expert:
**Investigating Notification Mechanisms in the Bluetooth Subsystem**
Alright, I'm diving into this `net/bluetooth/` directory again, and something's caught my eye. Specifically, I'm thinking about how the system handles notifications. The syntax `\.notify =`... what's going on there? I'm immediately curious about how that's used, how these notifications are actually implemented at that level. Is it a callback assignment, or perhaps a structure member initialisation? What's the context? What pieces of the puzzle is this part of? My brain's already starting to trace possible data flows and signal paths, wondering if this is related to asynchronous events, connection state changes, or maybe something specific to GATT notifications. I need to dig in and see the broader picture. My initial impression is that this could be a really critical piece of the framework. Gotta investigate!
|
| 139/2 |
2026/05/19 06:09 |
tool |
grepper |
0m
Args: map[Expression:\.notify =]
Results: map[Output:Documentation/wmi/driver-development-guide.rst=52=to matching WMI devices using a struct wmi_device_id table:
--
Documentation/wmi/driver-development-guide.rst-72- .shutdown = foo_shutdown, /* optional, called during shutdown */
Documentation/wmi/driver-development-guide.rst:73: .notify = foo_notify, /* optional, for event handling */
Documentation/wmi/driver-development-guide.rst-74- .no_notify_data = true, /* optional, enables events containing no additional data */
--
drivers/acpi/acpi_video.c=1881=static void acpi_video_dev_add_notify_handler(struct acpi_video_device *device)
--
drivers/acpi/acpi_video.c-1890- else
drivers/acpi/acpi_video.c:1891: device->flags.notify = 1;
drivers/acpi/acpi_video.c-1892-}
--
drivers/acpi/acpi_video.c=1948=static void acpi_video_dev_remove_notify_handler(struct acpi_video_device *dev)
--
drivers/acpi/acpi_video.c-1952- acpi_video_device_notify);
drivers/acpi/acpi_video.c:1953: dev->flags.notify = 0;
drivers/acpi/acpi_video.c-1954- }
--
drivers/hwmon/acpi_power_meter.c=984=static struct acpi_driver acpi_power_meter_driver = {
--
drivers/hwmon/acpi_power_meter.c-990- .remove = acpi_power_meter_remove,
drivers/hwmon/acpi_power_meter.c:991: .notify = acpi_power_meter_notify,
drivers/hwmon/acpi_power_meter.c-992- },
--
drivers/infiniband/hw/qedr/main.c=1038=static struct qedr_driver qedr_drv = {
--
drivers/infiniband/hw/qedr/main.c-1041- .remove = qedr_remove,
drivers/infiniband/hw/qedr/main.c:1042: .notify = qedr_notify,
drivers/infiniband/hw/qedr/main.c-1043-};
--
drivers/md/dm-vdo/vdo.c=987=int vdo_register_read_only_listener(struct vdo *vdo, void *listener,
--
drivers/md/dm-vdo/vdo.c-1006- .listener = listener,
drivers/md/dm-vdo/vdo.c:1007: .notify = notification,
drivers/md/dm-vdo/vdo.c-1008- .next = thread->listeners,
--
drivers/media/pci/cobalt/cobalt-driver.c=656=static int cobalt_probe(struct pci_dev *pci_dev,
--
drivers/media/pci/cobalt/cobalt-driver.c-681- "cobalt-%d", cobalt->instance);
drivers/media/pci/cobalt/cobalt-driver.c:682: cobalt->v4l2_dev.notify = cobalt_notify;
drivers/media/pci/cobalt/cobalt-driver.c-683- cobalt_info("Initializing card %d\n", cobalt->instance);
--
drivers/media/pci/cx23885/cx23885-core.c=1967=static void cx23885_v4l2_dev_notify_init(struct cx23885_dev *dev)
--
drivers/media/pci/cx23885/cx23885-core.c-1971- INIT_WORK(&dev->ir_tx_work, cx23885_ir_tx_work_handler);
drivers/media/pci/cx23885/cx23885-core.c:1972: dev->v4l2_dev.notify = cx23885_v4l2_dev_notify;
drivers/media/pci/cx23885/cx23885-core.c-1973-}
--
drivers/media/pci/zoran/zoran_card.c=1220=static int zoran_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
--
drivers/media/pci/zoran/zoran_card.c-1254-
drivers/media/pci/zoran/zoran_card.c:1255: zr->v4l2_dev.notify = zoran_subdev_notify;
drivers/media/pci/zoran/zoran_card.c-1256- if (v4l2_device_register(&pdev->dev, &zr->v4l2_dev))
--
drivers/media/platform/raspberrypi/rp1-cfe/cfe.c=2148=static int cfe_probe_complete(struct cfe_device *cfe)
--
drivers/media/platform/raspberrypi/rp1-cfe/cfe.c-2151-
drivers/media/platform/raspberrypi/rp1-cfe/cfe.c:2152: cfe->v4l2_dev.notify = cfe_notify;
drivers/media/platform/raspberrypi/rp1-cfe/cfe.c-2153-
--
drivers/media/platform/renesas/rcar-vin/rcar-v4l2.c=694=int rvin_v4l2_register(struct rvin_dev *vin)
--
drivers/media/platform/renesas/rcar-vin/rcar-v4l2.c-698-
drivers/media/platform/renesas/rcar-vin/rcar-v4l2.c:699: vin->v4l2_dev.notify = rvin_notify;
drivers/media/platform/renesas/rcar-vin/rcar-v4l2.c-700-
--
drivers/media/usb/au0828/au0828-core.c=558=static int au0828_media_device_register(struct au0828_dev *dev,
--
drivers/media/usb/au0828/au0828-core.c-628- dev->entity_notify.notify_data = (void *) dev;
drivers/media/usb/au0828/au0828-core.c:629: dev->entity_notify.notify = (void *) au0828_media_graph_notify;
drivers/media/usb/au0828/au0828-core.c-630- media_device_register_entity_notify(dev->media_dev,
--
drivers/net/ethernet/fungible/funeth/funeth_main.c=249=static struct fun_irq *fun_alloc_qirq(struct funeth_priv *fp, unsigned int idx,
--
drivers/net/ethernet/fungible/funeth/funeth_main.c-271- cpumask_set_cpu(cpu, &irq->affinity_mask);
drivers/net/ethernet/fungible/funeth/funeth_main.c:272: irq->aff_notify.notify = fun_irq_aff_notify;
drivers/net/ethernet/fungible/funeth/funeth_main.c-273- irq->aff_notify.release = fun_irq_aff_release;
--
drivers/net/ethernet/intel/i40e/i40e_main.c=4112=static int i40e_vsi_request_irq_msix(struct i40e_vsi *vsi, char *basename)
--
drivers/net/ethernet/intel/i40e/i40e_main.c-4154- q_vector->irq_num = irq_num;
drivers/net/ethernet/intel/i40e/i40e_main.c:4155: q_vector->affinity_notify.notify = i40e_irq_affinity_notify;
drivers/net/ethernet/intel/i40e/i40e_main.c-4156- q_vector->affinity_notify.release = i40e_irq_affinity_release;
--
drivers/net/ethernet/pensando/ionic/ionic_lif.c=504=static int ionic_alloc_qcq_interrupt(struct ionic_lif *lif, struct ionic_qcq *qcq)
--
drivers/net/ethernet/pensando/ionic/ionic_lif.c-541- qcq->intr.affinity_mask = affinity_mask;
drivers/net/ethernet/pensando/ionic/ionic_lif.c:542: qcq->intr.aff_notify.notify = ionic_irq_aff_notify;
drivers/net/ethernet/pensando/ionic/ionic_lif.c-543- qcq->intr.aff_notify.release = ionic_irq_aff_release;
--
drivers/net/wireless/ath/wcn36xx/smd.c=696=int wcn36xx_smd_init_scan(struct wcn36xx *wcn, enum wcn36xx_hal_sys_mode mode,
--
drivers/net/wireless/ath/wcn36xx/smd.c-709- msg_body.frame_type = 2;
drivers/net/wireless/ath/wcn36xx/smd.c:710: msg_body.notify = 1;
drivers/net/wireless/ath/wcn36xx/smd.c-711- msg_body.scan_entry.bss_index[0] = vif_priv->bss_index;
--
drivers/net/wireless/ath/wcn36xx/smd.c=797=int wcn36xx_smd_finish_scan(struct wcn36xx *wcn,
--
drivers/net/wireless/ath/wcn36xx/smd.c-811- /* Notify BSSID with null data packet */
drivers/net/wireless/ath/wcn36xx/smd.c:812: msg_body.notify = 1;
drivers/net/wireless/ath/wcn36xx/smd.c-813- msg_body.frame_type = 2;
--
drivers/nvdimm/pmem.c=751=static struct nd_device_driver nd_pmem_driver = {
--
drivers/nvdimm/pmem.c-753- .remove = nd_pmem_remove,
drivers/nvdimm/pmem.c:754: .notify = nd_pmem_notify,
drivers/nvdimm/pmem.c-755- .shutdown = nd_pmem_shutdown,
--
drivers/nvdimm/region.c=143=static struct nd_device_driver nd_region_driver = {
--
drivers/nvdimm/region.c-145- .remove = nd_region_remove,
drivers/nvdimm/region.c:146: .notify = nd_region_notify,
drivers/nvdimm/region.c-147- .drv = {
--
drivers/pci/hotplug/acpiphp_glue.c=59=static struct acpiphp_context *acpiphp_init_context(struct acpi_device *adev)
--
drivers/pci/hotplug/acpiphp_glue.c-67- context->refcount = 1;
drivers/pci/hotplug/acpiphp_glue.c:68: context->hp.notify = acpiphp_hotplug_notify;
drivers/pci/hotplug/acpiphp_glue.c-69- context->hp.fixup = acpiphp_post_dock_fixup;
--
drivers/platform/chrome/chromeos_tbmc.c=107=static struct acpi_driver chromeos_tbmc_driver = {
--
drivers/platform/chrome/chromeos_tbmc.c-112- .add = chromeos_tbmc_add,
drivers/platform/chrome/chromeos_tbmc.c:113: .notify = chromeos_tbmc_notify,
drivers/platform/chrome/chromeos_tbmc.c-114- },
--
drivers/platform/chrome/wilco_ec/event.c=516=static struct acpi_driver event_driver = {
--
drivers/platform/chrome/wilco_ec/event.c-521- .add = event_device_add,
drivers/platform/chrome/wilco_ec/event.c:522: .notify = event_device_notify,
drivers/platform/chrome/wilco_ec/event.c-523- .remove = event_device_remove,
--
drivers/platform/loongarch/loongson-laptop.c=541=static struct generic_sub_driver generic_sub_drivers[] __refdata = {
--
drivers/platform/loongarch/loongson-laptop.c-544- .init = event_init,
drivers/platform/loongarch/loongson-laptop.c:545: .notify = event_notify,
drivers/platform/loongarch/loongson-laptop.c-546- .handle = &hotkey_handle,
--
drivers/platform/surface/surface_aggregator_hub.c=266=static const struct ssam_hub_desc base_hub = {
--
drivers/platform/surface/surface_aggregator_hub.c-275- .ops = {
drivers/platform/surface/surface_aggregator_hub.c:276: .notify = ssam_base_hub_notif,
drivers/platform/surface/surface_aggregator_hub.c-277- .get_state = ssam_base_hub_query_state,
--
drivers/platform/surface/surface_aggregator_hub.c=331=static const struct ssam_hub_desc kip_hub = {
--
drivers/platform/surface/surface_aggregator_hub.c-340- .ops = {
drivers/platform/surface/surface_aggregator_hub.c:341: .notify = ssam_kip_hub_notif,
drivers/platform/surface/surface_aggregator_hub.c-342- .get_state = ssam_kip_hub_query_state,
--
drivers/platform/surface/surface_aggregator_tabletsw.c=301=static const struct ssam_tablet_sw_desc ssam_kip_sw_desc = {
--
drivers/platform/surface/surface_aggregator_tabletsw.c-306- .ops = {
drivers/platform/surface/surface_aggregator_tabletsw.c:307: .notify = ssam_kip_sw_notif,
drivers/platform/surface/surface_aggregator_tabletsw.c-308- .get_state = ssam_kip_get_cover_state,
--
drivers/platform/surface/surface_aggregator_tabletsw.c=600=static const struct ssam_tablet_sw_desc ssam_pos_sw_desc = {
--
drivers/platform/surface/surface_aggregator_tabletsw.c-605- .ops = {
drivers/platform/surface/surface_aggregator_tabletsw.c:606: .notify = ssam_pos_sw_notif,
drivers/platform/surface/surface_aggregator_tabletsw.c-607- .get_state = ssam_pos_get_posture,
--
drivers/platform/surface/surfacepro3_button.c=253=static struct acpi_driver surface_button_driver = {
--
drivers/platform/surface/surfacepro3_button.c-259- .remove = surface_button_remove,
drivers/platform/surface/surfacepro3_button.c:260: .notify = surface_button_notify,
drivers/platform/surface/surfacepro3_button.c-261- },
--
drivers/platform/x86/acer-wireless.c=56=static struct acpi_driver acer_wireless_driver = {
--
drivers/platform/x86/acer-wireless.c-61- .add = acer_wireless_add,
drivers/platform/x86/acer-wireless.c:62: .notify = acer_wireless_notify,
drivers/platform/x86/acer-wireless.c-63- },
--
drivers/platform/x86/asus-laptop.c=1927=static struct acpi_driver asus_acpi_driver = {
--
drivers/platform/x86/asus-laptop.c-1934- .remove = asus_acpi_remove,
drivers/platform/x86/asus-laptop.c:1935: .notify = asus_acpi_notify,
drivers/platform/x86/asus-laptop.c-1936- },
--
drivers/platform/x86/asus-wireless.c=184=static struct acpi_driver asus_wireless_driver = {
--
drivers/platform/x86/asus-wireless.c-190- .remove = asus_wireless_remove,
drivers/platform/x86/asus-wireless.c:191: .notify = asus_wireless_notify,
drivers/platform/x86/asus-wireless.c-192- },
--
drivers/platform/x86/classmate-laptop.c=435=static struct acpi_driver cmpc_accel_acpi_driver_v4 = {
--
drivers/platform/x86/classmate-laptop.c-441- .remove = cmpc_accel_remove_v4,
drivers/platform/x86/classmate-laptop.c:442: .notify = cmpc_accel_handler_v4,
drivers/platform/x86/classmate-laptop.c-443- },
--
drivers/platform/x86/classmate-laptop.c=660=static struct acpi_driver cmpc_accel_acpi_driver = {
--
drivers/platform/x86/classmate-laptop.c-666- .remove = cmpc_accel_remove,
drivers/platform/x86/classmate-laptop.c:667: .notify = cmpc_accel_handler,
drivers/platform/x86/classmate-laptop.c-668- }
--
drivers/platform/x86/classmate-laptop.c=753=static struct acpi_driver cmpc_tablet_acpi_driver = {
--
drivers/platform/x86/classmate-laptop.c-759- .remove = cmpc_tablet_remove,
drivers/platform/x86/classmate-laptop.c:760: .notify = cmpc_tablet_handler,
drivers/platform/x86/classmate-laptop.c-761- },
--
drivers/platform/x86/classmate-laptop.c=1061=static struct acpi_driver cmpc_keys_acpi_driver = {
--
drivers/platform/x86/classmate-laptop.c-1067- .remove = cmpc_keys_remove,
drivers/platform/x86/classmate-laptop.c:1068: .notify = cmpc_keys_handler,
drivers/platform/x86/classmate-laptop.c-1069- }
--
drivers/platform/x86/dell/dell-rbtn.c=289=static struct acpi_driver rbtn_driver = {
--
drivers/platform/x86/dell/dell-rbtn.c-295- .remove = rbtn_remove,
drivers/platform/x86/dell/dell-rbtn.c:296: .notify = rbtn_notify,
drivers/platform/x86/dell/dell-rbtn.c-297- },
--
drivers/platform/x86/dell/dell-wmi-base.c=822=static struct wmi_driver dell_wmi_driver = {
--
drivers/platform/x86/dell/dell-wmi-base.c-828- .remove = dell_wmi_remove,
drivers/platform/x86/dell/dell-wmi-base.c:829: .notify = dell_wmi_notify,
drivers/platform/x86/dell/dell-wmi-base.c-830-};
--
drivers/platform/x86/eeepc-laptop.c=1463=static struct acpi_driver eeepc_acpi_driver = {
--
drivers/platform/x86/eeepc-laptop.c-1470- .remove = eeepc_acpi_remove,
drivers/platform/x86/eeepc-laptop.c:1471: .notify = eeepc_acpi_notify,
drivers/platform/x86/eeepc-laptop.c-1472- },
--
drivers/platform/x86/fujitsu-laptop.c=1089=static struct acpi_driver acpi_fujitsu_bl_driver = {
--
drivers/platform/x86/fujitsu-laptop.c-1094- .add = acpi_fujitsu_bl_add,
drivers/platform/x86/fujitsu-laptop.c:1095: .notify = acpi_fujitsu_bl_notify,
drivers/platform/x86/fujitsu-laptop.c-1096- },
--
drivers/platform/x86/fujitsu-laptop.c=1104=static struct acpi_driver acpi_fujitsu_laptop_driver = {
--
drivers/platform/x86/fujitsu-laptop.c-1110- .remove = acpi_fujitsu_laptop_remove,
drivers/platform/x86/fujitsu-laptop.c:1111: .notify = acpi_fujitsu_laptop_notify,
drivers/platform/x86/fujitsu-laptop.c-1112- },
--
drivers/platform/x86/lenovo/ideapad-laptop.c=2345=static struct wmi_driver ideapad_wmi_driver = {
--
drivers/platform/x86/lenovo/ideapad-laptop.c-2350- .probe = ideapad_wmi_probe,
drivers/platform/x86/lenovo/ideapad-laptop.c:2351: .notify = ideapad_wmi_notify,
drivers/platform/x86/lenovo/ideapad-laptop.c-2352-};
--
drivers/platform/x86/lenovo/thinkpad_acpi.c=4104=static struct tp_acpi_drv_struct ibm_hotkey_acpidriver = {
drivers/platform/x86/lenovo/thinkpad_acpi.c-4105- .hid = ibm_htk_device_ids,
drivers/platform/x86/lenovo/thinkpad_acpi.c:4106: .notify = hotkey_notify,
drivers/platform/x86/lenovo/thinkpad_acpi.c-4107- .handle = &hkey_handle,
--
drivers/platform/x86/lenovo/wmi-camera.c=131=static struct wmi_driver lenovo_wmi_driver = {
--
drivers/platform/x86/lenovo/wmi-camera.c-138- .probe = lenovo_wmi_probe,
drivers/platform/x86/lenovo/wmi-camera.c:139: .notify = lenovo_wmi_notify,
drivers/platform/x86/lenovo/wmi-camera.c-140- .remove = lenovo_wmi_remove,
--
drivers/platform/x86/lenovo/wmi-events.c=180=static struct wmi_driver lwmi_events_driver = {
--
drivers/platform/x86/lenovo/wmi-events.c-186- .probe = lwmi_events_probe,
drivers/platform/x86/lenovo/wmi-events.c:187: .notify = lwmi_events_notify,
drivers/platform/x86/lenovo/wmi-events.c-188- .no_singleton = true,
--
drivers/platform/x86/lenovo/ymc.c=151=static struct wmi_driver lenovo_ymc_driver = {
--
drivers/platform/x86/lenovo/ymc.c-156- .probe = lenovo_ymc_probe,
drivers/platform/x86/lenovo/ymc.c:157: .notify = lenovo_ymc_notify,
drivers/platform/x86/lenovo/ymc.c-158-};
--
drivers/platform/x86/lenovo/yogabook.c=407=static struct wmi_driver yogabook_wmi_driver = {
--
drivers/platform/x86/lenovo/yogabook.c-415- .remove = yogabook_wmi_remove,
drivers/platform/x86/lenovo/yogabook.c:416: .notify = yogabook_wmi_notify,
drivers/platform/x86/lenovo/yogabook.c-417-};
--
drivers/platform/x86/lg-laptop.c=893=static struct acpi_driver acpi_driver = {
--
drivers/platform/x86/lg-laptop.c-899- .remove = acpi_remove,
drivers/platform/x86/lg-laptop.c:900: .notify = acpi_notify,
drivers/platform/x86/lg-laptop.c-901- },
--
drivers/platform/x86/panasonic-laptop.c=204=static struct acpi_driver acpi_pcc_driver = {
--
drivers/platform/x86/panasonic-laptop.c-210- .remove = acpi_pcc_hotkey_remove,
drivers/platform/x86/panasonic-laptop.c:211: .notify = acpi_pcc_hotkey_notify,
drivers/platform/x86/panasonic-laptop.c-212- },
--
drivers/platform/x86/redmi-wmi.c=115=static struct wmi_driver redmi_wmi_driver = {
--
drivers/platform/x86/redmi-wmi.c-121- .probe = redmi_wmi_probe,
drivers/platform/x86/redmi-wmi.c:122: .notify = redmi_wmi_notify,
drivers/platform/x86/redmi-wmi.c-123- .no_singleton = true,
--
drivers/platform/x86/sony-laptop.c=3300=static struct acpi_driver sony_nc_driver = {
--
drivers/platform/x86/sony-laptop.c-3306- .remove = sony_nc_remove,
drivers/platform/x86/sony-laptop.c:3307: .notify = sony_nc_notify,
drivers/platform/x86/sony-laptop.c-3308- },
--
drivers/platform/x86/system76_acpi.c=809=static struct acpi_driver system76_driver = {
--
drivers/platform/x86/system76_acpi.c-815- .remove = system76_remove,
drivers/platform/x86/system76_acpi.c:816: .notify = system76_notify,
drivers/platform/x86/system76_acpi.c-817- },
--
drivers/platform/x86/topstar-laptop.c=356=static struct acpi_driver topstar_acpi_driver = {
--
drivers/platform/x86/topstar-laptop.c-362- .remove = topstar_acpi_remove,
drivers/platform/x86/topstar-laptop.c:363: .notify = topstar_acpi_notify,
drivers/platform/x86/topstar-laptop.c-364- },
--
drivers/platform/x86/toshiba_bluetooth.c=53=static struct acpi_driver toshiba_bt_rfkill_driver = {
--
drivers/platform/x86/toshiba_bluetooth.c-59- .remove = toshiba_bt_rfkill_remove,
drivers/platform/x86/toshiba_bluetooth.c:60: .notify = toshiba_bt_rfkill_notify,
drivers/platform/x86/toshiba_bluetooth.c-61- },
--
drivers/platform/x86/toshiba_haps.c=252=static struct acpi_driver toshiba_haps_driver = {
--
drivers/platform/x86/toshiba_haps.c-258- .remove = toshiba_haps_remove,
drivers/platform/x86/toshiba_haps.c:259: .notify = toshiba_haps_notify,
drivers/platform/x86/toshiba_haps.c-260- },
--
drivers/platform/x86/uniwill/uniwill-wmi.c=74=static struct wmi_driver uniwill_wmi_driver = {
--
drivers/platform/x86/uniwill/uniwill-wmi.c-79- .id_table = uniwill_wmi_id_table,
drivers/platform/x86/uniwill/uniwill-wmi.c:80: .notify = uniwill_wmi_notify,
drivers/platform/x86/uniwill/uniwill-wmi.c-81- .no_singleton = true,
--
drivers/platform/x86/xiaomi-wmi.c=82=static struct wmi_driver xiaomi_wmi_driver = {
--
drivers/platform/x86/xiaomi-wmi.c-87- .probe = xiaomi_wmi_probe,
drivers/platform/x86/xiaomi-wmi.c:88: .notify = xiaomi_wmi_notify,
drivers/platform/x86/xiaomi-wmi.c-89- .no_singleton = true,
--
drivers/platform/x86/xo15-ebook.c=151=static struct acpi_driver xo15_ebook_driver = {
--
drivers/platform/x86/xo15-ebook.c-157- .remove = ebook_switch_remove,
drivers/platform/x86/xo15-ebook.c:158: .notify = ebook_switch_notify,
drivers/platform/x86/xo15-ebook.c-159- },
--
drivers/s390/block/scm_drv.c=71=static struct scm_driver scm_drv = {
--
drivers/s390/block/scm_drv.c-75- },
drivers/s390/block/scm_drv.c:76: .notify = scm_notify,
drivers/s390/block/scm_drv.c-77- .probe = scm_probe,
--
drivers/s390/virtio/virtio_ccw.c=1463=static struct ccw_driver virtio_ccw_driver = {
--
drivers/s390/virtio/virtio_ccw.c-1472- .set_online = virtio_ccw_online,
drivers/s390/virtio/virtio_ccw.c:1473: .notify = virtio_ccw_cio_notify,
drivers/s390/virtio/virtio_ccw.c-1474- .int_class = IRQIO_VIR,
--
drivers/staging/media/imx/imx-media-dev-common.c=332=struct imx_media_dev *imx_media_dev_init(struct device *dev,
--
drivers/staging/media/imx/imx-media-dev-common.c-350- imxmd->v4l2_dev.mdev = &imxmd->md;
drivers/staging/media/imx/imx-media-dev-common.c:351: imxmd->v4l2_dev.notify = imx_media_notify;
drivers/staging/media/imx/imx-media-dev-common.c-352- strscpy(imxmd->v4l2_dev.name, "imx-media",
--
drivers/staging/media/tegra-video/video.c=44=static int host1x_video_probe(struct host1x_device *dev)
--
drivers/staging/media/tegra-video/video.c-68- vid->v4l2_dev.release = tegra_v4l2_dev_release;
drivers/staging/media/tegra-video/video.c:69: vid->v4l2_dev.notify = tegra_v4l2_dev_notify;
drivers/staging/media/tegra-video/video.c-70- ret = v4l2_device_register(&dev->dev, &vid->v4l2_dev);
--
drivers/tee/qcomtee/primordial_obj.c=104=static struct qcomtee_object_operations qcomtee_primordial_obj_ops = {
drivers/tee/qcomtee/primordial_obj.c-105- .dispatch = qcomtee_primordial_obj_dispatch,
drivers/tee/qcomtee/primordial_obj.c:106: .notify = qcomtee_primordial_obj_notify,
drivers/tee/qcomtee/primordial_obj.c-107-};
--
drivers/tee/qcomtee/user_obj.c=350=static struct qcomtee_object_operations qcomtee_user_object_ops = {
drivers/tee/qcomtee/user_obj.c-351- .release = qcomtee_user_object_release,
drivers/tee/qcomtee/user_obj.c:352: .notify = qcomtee_user_object_notify,
drivers/tee/qcomtee/user_obj.c-353- .dispatch = qcomtee_user_object_dispatch,
--
drivers/vdpa/alibaba/eni_vdpa.c=469=static int eni_vdpa_probe(struct pci_dev *pdev, const struct pci_device_id *id)
--
drivers/vdpa/alibaba/eni_vdpa.c-513- eni_vdpa->vring[i].irq = VIRTIO_MSI_NO_VECTOR;
drivers/vdpa/alibaba/eni_vdpa.c:514: eni_vdpa->vring[i].notify = ldev->ioaddr + VIRTIO_PCI_QUEUE_NOTIFY;
drivers/vdpa/alibaba/eni_vdpa.c-515- }
--
drivers/vdpa/mlx5/net/mlx5_vnet.c=2516=static void set_cvq_ready(struct mlx5_vdpa_dev *mvdev, bool ready)
--
drivers/vdpa/mlx5/net/mlx5_vnet.c-2523-
drivers/vdpa/mlx5/net/mlx5_vnet.c:2524: cvq->vring.notify = mlx5_cvq_notify;
drivers/vdpa/mlx5/net/mlx5_vnet.c-2525-}
--
drivers/vdpa/pds/vdpa_dev.c=452=static void pds_vdpa_set_status(struct vdpa_device *vdpa_dev, u8 status)
--
drivers/vdpa/pds/vdpa_dev.c-484- for (i = 0; i < pdsv->num_vqs; i++) {
drivers/vdpa/pds/vdpa_dev.c:485: pdsv->vqs[i].notify =
drivers/vdpa/pds/vdpa_dev.c-486- vp_modern_map_vq_notify(&pdsv->vdpa_aux->vd_mdev,
--
drivers/vdpa/pds/vdpa_dev.c=495=static void pds_vdpa_init_vqs_entry(struct pds_vdpa_device *pdsv, int qid,
--
drivers/vdpa/pds/vdpa_dev.c-502- pdsv->vqs[qid].irq = VIRTIO_MSI_NO_VECTOR;
drivers/vdpa/pds/vdpa_dev.c:503: pdsv->vqs[qid].notify = notify;
drivers/vdpa/pds/vdpa_dev.c-504-}
--
drivers/vdpa/vdpa_sim/vdpa_sim.c=93=static void vdpasim_queue_ready(struct vdpasim *vdpasim, unsigned int idx)
--
drivers/vdpa/vdpa_sim/vdpa_sim.c-123- vq->vring.last_used_idx = last_avail_idx;
drivers/vdpa/vdpa_sim/vdpa_sim.c:124: vq->vring.notify = vdpasim_vq_notify;
drivers/vdpa/vdpa_sim/vdpa_sim.c-125-}
--
drivers/vdpa/vdpa_sim/vdpa_sim.c=127=static void vdpasim_vq_reset(struct vdpasim *vdpasim,
--
drivers/vdpa/vdpa_sim/vdpa_sim.c-138-
drivers/vdpa/vdpa_sim/vdpa_sim.c:139: vq->vring.notify = NULL;
drivers/vdpa/vdpa_sim/vdpa_sim.c-140-}
--
drivers/vdpa/virtio_pci/vp_vdpa.c=500=static int vp_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name,
--
drivers/vdpa/virtio_pci/vp_vdpa.c-559- vp_vdpa->vring[i].irq = VIRTIO_MSI_NO_VECTOR;
drivers/vdpa/virtio_pci/vp_vdpa.c:560: vp_vdpa->vring[i].notify =
drivers/vdpa/virtio_pci/vp_vdpa.c-561- vp_modern_map_vq_notify(mdev, i,
--
fs/smb/client/smb2ops.c=5424=struct smb_version_operations smb21_operations = {
--
fs/smb/client/smb2ops.c-5507- .enum_snapshots = smb3_enum_snapshots,
fs/smb/client/smb2ops.c:5508: .notify = smb3_notify,
fs/smb/client/smb2ops.c-5509- .get_dfs_refer = smb2_get_dfs_refer,
--
fs/smb/client/smb2ops.c=5528=struct smb_version_operations smb30_operations = {
--
fs/smb/client/smb2ops.c-5620- .enum_snapshots = smb3_enum_snapshots,
fs/smb/client/smb2ops.c:5621: .notify = smb3_notify,
fs/smb/client/smb2ops.c-5622- .init_transform_rq = smb3_init_transform_rq,
--
fs/smb/client/smb2ops.c=5644=struct smb_version_operations smb311_operations = {
--
fs/smb/client/smb2ops.c-5736- .enum_snapshots = smb3_enum_snapshots,
fs/smb/client/smb2ops.c:5737: .notify = smb3_notify,
fs/smb/client/smb2ops.c-5738- .init_transform_rq = smb3_init_transform_rq,
--
lib/cpu_rmap.c=310=int irq_cpu_rmap_add(struct cpu_rmap *rmap, int irq)
--
lib/cpu_rmap.c-316- return -ENOMEM;
lib/cpu_rmap.c:317: glue->notify.notify = irq_cpu_rmap_notify;
lib/cpu_rmap.c-318- glue->notify.release = irq_cpu_rmap_release;
--
net/core/dev.c=7355=void netif_napi_set_irq_locked(struct napi_struct *napi, int irq)
--
net/core/dev.c-7388- /* Use core IRQ notifier */
net/core/dev.c:7389: napi->notify.notify = netif_napi_irq_notify;
net/core/dev.c-7390- napi->notify.release = netif_napi_affinity_release;
--
net/core/dev.c-7408-#endif
net/core/dev.c:7409: napi->notify.notify = NULL;
net/core/dev.c-7410- napi->notify.release = NULL;
--
sound/drivers/aloop.c=1428=static int loopback_notify_put(struct snd_kcontrol *kcontrol,
--
sound/drivers/aloop.c-1439- loopback->setup[kcontrol->id.subdevice]
sound/drivers/aloop.c:1440: [kcontrol->id.device].notify = val;
sound/drivers/aloop.c-1441- change = 1;
--
tools/testing/selftests/bpf/benchs/bench_htab_mem.c=104=static int htab_mem_bench_init_barriers(void)
--
tools/testing/selftests/bpf/benchs/bench_htab_mem.c-120-
tools/testing/selftests/bpf/benchs/bench_htab_mem.c:121: ctx.notify = barriers;
tools/testing/selftests/bpf/benchs/bench_htab_mem.c-122- return 0;
]
|
| 140/2 |
2026/05/19 06:09 |
llm |
expert |
0m
Model:
Tokens:
input: 207643
output: 66
thoughts: 1429
Thoughts: **Analyzing a Bluetooth OOM Hang**
Okay, first things first, let's establish a baseline. It seems `hdev->notify` isn't relevant here. I've confirmed that the critical functions `hci_conn_cleanup`, `hci_conn_del`, `hci_conn_hash_flush`, and `hci_dev_close_sync` all *don't* indefinitely block. Specifically, `hci_dev_close_sync` doesn't hang within `hci_conn_hash_flush`. And, notably, `le_conn_timeout` releases `hdev->lock` if it doesn't block. This is important.
So, the observed 143-second hang⦠it *has* to be OOM. The only plausible explanation is a prolonged `skb_clone` operation due to out-of-memory conditions. The lockdep trace points directly to `kworker/u9:10` holding `hdev->lock` while stuck in `skb_clone`, and `syz-executor:5969` is waiting on the `rx_work`. This is a classic OOM scenario, something Syzkaller often flags.
The key question is exploitability. Can this be leveraged? Since the bug is triggered by closing a vhci file descriptor, which requires `/dev/vhci` access, which is usually restricted to root or `CAP_NET_ADMIN`, the answer is no. Even if an unprivileged user has access, the result is only an OOM hang. Therefore, this is a Denial of Service, but not an exploitable one.
I went back and checked if `rx_work` *could* be blocked on `hdev->lock` held by some other process. I looked at several locations where `syz-executor:5969` might be holding `hdev->lock`: `hci_unregister_dev`, `hci_dev_close_sync`, `hci_inquiry`, and `hci_dev_do_reset`. None of these hold the lock while flushing `rx_work`. It's clear that `rx_work` *must* be blocked within a memory allocation, likely `skb_clone`, either directly or indirectly. This confirms the OOM.
I then reviewed the reproducer itself. It's empty! Just a few `mmap` calls and then exits. This is the crucial clue. A reproducer that causes a deadlock *should* contain the key syscalls. The fact that this one is empty strongly suggests that the hang is due to either a general OOM situation or the side-effects of some background process running simultaneously (or prior state). It's not a specific bug in Bluetooth code triggered by the reproducer's limited syscalls.
Thus, the conclusion is clear: this is *not* a security vulnerability. It's a generic OOM hang, and should be labeled as:
* Exploitable: False
* Denial Of Service: True (OOM hang)
* Unprivileged: False
* UserNamespace: False
* VMGuestTrigger: False
* VMHostTrigger: False
* NetworkTrigger: False
* RemoteTrigger: False
* PeripheralTrigger: False
* FilesystemTrigger: False
|
| 141/2 |
2026/05/19 06:09 |
tool |
set-results |
0m
Args: map[DenialOfService:true Exploitable:false FilesystemTrigger:false NetworkTrigger:false PeripheralTrigger:false RemoteTrigger:false Unprivileged:false UserNamespace:false VMGuestTrigger:false VMHostTrigger:false]
Results: map[DenialOfService:true Exploitable:false FilesystemTrigger:false NetworkTrigger:false PeripheralTrigger:false RemoteTrigger:false Unprivileged:false UserNamespace:false VMGuestTrigger:false VMHostTrigger:false]
|
| 142/2 |
2026/05/19 06:09 |
llm |
expert |
0m
Model:
Tokens:
input: 209904
output: 697
thoughts: 185
Thoughts: **Final Response: OOM Hang Analysis**
Okay, the analysis is done, time to put together the final explanation. Essentially, we've got an OOM-related hang. The problem traces back to a hung task in `__flush_work`, originating from a chain of function calls: `get_signal` -> `task_work_run` -> `fput` -> `vhci_release` -> `hci_unregister_dev` -> `disable_work_sync(&hdev->rx_work)`. The `rx_work` itself is getting blocked within `hci_event_packet` at `hci_dev_lock(hdev)`. The critical point is that the `hdev->lock` is being held, either by the `rx_work` thread itself (most likely blocked in `skb_clone` due to an out-of-memory condition), or by a different thread that's also blocked on memory allocation. The reproducer confirms this is a general OOM issue, not some specific, quirky bug. From what I can see, it's not something exploitable, so no security vulnerability here.
|
| 143/1 |
2026/05/19 06:10 |
action |
format-explanation |
0m
Results: map[Explanation:Based on the analysis of the bug report and the kernel source code, here is the
assessment of the issue:
**Root Cause Analysis:**
The bug report indicates a hung task (`syz-executor:5969`) that has been blocked
for more than 143 seconds in `__flush_work`. The call trace shows this is
happening during task exit/signal handling: `get_signal` -> `task_work_run` ->
`fput`.
In the context of Bluetooth, closing a `/dev/vhci` file descriptor triggers
`vhci_release`, which calls `hci_unregister_dev`. Inside `hci_unregister_dev`,
the kernel calls `disable_work_sync(&hdev->rx_work)` to flush and disable the
receive workqueue. This is where `syz-executor` is blocked, waiting for
`rx_work` to finish.
Looking at the lockdep output for the kworkers:
1. `kworker/u9:10/11292` is running `rx_work` and is blocked at
`hci_event_packet+0x162/0x1260 net/bluetooth/hci_event.c:7736`. This line
corresponds to `hci_dev_lock(hdev)`.
2. Lockdep shows that `kworker/u9:10/11292` actually *holds* `hdev->lock`
(acquired at line 7736). Since it releases the lock just 3 lines later at 7739,
it must be blocked between these lines.
3. The only operation between acquiring and releasing the lock is
`skb_clone(skb, GFP_KERNEL)`.
A `GFP_KERNEL` allocation can block indefinitely if the system is under severe
memory pressure (Out-Of-Memory condition). Because `rx_work` is stuck in memory
reclaim while holding `hdev->lock`, any other thread trying to acquire
`hdev->lock` or flush `rx_work` (like `syz-executor` in `hci_unregister_dev`)
will also hang.
**Conclusion:**
This is a classic OOM (Out-Of-Memory) hang. The empty reproducer provided by
syzkaller strongly supports this, as it indicates the hang occurred
spontaneously due to the accumulated state of the system (memory exhaustion)
rather than a specific sequence of syscalls.
Since this is a generic resource exhaustion issue and not a logical deadlock or
memory corruption bug, it does not pose a direct security vulnerability
(privilege escalation or memory safety issue). It can cause a Denial of Service
(system hang), but triggering it requires exhausting system memory, which is a
generic system-wide issue rather than a Bluetooth-specific flaw. Furthermore,
accessing `/dev/vhci` to trigger the specific cleanup path typically requires
root privileges or `CAP_NET_ADMIN`.
**Security Impact:**
* **Exploitable:** No. This is a resource exhaustion hang, not a memory
corruption or logic bug.
* **Denial of Service:** Yes, it results in a task hang, but it is a generic OOM
side-effect.
* **Unprivileged Access:** No. Access to `/dev/vhci` is restricted.]
|