summaryrefslogtreecommitdiff
path: root/drivers/tty/tty_buffer.c
diff options
context:
space:
mode:
authorPhilip Cuadra <philipcuadra@google.com>2017-06-28 12:45:08 -0700
committerMichael Bestas <mkbestas@lineageos.org>2019-12-23 23:43:34 +0200
commit642b725c9cc052c2c1f2eaf44c34d7ffa8b4290f (patch)
treec73bc55611c08d2e4ce37d17554169904364f8e3 /drivers/tty/tty_buffer.c
parent17e12f2572b325222a987c35c5d8922e92965c74 (diff)
tty: move tty_port workqueue to be a kthread
This makes each tty_port have their own kthread, hopefully allowing them a bit more freedom in scheduling when they reveive data. Based on a patch from Philip Cuadra <philipcuadra@google.com> Based on a patch from Greg Kroah-Hartman <gregkh@linuxfoundation.org> Bug: 36106419 Test: run Bluetooth audio, ensure separate tty thread is created. Signed-off-by: Philip Cuadra <philipcuadra@google.com> Change-Id: I9fd25235b26a66acb37a40304c356209b74ad46c
Diffstat (limited to 'drivers/tty/tty_buffer.c')
-rw-r--r--drivers/tty/tty_buffer.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c
index 4706df20191b..8917b6f87b04 100644
--- a/drivers/tty/tty_buffer.c
+++ b/drivers/tty/tty_buffer.c
@@ -71,7 +71,7 @@ void tty_buffer_unlock_exclusive(struct tty_port *port)
atomic_dec(&buf->priority);
mutex_unlock(&buf->lock);
if (restart)
- queue_work(system_unbound_wq, &buf->work);
+ queue_kthread_work(&port->worker, &buf->work);
}
EXPORT_SYMBOL_GPL(tty_buffer_unlock_exclusive);
@@ -132,6 +132,7 @@ void tty_buffer_free_all(struct tty_port *port)
buf->tail = &buf->sentinel;
atomic_set(&buf->mem_used, 0);
+ kthread_stop(port->worker_thread);
}
/**
@@ -404,7 +405,7 @@ void tty_schedule_flip(struct tty_port *port)
* flush_to_ldisc() sees buffer data.
*/
smp_store_release(&buf->tail->commit, buf->tail->used);
- queue_work(system_unbound_wq, &buf->work);
+ queue_kthread_work(&port->worker, &buf->work);
}
EXPORT_SYMBOL(tty_schedule_flip);
@@ -472,7 +473,7 @@ receive_buf(struct tty_struct *tty, struct tty_buffer *head, int count)
* 'consumer'
*/
-static void flush_to_ldisc(struct work_struct *work)
+static void flush_to_ldisc(struct kthread_work *work)
{
struct tty_port *port = container_of(work, struct tty_port, buf.work);
struct tty_bufhead *buf = &port->buf;
@@ -562,8 +563,20 @@ void tty_buffer_init(struct tty_port *port)
init_llist_head(&buf->free);
atomic_set(&buf->mem_used, 0);
atomic_set(&buf->priority, 0);
- INIT_WORK(&buf->work, flush_to_ldisc);
buf->mem_limit = TTYB_DEFAULT_MEM_LIMIT;
+ init_kthread_work(&buf->work, flush_to_ldisc);
+ init_kthread_worker(&port->worker);
+ port->worker_thread = kthread_run(kthread_worker_fn, &port->worker,
+ "tty_worker_thread");
+ if (IS_ERR(port->worker_thread)) {
+ /*
+ * Not good, we can't unwind, this tty is going to be really
+ * sad...
+ */
+ pr_err("Unable to start tty_worker_thread\n");
+ }
+
+
}
/**
@@ -591,15 +604,15 @@ void tty_buffer_set_lock_subclass(struct tty_port *port)
bool tty_buffer_restart_work(struct tty_port *port)
{
- return queue_work(system_unbound_wq, &port->buf.work);
+ return queue_kthread_work(&port->worker, &port->buf.work);
}
bool tty_buffer_cancel_work(struct tty_port *port)
{
- return cancel_work_sync(&port->buf.work);
+ return kthread_cancel_work_sync(&port->buf.work);
}
void tty_buffer_flush_work(struct tty_port *port)
{
- flush_work(&port->buf.work);
+ flush_kthread_work(&port->buf.work);
}