diff options
author | Holmes Chou <holmeschou@google.com> | 2022-01-05 13:55:37 +0800 |
---|---|---|
committer | Holmes Chou <holmeschou@google.com> | 2022-02-08 18:11:41 +0800 |
commit | e519fa315845e931638f5bd86351ec48fae0cc37 (patch) | |
tree | 74d19c1c0f0f363861bf82cbf0a5eeef9a24f550 | |
parent | 431ab6acf7df78be8ca23fcf705ada09a68382b5 (diff) | |
download | lwis-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.h | 6 | ||||
-rw-r--r-- | lwis_device_i2c.c | 3 | ||||
-rw-r--r-- | lwis_device_ioreg.c | 3 | ||||
-rw-r--r-- | lwis_periodic_io.c | 17 | ||||
-rw-r--r-- | lwis_transaction.c | 11 | ||||
-rw-r--r-- | lwis_util.c | 27 | ||||
-rw-r--r-- | lwis_util.h | 7 |
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_ |