Skip to content

Commit

Permalink
tty: move tty_port workqueue to be a kthread
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Philip Cuadra authored and mikeNG committed Dec 23, 2019
1 parent 17e12f2 commit 642b725
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 9 deletions.
27 changes: 20 additions & 7 deletions drivers/tty/tty_buffer.c
Expand Up @@ -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);

Expand Down Expand Up @@ -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);
}

/**
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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");
}


}

/**
Expand Down Expand Up @@ -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);
}
6 changes: 4 additions & 2 deletions include/linux/tty.h
Expand Up @@ -12,7 +12,7 @@
#include <uapi/linux/tty.h>
#include <linux/rwsem.h>
#include <linux/llist.h>

#include <linux/kthread.h>

/*
* Lock subclasses for tty locks
Expand Down Expand Up @@ -82,7 +82,7 @@ static inline char *flag_buf_ptr(struct tty_buffer *b, int ofs)

struct tty_bufhead {
struct tty_buffer *head; /* Queue head */
struct work_struct work;
struct kthread_work work;
struct mutex lock;
atomic_t priority;
struct tty_buffer sentinel;
Expand Down Expand Up @@ -240,6 +240,8 @@ struct tty_port {
based drain is needed else
set to size of fifo */
struct kref kref; /* Ref counter */
struct kthread_worker worker; /* worker thread */
struct task_struct *worker_thread; /* worker thread */
};

/*
Expand Down

0 comments on commit 642b725

Please sign in to comment.