summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHolmes Chou <holmeschou@google.com>2022-01-05 13:55:37 +0800
committerHolmes Chou <holmeschou@google.com>2022-02-08 18:11:41 +0800
commite519fa315845e931638f5bd86351ec48fae0cc37 (patch)
tree74d19c1c0f0f363861bf82cbf0a5eeef9a24f550
parent431ab6acf7df78be8ca23fcf705ada09a68382b5 (diff)
downloadlwis-e519fa315845e931638f5bd86351ec48fae0cc37.tar.gz
LWIS: Convert LWIS periodic IO workq to kthread
Start using a dedicated kthread for lwis periodic io, instead of relying on generic workqueue. This allows assigning priority to these worker threads as necessary. Bug: 199950581 Test: GCA, CTS Signed-off-by: Holmes Chou <holmeschou@google.com> Change-Id: Ia14c2568bcd9d3708c2971e6d80f62b6f8d43655
-rw-r--r--lwis_device.h6
-rw-r--r--lwis_device_i2c.c3
-rw-r--r--lwis_device_ioreg.c3
-rw-r--r--lwis_periodic_io.c17
-rw-r--r--lwis_transaction.c11
-rw-r--r--lwis_util.c27
-rw-r--r--lwis_util.h7
7 files changed, 45 insertions, 29 deletions
diff --git a/lwis_device.h b/lwis_device.h
index 9f2607f..76764e7 100644
--- a/lwis_device.h
+++ b/lwis_device.h
@@ -265,6 +265,8 @@ struct lwis_device {
/* Worker thread */
struct kthread_worker transaction_worker;
struct task_struct *transaction_worker_thread;
+ struct kthread_worker periodic_io_worker;
+ struct task_struct *periodic_io_worker_thread;
};
/*
@@ -303,11 +305,9 @@ struct lwis_client {
int64_t transaction_counter;
/* Hash table of hrtimer keyed by time out duration */
DECLARE_HASHTABLE(timer_list, PERIODIC_IO_HASH_BITS);
- /* Workqueue variables for periodic io */
- struct workqueue_struct *periodic_io_wq;
- struct work_struct periodic_io_work;
/* Work item */
struct kthread_work transaction_work;
+ struct kthread_work periodic_io_work;
/* Spinlock used to synchronize access to periodic io data structs */
spinlock_t periodic_io_lock;
/* Queue of all periodic_io pending processing */
diff --git a/lwis_device_i2c.c b/lwis_device_i2c.c
index 4d229e8..1dcf06b 100644
--- a/lwis_device_i2c.c
+++ b/lwis_device_i2c.c
@@ -255,7 +255,8 @@ static int lwis_i2c_device_probe(struct platform_device *plat_dev)
}
/* Create an associated kworker thread */
- ret = lwis_create_kthread_worker(&i2c_dev->base_dev, "lwis_i2c_kthread");
+ ret = lwis_create_kthread_workers(&i2c_dev->base_dev, "lwis_i2c_trans_kthread",
+ "lwis_i2c_prd_io_kthread");
if (ret) {
dev_err(i2c_dev->base_dev.dev,"Failed to create lwis_i2c_kthread");
lwis_base_unprobe((struct lwis_device *)i2c_dev);
diff --git a/lwis_device_ioreg.c b/lwis_device_ioreg.c
index 5f40e73..7b00463 100644
--- a/lwis_device_ioreg.c
+++ b/lwis_device_ioreg.c
@@ -127,7 +127,8 @@ static int lwis_ioreg_device_probe(struct platform_device *plat_dev)
}
/* Create an associated kworker thread */
- ret = lwis_create_kthread_worker(&ioreg_dev->base_dev, "lwis_ioreg_kthread");
+ ret = lwis_create_kthread_workers(&ioreg_dev->base_dev, "lwis_ioreg_trans_kthread",
+ "lwis_ioreg_prd_io_kthread");
if (ret) {
dev_err(ioreg_dev->base_dev.dev, "Failed to create lwis_ioreg_kthread");
lwis_base_unprobe((struct lwis_device *)ioreg_dev);
diff --git a/lwis_periodic_io.c b/lwis_periodic_io.c
index 7f37418..d3b56cb 100644
--- a/lwis_periodic_io.c
+++ b/lwis_periodic_io.c
@@ -13,6 +13,7 @@
#include "lwis_periodic_io.h"
#include <linux/completion.h>
+#include <linux/kthread.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
@@ -56,7 +57,8 @@ static enum hrtimer_restart periodic_io_timer_func(struct hrtimer *timer)
}
}
if (active_periodic_io_present) {
- queue_work(client->periodic_io_wq, &client->periodic_io_work);
+ kthread_queue_work(&client->lwis_dev->periodic_io_worker,
+ &client->periodic_io_work);
}
spin_unlock_irqrestore(&client->periodic_io_lock, flags);
if (!active_periodic_io_present) {
@@ -298,7 +300,7 @@ event_push:
return ret;
}
-static void periodic_io_work_func(struct work_struct *work)
+static void periodic_io_work_func(struct kthread_work *work)
{
int error_code;
unsigned long flags;
@@ -446,8 +448,7 @@ void lwis_periodic_io_free(struct lwis_device *lwis_dev, struct lwis_periodic_io
int lwis_periodic_io_init(struct lwis_client *client)
{
INIT_LIST_HEAD(&client->periodic_io_process_queue);
- client->periodic_io_wq = create_workqueue("lwisperiod");
- INIT_WORK(&client->periodic_io_work, periodic_io_work_func);
+ kthread_init_work(&client->periodic_io_work, periodic_io_work_func);
client->periodic_io_counter = 0;
hash_init(client->timer_list);
return 0;
@@ -515,8 +516,8 @@ int lwis_periodic_io_client_flush(struct lwis_client *client)
}
/* Wait until all workload in process queue are processed */
- if (client->periodic_io_wq) {
- drain_workqueue(client->periodic_io_wq);
+ if (client->lwis_dev->periodic_io_worker_thread) {
+ kthread_flush_worker(&client->lwis_dev->periodic_io_worker);
}
spin_lock_irqsave(&client->periodic_io_lock, flags);
@@ -546,10 +547,6 @@ int lwis_periodic_io_client_cleanup(struct lwis_client *client)
return ret;
}
- if (client->periodic_io_wq) {
- destroy_workqueue(client->periodic_io_wq);
- }
-
spin_lock_irqsave(&client->periodic_io_lock, flags);
hash_for_each_safe (client->timer_list, i, tmp, it_periodic_io_list, node) {
hash_del(&it_periodic_io_list->node);
diff --git a/lwis_transaction.c b/lwis_transaction.c
index 4388bfd..e467be3 100644
--- a/lwis_transaction.c
+++ b/lwis_transaction.c
@@ -614,11 +614,14 @@ static int queue_transaction_locked(struct lwis_client *client,
if (info->trigger_event_id == LWIS_EVENT_ID_NONE) {
/* Immediate trigger. */
if (info->run_at_real_time) {
- list_add_tail(&transaction->process_queue_node, &client->transaction_process_queue_tasklet);
+ list_add_tail(&transaction->process_queue_node,
+ &client->transaction_process_queue_tasklet);
tasklet_schedule(&client->transaction_tasklet);
} else {
- list_add_tail(&transaction->process_queue_node, &client->transaction_process_queue);
- kthread_queue_work(&client->lwis_dev->transaction_worker, &client->transaction_work);
+ list_add_tail(&transaction->process_queue_node,
+ &client->transaction_process_queue);
+ kthread_queue_work(&client->lwis_dev->transaction_worker,
+ &client->transaction_work);
}
} else {
/* Trigger by event. */
@@ -777,7 +780,7 @@ int lwis_transaction_event_trigger(struct lwis_client *client, int64_t event_id,
}
if (!list_empty(&client->transaction_process_queue)) {
kthread_queue_work(&client->lwis_dev->transaction_worker,
- &client->transaction_work);
+ &client->transaction_work);
}
spin_unlock_irqrestore(&client->transaction_lock, flags);
diff --git a/lwis_util.c b/lwis_util.c
index 87499da..fb98c65 100644
--- a/lwis_util.c
+++ b/lwis_util.c
@@ -94,14 +94,29 @@ const char *lwis_device_type_to_string(int32_t type)
}
}
-int lwis_create_kthread_worker(struct lwis_device *dev, const char *transaction_worker_name)
+int lwis_create_kthread_workers(struct lwis_device *lwis_dev, const char *transaction_worker_name,
+ const char *periodic_io_worker_name)
{
- kthread_init_worker(&dev->transaction_worker);
- dev->transaction_worker_thread = kthread_run(kthread_worker_fn, &dev->transaction_worker,
- transaction_worker_name);
- if (IS_ERR(dev->transaction_worker_thread))
+ if (!lwis_dev) {
+ pr_err("lwis_create_kthread_workers: lwis_dev is NULL\n");
+ return -ENODEV;
+ }
+
+ kthread_init_worker(&lwis_dev->transaction_worker);
+ lwis_dev->transaction_worker_thread = kthread_run(kthread_worker_fn,
+ &lwis_dev->transaction_worker, transaction_worker_name);
+ if (IS_ERR(lwis_dev->transaction_worker_thread)) {
+ dev_err(lwis_dev->dev, "transaction kthread_run failed\n");
return -EINVAL;
+ }
- return 0;
+ kthread_init_worker(&lwis_dev->periodic_io_worker);
+ lwis_dev->periodic_io_worker_thread = kthread_run(kthread_worker_fn,
+ &lwis_dev->periodic_io_worker, periodic_io_worker_name);
+ if (IS_ERR(lwis_dev->periodic_io_worker_thread)) {
+ dev_err(lwis_dev->dev, "periodic_io kthread_run failed\n");
+ return -EINVAL;
+ }
+ return 0;
}
diff --git a/lwis_util.h b/lwis_util.h
index 98cfb8c..36c9f8d 100644
--- a/lwis_util.h
+++ b/lwis_util.h
@@ -65,10 +65,9 @@ static inline ktime_t lwis_get_time()
}
/*
- * lwis_create_kthread_worker: Creates a kthread worker associated with
- * this lwis device.
+ * lwis_create_kthread_workers: Creates kthread workers associated with this lwis device.
*/
-
-int lwis_create_kthread_worker(struct lwis_device *dev, const char *transaction_worker_name);
+int lwis_create_kthread_workers(struct lwis_device *lwis_dev, const char *transaction_worker_name,
+ const char *periodic_io_worker_name);
#endif // LWIS_UTIL_H_