When TTY_NO_WRITE_SPLIT is set and 64 KiB chunks are used, allow vmalloc() fallback. Supply __GFP_RETRY_MAYFAIL to make kmalloc() preferable over vmalloc() since we may want a better performance. Note, both current users copy data to another buffer anyway, so the type of our allocation doesn't affect their expectations. Signed-off-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> --- drivers/tty/tty_io.c | 9 +++------ drivers/usb/class/cdc-acm.c | 4 ---- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 6616d4a0d41d..8fedfe88dff7 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -170,7 +170,7 @@ static void free_tty_struct(struct tty_struct *tty) { tty_ldisc_deinit(tty); put_device(tty->dev); - kfree(tty->write_buf); + kvfree(tty->write_buf); tty->magic = 0xDEADDEAD; kfree(tty); } @@ -997,9 +997,6 @@ static inline ssize_t do_tty_write( * layer has problems with bigger chunks. It will * claim to be able to handle more characters than * it actually does. - * - * FIXME: This can probably go away now except that 64K chunks - * are too likely to fail unless switched to vmalloc... */ chunk = 2048; if (test_bit(TTY_NO_WRITE_SPLIT, &tty->flags)) @@ -1014,12 +1011,12 @@ static inline ssize_t do_tty_write( if (chunk < 1024) chunk = 1024; - buf_chunk = kmalloc(chunk, GFP_KERNEL); + buf_chunk = kvmalloc(chunk, GFP_KERNEL | __GFP_RETRY_MAYFAIL); if (!buf_chunk) { ret = -ENOMEM; goto out; } - kfree(tty->write_buf); + kvfree(tty->write_buf); tty->write_cnt = chunk; tty->write_buf = buf_chunk; } diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index b3ce7338cb6b..9b9aea24d58c 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -685,10 +685,6 @@ static int acm_port_activate(struct tty_port *port, struct tty_struct *tty) if (retval) goto error_get_interface; - /* - * FIXME: Why do we need this? Allocating 64K of physically contiguous - * memory is really nasty... - */ set_bit(TTY_NO_WRITE_SPLIT, &tty->flags); acm->control->needs_remote_wakeup = 1; -- 2.34.1