tty: tty_io: Switch to vmalloc() fallback in case of TTY_NO_WRITE_SPLIT
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Mon, 20 Dec 2021 13:32:50 +0000 (15:32 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 21 Dec 2021 08:18:44 +0000 (09:18 +0100)
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@linux.intel.com>
Link: https://lore.kernel.org/r/20211220133250.3070-1-andriy.shevchenko@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/tty_io.c
drivers/usb/class/cdc-acm.c

index a4cfd254fda274e2e57b502f4f8032fbfb2e1624..7e8b3bd59c7b3c72de5f17b412a7e9b4c042282b 100644 (file)
@@ -169,7 +169,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);
 }
@@ -986,9 +986,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))
@@ -1003,12 +1000,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;
        }
index b3ce7338cb6b3513e3b130049e9d376017f1dba6..9b9aea24d58c41741e9855d0febce9110c13d9a0 100644 (file)
@@ -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;