From patchwork Wed Sep 19 19:52:50 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Seraj Alijan X-Patchwork-Id: 10606427 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C6C7A112B for ; Wed, 19 Sep 2018 19:53:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B5EB128708 for ; Wed, 19 Sep 2018 19:53:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A989928C72; Wed, 19 Sep 2018 19:53:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CA4AF28708 for ; Wed, 19 Sep 2018 19:53:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731869AbeITBcu (ORCPT ); Wed, 19 Sep 2018 21:32:50 -0400 Received: from mail-eopbgr00050.outbound.protection.outlook.com ([40.107.0.50]:13958 "EHLO EUR02-AM5-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726718AbeITBct (ORCPT ); Wed, 19 Sep 2018 21:32:49 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sondrel.onmicrosoft.com; s=selector1-sondrel-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=p4rBA6AtHMexC3wuF7VEk6E+VSvMgCC0W+CTXSLjexI=; b=BZMCt4HeBrnd5fcNAMo1IpHLLL/qXgnZxQcboBhcG7TjoUxDA/4Yf7UmEFlYLOctHtlxOc8QxY37KaKWyWhSumqdZkObgl+Zyv/2sjKAK23rhelEicdnpnUgIjlZJS5oI5cBjHZx8VYWttkop3lUPT4YF/FD0IZFiYcC1yqaMSE= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=seraj.mohammed@sondrel.com; Received: from Seraj-pc.hh.imgtec.org (195.88.9.101) by DB6P191MB0245.EURP191.PROD.OUTLOOK.COM (2603:10a6:4:8e::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1143.15; Wed, 19 Sep 2018 19:53:19 +0000 From: Seraj Alijan To: vkoul@kernel.org Cc: dmaengine@vger.kernel.org, dan.j.williams@intel.com, james.hartley@sondrel.com, sifan.naeem@sondrel.com, ed.blake@sondrel.com, Seraj Alijan Subject: [PATCH V3 1/5] dmaengine: dmatest: Add support for multi channel testing Date: Wed, 19 Sep 2018 20:52:50 +0100 Message-Id: <1537386774-20749-2-git-send-email-seraj.alijan@sondrel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1537386774-20749-1-git-send-email-seraj.alijan@sondrel.com> References: <1537386774-20749-1-git-send-email-seraj.alijan@sondrel.com> MIME-Version: 1.0 X-Originating-IP: [195.88.9.101] X-ClientProxiedBy: CWLP265CA0040.GBRP265.PROD.OUTLOOK.COM (2603:10a6:401:11::28) To DB6P191MB0245.EURP191.PROD.OUTLOOK.COM (2603:10a6:4:8e::17) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 54ae4447-cac3-4644-05ef-08d61e698c8a X-Microsoft-Antispam: BCL:0;PCL:0;RULEID:(7020095)(4652040)(8989299)(4534165)(4627221)(201703031133081)(201702281549075)(8990200)(5600074)(711020)(2017052603328)(7153060)(7193020);SRVR:DB6P191MB0245; X-Microsoft-Exchange-Diagnostics: 1;DB6P191MB0245;3:0EFw5lsvycsUtNpE/UH6/fE5CCwT957Fi/R04AMP0nmH3ZPnje+W9gZJqvPLiJ7PzedrT4Nzdej14+j1foeK9Sw6QCKvgkZzmSd5Iu2HZbqUOqJDWJBpB4fZIdmI4BmsTAyrQshW8Rtlsy/QuS5r/fDOsDQyyB8VFDx7kdYAc+tQJIbUIZX1K86uLr+0r9pA43tZ6fuJpsBy/7Fa2fB6Y47+UuXbn0lrbDlVbbvicOchNnFMyR6meElQ+oBld3rD;25:Orzi58rUOfpKBc191olz0etv7eFwTZTWl14PARddgiAilNMRm4DL2jdiHCGMz0+uno3uXvrPC7ubZ2KCJYL4n6zJCFdgosdtNkFd7VTgFD8udpxZcYKgPkOEZAPNJUU7w6a5hfb1C0ECH0t+3caWD6Aq+P0dcNg4939utPFmh+Ri/DSvIvwX4qTEuJkPVkeLdf0b5Qkdhn2Yll4veaRI17wUdb8g3ExPO1kAD5vylHbq5d1y2j7qqPFG3yQa3Azo5/6FBlmoyO/lWk6rovVd5uZHV73KFYBFvXPiIoHoAmi+nNN1JVQxkVc6bdZtNtltKg2CFA6UIlmv6YTb9X0YTQ==;31:mICQ+waKY2qMoJYO7j6l5c1Kkm18i8WEYU3Bo2llUAnDa3uMREh1JFKSx3/AiyyflZCe1Apd0eIPL5YKgt12Jj4lOz+mt/LPMyi+gH37Owmj1HjukqMWn9VmF9aALcGyP05UL2cAj+LZYk+DVux5sPPFGHCnCmOn/hxlbyeuDMeF7eXC43r/NTJklACnPpoF0nCM3p9l1G5h1nXiHG2KfKy2boLZQfFy4yOLiyr14wM= X-MS-TrafficTypeDiagnostic: DB6P191MB0245: X-Microsoft-Exchange-Diagnostics: 1;DB6P191MB0245;20:vjdD/yMFljCBLn4GJ8xZV66YdoyloPqYrittnj5oeuqXmwJNfnUPmNhU6RyTEyXj9vtzVUhXobULaTm1PzEMP+2PCjCAoj7BtXo2qT71uAeEtFPC7uAN+0iG982QYVWm5Dsofa4cDlK3Nded+CVvOeQO/Xnt7unAYuWNn4uZiXCpcfmC4MLuf34ci7FCLpWo+qsZjTHgdOEsI+zDIYhX6G1d548seWukqraDCgciAWivIA4Q6jYrE7QNrvOWkMK7FrGrAFnVvuxkTLnLIn9qu/QuXTiNAwAAjsRk0ZnoWxF46+UFZNKqmRZGPA5A1HBD/YciYRFgergjI7XVxY2ognP8r2+e0UYAnEfwgdH02jB+DFA0bwWQoaJXMxyVaSmUyvFlcz44XNN27O+Ak4l0G2J2FqMsiXXuSbKYWeIG2hj+psphhvFpSfHDux/aP0iUy2EdEfqNfID5tbyKerWgCbGHZcVgmDkL6kJ0z2qx8YhEEnklwHEFRf49RZ2cgkCZ;4:rOqH8b6L1CuinwyRb4Ajn+AV9Io3ikyz0dvKBZCfmXvCiUyLfwyOFmELL2VfICTDk5y55kbb78OVSDGvPxRqU6vsaAiDHh86N+hqGdcWJnRqiHxj6iOgI/G0KdP2Gb/ZvJcNIwIWPZU4PbOq1uT4fkUf7RF9N8vX4nPctCrVgVGHA0rI3PjYJubD65hFGXTtaTVYG1sgrGtB0jDF8FADJQSiJSCxGW5G3vkzIb7GTlSeMP2yMeYi6O93JOXkT8I1QpzBmwDzl5IK0/ukZEBj7Q== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-MS-Exchange-SenderADCheck: 1 X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040522)(2401047)(5005006)(8121501046)(93006095)(93001095)(3002001)(3231355)(944501410)(52105095)(10201501046)(149027)(150027)(6041310)(20161123560045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123562045)(20161123558120)(20161123564045)(201708071742011)(7699051);SRVR:DB6P191MB0245;BCL:0;PCL:0;RULEID:;SRVR:DB6P191MB0245; X-Forefront-PRVS: 0800C0C167 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(39840400004)(366004)(396003)(136003)(376002)(346002)(189003)(199004)(316002)(16586007)(53936002)(25786009)(5660300001)(2351001)(76176011)(81166006)(50466002)(52116002)(51416003)(2906002)(36756003)(6916009)(6116002)(3846002)(14444005)(48376002)(8936002)(386003)(478600001)(81156014)(6506007)(66066001)(97736004)(486006)(107886003)(2361001)(105586002)(106356001)(6666003)(6486002)(7736002)(6512007)(4326008)(47776003)(50226002)(956004)(16526019)(11346002)(476003)(186003)(2616005)(26005)(44832011)(446003)(68736007)(305945005)(8676002)(16060500001);DIR:OUT;SFP:1101;SCL:1;SRVR:DB6P191MB0245;H:Seraj-pc.hh.imgtec.org;FPR:;SPF:None;LANG:en;PTR:InfoNoRecords;MX:1;A:1; Received-SPF: None (protection.outlook.com: sondrel.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: 1;DB6P191MB0245;23:H6Vzh5gBZrxK9VjJdGDlzACDODoJNwFs58dGgif9GOZOHcfLRbLcxFqWXQb9r2e8toDANPy8cFIOlCJ9R4LgHDQI0dJuopt4JbW5axzecT7O4Ym65ru/rbUX+7zo6wQ57m5pBqyqKeD9B+2Bi+Vc/SKWYCuy3cxW2TLdJXa9JB+b54kh+hu8lEilI5c0hGxbX2oKs2DAt3XoyVxtZPhkE8pIKAOnverOE/GAhzvS6oQcRY45lRmMsEKyUrKAkTR47UsAbw3u1icLuU8mfm19Bd0EPiPguG7GZhIrmXvv0LkYZTC6z158s+wgj0ZsyRzrxlMhO9PKbuFO3nN2TINxSXhhpN9Y0q1LUUT0wi15VvQp7rlzBc94t44Z/DYm6Q0M/fvs4CIOT7JJ49gO2MTAygUBxdyBf9tLFQUoNsgeIvJ3iRbF6DLnIr7sp0q+wRpA9g6m19hmsucdWNZCwyYuni0rLGpDnBxdfQYRNfZhIN6871o+2OVNqKUG2gcUZ2J0rC1m+Lioewa6p5Cq/bgrfQ33CwJZ2N3fnzoilQiAMmHCd8rLec4IB063YDixq/yTtvYXlef98Ji6UiyVxVcTAaj2V6TBQgYSQQTkihi8zZbulxTrOr9KerSkWiXvuFDTT5lEQOsAhim5UWkLcx1nI2WLaAdow01cqpz0DxmFBcBXhGEbCyh6XvOwmAd3TUpCWewYNU8DjOf5GiL4uwWrGnysa2mhWvSEiVPZOWZOQMclusNVA/r/A4K9iW4Z6nU0MoDozeEV7MmOEBthaNjdCYgQVeh5AZpDq/KRYAkShRIvTLeZB0l4SQNaySxJkh8NtVwgh8W33IX2tRKw5j98wfBNA+7SA70gnMtyUheG05/06ON3wBbXeJwTVm+Q8ZLCrKBZhS5XhbhTb2be1oZm3pM7XlPmK/VMtaNByij4faHyGS/DCri3WORw59ptjsNYOtBPLNB4DsUKT9WAntIz0qNQO7Wo0yZG51xgBomh0TwQ2/42V9UNHYAKi8IHnWnahT0Bv9uAisjEu0oSIQCm8iKXZauje65gNSH2KB3EaCDbASNjIGH9pQwZrenYjJJAeVaYKTa5uhDIGbK6XCZV8GtT5PIjlsJaJ1qdShAeNhnlYMiw3hr3bPhzFHsi1dvrss5mDDsc83EcfsOLFWRQv/oE5r8+/D+Y0a9RhNoQwafInOkHR5/Syqo4m2kwIoWDHxIWOLKNFX/6+COop+RplOPWXbfddsuNLB/9g8lxP47Up+YavSqADsW1NvPgyFTk X-Microsoft-Antispam-Message-Info: fkyfSXRkOMsgTiabXLbpAOZXjC0dvaDU8uXSW4si5hPC9MhS+GjKp6zYYcrYEiFw4jNPuiEBeO9TOaopxSBLk5tOC6SC3F1qFZMewDkgerBRffe3vY0J9NZxfC+GuWuDSWhtHGirEA5v1cBZSlsJu+gex+hapBY3VzjYntXxZTaHpFky0tpl6+inuBYEtV8YMx3ki6Zrp3s/umQT6GnLYFTn6zBOGaS8i6xyvRaWnsgclvQUF9gwmHJYhNy/VQjy7LpdbSg+un7LB9HEIZZaL4mHnWcPyoLX3MQB7KHi57uRcDZuZ6tcg/poCZS7ffEpYq+X6p4P4h8LkQHAJr9bphKIGdv5opO1811cN3Md7fs= X-Microsoft-Exchange-Diagnostics: 1;DB6P191MB0245;6:MIh/kjTu1+s3Mxh7rlVQre7LkYgWqvdP+HsRjR7zL/tkDTjtGec2udJIMvFiQbIskMNvCCTJVGFYFoWgAqNdLvUeLkrRkoeVjMhWmUWN+H1P0caNbjItuoyIjl3SsOUsp+4qxH+8MwSp5ul0PASe8i9xkzz0h1VHIRjBNDPFXaBvgdMy6VsrY2nvho/YFBP2aqrv0eXmW/K5Pq3S5s737B4iu2Lu0jw0bY9B8eEuTPsfrmQ8FGlJe9A3GZLW36SF6fvTCfn6txk4bNI3lXQ8vN/W48fb51O1B4hcqQhvSizy3/T4TKYxO8i5LcoyAwvpvZPKGh8pDvfmfIOQLyjqH8wz6/yewZAwEpFSpfcHnFDQrOJ6QGI7rKNbtXAH+mm0ntXw3ZXTQPJp85LfMHcgbf+ajXMdP3Hqf/+yeSLH8CjG9Y2lTdPaavzyfNq7zdR9C1zuy+eHgO/jCMHG1Nmi1A==;5:Qb24e2LcblAjSk27xO5xQuKDAgNFqCkXl2sPxAzE2YjldCTOt06xKGIDzSVuXXxqOxuNOR4amP7j6Za/ISQBmN3PaqAjD951Azl6JjqEqbOSM1giFzagjV/VycPAqDTMr/6fd7Oqm997byCGxs+w5hQS59rCmgPXVfDDkL+8jwY=;7:7j7xchy9TKJUaP0e0fSUiQeUzXiRdTEaA8EJRAmLFac7HySBDC0N8sUFyE6zIp0mskhIjZcYAgPQOPwFIzogEFoDjksZLdsRMEAbZTSr+FzZ3gwtTHCKlG4oK8l4ZQLEMYUZthOVQUaGMyY+fd5SVvBpbMxEKjA73++RPi5Lnjxc9mFMZI+Qkn8Cn9oHb+J4jixFWwrOVsowyL6rUvAnz6xy6Xgc09cIQMCv1H+/z9YeJ3+I4Of65DzwiKWzUQ15 SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: sondrel.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 19 Sep 2018 19:53:19.5386 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 54ae4447-cac3-4644-05ef-08d61e698c8a X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 4faa3872-698e-4896-80ec-148b916cb1ba X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB6P191MB0245 Sender: dmaengine-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add support for running tests on multiple channels simultaneously as the driver currently limits to 1 channel per test run. This will add support for stress testing DMA controllers with multi channel capabilities. This is done by adding a callback function to the "channel" parameter that registers the requested channel prior to the "run" parameter being set to 1. Each time the "channel" parameter is populated with a new dma channel, a new test is appended to the thread queue. Once the "run" parameter is set to 1, the test will kick start all pending threads. Signed-off-by: Seraj Alijan --- drivers/dma/dmatest.c | 196 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 177 insertions(+), 19 deletions(-) diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c index aa1712b..ea69033 100644 --- a/drivers/dma/dmatest.c +++ b/drivers/dma/dmatest.c @@ -27,11 +27,6 @@ static unsigned int test_buf_size = 16384; module_param(test_buf_size, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(test_buf_size, "Size of the memcpy test buffer"); -static char test_channel[20]; -module_param_string(channel, test_channel, sizeof(test_channel), - S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(channel, "Bus ID of the channel to test (default: any)"); - static char test_device[32]; module_param_string(device, test_device, sizeof(test_device), S_IRUGO | S_IWUSR); @@ -139,6 +134,28 @@ static bool dmatest_run; module_param_cb(run, &run_ops, &dmatest_run, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(run, "Run the test (default: false)"); +static int dmatest_chan_set(const char *val, const struct kernel_param *kp); +static int dmatest_chan_get(char *val, const struct kernel_param *kp); +static const struct kernel_param_ops multi_chan_ops = { + .set = dmatest_chan_set, + .get = dmatest_chan_get, +}; + +static char test_channel[20]; +static struct kparam_string newchan_kps = { + .string = test_channel, + .maxlen = 20, +}; +module_param_cb(channel, &multi_chan_ops, &newchan_kps, 0644); +MODULE_PARM_DESC(channel, "Bus ID of the channel to test (default: any)"); + +static int dmatest_test_list_get(char *val, const struct kernel_param *kp); +static const struct kernel_param_ops test_list_ops = { + .get = dmatest_test_list_get, +}; +module_param_cb(test_list, &test_list_ops, NULL, 0444); +MODULE_PARM_DESC(test_list, "Print current test list"); + /* Maximum amount of mismatched bytes in buffer to print */ #define MAX_ERROR_COUNT 32 @@ -179,6 +196,7 @@ struct dmatest_thread { wait_queue_head_t done_wait; struct dmatest_done test_done; bool done; + bool pending; }; struct dmatest_chan { @@ -206,6 +224,22 @@ static bool is_threaded_test_run(struct dmatest_info *info) return false; } +static bool is_threaded_test_pending(struct dmatest_info *info) +{ + struct dmatest_chan *dtc; + + list_for_each_entry(dtc, &info->channels, node) { + struct dmatest_thread *thread; + + list_for_each_entry(thread, &dtc->threads, node) { + if (thread->pending) + return true; + } + } + + return false; +} + static int dmatest_wait_get(char *val, const struct kernel_param *kp) { struct dmatest_info *info = &test_info; @@ -476,6 +510,7 @@ static int dmatest_func(void *data) ret = -ENOMEM; smp_rmb(); + thread->pending = false; info = thread->info; params = &info->params; chan = thread->chan; @@ -886,7 +921,7 @@ static int dmatest_add_threads(struct dmatest_info *info, /* srcbuf and dstbuf are allocated by the thread itself */ get_task_struct(thread->task); list_add_tail(&thread->node, &dtc->threads); - wake_up_process(thread->task); + thread->pending = true; } return i; @@ -932,7 +967,7 @@ static int dmatest_add_channel(struct dmatest_info *info, thread_count += cnt > 0 ? cnt : 0; } - pr_info("Started %u threads using %s\n", + pr_info("Added %u threads using %s\n", thread_count, dma_chan_name(chan)); list_add_tail(&dtc->node, &info->channels); @@ -977,7 +1012,7 @@ static void request_channels(struct dmatest_info *info, } } -static void run_threaded_test(struct dmatest_info *info) +static void add_threaded_test(struct dmatest_info *info) { struct dmatest_params *params = &info->params; @@ -1000,6 +1035,24 @@ static void run_threaded_test(struct dmatest_info *info) request_channels(info, DMA_PQ); } +static void run_pending_tests(struct dmatest_info *info) +{ + struct dmatest_chan *dtc; + unsigned int thread_count = 0; + + list_for_each_entry(dtc, &info->channels, node) { + struct dmatest_thread *thread; + + thread_count = 0; + list_for_each_entry(thread, &dtc->threads, node) { + wake_up_process(thread->task); + thread_count++; + } + pr_info("Started %u threads using %s\n", + thread_count, dma_chan_name(dtc->chan)); + } +} + static void stop_threaded_test(struct dmatest_info *info) { struct dmatest_chan *dtc, *_dtc; @@ -1016,7 +1069,7 @@ static void stop_threaded_test(struct dmatest_info *info) info->nr_channels = 0; } -static void restart_threaded_test(struct dmatest_info *info, bool run) +static void start_threaded_tests(struct dmatest_info *info) { /* we might be called early to set run=, defer running until all * parameters have been evaluated @@ -1024,11 +1077,7 @@ static void restart_threaded_test(struct dmatest_info *info, bool run) if (!info->did_init) return; - /* Stop any running test first */ - stop_threaded_test(info); - - /* Run test with new parameters */ - run_threaded_test(info); + run_pending_tests(info); } static int dmatest_run_get(char *val, const struct kernel_param *kp) @@ -1039,7 +1088,8 @@ static int dmatest_run_get(char *val, const struct kernel_param *kp) if (is_threaded_test_run(info)) { dmatest_run = true; } else { - stop_threaded_test(info); + if (!is_threaded_test_pending(info)) + stop_threaded_test(info); dmatest_run = false; } mutex_unlock(&info->lock); @@ -1057,18 +1107,125 @@ static int dmatest_run_set(const char *val, const struct kernel_param *kp) if (ret) { mutex_unlock(&info->lock); return ret; + } else if (dmatest_run) { + if (is_threaded_test_pending(info)) + start_threaded_tests(info); + else + pr_info("Could not start test, no channels configured\n"); + } else { + stop_threaded_test(info); + } + + mutex_unlock(&info->lock); + + return ret; +} + +static int dmatest_chan_set(const char *val, const struct kernel_param *kp) +{ + struct dmatest_info *info = &test_info; + struct dmatest_chan *dtc; + char chan_reset_val[20]; + int ret = 0; + + mutex_lock(&info->lock); + ret = param_set_copystring(val, kp); + if (ret) { + mutex_unlock(&info->lock); + return ret; + } + /*Clear any previously run threads */ + if (!is_threaded_test_run(info) && !is_threaded_test_pending(info)) + stop_threaded_test(info); + /* Reject channels that are already registered */ + if (is_threaded_test_pending(info)) { + list_for_each_entry(dtc, &info->channels, node) { + if (strcmp(dma_chan_name(dtc->chan), + strim(test_channel)) == 0) { + dtc = list_last_entry(&info->channels, + struct dmatest_chan, + node); + strlcpy(chan_reset_val, + dma_chan_name(dtc->chan), + sizeof(chan_reset_val)); + ret = -EBUSY; + goto add_chan_err; + } + } } - if (is_threaded_test_run(info)) + add_threaded_test(info); + + /* Check if channel was added successfully */ + dtc = list_last_entry(&info->channels, struct dmatest_chan, node); + + if (dtc->chan) { + /* + * if new channel was not successfully added, revert the the + * "test_channel" string to the name of the last successfully + * added channel. exception for when users issues empty string + * to channel parameter. + */ + if ((strcmp(dma_chan_name(dtc->chan), strim(test_channel)) != 0) + && (strcmp("", strim(test_channel)) != 0)) { + ret = -EINVAL; + strlcpy(chan_reset_val, dma_chan_name(dtc->chan), + sizeof(chan_reset_val)); + goto add_chan_err; + } + + } else { + /* Clear test_channel if no channels were added successfully */ + strlcpy(chan_reset_val, "", sizeof(chan_reset_val)); ret = -EBUSY; - else if (dmatest_run) - restart_threaded_test(info, dmatest_run); + goto add_chan_err; + } + + mutex_unlock(&info->lock); + + return ret; +add_chan_err: + param_set_copystring(chan_reset_val, kp); mutex_unlock(&info->lock); return ret; } +static int dmatest_chan_get(char *val, const struct kernel_param *kp) +{ + struct dmatest_info *info = &test_info; + + mutex_lock(&info->lock); + if (!is_threaded_test_run(info) && !is_threaded_test_pending(info)) { + stop_threaded_test(info); + strlcpy(test_channel, "", sizeof(test_channel)); + } + mutex_unlock(&info->lock); + + return param_get_string(val, kp); +} + +static int dmatest_test_list_get(char *val, const struct kernel_param *kp) +{ + struct dmatest_info *info = &test_info; + struct dmatest_chan *dtc; + unsigned int thread_count = 0; + + list_for_each_entry(dtc, &info->channels, node) { + struct dmatest_thread *thread; + + thread_count = 0; + list_for_each_entry(thread, &dtc->threads, node) { + thread_count++; + } + pr_info("%u threads using %s\n", + thread_count, dma_chan_name(dtc->chan)); + } + + return 0; +} + static int __init dmatest_init(void) { struct dmatest_info *info = &test_info; @@ -1076,7 +1233,8 @@ static int __init dmatest_init(void) if (dmatest_run) { mutex_lock(&info->lock); - run_threaded_test(info); + add_threaded_test(info); + run_pending_tests(info); mutex_unlock(&info->lock); }