summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2010-02-18 16:43:47 +0000
committerGreg Kroah-Hartman <gregkh@suse.de>2010-03-02 14:43:23 -0800
commitd9661adfb8e53a7647360140af3b92284cbe52d4 (patch)
tree92946118969a8cbd5918ac6b35142f0051aabc4e
parent4165fe4ef7305609a96c7f248cefb9c414d0ede5 (diff)
tty: Keep the default buffering to sub-page units
We allocate during interrupts so while our buffering is normally diced up small anyway on some hardware at speed we can pressure the VM excessively for page pairs. We don't really need big buffers to be linear so don't try so hard. In order to make this work well we will tidy up excess callers to request_room, which cannot itself enforce this break up. Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/char/tty_buffer.c6
-rw-r--r--include/linux/tty.h10
2 files changed, 14 insertions, 2 deletions
diff --git a/drivers/char/tty_buffer.c b/drivers/char/tty_buffer.c
index 66fa4e10d76b..f27c4d6d956e 100644
--- a/drivers/char/tty_buffer.c
+++ b/drivers/char/tty_buffer.c
@@ -247,7 +247,8 @@ int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars,
{
int copied = 0;
do {
- int space = tty_buffer_request_room(tty, size - copied);
+ int goal = min(size - copied, TTY_BUFFER_PAGE);
+ int space = tty_buffer_request_room(tty, goal);
struct tty_buffer *tb = tty->buf.tail;
/* If there is no space then tb may be NULL */
if (unlikely(space == 0))
@@ -283,7 +284,8 @@ int tty_insert_flip_string_flags(struct tty_struct *tty,
{
int copied = 0;
do {
- int space = tty_buffer_request_room(tty, size - copied);
+ int goal = min(size - copied, TTY_BUFFER_PAGE);
+ int space = tty_buffer_request_room(tty, goal);
struct tty_buffer *tb = tty->buf.tail;
/* If there is no space then tb may be NULL */
if (unlikely(space == 0))
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 6abfcf5b5887..d96e5882f129 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -68,6 +68,16 @@ struct tty_buffer {
unsigned long data[0];
};
+/*
+ * We default to dicing tty buffer allocations to this many characters
+ * in order to avoid multiple page allocations. We assume tty_buffer itself
+ * is under 256 bytes. See tty_buffer_find for the allocation logic this
+ * must match
+ */
+
+#define TTY_BUFFER_PAGE ((PAGE_SIZE - 256) / 2)
+
+
struct tty_bufhead {
struct delayed_work work;
spinlock_t lock;