Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (C) 2014 Google, Inc.
0004  */
0005 
0006 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0007 
0008 #include <linux/delay.h>
0009 #include <linux/init.h>
0010 #include <linux/hrtimer.h>
0011 #include <linux/module.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/time.h>
0014 #include <linux/numa.h>
0015 #include <linux/nodemask.h>
0016 #include <linux/topology.h>
0017 
0018 #define TEST_PROBE_DELAY    (5 * 1000)  /* 5 sec */
0019 #define TEST_PROBE_THRESHOLD    (TEST_PROBE_DELAY / 2)
0020 
0021 static atomic_t warnings, errors, timeout, async_completed;
0022 
0023 static int test_probe(struct platform_device *pdev)
0024 {
0025     struct device *dev = &pdev->dev;
0026 
0027     /*
0028      * Determine if we have hit the "timeout" limit for the test if we
0029      * have then report it as an error, otherwise we wil sleep for the
0030      * required amount of time and then report completion.
0031      */
0032     if (atomic_read(&timeout)) {
0033         dev_err(dev, "async probe took too long\n");
0034         atomic_inc(&errors);
0035     } else {
0036         dev_dbg(&pdev->dev, "sleeping for %d msecs in probe\n",
0037              TEST_PROBE_DELAY);
0038         msleep(TEST_PROBE_DELAY);
0039         dev_dbg(&pdev->dev, "done sleeping\n");
0040     }
0041 
0042     /*
0043      * Report NUMA mismatch if device node is set and we are not
0044      * performing an async init on that node.
0045      */
0046     if (dev->driver->probe_type == PROBE_PREFER_ASYNCHRONOUS) {
0047         if (IS_ENABLED(CONFIG_NUMA) &&
0048             dev_to_node(dev) != numa_node_id()) {
0049             dev_warn(dev, "NUMA node mismatch %d != %d\n",
0050                  dev_to_node(dev), numa_node_id());
0051             atomic_inc(&warnings);
0052         }
0053 
0054         atomic_inc(&async_completed);
0055     }
0056 
0057     return 0;
0058 }
0059 
0060 static struct platform_driver async_driver = {
0061     .driver = {
0062         .name = "test_async_driver",
0063         .probe_type = PROBE_PREFER_ASYNCHRONOUS,
0064     },
0065     .probe = test_probe,
0066 };
0067 
0068 static struct platform_driver sync_driver = {
0069     .driver = {
0070         .name = "test_sync_driver",
0071         .probe_type = PROBE_FORCE_SYNCHRONOUS,
0072     },
0073     .probe = test_probe,
0074 };
0075 
0076 static struct platform_device *async_dev[NR_CPUS * 2];
0077 static struct platform_device *sync_dev[2];
0078 
0079 static struct platform_device *
0080 test_platform_device_register_node(char *name, int id, int nid)
0081 {
0082     struct platform_device *pdev;
0083     int ret;
0084 
0085     pdev = platform_device_alloc(name, id);
0086     if (!pdev)
0087         return NULL;
0088 
0089     if (nid != NUMA_NO_NODE)
0090         set_dev_node(&pdev->dev, nid);
0091 
0092     ret = platform_device_add(pdev);
0093     if (ret) {
0094         platform_device_put(pdev);
0095         return ERR_PTR(ret);
0096     }
0097 
0098     return pdev;
0099 
0100 }
0101 
0102 static int __init test_async_probe_init(void)
0103 {
0104     struct platform_device **pdev = NULL;
0105     int async_id = 0, sync_id = 0;
0106     unsigned long long duration;
0107     ktime_t calltime;
0108     int err, nid, cpu;
0109 
0110     pr_info("registering first set of asynchronous devices...\n");
0111 
0112     for_each_online_cpu(cpu) {
0113         nid = cpu_to_node(cpu);
0114         pdev = &async_dev[async_id];
0115         *pdev = test_platform_device_register_node("test_async_driver",
0116                                async_id,
0117                                nid);
0118         if (IS_ERR(*pdev)) {
0119             err = PTR_ERR(*pdev);
0120             *pdev = NULL;
0121             pr_err("failed to create async_dev: %d\n", err);
0122             goto err_unregister_async_devs;
0123         }
0124 
0125         async_id++;
0126     }
0127 
0128     pr_info("registering asynchronous driver...\n");
0129     calltime = ktime_get();
0130     err = platform_driver_register(&async_driver);
0131     if (err) {
0132         pr_err("Failed to register async_driver: %d\n", err);
0133         goto err_unregister_async_devs;
0134     }
0135 
0136     duration = (unsigned long long)ktime_ms_delta(ktime_get(), calltime);
0137     pr_info("registration took %lld msecs\n", duration);
0138     if (duration > TEST_PROBE_THRESHOLD) {
0139         pr_err("test failed: probe took too long\n");
0140         err = -ETIMEDOUT;
0141         goto err_unregister_async_driver;
0142     }
0143 
0144     pr_info("registering second set of asynchronous devices...\n");
0145     calltime = ktime_get();
0146     for_each_online_cpu(cpu) {
0147         nid = cpu_to_node(cpu);
0148         pdev = &sync_dev[sync_id];
0149 
0150         *pdev = test_platform_device_register_node("test_async_driver",
0151                                async_id,
0152                                nid);
0153         if (IS_ERR(*pdev)) {
0154             err = PTR_ERR(*pdev);
0155             *pdev = NULL;
0156             pr_err("failed to create async_dev: %d\n", err);
0157             goto err_unregister_async_driver;
0158         }
0159 
0160         async_id++;
0161     }
0162 
0163     duration = (unsigned long long)ktime_ms_delta(ktime_get(), calltime);
0164     dev_info(&(*pdev)->dev,
0165          "registration took %lld msecs\n", duration);
0166     if (duration > TEST_PROBE_THRESHOLD) {
0167         dev_err(&(*pdev)->dev,
0168             "test failed: probe took too long\n");
0169         err = -ETIMEDOUT;
0170         goto err_unregister_async_driver;
0171     }
0172 
0173 
0174     pr_info("registering first synchronous device...\n");
0175     nid = cpu_to_node(cpu);
0176     pdev = &sync_dev[sync_id];
0177 
0178     *pdev = test_platform_device_register_node("test_sync_driver",
0179                            sync_id,
0180                            NUMA_NO_NODE);
0181     if (IS_ERR(*pdev)) {
0182         err = PTR_ERR(*pdev);
0183         *pdev = NULL;
0184         pr_err("failed to create sync_dev: %d\n", err);
0185         goto err_unregister_async_driver;
0186     }
0187 
0188     sync_id++;
0189 
0190     pr_info("registering synchronous driver...\n");
0191     calltime = ktime_get();
0192     err = platform_driver_register(&sync_driver);
0193     if (err) {
0194         pr_err("Failed to register async_driver: %d\n", err);
0195         goto err_unregister_sync_devs;
0196     }
0197 
0198     duration = (unsigned long long)ktime_ms_delta(ktime_get(), calltime);
0199     pr_info("registration took %lld msecs\n", duration);
0200     if (duration < TEST_PROBE_THRESHOLD) {
0201         dev_err(&(*pdev)->dev,
0202             "test failed: probe was too quick\n");
0203         err = -ETIMEDOUT;
0204         goto err_unregister_sync_driver;
0205     }
0206 
0207     pr_info("registering second synchronous device...\n");
0208     pdev = &sync_dev[sync_id];
0209     calltime = ktime_get();
0210 
0211     *pdev = test_platform_device_register_node("test_sync_driver",
0212                            sync_id,
0213                            NUMA_NO_NODE);
0214     if (IS_ERR(*pdev)) {
0215         err = PTR_ERR(*pdev);
0216         *pdev = NULL;
0217         pr_err("failed to create sync_dev: %d\n", err);
0218         goto err_unregister_sync_driver;
0219     }
0220 
0221     sync_id++;
0222 
0223     duration = (unsigned long long)ktime_ms_delta(ktime_get(), calltime);
0224     dev_info(&(*pdev)->dev,
0225          "registration took %lld msecs\n", duration);
0226     if (duration < TEST_PROBE_THRESHOLD) {
0227         dev_err(&(*pdev)->dev,
0228             "test failed: probe was too quick\n");
0229         err = -ETIMEDOUT;
0230         goto err_unregister_sync_driver;
0231     }
0232 
0233     /*
0234      * The async events should have completed while we were taking care
0235      * of the synchronous events. We will now terminate any outstanding
0236      * asynchronous probe calls remaining by forcing timeout and remove
0237      * the driver before we return which should force the flush of the
0238      * pending asynchronous probe calls.
0239      *
0240      * Otherwise if they completed without errors or warnings then
0241      * report successful completion.
0242      */
0243     if (atomic_read(&async_completed) != async_id) {
0244         pr_err("async events still pending, forcing timeout\n");
0245         atomic_inc(&timeout);
0246         err = -ETIMEDOUT;
0247     } else if (!atomic_read(&errors) && !atomic_read(&warnings)) {
0248         pr_info("completed successfully\n");
0249         return 0;
0250     }
0251 
0252 err_unregister_sync_driver:
0253     platform_driver_unregister(&sync_driver);
0254 err_unregister_sync_devs:
0255     while (sync_id--)
0256         platform_device_unregister(sync_dev[sync_id]);
0257 err_unregister_async_driver:
0258     platform_driver_unregister(&async_driver);
0259 err_unregister_async_devs:
0260     while (async_id--)
0261         platform_device_unregister(async_dev[async_id]);
0262 
0263     /*
0264      * If err is already set then count that as an additional error for
0265      * the test. Otherwise we will report an invalid argument error and
0266      * not count that as we should have reached here as a result of
0267      * errors or warnings being reported by the probe routine.
0268      */
0269     if (err)
0270         atomic_inc(&errors);
0271     else
0272         err = -EINVAL;
0273 
0274     pr_err("Test failed with %d errors and %d warnings\n",
0275            atomic_read(&errors), atomic_read(&warnings));
0276 
0277     return err;
0278 }
0279 module_init(test_async_probe_init);
0280 
0281 static void __exit test_async_probe_exit(void)
0282 {
0283     int id = 2;
0284 
0285     platform_driver_unregister(&async_driver);
0286     platform_driver_unregister(&sync_driver);
0287 
0288     while (id--)
0289         platform_device_unregister(sync_dev[id]);
0290 
0291     id = NR_CPUS * 2;
0292     while (id--)
0293         platform_device_unregister(async_dev[id]);
0294 }
0295 module_exit(test_async_probe_exit);
0296 
0297 MODULE_DESCRIPTION("Test module for asynchronous driver probing");
0298 MODULE_AUTHOR("Dmitry Torokhov <dtor@chromium.org>");
0299 MODULE_LICENSE("GPL");