aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/dmatest.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dma/dmatest.c')
-rw-r--r--drivers/dma/dmatest.c72
1 files changed, 47 insertions, 25 deletions
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
index 26b502069638..dd4d84d556d5 100644
--- a/drivers/dma/dmatest.c
+++ b/drivers/dma/dmatest.c
@@ -161,6 +161,43 @@ struct dmatest_chan {
161 struct list_head threads; 161 struct list_head threads;
162}; 162};
163 163
164static DECLARE_WAIT_QUEUE_HEAD(thread_wait);
165static bool wait;
166
167static bool is_threaded_test_run(struct dmatest_info *info)
168{
169 struct dmatest_chan *dtc;
170
171 list_for_each_entry(dtc, &info->channels, node) {
172 struct dmatest_thread *thread;
173
174 list_for_each_entry(thread, &dtc->threads, node) {
175 if (!thread->done)
176 return true;
177 }
178 }
179
180 return false;
181}
182
183static int dmatest_wait_get(char *val, const struct kernel_param *kp)
184{
185 struct dmatest_info *info = &test_info;
186 struct dmatest_params *params = &info->params;
187
188 if (params->iterations)
189 wait_event(thread_wait, !is_threaded_test_run(info));
190 wait = true;
191 return param_get_bool(val, kp);
192}
193
194static struct kernel_param_ops wait_ops = {
195 .get = dmatest_wait_get,
196 .set = param_set_bool,
197};
198module_param_cb(wait, &wait_ops, &wait, S_IRUGO);
199MODULE_PARM_DESC(wait, "Wait for tests to complete (default: false)");
200
164static bool dmatest_match_channel(struct dmatest_params *params, 201static bool dmatest_match_channel(struct dmatest_params *params,
165 struct dma_chan *chan) 202 struct dma_chan *chan)
166{ 203{
@@ -660,12 +697,7 @@ err_thread_type:
660 dmaengine_terminate_all(chan); 697 dmaengine_terminate_all(chan);
661 698
662 thread->done = true; 699 thread->done = true;
663 700 wake_up(&thread_wait);
664 if (params->iterations > 0)
665 while (!kthread_should_stop()) {
666 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait_dmatest_exit);
667 interruptible_sleep_on(&wait_dmatest_exit);
668 }
669 701
670 return ret; 702 return ret;
671} 703}
@@ -681,6 +713,7 @@ static void dmatest_cleanup_channel(struct dmatest_chan *dtc)
681 pr_debug("thread %s exited with status %d\n", 713 pr_debug("thread %s exited with status %d\n",
682 thread->task->comm, ret); 714 thread->task->comm, ret);
683 list_del(&thread->node); 715 list_del(&thread->node);
716 put_task_struct(thread->task);
684 kfree(thread); 717 kfree(thread);
685 } 718 }
686 719
@@ -719,18 +752,19 @@ static int dmatest_add_threads(struct dmatest_info *info,
719 thread->chan = dtc->chan; 752 thread->chan = dtc->chan;
720 thread->type = type; 753 thread->type = type;
721 smp_wmb(); 754 smp_wmb();
722 thread->task = kthread_run(dmatest_func, thread, "%s-%s%u", 755 thread->task = kthread_create(dmatest_func, thread, "%s-%s%u",
723 dma_chan_name(chan), op, i); 756 dma_chan_name(chan), op, i);
724 if (IS_ERR(thread->task)) { 757 if (IS_ERR(thread->task)) {
725 pr_warn("Failed to run thread %s-%s%u\n", 758 pr_warn("Failed to create thread %s-%s%u\n",
726 dma_chan_name(chan), op, i); 759 dma_chan_name(chan), op, i);
727 kfree(thread); 760 kfree(thread);
728 break; 761 break;
729 } 762 }
730 763
731 /* srcbuf and dstbuf are allocated by the thread itself */ 764 /* srcbuf and dstbuf are allocated by the thread itself */
732 765 get_task_struct(thread->task);
733 list_add_tail(&thread->node, &dtc->threads); 766 list_add_tail(&thread->node, &dtc->threads);
767 wake_up_process(thread->task);
734 } 768 }
735 769
736 return i; 770 return i;
@@ -863,22 +897,6 @@ static void restart_threaded_test(struct dmatest_info *info, bool run)
863 run_threaded_test(info); 897 run_threaded_test(info);
864} 898}
865 899
866static bool is_threaded_test_run(struct dmatest_info *info)
867{
868 struct dmatest_chan *dtc;
869
870 list_for_each_entry(dtc, &info->channels, node) {
871 struct dmatest_thread *thread;
872
873 list_for_each_entry(thread, &dtc->threads, node) {
874 if (!thread->done)
875 return true;
876 }
877 }
878
879 return false;
880}
881
882static int dmatest_run_get(char *val, const struct kernel_param *kp) 900static int dmatest_run_get(char *val, const struct kernel_param *kp)
883{ 901{
884 struct dmatest_info *info = &test_info; 902 struct dmatest_info *info = &test_info;
@@ -920,6 +938,7 @@ static int dmatest_run_set(const char *val, const struct kernel_param *kp)
920static int __init dmatest_init(void) 938static int __init dmatest_init(void)
921{ 939{
922 struct dmatest_info *info = &test_info; 940 struct dmatest_info *info = &test_info;
941 struct dmatest_params *params = &info->params;
923 942
924 if (dmatest_run) { 943 if (dmatest_run) {
925 mutex_lock(&info->lock); 944 mutex_lock(&info->lock);
@@ -927,6 +946,9 @@ static int __init dmatest_init(void)
927 mutex_unlock(&info->lock); 946 mutex_unlock(&info->lock);
928 } 947 }
929 948
949 if (params->iterations && wait)
950 wait_event(thread_wait, !is_threaded_test_run(info));
951
930 /* module parameters are stable, inittime tests are started, 952 /* module parameters are stable, inittime tests are started,
931 * let userspace take over 'run' control 953 * let userspace take over 'run' control
932 */ 954 */