Re: [PATCH v1] tty: n_tty: use kvzalloc/kvfree for line discipline data
From: Xin Chen
Date: Tue Aug 18 2026 - 02:59:11 EST
On Tue, Aug 18, 2026, Greg KH wrote:
> But that's not a problem with the tty layer, if something else happens
> to "drain" the pool again you can not create a skb. You are not
> solving the root problem here.
You are right that this does not prevent every possible order-0
exhaustion. However, the specific and reproducible trigger is
n_tty_open() consuming order-0 pages via vzalloc() immediately before
skb_clone() runs. Eliminating that unnecessary pressure removes the
failure in practice, even if it does not make skb_clone() immune to
all possible memory pressure.
> But that's not really a change, when was vmalloc() first used?
> As nothing has changed here, then why is this suddenly showing up now?
ldata was originally allocated with kzalloc() (introduced in commit
70ece7a73159, "TTY: n_tty, add ldisc data to n_tty", 2012). Commit
ebec3f8f5271 switched it to vmalloc()/vzalloc() in 2018 as a side
effect of fixing an echo buffer race — the allocation change was
incidental, not intentional. The issue surfaces now because the BT
enable-disable sanity test exercises a back-to-back open pattern that
was not common before serdev-based UART transports became widespread.
> Again, that sounds like a bluetooth issue, and why can't you just
> properly handle the skb out of memory issue?
The skb_clone() failure is silent — it returns NULL and the code
continues without error, leaving hdev->req_skb NULL. By the time
the BT layer observes the problem (a -ETIMEDOUT 10 seconds later),
it is several layers removed from the skb_clone() failure: the
firmware has already replied successfully, hci_req_cmd_complete()
has already run and found req_skb NULL, and the completion callback
was never invoked. At that point the BT layer has no way to
distinguish a memory failure from a genuine firmware timeout, let
alone recover from it. And even if the NULL req_skb were detected
and surfaced as an error immediately, there is nothing the BT layer
could do to recover — it cannot reclaim memory or retry the
allocation itself. The only option would be to wait for the memory
to be reclaimed and retry the entire BT enable sequence from
userspace, which is exactly the kind of fragile error handling we
want to avoid. The tty change is simpler and correct: ldata was
originally a kzalloc() allocation and there is no reason for it to
use vmalloc-backed pages that interfere with unrelated allocations.
> No, that did not change the behavior of the tty call here to use a
> different pool, all it did was change the zeroing out of the buffer
> allocated.
You are correct, I apologize for the wrong Fixes: tag. The switch
from kzalloc() to vmalloc() was introduced by commit 20bafb3d23d1
("n_tty: Move buffers into n_tty_data", 2013), which merged the
read_buf and echo_buf (each 4 KB) into n_tty_data, making the
structure too large for kmalloc() at the time. That is the correct
Fixes: tag. I will update it in v2:
Fixes: 20bafb3d23d1 ("n_tty: Move buffers into n_tty_data")
Thanks,
Xin