aboutsummaryrefslogtreecommitdiff
path: root/drivers/tty/tty_buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/tty_buffer.c')
-rw-r--r--drivers/tty/tty_buffer.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c
index 1a5673acd9b1..96be90db53b7 100644
--- a/drivers/tty/tty_buffer.c
+++ b/drivers/tty/tty_buffer.c
@@ -59,6 +59,13 @@ void tty_buffer_lock_exclusive(struct tty_port *port)
}
EXPORT_SYMBOL_GPL(tty_buffer_lock_exclusive);
+static bool tty_buffer_queue_work(struct tty_bufhead *buf)
+{
+ struct workqueue_struct *flip_wq = READ_ONCE(buf->flip_wq);
+
+ return queue_work(flip_wq ?: system_dfl_wq, &buf->work);
+}
+
/**
* tty_buffer_unlock_exclusive - release exclusive access
* @port: tty port owning the flip buffer
@@ -76,7 +83,7 @@ void tty_buffer_unlock_exclusive(struct tty_port *port)
mutex_unlock(&buf->lock);
if (restart)
- queue_work(system_dfl_wq, &buf->work);
+ tty_buffer_queue_work(buf);
}
EXPORT_SYMBOL_GPL(tty_buffer_unlock_exclusive);
@@ -177,7 +184,7 @@ static struct tty_buffer *tty_buffer_alloc(struct tty_port *port, size_t size)
*/
if (atomic_read(&port->buf.mem_used) > port->buf.mem_limit)
return NULL;
- p = kmalloc(struct_size(p, data, 2 * size), GFP_ATOMIC | __GFP_NOWARN);
+ p = kmalloc_flex(*p, data, 2 * size, GFP_ATOMIC | __GFP_NOWARN);
if (p == NULL)
return NULL;
@@ -530,7 +537,7 @@ void tty_flip_buffer_push(struct tty_port *port)
struct tty_bufhead *buf = &port->buf;
tty_flip_buffer_commit(buf->tail);
- queue_work(system_dfl_wq, &buf->work);
+ tty_buffer_queue_work(buf);
}
EXPORT_SYMBOL(tty_flip_buffer_push);
@@ -560,7 +567,7 @@ int tty_insert_flip_string_and_push_buffer(struct tty_port *port,
tty_flip_buffer_commit(buf->tail);
spin_unlock_irqrestore(&port->lock, flags);
- queue_work(system_dfl_wq, &buf->work);
+ tty_buffer_queue_work(buf);
return size;
}
@@ -613,7 +620,7 @@ void tty_buffer_set_lock_subclass(struct tty_port *port)
bool tty_buffer_restart_work(struct tty_port *port)
{
- return queue_work(system_dfl_wq, &port->buf.work);
+ return tty_buffer_queue_work(&port->buf);
}
bool tty_buffer_cancel_work(struct tty_port *port)