Re: [PATCH v1] tty: n_tty: use kvzalloc/kvfree for line discipline data
Xin Chen <[email protected]>
| Newsgroups | org.kernel.vger.linux-serial,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
On Mon, Aug 18, 2026, Greg KH wrote: > What specific "damage"? The specific damage is that hci_send_cmd_sync() calls skb_clone(hdev->sent_cmd, GFP_KERNEL) to set hdev->req_skb. If that clone fails, hdev->req_skb stays NULL. When the firmware reply arrives, hci_req_cmd_complete() checks hdev->req_skb to find the registered completion callback; finding NULL, it never calls hci_cmd_sync_complete(), req_status stays HCI_REQ_PEND, and the waiter in __hci_cmd_sync_sk() times out with -ETIMEDOUT. The command was sent and the firmware replied successfully — the damage is purely that the completion path is broken. > But it's not consuming them "unnecessarily" as the memory is needed. > Why not fix the root problem here of having this be called so many > times that you are running out of memory? The repeated calls are a normal consequence of the serdev open/close retry logic in the BT transport layer; constraining that would require changes in a different subsystem and would not address the underlying fragility. The real question is why skb_clone(GFP_KERNEL) fails at all when the system is not truly OOM. > And why isn't memory being reclaimed properly if we do not have any > left in that free list? The allocation can sleep, so it should be > always succeeding if the system isn't truly out of memory, as you > imply it is not. This is the crux of the issue. vzalloc() allocates order-0 pages through vm_area_alloc_pages(), which takes the bulk allocation path (alloc_pages_bulk_noprof) for order-0. The bulk allocator uses ALLOC_WMARK_LOW and does not perform direct reclaim — it is intentionally a fast, non-sleeping path. When the low watermark check fails it falls through to goto failed, and vm_area_alloc_pages() falls back to single-page alloc_pages() calls which can reclaim. So vzalloc() itself can succeed even under pressure, but only after consuming whatever order-0 pages were available via the bulk path first. The problem is that skb_clone(GFP_KERNEL) in hci_send_cmd_sync() is a single kmalloc-backed allocation. It does not retry on failure and has no reclaim loop of its own; if the zone is below the low watermark at the moment it runs, it fails and returns NULL. The window is narrow but real: the bulk path in vzalloc() drains the PCP/buddy order-0 lists below the low watermark; skb_clone() runs before kswapd has had a chance to refill them; it fails silently. Switching to kvzalloc_obj() serves the ~10 KB n_tty_data from the kmalloc-16384 slab (an order-2 compound page), which does not touch the order-0 free list at all, eliminating the pressure window entirely. Thanks, Xin Chen