From patchwork Tue Jan 17 16:28:37 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergei Trofimov X-Patchwork-Id: 91691 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp574302qgi; Tue, 17 Jan 2017 08:29:40 -0800 (PST) X-Received: by 10.237.37.50 with SMTP id v47mr32914497qtc.126.1484670580692; Tue, 17 Jan 2017 08:29:40 -0800 (PST) Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id j22si16937564qtj.123.2017.01.17.08.29.40; Tue, 17 Jan 2017 08:29:40 -0800 (PST) Received-SPF: pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id 47D3A60ED5; Tue, 17 Jan 2017 16:29:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAD_ENC_HEADER,BAYES_00, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id 48B5060951; Tue, 17 Jan 2017 16:29:02 +0000 (UTC) X-Original-To: lng-odp@lists.linaro.org Delivered-To: lng-odp@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id A844660955; Tue, 17 Jan 2017 16:28:54 +0000 (UTC) Received: from EUR01-HE1-obe.outbound.protection.outlook.com (mail-he1eur01on0069.outbound.protection.outlook.com [104.47.0.69]) by lists.linaro.org (Postfix) with ESMTPS id 27FAA60641 for ; Tue, 17 Jan 2017 16:28:52 +0000 (UTC) Received: from e109786-lin.cambridge.arm.com (217.140.96.140) by AM5PR0801MB1746.eurprd08.prod.outlook.com (10.169.247.12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.845.12; Tue, 17 Jan 2017 16:28:50 +0000 From: Sergei Trofimov To: Date: Tue, 17 Jan 2017 16:28:37 +0000 Message-ID: <1484670521-28503-2-git-send-email-sergei.trofimov@arm.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1484670521-28503-1-git-send-email-sergei.trofimov@arm.com> References: <1484670521-28503-1-git-send-email-sergei.trofimov@arm.com> MIME-Version: 1.0 X-Originating-IP: [217.140.96.140] X-ClientProxiedBy: DB6PR0301CA0004.eurprd03.prod.outlook.com (10.168.49.14) To AM5PR0801MB1746.eurprd08.prod.outlook.com (10.169.247.12) X-MS-Office365-Filtering-Correlation-Id: d55d6023-8017-4925-381f-08d43ef5eb99 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001); SRVR:AM5PR0801MB1746; X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1746; 3:nong69LN6LRYpHroVskbSO3YbhoMc9irO6IoTe0u3WZgPnB87pwZqCtc36a4O2GbXtrmJWnMVN4Zs/JJ2yhJIh/zlsSXBP7dljk12/eqNk9GPvls0lrino+n7TW4JEA4tVYTNYv3ectr7MZM6fnqiW6NCKw6b+h9VMjQwMMndk+AyikQIp/RIr/Pq4K9DEqWuTshmL6unZkldDXMjy7Hbwfdt6gfL4amULIA7M5j4QGXpkPaHPrFNWyZzj0sbp0IBD47uSiwjSCVJaL2Kat8sA== X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1746; 25:oFF4VsODg9VHh3Q+fe6IKYRLcBzQR4HzOx/ed3Z/QnoZKrbuUE4F9vmL+mQxhYdv2QXHQfvq+n3obDDx0IYMuTL8qOqLHMCn8LlFXrYOvsCFN6swzPynqjJtbJrtYU+oYRi4U3d/be30sFeLp4y8St5nL12IgY1zurwlqa2R2WIm9uM2usdEXFUFZ5xTDC3k9g4N/wNX28F2wT9pJkYNEIPFubOynDukg4XnVIsYyFNjQ03pZ/PmUlgYzvplfb1sR+3eMn9cWstz/icevj+N+TvvOtpDoJ6tQX1vECHA19UiZiVaOwRF96sZTsPhqp6nGQeJ/dSO71FymxKVA4WqTn/sHlnFBv7I0wQvtRoqUeHayShsjgV0gDFyL9agwCLLzXnk4AnbYsGV1tn4+x1c/UxN+5QlqL1Wweiq0k0oHoeXaHxvpWJyYT1U6Xyzt6u1VL8odh724Q+irlkYiZPuSCQDFTy3K7VfSaJQpKfl1JDbnlKUhyZRIAu2c2zu+102LKyVmeQoEOQC/6rBaIeHTh6hxgbNKpdnkKY7J99RdrTuL8mKzES5u3VtJ462MyLHXtbtzHTtfWUhWoAgmwiPzfM3VfFaIAsbthhA5BMZRCj3kHFzWU6DS5nU4XWumL5GoeDG63Kq+mx5a6uWL+gjsn3yEK8JbEraInO1FV2D2ZXyTBKpUk1FnxQDdDIuFQogdOQF5BloouziKRxXvisYU0+gYDWtfleTAkKbN5Wc7WDcTbm1qWapAURUkzOgbXY45QrcNDefveK/B/EoPp9SLw== X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1746; 31:TJLP7Slgv0shUs5EjriiIwvDkT2cnnO2n9GbIWf3k29CrlrVvVUjf1XNrN7PIKWXj/H7KKXyFrfmerRH7Zv8k6bKBZJBHtZDjr71wvn3DYkpWbBUZhAP5MdX0tz7x1GVYKZrcufOPCLxmBpYR3YGwAT5g84BixCTzoDQbh1b22x1ydBCTp9TAIngfuHEeaG6dahzEDU4o8HORB02RFjBbynbnACGdjYSG2xFMJJ/hMUc4x7SjMAYguEO2kCHDvDEQmxGnBX7JMmL8cndbNGFGQ==; 20:NFMYPsutTzPnnvYHXKI7mq9WG0YemGSBaDCEBMgeTNOUPCjeNnmKG/VraDzjQjdLYJZ9aJaicy6txcTZLE+N+XS1nJBiKudnAvE/Kn0aJQDYIDD+UZvVyTr45HrTJyI1Z027WeU6rHBoSf1OqBYlcR4Bewjfg9S7/aCYpXk+WrY= NoDisclaimer: True X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(180628864354917); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040375)(601004)(2401047)(5005006)(8121501046)(10201501046)(3002001)(6055026)(6041248)(20161123555025)(20161123560025)(20161123564025)(20161123562025)(6072148); SRVR:AM5PR0801MB1746; BCL:0; PCL:0; RULEID:; SRVR:AM5PR0801MB1746; X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1746; 4:W6+Y7mqA1pWFPFI54QSkYSWrOIMK2sixjqjOjJVtnRTLHTybVpHkJGbVWoZV0RVl2H6pKFx+T3SpBB9YiIN+jQmUo7PYecgKxG0muv5mln4msEvqRMh3b9gRsXnpaIATROGRTJUOgXVk0PNHCFoSq3ldImJNmM3CIx5gnBSluvK6v+T0zz46YZHVDpjnOdJXJcUA0LsTS3UVuvXiPycAcXQOOT1yRc9yLFRsZoPwTTTQnOQkRllwrBakcH2/jEe5Rf+3PP7GK+gGaXKL/jisQ5OTMTvYPxryhUbjKcXjdued3D6E51ckZ7ZRh1igDuyLuMfZ2afb6pxG6dzal7izF+Nj7K6MQWLD4v0VrodIR4Y+X9dZegpMcgp5SJYk0j4m+4C16q3CL9R4p3uL1jmUapI503F/U+rmEQQ+nk4a1yUC/ytg5mWUHCiXhPdeBBRyUV6ZYXqs06a4x7Z9MN634pNAnJXMaMWq1waqPI4LPn547olsZJGgO+jXnWiF2B/8Ji3qoJcuaN3D1fquNNynXlLKec+xDSQl46YD1cmUF8STfq4doAa+8C/Npvkh1i3adXY8P7slXVLbxZxonEBCZr0gUQUvdCKoXcO+zzWSNPVLJUBR4JyF0Z0D+jv/S7+uiyJlZS6Mr2HVadzOIAycuQ== X-Forefront-PRVS: 01901B3451 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6009001)(7916002)(39450400003)(39840400002)(39410400002)(39860400002)(39850400002)(199003)(189002)(6666003)(81166006)(8676002)(50226002)(81156014)(305945005)(450100001)(7736002)(38730400001)(2950100002)(6116002)(97736004)(92566002)(6916009)(47776003)(2906002)(3846002)(54906002)(33646002)(66066001)(48376002)(50466002)(50986999)(189998001)(4326007)(76176999)(25786008)(36756003)(6486002)(110136003)(106356001)(105586002)(5660300001)(101416001)(68736007)(42186005)(2351001)(86362001)(5003940100001)(217873001); DIR:OUT; SFP:1101; SCL:1; SRVR:AM5PR0801MB1746; H:e109786-lin.cambridge.arm.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: arm.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; AM5PR0801MB1746; 23:+8gaI3cUiXL9PmpXVSR5yQBwFSE1QaiYKkqvtJ9?= IMmxp66N2tnpoCis4QdrnRRFizmTFE5LUI3o1OSFJmKGEfTdWsAO+jz05aryj8oIc6MqhO6veWoDbebLdpjwAnA/cJZZUdYbVpAvUTgHmMAnB00nXIWtoGc9lherZl86x+2doV3AUXux6Z8iCCf9WrNFoIUhU+l4dnjvztqppxd7zjV9jKynJ44T0HrGOHXqbnoTUQ5B0Fgx9uM3q4LBATmfYC8ZLMZkrJbV2RT7TAeHsbDFxJpEYyDaZHOJjEb4xAZZXNQJMW5H3rAt+6emVzjRctIvQSyWTswhJIrlYk9ddQYLPCVtPrnHvy7l2Dp0YGlSF9ifByNKvTdeBRCqMlQMB2AS1r4bwY57MyrdsMGj/aIsR3YXG+7Fi/D2kOdj3SsfVUnYwhNYjj1nAuX9QwsBMLI+wFhM7CS9jsbq3F5vjAi6lX6mxV0pCeWM9KkyT7xl03JVjo8ta+nUnzprNhSUdeHh0MWJqtonXZZnPkRPTmYKjscKOlsVEe/7W54IpKq6udCV5TPKz1oxNusB0q2f21klJY8zcSk/lltQwXM9rt9EQhlJevpe/ejLEHdvGyTPe/j76jKf5PE8VN8KJlxSEFkEs8RE7kx1q9TrgR6UPh3Q5Qikdxd5PHuovk6eNt07muNmFA+PemL8dY17FodAqOi9vxeo0w4zULUU7RLJUBfBmxLAwsdV1z3bsF76s5wcpmh+J0dQgvXRkNU02937T0/DVyh1PGxYbikJ+Am5D0S8+RaaLp6j7z2bT215FTxN/+0rINSsFqIStu8NOr7sV90vMzJ8lRnrA6psP0GaPlLvkS9fZt3b2x3Gaem8nAcV3QxCqkSu7KxgUhO7Lfz42Uwf2bvwCcXmOMjVRf6LVuF43YsvdP7lPgejEZMYwtOLBTXDXomhinc6vHWxQ4utyBACmVfTO9yYSErwOWy9RYPhab75zlSPBxfYK4njYUXjHO6rjWboXS+sAFPvhMl1mLluRtp/tnwOodxN46InYRCGdVj52E2iOeDHaTn3xLOMNjpiA5Su3ilhRuqqKUXX2amw4gX0ktYFuiZdXii97WkbBMv1VuMrWlaBIeH4kbZKVmGylGqSVNROY4/Rz5r3iM6sdjMTiyhMHbvATqGs5K44NLygFRQ638Pp4bk9sUFs2S0ajcJrreTpcAb7Noud+3nWsol/+H5XFR8Lw+sExew== X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1746; 6:seLHcTQQOqzpUS63a4os4URQq1AVsTlrIo8R7dCM9CH0ipM/TR7J2QPw8l1uaAcB3WZzbHO2wnxlgHiLmOG8Tz5lDYm0Dx6x9YDaOPEQU4LwniSn9aFg0zr8HNvpDvplWHHO6Fa0M7Mb+QET73JyGLNnLS1ZbkiFExESbds0w6vs2dv3aNzMu3W5kYxMTRfeBjzErZ5DPTgYpS9l2LqXHedJs89h5x+sNLxuZn6TcnBkIycwvpYZA4H3mhXOsfv0IEOO/HcXwX+/AF91Rmsn4/lynK8dTyFy53muA+c/uygtyMuj7GG3t3QClg3ivvq5wnLlz4LFl5cda4zSKUS5tCmN+qUt7q0tbpj6e7JBUbKepZC8NODDb9fhMgP+PnYmXmir44m35TIDNJq+vz+GJFXtvzskebbbrASMPQzhjz3sSI+HxkJZ3BMhZpBef1rM/HN+nOh3AnDGHprKotDZSg==; 5:ucnO6wvuRDL9ZKGSeNuapWdVi45Wi5eUAtVbjnkWvVzGCV6arXYSdkP7D6PsxuDzbQCM0iGtALq2sbhedD2NxxllV+ckCjZ9ICX1a2VkgRbNKatRxRDY6Dm5Zw/4wL7+kj7gxCCrrP4MHaW+hRnjMg==; 24:QyP6FNJPscZDuc46d2CY03VHmgxsYzpd67+7ZHUBsBjUuuhfwl76syGLd+im2Jkp/xWGIRLWW6c0lc8eEfHgy9WiSwb88Q7rQ3wviBBSRyk= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1746; 7:M0O3JaSA6HAfwVfNBvxeTpYN3XLdF2k9urlrum32mBuLoymrVwxypUWmlbvqf6X6/ffsBqd5uUl41GQQtbW5Tt/qmxu1HfyhWvXjNzjqGSxZ+n8ssr4X+DQ4mqDuZjPIj2MXgNapNdYg9jtisLhWiqxRRe/AMmaAEXBhBWeYX2Ofvc+UYwRlA042X9/M/TF10MZ4f94bvs5gUuNubLR31n2C40BxNpTXfuS+He96gxrckpI7drwYLFESNOBIOix6tF5rk59WNUajdRGcF9Lva4Mxix4lzAFKlW+mfTQefAZzrdvKqwNYnfj+hlzdPecsNk+ddMW0fPaqnj1GipOvqU0j382BP/wDWcx04NsokehNOVw3gJ3LSpgewLESD8H7ttWAX3VNAd/tT3AI7zdNTqQHmqXLuPbyXUEEShRkdp4JcQMsHQFllSpYYzjhmUlAmfJT5jhlB1u/XAajwD8xmw== X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Jan 2017 16:28:50.4157 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM5PR0801MB1746 Cc: nd@arm.com Subject: [lng-odp] [API-NEXT PATCH 1/5] power: added API for managing CPU DVFS X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "The OpenDataPlane \(ODP\) List" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: lng-odp-bounces@lists.linaro.org Sender: "lng-odp" Added APIs for quiering available CPU power/frequency domains and setting their frequencies. Current implementation assumes that Linux is using userspace cpufreq governor. Signed-off-by: Sergei Trofimov --- include/odp/api/spec/power.h | 116 ++++++++++ include/odp_api.h | 1 + platform/Makefile.inc | 1 + platform/linux-generic/Makefile.am | 2 + platform/linux-generic/include/odp/api/power.h | 1 + platform/linux-generic/odp_power.c | 294 +++++++++++++++++++++++++ 6 files changed, 415 insertions(+) create mode 100644 include/odp/api/spec/power.h create mode 100644 platform/linux-generic/include/odp/api/power.h create mode 100644 platform/linux-generic/odp_power.c -- 1.9.1 diff --git a/include/odp/api/spec/power.h b/include/odp/api/spec/power.h new file mode 100644 index 0000000..26dd64e --- /dev/null +++ b/include/odp/api/spec/power.h @@ -0,0 +1,116 @@ +/* Copyright (c) 2016, ARM Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + + +/** + * @file + * + * CPU power management + */ + +#ifndef ODP_POWER_H +#define ODP_POWER_H + +#include +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * CPU power domain description. + * + */ +typedef struct odp_power_domain_s{ + /** Number of possible performance levels in the domain. */ + int num_perf_levels; + /** Valid performance levels for the domain. Higher numeric values + * represent more performance. The units for performance levels are + * platform-specific. */ + int *perf_levels; + /** CPUs in this power domain */ + odp_cpumask_t cpus; +} odp_power_domain_t; + + +/** + * Information about the discovered power domains. + * + */ +typedef struct odp_power_domain_info_s { + /** Number of discovered power domains */ + int num_domains; + /** Discovered power domains */ + odp_power_domain_t *domains; +} odp_power_domain_info_t; + +/** + * Populate power domains info for this platform. + * + * Discover power domains available on the platform and populate the + * domain info object with them. + * + * + * @param info power domains info to be initialized + * + * @return zero on success or negative error value on error + * + */ +int odp_power_domain_info_populate(odp_power_domain_info_t *info); + +/** + * Destroy a previously init'd info struct, releasing associated resources. + * + * + * @param info power domains info to be terminated + * + */ +void odp_power_domain_info_destroy(odp_power_domain_info_t *info); + +/** + * Return the power domain associated with the specified cpu + * + * @param info contains information about power domains + * @param cpu CPU whose power domain will be returned + * + * @return a pointer to the power domain or NULL on error + * + */ +odp_power_domain_t *odp_power_domain_for_cpu(odp_power_domain_info_t *info, int cpu); + +/** + * Set performance level of the specified domain + * + * @param domain domain for which frequency will be set + * @param level the performance level to set + * + * @return zero on success or negative error value on error + * + */ +int odp_power_domain_set_perf_level(odp_power_domain_t *domain, int level); + + +/** + * Return the current performance level of the specified domain + * + * @param domain domain for which performance level will be set + * + * @return performance level + * + */ +uint64_t odp_power_domain_get_perf_level(odp_power_domain_t *domain); + +#ifdef __cplusplus +} +#endif + +#include +#endif // ODP_POWER_H diff --git a/include/odp_api.h b/include/odp_api.h index 73e5309..983e44f 100644 --- a/include/odp_api.h +++ b/include/odp_api.h @@ -58,6 +58,7 @@ extern "C" { #include #include #include +#include #ifdef __cplusplus } diff --git a/platform/Makefile.inc b/platform/Makefile.inc index aefbf9a..8427117 100644 --- a/platform/Makefile.inc +++ b/platform/Makefile.inc @@ -40,6 +40,7 @@ odpapispecinclude_HEADERS = \ $(top_srcdir)/include/odp/api/spec/packet_io.h \ $(top_srcdir)/include/odp/api/spec/packet_io_stats.h \ $(top_srcdir)/include/odp/api/spec/pool.h \ + $(top_srcdir)/include/odp/api/spec/power.h \ $(top_srcdir)/include/odp/api/spec/queue.h \ $(top_srcdir)/include/odp/api/spec/random.h \ $(top_srcdir)/include/odp/api/spec/rwlock.h \ diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 6bbe775..738c582 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -43,6 +43,7 @@ odpapiinclude_HEADERS = \ $(srcdir)/include/odp/api/packet_io.h \ $(srcdir)/include/odp/api/packet_io_stats.h \ $(srcdir)/include/odp/api/pool.h \ + $(srcdir)/include/odp/api/power.h \ $(srcdir)/include/odp/api/queue.h \ $(srcdir)/include/odp/api/random.h \ $(srcdir)/include/odp/api/rwlock.h \ @@ -205,6 +206,7 @@ __LIB__libodp_linux_la_SOURCES = \ pktio/ring.c \ odp_pkt_queue.c \ odp_pool.c \ + odp_power.c \ odp_queue.c \ odp_rwlock.c \ odp_rwlock_recursive.c \ diff --git a/platform/linux-generic/include/odp/api/power.h b/platform/linux-generic/include/odp/api/power.h new file mode 100644 index 0000000..f012bf5 --- /dev/null +++ b/platform/linux-generic/include/odp/api/power.h @@ -0,0 +1 @@ +#include diff --git a/platform/linux-generic/odp_power.c b/platform/linux-generic/odp_power.c new file mode 100644 index 0000000..df41655 --- /dev/null +++ b/platform/linux-generic/odp_power.c @@ -0,0 +1,294 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define MAX_PATH 255 +#define MAX_LINE MAX_PATH +#define MAX_PERF_LEVEL INT_MAX +#define MIN_PERF_LEVEL 0 + +typedef enum { + INT, + /*UINT,*/ + /*DOUBLE,*/ + POINTER +} ll_entry_type_t; + +struct ll_entry_s; +typedef struct ll_entry_s { + struct ll_entry_s *next; + union { + int64_t i64; + uint64_t u64; + double d; + void *p; + } value; + ll_entry_type_t type; +} ll_entry_t; + +typedef struct { + int num; + ll_entry_t *head; + ll_entry_t **ptail; +} llist_t; + +#define DEFINE_LLIST_ADD(NAME, TYPE, VALNAME, TYPE_ENUM) \ + static int llist_add_##NAME(llist_t *list, TYPE val);\ + static int llist_add_##NAME(llist_t *list, TYPE val) {\ + ll_entry_t *new = malloc(sizeof(ll_entry_t));\ + if (new == NULL)\ + return ENOMEM;\ + new->next = NULL;\ + new->type = TYPE_ENUM;\ + new->value.VALNAME = val;\ + *(list->ptail) = new;\ + list->ptail = &(new->next);\ + list->num++;\ + return 0;\ + } + +DEFINE_LLIST_ADD(int,int64_t,i64,INT); +DEFINE_LLIST_ADD(ptr,void *,p,POINTER); +/*DEFINE_LLIST_ADD(uint,uint64_t,u64,UINT);*/ +/*DEFINE_LLIST_ADD(double,double,d,DOUBLE);*/ + +static void llist_init(llist_t *list) { + list->num = 0; + list->head = NULL; + list->ptail = &list->head; +} + +static void llist_fini(llist_t *list) { + ll_entry_t *current, *next; + next = list->head; + while (next != NULL) { + current = next; + next = next->next; + free(current); + } + list->num = 0; +} + +static int read_int_list(char *path, int **list, int *num); +static int int_cmp(const void *val1, const void *val2); +static void get_related_cpus(int cpu_id, int **related_cpus, int *num); +static inline int check_in_array(int *arr, int size, int item); +static void get_available_cpu_frequencies(int cpu_id, int **freqs, int *num); + +int odp_power_domain_info_populate(odp_power_domain_info_t *info) { + int num_cpus = sysconf(_SC_NPROCESSORS_CONF); + + info->num_domains = 0; + + llist_t dom_list; + llist_init(&dom_list); + odp_cpumask_t processed; + odp_cpumask_zero(&processed); + int i; + for(i = 0; i < num_cpus; i++) { + + if (odp_cpumask_isset(&processed, (1ULL << i))) { + continue; + } + + odp_power_domain_t *dom = malloc(sizeof(odp_power_domain_t)); + if (dom == NULL) + goto return_nomem; + odp_cpumask_zero(&dom->cpus); + + int *related; + int num; + get_related_cpus(i, &related, &num); + get_available_cpu_frequencies(i, &(dom->perf_levels), &(dom->num_perf_levels)); + qsort(dom->perf_levels, dom->num_perf_levels, sizeof(int), int_cmp); + + int j; + for (j = 0; j < num; j++) { + + odp_cpumask_set(&dom->cpus, related[j]); + odp_cpumask_set(&processed, related[j]); + } + + llist_add_ptr(&dom_list, (void *)dom); + } + + info->domains = malloc(sizeof(odp_power_domain_t) * dom_list.num); + if (info->domains == NULL) + goto return_nomem; + + ll_entry_t *dom_entry = dom_list.head; + for (i = 0; i < dom_list.num; i++) { + memcpy(&(info->domains[i]), dom_entry->value.p, sizeof(odp_power_domain_t)); + free(dom_entry->value.p); + dom_entry = dom_entry->next; + } + info->num_domains = dom_list.num; + llist_fini(&dom_list); + + return 0; + +return_nomem: + dom_entry = dom_list.head; + for (i = 0; i < dom_list.num; i++) { + free(dom_entry->value.p); + dom_entry = dom_entry->next; + } + llist_fini(&dom_list); + return -ENOMEM; +} + +void odp_power_domain_info_destroy(odp_power_domain_info_t *info) +{ + int i; + for (i = 0; i < info->num_domains; i++) { + free(info->domains[i].perf_levels); + } + free(info->domains); +} + +odp_power_domain_t *odp_power_domain_for_cpu(odp_power_domain_info_t *info, int cpu) { + int i; + for (i = 0; i < info->num_domains; i++) { + odp_power_domain_t *dom = &info->domains[i]; + if (odp_cpumask_isset(&dom->cpus, cpu)) + return dom; + } + + return NULL; +} + +int odp_power_domain_set_perf_level(odp_power_domain_t *domain, int level) { + if (level == MAX_PERF_LEVEL) { + level = domain->perf_levels[domain->num_perf_levels - 1]; + } + if (level == MIN_PERF_LEVEL) { + level = domain->perf_levels[0]; + } + if (!check_in_array(domain->perf_levels, domain->num_perf_levels, level)) { + return -EINVAL; + } + + // Note: this assumes that the current governor is userspace + char path[MAX_PATH]; + int cpu = odp_cpumask_first(&domain->cpus); + snprintf(path, MAX_PATH, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_setspeed", cpu); + + FILE *f = fopen(path, "w"); + if (f == NULL) { + return errno; + } + + int err = fprintf(f, "%d", level); + if (err < 0) { + fclose(f); + return err; + } + + err = fclose(f); + return err; + +} + +uint64_t odp_power_domain_get_perf_level(odp_power_domain_t *domain) { + char path[MAX_PATH]; + int cpu = odp_cpumask_first(&domain->cpus); + snprintf(path, MAX_PATH, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_cur_freq", cpu); + + FILE *f = fopen(path, "r"); + if (f == NULL) { + return errno; + } + + char buffer[MAX_PATH]; + char *ret = fgets(buffer, MAX_PATH, f); + fclose(f); + if (ret == NULL) + return 0; + + return atoi(buffer); +} + +static int read_int_list(char *path, int **list, int *num) { + FILE *f = fopen(path, "r"); + char line[MAX_PATH]; + + char *ret = fgets(line, MAX_PATH, f); + fclose(f); + if (ret == NULL) + return -EIO; + + llist_t llist; + llist_init(&llist); + + *num = 0; + char *part = strtok(line, " "); + while(part != NULL) { + if (part[0] == '\n') + break; + llist_add_int(&llist, atoi(part)); + part = strtok(NULL, " "); + } + + *list = malloc(sizeof(int) * llist.num); + if (*list == NULL) { + llist_fini(&llist); + return -ENOMEM; + } + + int i = 0; + ll_entry_t *entry = llist.head; + while (entry != NULL) { + (*list)[i++] = entry->value.i64; + entry = entry->next; + } + *num = llist.num; + + llist_fini(&llist); + + return 0; +} + +static int int_cmp(const void *val1, const void *val2) { + int one = *((const int *)val1); + int two = *((const int *)val2); + + if (one > two) + return 1; + if (one < two) + return -1; + return 0; +} + +static inline int check_in_array(int *arr, int size, int item) { + int i; + for (i = 0; i < size; i++) { + if (arr[i] == item) + return 1; + } + + return 0; +} + +static void get_related_cpus(int cpu_id, int **related_cpus, int *num) { + char path[MAX_PATH]; + snprintf(path, MAX_PATH, "/sys/devices/system/cpu/cpu%d/cpufreq/affected_cpus", cpu_id); + int ret = read_int_list(path, related_cpus, num); + if (ret) + fprintf(stderr, "ERROR: could not read affected_cpus for CPU %d\n", cpu_id); +} + +static void get_available_cpu_frequencies(int cpu_id, int **freqs, int *num) { + char path[MAX_PATH]; + snprintf(path, MAX_PATH, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_available_frequencies", cpu_id); + int ret = read_int_list(path, freqs, num); + if (ret) + fprintf(stderr, "ERROR: could not read avaliable frequencies for CPU %d\n", cpu_id); +} + From patchwork Tue Jan 17 16:28:38 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergei Trofimov X-Patchwork-Id: 91692 Delivered-To: patch@linaro.org Received: by 10.182.3.34 with SMTP id 2csp522734obz; Tue, 17 Jan 2017 08:30:40 -0800 (PST) X-Received: by 10.107.21.196 with SMTP id 187mr1400994iov.105.1484670640420; Tue, 17 Jan 2017 08:30:40 -0800 (PST) Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id j25si12760381iti.119.2017.01.17.08.30.40; Tue, 17 Jan 2017 08:30:40 -0800 (PST) Received-SPF: pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id D447860954; Tue, 17 Jan 2017 16:30:39 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAD_ENC_HEADER,BAYES_00, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id AC9FD60ECF; Tue, 17 Jan 2017 16:29:04 +0000 (UTC) X-Original-To: lng-odp@lists.linaro.org Delivered-To: lng-odp@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id 5F6AA60954; Tue, 17 Jan 2017 16:28:56 +0000 (UTC) Received: from EUR01-HE1-obe.outbound.protection.outlook.com (mail-he1eur01on0069.outbound.protection.outlook.com [104.47.0.69]) by lists.linaro.org (Postfix) with ESMTPS id AE5DF60653 for ; Tue, 17 Jan 2017 16:28:52 +0000 (UTC) Received: from e109786-lin.cambridge.arm.com (217.140.96.140) by AM5PR0801MB1746.eurprd08.prod.outlook.com (10.169.247.12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.845.12; Tue, 17 Jan 2017 16:28:50 +0000 From: Sergei Trofimov To: Date: Tue, 17 Jan 2017 16:28:38 +0000 Message-ID: <1484670521-28503-3-git-send-email-sergei.trofimov@arm.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1484670521-28503-1-git-send-email-sergei.trofimov@arm.com> References: <1484670521-28503-1-git-send-email-sergei.trofimov@arm.com> MIME-Version: 1.0 X-Originating-IP: [217.140.96.140] X-ClientProxiedBy: DB6PR0301CA0004.eurprd03.prod.outlook.com (10.168.49.14) To AM5PR0801MB1746.eurprd08.prod.outlook.com (10.169.247.12) X-MS-Office365-Filtering-Correlation-Id: f3e7ec40-6865-4b80-7a93-08d43ef5ebdd X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001); SRVR:AM5PR0801MB1746; X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1746; 3:eHm1o9HyQNBw90nwNtEZSY2AKshWHOsM7hiekuWVe5+I3YCftCDNm54yd7qlxrcaaAgHoy2nVeXBfEEYjZrPsUAF2sXm8N2phmHclRL2eWFdBaxcno2Xx0c0oOSVzrGmg5Kuv05ifmg+yROfb9vK8001J7lba16xnN5OoZmam5uEbAiC3C8XhWQwA4uZAbR7JKnVYA0hyatZuHHUugvnTyjHrvOI/WFs8w7gWPAi1XSgV4jCrRDktpI7j00Tctxd8caQ6hRWKcY1/LeNp+7X3Q==; 25:BKjzJlCpz75WfyojrA97knfqI0CmdYViB681gRz2dS+nz2CxDOxh/1c9+8i65+rdzo0L7MRjQ/ChgkiX79mio9GIT3/7mM5hPc3Bs8QwSFWPbd0MK3HfIMqKOKWSAy1EnBp/UYfN//s8lXI23zIwm4sYxYNRH3ti92PPO2zI8udcM3qboIj2/Z5JBg8ko+grl6cdpW1la6Sk1zIh1HZnk1gAKWwpEFcvMa778iii5U/x9RpGOU1HejAeot7M7aIdYvmi/Yf2unnflO80dHxpugJZTZlkQhGpQVr+t17IEdZFKq/jvO+lKSRjvD2vNuocES44z9cO4aQcq3Oog0oMSuZZqMQ+oEc6UJrHoRS1+gjmIedXLvv4m1p1Tfcm8c5ybAlvQ9NowCiPkM79XBiTqXMAIx36kHZ7MxwvOCK/T+cAqJXs6eE2IfmNo6vL6aB/dxqrtskAer/U7oTI5jgCxA== X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1746; 31:hnfxLmf6hMQcHtB0N/eaAc3Iud7EHSVxG7gCwtivf6zcnsdOA2t8l5N5QOMW3xh+LxqM0HNkwStZpytd/z1lzjLvjsnSLmUeGdW4NdBb+FdmYsk6DWeEhsmSV9BqZMMWR+5kV/vH5AxL5LonctqxcsnpRDoBUY2M08KVHdJVIIHyOm381wxDpYBfhp7eXOyiEiP50ARh4oifGoWsMtJQvDMztQlDEWB7ATMqG/hCx2XRFuo1PYQ0AjgG/RmyKc39u69/nsr/PsFm100DY8YKiQ==; 20:RQRIU5ZECqsP95rjfDqodm9UizjIeCeTdg54dkHf40rf+ssHNqRNvLdXgMMYR1bePBnHI06gIfmxK0IDszHQ2HsjUk0YoPxywDqx5wom0LWJroeg/qEGfMg/N1o4SwX+dtVMr/h37oYB8s0leMys9o5XDjkU+a9yKFE6rnXMCJE= NoDisclaimer: True X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(180628864354917); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040375)(601004)(2401047)(5005006)(8121501046)(10201501046)(3002001)(6055026)(6041248)(20161123555025)(20161123560025)(20161123564025)(20161123562025)(6072148); SRVR:AM5PR0801MB1746; BCL:0; PCL:0; RULEID:; SRVR:AM5PR0801MB1746; X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1746; 4:Kw3st2ctlBWW1lymgSI2igK/t0w2Jqv8DVdgMVjjIOoQolI2lvyWZ6O5WRnuljfhp6TDYPg1hdK9qUlB4aPY1GrjTnTE1W36m0rKm7nWoUnaL8VD4G/fdd6m5sRRh9Ur21SKBJNo5HvlAERfDdLEWX+1DFRpaBiusg0UQjjCrtac4+Ch+1tHFuABAuJwOlbJtUQ2eqtczzS5aCCdEOmtIT5vB7G9xCiMEj8Zad1OAsIwqFvw8IZL8IIxqTWEd7lDHRhGKcebaoNZrRJvG1wGqqs6jHven0mZkb80mDEBgbLlhFQIsSK27OoK4RmIawcZSPC8Ob0nncEucX0MsqzyjNZwMvipUQDskiAHdvVoqGswQCl7b7Iq3X43azHxPHzTMq1Fm+mXz+zhdYoswmSm2eo1KtZ9mh7P88+uakqsEd09jEBttC176Vjapwjdy8lBPuAN6P4+CdEJoyfLTVu/TMvhHYIaTB9pTgWwoz3+fEriC4g8jGwYDNQDV5qYTOY5enqbWWDRBvLZVk9ipfycxUN0nLoJbA+Wi6Oceugq+OJxFlZ3+OqFGrac11kZTPNPgTNCdA0368PGf0VUFLWtdrrmJVvgldyEElhwaaU2om/JDgknjZja7929bviuzw+43GgxMguMsnBTstmKkGh/jw== X-Forefront-PRVS: 01901B3451 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6009001)(7916002)(39450400003)(39840400002)(39410400002)(39860400002)(39850400002)(199003)(189002)(6666003)(81166006)(8676002)(50226002)(81156014)(305945005)(450100001)(7736002)(38730400001)(2950100002)(6116002)(97736004)(92566002)(6916009)(47776003)(2906002)(3846002)(54906002)(33646002)(66066001)(48376002)(50466002)(50986999)(189998001)(4326007)(76176999)(25786008)(36756003)(6486002)(110136003)(106356001)(105586002)(5660300001)(101416001)(68736007)(42186005)(2351001)(86362001)(5003940100001)(217873001); DIR:OUT; SFP:1101; SCL:1; SRVR:AM5PR0801MB1746; H:e109786-lin.cambridge.arm.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: arm.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; AM5PR0801MB1746; 23:V2WBg1qvBTNaV/6cUAbgv95AX41b+hjQDIX8Btz?= IS+vDyrTgeOfe50fOCaxHKeIxCTWfPglFN/6VC2a+AUqG6ZR8E997AYd32rNwZJ0eIVX4hEhDTMwK34kh3vnv9xMR1EMLyNCXVfG+Ci2dDZNUrQEMyzHtLpKs0/AuGCf8plWLevBKyfErEBka7+C97IChKoT4Hk0GRhPM3A8ef9wc7yappjcL2NX+hrkovJJOTbbNL3WrWSIbqzbla+LAITexRFJXB/uswjh6kEnQmeMFW9mLgpyJYt6AlGI2E86ugnBHVmkC/7tuVxDQ8wMbwZZ+ZHbiKq+kr0LejO36I3NzMBZB0OAcDrh9aXvCDXtaIKyu/Zb89J1i3rFCz+Ktx9Iy0NUApTJY0XXOr4cr5EDtNq4BzV33PALNdh5T4qgQ/YpAKM9MUc51nrpYhSLsuxM7V8hDYPn4lLjlKgc4z4N1PDNzKnvv1IRpJBbZuZ5TANfF6Ua1IPoKJxzhMOF3Z2lT+y/DBwBvf7Q04gc7qYBgYbNBDqf3wCGCQnzB62KdqUEMBpNgprsLvVbsMfQHMIktbjXSNFOc5tvied6mgjRDdChL96OVoh8bSfofgJy6s0FJsus8tcfZ2GM/nsZLjd+1EeN3LCtSDUIgkO4q7832KgPzHRDMn4OnWZQQATZNoFnq3AB6eOjNxe2yBjoQWomY2HNvtlL4EnXAuZRCIRmvCp2DcWMrQ7bOjibfrW603PBcBamzrWdqpFhEeUlNHzW5ALhm35AllA+QGPCp5ofYRY/yVqEeZC0ssAU8ZuL02MyLHD3P9GtaXfgSLL0O4ZHhZMV0Z1AkKVBl+ErP4vMMDwcxAawxDbJqsQnCYRSEpvlETgXhAgDeRj5wuBVsY/crpUg/Ya522X+8jl2WH/co5yW1tfVs1xFFSJNy9fMDN01D6wjsPodJYFdQditChiWy8fujYYbiZJj3FXUtjt033MjizBiwuXQOkQpDI3n6bN4+I9M6SLbgfLmEy8ztdaUvE4DveZfrkrAlO6IDV47GYUZBxc2SaTX09HCnisZOqrkoi119cjk1tkhhPxpI3lKTDfU/pfpkgWScsgLjAPBCjJTH4wDKeBD/7hQipRC34Do33Oa0nteYrvLyHDK/7JuznkhUkHH0p8QNccPckJDSTOzGQvK0qdXFBFSk64nx/i7NB8EdqOKeRSb39BHb8xodTPoU2SlrsxTtMybO54BKwQ== X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1746; 6:ZsUKCdIkmhF6uJ6JO3RBje86oiy72hs8rAQQ/L2e2yjWjzGnCb6m+yAPuM9tG9cT3cCAWWGMhJdzd+7R7z95azgvwCJCX2g/uamuOwtULrqpLR/6Hh1KN48oeAJgH83tXayopzWgLQsdQ5x8kdAQ4rytMjZi/MsajcyXLgDehDFU7nKlo392NDQoZn2kVr19qrUuvTKW3B4p52Bg597lmlPn5qSH9f9X6egIMgfgHeZJgwrNhWKZWN6QuqRZxJNLbuv5H8JzxSpQ9/nPUf/dTmYaFjvUExODPaAiGNXk1M2wiV7BFXNzDM7JubFxEkSxkdOjv+WOKoYV1axtlP0c6e6P0Ijtyh+VjqSmrC7lXqIJv9AX5dEUtoEZTjg8rmkpcH2+9HD/IYgX/TaqKk0pQB5BI/nUioH2ysg2V4Jjj7+sE7zTshitOxi6Pd7wLkwBUIgCbZ4WwX4lH+CLzqpScw==; 5:kkKpLEeY7g3FsivF4gTq22K0SpnP+jKJvn1+tvy8LqEPI570q3n6aheJ86K+Q6cFYhXGg1WLx2g8jTjpD+c5TjPVXwlpTa+1djBDGs8R+nip8zbG4bqRShoZd5jlyhcut2OcQwatdlHACAXhRJFpXw==; 24:D6Ub7gcmbd2T07TRba6SjY1ET3wScW4mNT9sn8jGc5y81fTl0ZpFzmqU1ecFD2wkSUIXrLCTOpwbpHAtQMfap5MyZ1dFxFMQZHyCPhUhL6A= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1746; 7:l65t44e5YEZSlZye/eoZeKm21W7vS66IRz4Jt6v9XtA0Iz0ozAQIyCBUAFohq7r1VU3Dtg5tDtF+LIokv+n960gY68Id23CJJQJwKBCKPzRWQhSaq95Vr0+59NuvUyTWc3Ig7rsGc791MVIWwzKBxOei9UECwR8r9dIMRDQ+X4GfTxupgBj9CATAkkHB51dGqW/ytsMC1JDUGKbZSQ6rTHHoGtoEyOIkykA90Wp2GKFyt3GBr2CWyb5F+5Qc1IkdkTPSDX2mGnTS23PDhowCTJnpi2aNXJYPW6G5gj+LwHlxNngPr3KaN5bdmsZg2AcR9DGgbd2vSIYMYZFcM4am7cIhCg2yh/EbtPwvsTYf2wK2F11RCGpBhqd1UBAWLRx6Bs8s4HtgKeh+CGgdTuLj5hiMoJ+OzmjF9Q7IXBTp702xtSh7K+IgF2ml/lJd2koFTpvYKuMrKrqLhxa9Hi8/XQ== X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Jan 2017 16:28:50.9121 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM5PR0801MB1746 Cc: nd@arm.com Subject: [lng-odp] [API-NEXT PATCH 2/5] odp_queue: added support for queue depth tracking X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "The OpenDataPlane \(ODP\) List" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: lng-odp-bounces@lists.linaro.org Sender: "lng-odp" - Added a counter to queue_entry_t to keep track of the current queue depth (number of enqueued events). - Added odp_queue_depth function to the API to query the above counter. Signed-off-by: Sergei Trofimov --- include/odp/api/spec/queue.h | 15 +++++++++++ .../linux-generic/include/odp_queue_internal.h | 2 ++ platform/linux-generic/odp_queue.c | 30 +++++++++++++++++++++- test/common_plat/validation/api/queue/queue.c | 2 ++ 4 files changed, 48 insertions(+), 1 deletion(-) -- 1.9.1 diff --git a/include/odp/api/spec/queue.h b/include/odp/api/spec/queue.h index 7972fea..ed9284f 100644 --- a/include/odp/api/spec/queue.h +++ b/include/odp/api/spec/queue.h @@ -409,6 +409,21 @@ typedef struct odp_queue_info_t { int odp_queue_info(odp_queue_t queue, odp_queue_info_t *info); /** + * Retrieve current approximate depth of a queue + * + * The returned value is not guaranteed to be exact, but can be used as a + * general indicator of how "busy" the queue is. + * + * Invalid queue handles or handles to free/destroyed queues leads to + * undefined behaviour. + * + * @param queue Queue handle + * + * @retval Number of events currently in the queue. + */ +int odp_queue_depth(odp_queue_t queue); + +/** * @} */ diff --git a/platform/linux-generic/include/odp_queue_internal.h b/platform/linux-generic/include/odp_queue_internal.h index 8b55de1..a10628e 100644 --- a/platform/linux-generic/include/odp_queue_internal.h +++ b/platform/linux-generic/include/odp_queue_internal.h @@ -75,6 +75,8 @@ struct queue_entry_s { odp_pktin_queue_t pktin; odp_pktout_queue_t pktout; char name[ODP_QUEUE_NAME_LEN]; + + int depth; }; union queue_entry_u { diff --git a/platform/linux-generic/odp_queue.c b/platform/linux-generic/odp_queue.c index 6608695..d364801 100644 --- a/platform/linux-generic/odp_queue.c +++ b/platform/linux-generic/odp_queue.c @@ -33,6 +33,7 @@ #include #include +#include typedef struct queue_table_t { queue_entry_t queue[ODP_CONFIG_QUEUES]; @@ -99,6 +100,8 @@ static int queue_init(queue_entry_t *queue, const char *name, queue->s.head = NULL; queue->s.tail = NULL; + queue->s.depth = 0; + return 0; } @@ -443,6 +446,7 @@ static inline int enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], queue->s.tail->next = hdr; queue->s.tail = tail; + queue->s.depth += num; if (queue->s.status == QUEUE_STATUS_NOTSCHED) { queue->s.status = QUEUE_STATUS_SCHED; @@ -498,6 +502,7 @@ int odp_queue_enq(odp_queue_t handle, odp_event_t ev) queue_entry_t *queue; queue = queue_to_qentry(handle); + buf_hdr = buf_hdl_to_hdr(odp_buffer_from_event(ev)); return queue->s.enqueue(queue, buf_hdr); @@ -560,8 +565,11 @@ static inline int deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], } /* Write head only if updated */ - if (updated) + if (updated) { queue->s.head = hdr; + ODP_ASSERT(queue->s.depth >= (uint64_t)i); + queue->s.depth -= i; + } /* Queue is empty */ if (hdr == NULL) @@ -761,3 +769,23 @@ int sched_cb_queue_empty(uint32_t queue_index) return ret; } + +int odp_queue_depth(odp_queue_t handle) +{ + uint32_t queue_id; + queue_entry_t *queue; + int depth; + + queue_id = queue_to_id(handle); + + if (odp_unlikely(queue_id >= ODP_CONFIG_QUEUES)) { + ODP_ERR("Invalid queue handle:%" PRIu64 "\n", + odp_queue_to_u64(handle)); + return 0; + } + + queue = get_qentry(queue_id); + depth = queue->s.depth; + + return depth; +} diff --git a/test/common_plat/validation/api/queue/queue.c b/test/common_plat/validation/api/queue/queue.c index 1f7913a..6d603a4 100644 --- a/test/common_plat/validation/api/queue/queue.c +++ b/test/common_plat/validation/api/queue/queue.c @@ -216,6 +216,8 @@ void queue_test_param(void) * But here we assume that we succeed in enqueuing all buffers. */ ret = odp_queue_enq_multi(queue, enev, MAX_BUFFER_QUEUE); + int depth = odp_queue_depth(queue); + CU_ASSERT_EQUAL(depth, MAX_BUFFER_QUEUE); CU_ASSERT(MAX_BUFFER_QUEUE == ret); i = ret < 0 ? 0 : ret; for ( ; i < MAX_BUFFER_QUEUE; i++) From patchwork Tue Jan 17 16:28:39 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergei Trofimov X-Patchwork-Id: 91693 Delivered-To: patch@linaro.org Received: by 10.182.3.34 with SMTP id 2csp522986obz; Tue, 17 Jan 2017 08:31:20 -0800 (PST) X-Received: by 10.55.99.81 with SMTP id x78mr40927204qkb.62.1484670680079; Tue, 17 Jan 2017 08:31:20 -0800 (PST) Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id h30si16946617qta.318.2017.01.17.08.31.19; Tue, 17 Jan 2017 08:31:20 -0800 (PST) Received-SPF: pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id B78DC60954; Tue, 17 Jan 2017 16:31:19 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAD_ENC_HEADER,BAYES_00, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id 2094A60ECA; Tue, 17 Jan 2017 16:29:11 +0000 (UTC) X-Original-To: lng-odp@lists.linaro.org Delivered-To: lng-odp@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id A560160653; Tue, 17 Jan 2017 16:28:57 +0000 (UTC) Received: from EUR01-HE1-obe.outbound.protection.outlook.com (mail-he1eur01on0069.outbound.protection.outlook.com [104.47.0.69]) by lists.linaro.org (Postfix) with ESMTPS id 42D2D6094F for ; Tue, 17 Jan 2017 16:28:53 +0000 (UTC) Received: from e109786-lin.cambridge.arm.com (217.140.96.140) by AM5PR0801MB1746.eurprd08.prod.outlook.com (10.169.247.12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.845.12; Tue, 17 Jan 2017 16:28:51 +0000 From: Sergei Trofimov To: Date: Tue, 17 Jan 2017 16:28:39 +0000 Message-ID: <1484670521-28503-4-git-send-email-sergei.trofimov@arm.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1484670521-28503-1-git-send-email-sergei.trofimov@arm.com> References: <1484670521-28503-1-git-send-email-sergei.trofimov@arm.com> MIME-Version: 1.0 X-Originating-IP: [217.140.96.140] X-ClientProxiedBy: DB6PR0301CA0004.eurprd03.prod.outlook.com (10.168.49.14) To AM5PR0801MB1746.eurprd08.prod.outlook.com (10.169.247.12) X-MS-Office365-Filtering-Correlation-Id: 6c4e8a38-3314-44e9-565c-08d43ef5ec2f X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001); SRVR:AM5PR0801MB1746; X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1746; 3:bfMrH3ND1NZp7kVUgS4APOUyl0TwOymMAsrlfJRpSct7UjE7fCA0cqm1UjZTDk2I7mOJbGTR2iO9KTZbeYKi3PCEmz77y0ucZ7EBThNslCWEtpwv89e1XCsZRkoMSCcV9JxYceHaL3t6cp5+B2Zm4JzlCJVZUhV7mKQX6tQv8FxKO3JUbs0c6T9lnc72w1G0M3MKfLv+F+AF85oKrnrm5y/44yMyc8Pdt1wprkdN6yK1M5v3P9jkZWzgHDsOQfdGn8UgAGEpHtUG/G0pFsA7/g==; 25:DDQLJT5hgKMuc0DzqYuOhhJpzvhDwu9afNggyOkwz7qASHWBvJ6FhbN5uoVbrNIKK6n1Y6a2yPtBvcQrVTWCVtZZ9PqBLB1seIKMHFnUinFyHJKXn3zPYP1FzTIN62wmJNAmtjG7pztUxL/sw96WoArShKnQpHK9IWcX90h4C0G8B1zuF4vLJ284ae5rXyQgRMQBFPhV+r6TIFogmCS8YUu9afFBXZYwW5bj64OrCmZlrsWMjaeiWUXQ3knAQZkZWU1fhyUnnQqR5KBEk1YYT6hO+Di+1xybeLqvBz1Lb7WQPdb7fWSpB/BeNs7aAH+GFDmINlYBj7Rwl+OFjXmPmzmSBCLhDcKry7die6f32AHYCIFuQ6dzgUzanfJPvD1I0n5j1BCnjrkjAuMfLr9zVIIRF3kJEreD7QYDZ9K1ntVvs/y0yY/Q/sMF5BL+4S22HXDJ8ygYb6mxvgsd1kSfbw== X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1746; 31:7CpEdNmKHBH7i2Qs1wgHtQpxNKPm76NlZY364msCiQEBvc0nVngDMxg6EThLlbbZRVTxuzi+X3B1+WpGsuNXu4LOj8/4vHlr/5h4jjfRnTG+VZLiEVjB/59D1nmFgXKkjuLuJy4GhfEiiWUt6mqnUPysc41qz3yqlqtN1NhMMeZ9033fgERlESZRwxTE302vdvQdlNE+4+8tebSusc2FjxHBPgUW4/2sFFeBhORS6TA6YLiq8nO5Wy8+ctHG+s5v; 20:+k8WCFKSsxBVmGzDz82arR6X7ToarRd+TzT4N9oYV21hcBEzPr0aaVxoaYMb6NJjF5vh6Q9SBfl0URc6NkK4GaAlwwDcQyRBljsUgSe2prhe2OTP/nsPCqYP43xJ4cJrF8TM9oKpJ4y0wZOeiibrNGTKgNqXZSrECvdBHysyauI= NoDisclaimer: True X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(180628864354917); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040375)(601004)(2401047)(5005006)(8121501046)(10201501046)(3002001)(6055026)(6041248)(20161123555025)(20161123560025)(20161123564025)(20161123562025)(6072148); SRVR:AM5PR0801MB1746; BCL:0; PCL:0; RULEID:; SRVR:AM5PR0801MB1746; X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1746; 4:6kQ3oQBYCAdR0AZb8uPIuQVwwXe6SF+46pIH5BqE0C2J0NlEzsiGrGdMIux2wa5EuJuhcZogrLGVqgXMPt4rvAh+fubQQb4Yz5zj0k3E6/aQdmRI+KlVatYd6b1avyK1db5nxrDCZTPpSXam2ecgmAhTc7LBXz7tHuMpKTTJv/g0Tu68I2Ed/6S1kT7aDeBsyIgLjJMJbFg9ki0m/gJbVw7P0eNil+Scv81vDXvww1HoEmuTjUpVcaSQx7eMkxPoqRjrf1m5yopReFvIdy5XYhRmyNZoe/3nmB1bHsRvPk5ajfJpuqsx3SBJNWebb5QvZvwz781D9witrZDPcl9WsXxTDmje9sxlCc78xH2ER2ilNJ73VvUIxgtUOCtC7/WKKVsNbaKeb6lWl2fw/NEuV/raioSIJLpLA9i/mmtiy2H1hsSzcgdvxnSXOoxbHhw7OpTJ0kbl8CjMmG/ab0ddq2CDybs3K1lhu3d8kzNJ3m/0lr5K5ur3F7hALO6e8HNcXRcenQuxWVALF3RQWzWps+dQRvHtftE8K5rok55F+AXVFDgvjqw3yuwQUdslJp06EbIUJ+0Uz4Ha+bNyV8IFDlGISN34Hxv16RQtTvcHPgNKVIf+LV1jsdQ0mAJX6mpQpTXad29FMFKv+AuanaTGHw== X-Forefront-PRVS: 01901B3451 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6009001)(7916002)(39450400003)(39840400002)(39410400002)(39860400002)(39850400002)(199003)(189002)(6666003)(81166006)(8676002)(50226002)(81156014)(305945005)(450100001)(7736002)(38730400001)(2950100002)(6116002)(97736004)(92566002)(6916009)(47776003)(2906002)(3846002)(54906002)(33646002)(66066001)(48376002)(50466002)(50986999)(189998001)(4326007)(76176999)(25786008)(36756003)(6486002)(110136003)(106356001)(105586002)(5660300001)(101416001)(68736007)(15650500001)(42186005)(2351001)(86362001)(5003940100001)(217873001); DIR:OUT; SFP:1101; SCL:1; SRVR:AM5PR0801MB1746; H:e109786-lin.cambridge.arm.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: arm.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; AM5PR0801MB1746; 23:m6FL8fxLfqClZgN6PhMuj6tBVvLC/C14ebLxpz6?= Zyfb7A0WslJA45PdI5Qh3ZFHUMlNBTNQJiNsHWrItcRnT96Z28laeR1jEjZxGhST2C8nTlUbScuA6e/BLVxy1KOA59uDZGWXbHyRZLMwze0gLa1+I8Hgl9AjFe3ZUAq7fulTJBlXdyyLTtqDbmV1YNVAyiAPrfL+nyoVPXJl8k239AyOacRyzYuiWv/LoVpJS9Nu+yQiNHW9WvxM8oALXdZOIkzRbJbuivh5mdmlyrzaez2ZIExjjwP/Q2pNvlEBTTRk/A+/ds2l+1mLVEU76ZD4vKntkhJSC54aFN3mXRkDb5dozF+JxZQ6aBh2yBFaYRzejas36QPBLOJs+6KZwRmMOrb60wxq9wGjhOq4/15KAqAjaILSrWz7fX1GxlQ46U9D/1rcaeZzX24OqQ3KYqWcDI0pElxa1uvI3zqTusqZYFmKF52OVS3LZaNWgdjCHweLQHViW215CSwcGdd6aWDwoImSj23fRMdhqa02y2Ele6HhoKetpn5bAu6xUP18HGCpSUSru7GtFhRGxwXy7b5OKgkYPpkVKU02Zny2VinwFfn7FiLArpD5Hhr5/VGqB09s5byb+Xd8IjQQQsQuxk+Ipy2Nn2jWyJTl1Vnnmv+mfRuatUa4yH1yrKrdClPqliofPVfZ5OfTdgiGLNiw41KHNvrOJ1EQrA5klUHzGMzkoJSvvTxjdsVx1iQJfPAd44cC3nodDjZxth8X8uANMqlim4h4AZwNktYYmcUBq7A39l2whHVIY9k/qF8KXd/Fj4ZEyJnPbpHhUI1/QPzPxG0vIkscIOPr58iX26OLKfdNCYcZfcxZ9kacZpEVAfr7FXn6z/zNnZtlMsJLzdqEHjkz0dMrCN5iRvAcJD4fPlVfBc501mtYyDlN1WGtVjVIUF92IYrinxCRfNJYxxB8QhnXu+DQOKmiJ+QId+DNKw/bIbTdp6kKR/ookY/ox4nKP5uC4cI32nVr0u3FR8f7bHcAhuxWA2r0vDh0Dqe7htA7zd+Yx3B8bLo4+5wDMYMBCTuIgoWl5J1OzMZgvlMK3wytwEg5THt+KK0ICQuj9JegRveAMEpCRVky9dAmVzixl94vP08LS51JpzuZAu8qy8d/ZoSOIZQjAxeB7imv9zDm0e8oIde29sogWkMkuT1VwaSPZ4DREUL4FWH5qZZuIHzQgbtqDibFyaNDP26z1PBhwGu+xmglUELESmYP6J/Ul/F8= X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1746; 6:AemMuuYPyfrr0J+Za+SlvWT79Dfpav2S+diC80Ii7XEd/GwX5nfY5Gd4KzfvlcrDLfegc8lpe+HTEevAnnhMiryEkjl3IXl77t0+y3zNMglbFunCxK2vndmm5+MJoQdaBh+JFlXpwJ7DO6sc+0BvdMfnOil1LSMgXw6AyIYi1Y3RDvTFNRZAg3oYLzH1OG2yfrXr90r38t2w0w86a1Bn4XnQxrfbmNOHwaQTNut6gXbsGRhGsiaQeoakrI5IdRX+bVJpFo9PYqLtgwRxoq/lcC6+72r8vOwZeEvXlwHv0kPCfmsRmGOMno8NJ6+wUVOLEukirGStK2o4hCRo3X/2/y/MCaYLoLklK/WLHwnKhFbkEKoTm0ez5778i5UE/e55ODiiGX5UTTjqx9puZaUzyn/cVV9tbjJs1KcSnEjlU1ke/eI4vtKJ3dq18ZiA2/xAeBtV4CANFTpk1ijFcPWZIQ==; 5:ONH90XTEkePD8X9TBZ7ogkgkHo4mrT7IFmHAiDEtcfqVKtKbkI3Lz7D9t5ub+i5wo5hCLUViFro89G/uvwPBrTf22CzN4bZeSaZsxcxQG2YJ7LBnG/VKiy/EZ5gt4EIMyKg+9FDqJYU7DUY2TD7z7Q==; 24:d4v90dOwSCGJqmJIxHhmFV60Vx4SkR26DT3ogLGS8aeUmo7P1dARM2DIxaGu/tB2QvlIBQVaLtLaEK5Amu+xoc7rr/+z24mNkFocWoF8kHY= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1746; 7:dG3q4AFjtXuAEhxnqGnzUGKZ6Y4ByqKrpusNEct26aq2Vt+1fM6iQKYbdMvSK0VzJVgVsEssaFTgzUVMhkD/KRwXPZiXo1hogJe5xR6vACT6hfp9KcZFFURJ48/+XA9+pCjxLOmn7iVzLzRa5BWY7wvWmAXbB16vZ3w7GqoBCiAUnjp+tBr86er1kyjuGX78k5SwlVzl0XfJ7RZB3Sg5Y2PFzDQdcX8OqpSAE8N1jvs+JUXEh6m2mIE6GNE1jV0KhDLSwrXoaqpf9e7l2u8sJF7YImY6tKlyJtK1HNTRSTJ5/5m9roZs6Edst65lEXJToGEKLfp3zuoiT1ngnZ86vaiqoLsE9DEY36Js1sTxpH9t7/rauuRnS/IC6okq6Iz5rjj1JifnVm+7YtNjyu/dvVx/bQ14P75D7zfyt6FOEWdD+dD2cow9CTvhsGjh7LDNcDsdy4H2yr5oia5lTrsbzg== X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Jan 2017 16:28:51.4475 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM5PR0801MB1746 Cc: nd@arm.com Subject: [lng-odp] [API-NEXT PATCH 3/5] queue: adding a notification queue type X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "The OpenDataPlane \(ODP\) List" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: lng-odp-bounces@lists.linaro.org Sender: "lng-odp" This adds ODP_QUEUE_TYPE_NOTIF along side the existing plain and sched queues. Notification queues are similar to plain queues, in that they are dequeued manually. However it is also possible to wait on dequeue (via the new odp_queue_deq_wait) method, which will block on an empty queue in such a way that (if supported by the platform) the execution will yield allowing the CPU to either run another thread or idle. Signed-off-by: Sergei Trofimov --- include/odp/api/spec/queue.h | 23 +++++++++- .../linux-generic/include/odp_packet_io_queue.h | 4 +- .../linux-generic/include/odp_queue_internal.h | 8 +++- platform/linux-generic/odp_packet_io.c | 6 +-- platform/linux-generic/odp_queue.c | 49 ++++++++++++++++++++-- 5 files changed, 79 insertions(+), 11 deletions(-) -- 1.9.1 diff --git a/include/odp/api/spec/queue.h b/include/odp/api/spec/queue.h index ed9284f..5af676b 100644 --- a/include/odp/api/spec/queue.h +++ b/include/odp/api/spec/queue.h @@ -62,7 +62,15 @@ typedef enum odp_queue_type_t { * Scheduled queues are connected to the scheduler. Application must * not dequeue events directly from these queues but use the scheduler * instead. */ - ODP_QUEUE_TYPE_SCHED + ODP_QUEUE_TYPE_SCHED, + + /** Notification queue + * + * Behave similar to plain queues, however, threads can execute a waiting + * dequeue, causing them to block if the queue is empty. + * + */ + ODP_QUEUE_TYPE_NOTIF } odp_queue_type_t; /** @@ -309,6 +317,19 @@ odp_event_t odp_queue_deq(odp_queue_t queue); int odp_queue_deq_multi(odp_queue_t queue, odp_event_t events[], int num); /** + * Queue dequeue + * + * Dequeues next event from head of the queue, blocking if the queue + * is empty. Must be used only with ODP_QUEUE_TYPE_NOTIF type queues. + * + * @param queue Queue handle + * + * @return Event handle + * @retval ODP_EVENT_INVALID on failure (e.g. not a notification queue) + */ +odp_event_t odp_queue_deq_wait(odp_queue_t handle); + +/** * Queue type * * @param queue Queue handle diff --git a/platform/linux-generic/include/odp_packet_io_queue.h b/platform/linux-generic/include/odp_packet_io_queue.h index d1d4b22..a24adfc 100644 --- a/platform/linux-generic/include/odp_packet_io_queue.h +++ b/platform/linux-generic/include/odp_packet_io_queue.h @@ -29,14 +29,14 @@ ODP_STATIC_ASSERT(ODP_PKTIN_QUEUE_MAX_BURST >= QUEUE_MULTI_MAX, "ODP_PKTIN_DEQ_MULTI_MAX_ERROR"); int pktin_enqueue(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr); -odp_buffer_hdr_t *pktin_dequeue(queue_entry_t *queue); +odp_buffer_hdr_t *pktin_dequeue(queue_entry_t *queue, int wait); int pktin_enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num); int pktin_deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num); int pktout_enqueue(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr); -odp_buffer_hdr_t *pktout_dequeue(queue_entry_t *queue); +odp_buffer_hdr_t *pktout_dequeue(queue_entry_t *queue, int wait); int pktout_enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num); diff --git a/platform/linux-generic/include/odp_queue_internal.h b/platform/linux-generic/include/odp_queue_internal.h index a10628e..fb78124 100644 --- a/platform/linux-generic/include/odp_queue_internal.h +++ b/platform/linux-generic/include/odp_queue_internal.h @@ -26,9 +26,12 @@ extern "C" { #include #include #include + #include #include +#include + #define QUEUE_MULTI_MAX CONFIG_BURST_SIZE #define QUEUE_STATUS_FREE 0 @@ -42,7 +45,7 @@ extern "C" { union queue_entry_u; typedef int (*enq_func_t)(union queue_entry_u *, odp_buffer_hdr_t *); -typedef odp_buffer_hdr_t *(*deq_func_t)(union queue_entry_u *); +typedef odp_buffer_hdr_t *(*deq_func_t)(union queue_entry_u *, int); typedef int (*enq_multi_func_t)(union queue_entry_u *, odp_buffer_hdr_t **, int); @@ -77,6 +80,7 @@ struct queue_entry_s { char name[ODP_QUEUE_NAME_LEN]; int depth; + sem_t notif_sem; }; union queue_entry_u { @@ -88,7 +92,7 @@ union queue_entry_u { queue_entry_t *get_qentry(uint32_t queue_id); int queue_enq(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr); -odp_buffer_hdr_t *queue_deq(queue_entry_t *queue); +odp_buffer_hdr_t *queue_deq(queue_entry_t *queue, int wait); int queue_enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num); int queue_deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num); diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c index 98460a5..8063806 100644 --- a/platform/linux-generic/odp_packet_io.c +++ b/platform/linux-generic/odp_packet_io.c @@ -590,7 +590,7 @@ int pktout_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr) return (nbr == len ? 0 : -1); } -odp_buffer_hdr_t *pktout_dequeue(queue_entry_t *qentry ODP_UNUSED) +odp_buffer_hdr_t *pktout_dequeue(queue_entry_t *qentry ODP_UNUSED, int wait ODP_UNUSED) { ODP_ABORT("attempted dequeue from a pktout queue"); return NULL; @@ -625,13 +625,13 @@ int pktin_enqueue(queue_entry_t *qentry ODP_UNUSED, return -1; } -odp_buffer_hdr_t *pktin_dequeue(queue_entry_t *qentry) +odp_buffer_hdr_t *pktin_dequeue(queue_entry_t *qentry, int wait ODP_UNUSED) { odp_buffer_hdr_t *buf_hdr; odp_buffer_hdr_t *hdr_tbl[QUEUE_MULTI_MAX]; int pkts; - buf_hdr = queue_deq(qentry); + buf_hdr = queue_deq(qentry, 0); if (buf_hdr != NULL) return buf_hdr; diff --git a/platform/linux-generic/odp_queue.c b/platform/linux-generic/odp_queue.c index d364801..82fe794 100644 --- a/platform/linux-generic/odp_queue.c +++ b/platform/linux-generic/odp_queue.c @@ -34,6 +34,7 @@ #include #include #include +#include typedef struct queue_table_t { queue_entry_t queue[ODP_CONFIG_QUEUES]; @@ -88,6 +89,10 @@ static int queue_init(queue_entry_t *queue, const char *name, 0); } } + + if (param->type == ODP_QUEUE_TYPE_NOTIF) + sem_init(&queue->s.notif_sem, 0, 0); + queue->s.type = queue->s.param.type; queue->s.enqueue = queue_enq; @@ -452,8 +457,14 @@ static inline int enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], queue->s.status = QUEUE_STATUS_SCHED; sched = 1; /* retval: schedule queue */ } + UNLOCK(&queue->s.lock); + if (queue->s.type == ODP_QUEUE_TYPE_NOTIF) { + for (i = 0; i < num; i++) + sem_post(&queue->s.notif_sem); + } + /* Add queue to scheduling */ if (sched && sched_fn->sched_queue(queue->s.index)) ODP_ABORT("schedule_queue failed\n"); @@ -571,6 +582,12 @@ static inline int deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], queue->s.depth -= i; } + if (queue->s.type == ODP_QUEUE_TYPE_NOTIF) { + for (j = 0; j < i; j++) { + sem_trywait(&queue->s.notif_sem); + } + } + /* Queue is empty */ if (hdr == NULL) queue->s.tail = NULL; @@ -588,11 +605,20 @@ int queue_deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num) return deq_multi(queue, buf_hdr, num); } -odp_buffer_hdr_t *queue_deq(queue_entry_t *queue) +odp_buffer_hdr_t *queue_deq(queue_entry_t *queue, int wait) { odp_buffer_hdr_t *buf_hdr = NULL; int ret; + if (queue->s.type == ODP_QUEUE_TYPE_NOTIF) { + if (wait) { + sem_wait(&queue->s.notif_sem); + } else { + if (sem_trywait(&queue->s.notif_sem)) + return NULL; + } + } + ret = deq_multi(queue, &buf_hdr, 1); if (ret == 1) @@ -620,14 +646,31 @@ int odp_queue_deq_multi(odp_queue_t handle, odp_event_t events[], int num) return ret; } - odp_event_t odp_queue_deq(odp_queue_t handle) { queue_entry_t *queue; odp_buffer_hdr_t *buf_hdr; queue = queue_to_qentry(handle); - buf_hdr = queue->s.dequeue(queue); + buf_hdr = queue->s.dequeue(queue, 0); + + if (buf_hdr) + return odp_buffer_to_event(buf_hdr->handle.handle); + + return ODP_EVENT_INVALID; +} + +odp_event_t odp_queue_deq_wait(odp_queue_t handle) +{ + queue_entry_t *queue; + odp_buffer_hdr_t *buf_hdr; + + queue = queue_to_qentry(handle); + + if (queue->s.type != ODP_QUEUE_TYPE_NOTIF) + return ODP_EVENT_INVALID; + + buf_hdr = queue->s.dequeue(queue, 1); if (buf_hdr) return odp_buffer_to_event(buf_hdr->handle.handle); From patchwork Tue Jan 17 16:28:40 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergei Trofimov X-Patchwork-Id: 91694 Delivered-To: patch@linaro.org Received: by 10.182.3.34 with SMTP id 2csp523393obz; Tue, 17 Jan 2017 08:32:15 -0800 (PST) X-Received: by 10.36.116.202 with SMTP id o193mr20048853itc.96.1484670735769; Tue, 17 Jan 2017 08:32:15 -0800 (PST) Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id 204si12766156itv.80.2017.01.17.08.32.15; Tue, 17 Jan 2017 08:32:15 -0800 (PST) Received-SPF: pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id 4E87760954; Tue, 17 Jan 2017 16:32:15 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAD_ENC_HEADER,BAYES_00, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id 6E6B760EDA; Tue, 17 Jan 2017 16:29:15 +0000 (UTC) X-Original-To: lng-odp@lists.linaro.org Delivered-To: lng-odp@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id B413B6094F; Tue, 17 Jan 2017 16:28:57 +0000 (UTC) Received: from EUR01-HE1-obe.outbound.protection.outlook.com (mail-he1eur01on0069.outbound.protection.outlook.com [104.47.0.69]) by lists.linaro.org (Postfix) with ESMTPS id AF8F060513 for ; Tue, 17 Jan 2017 16:28:53 +0000 (UTC) Received: from e109786-lin.cambridge.arm.com (217.140.96.140) by AM5PR0801MB1746.eurprd08.prod.outlook.com (10.169.247.12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.845.12; Tue, 17 Jan 2017 16:28:51 +0000 From: Sergei Trofimov To: Date: Tue, 17 Jan 2017 16:28:40 +0000 Message-ID: <1484670521-28503-5-git-send-email-sergei.trofimov@arm.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1484670521-28503-1-git-send-email-sergei.trofimov@arm.com> References: <1484670521-28503-1-git-send-email-sergei.trofimov@arm.com> MIME-Version: 1.0 X-Originating-IP: [217.140.96.140] X-ClientProxiedBy: DB6PR0301CA0004.eurprd03.prod.outlook.com (10.168.49.14) To AM5PR0801MB1746.eurprd08.prod.outlook.com (10.169.247.12) X-MS-Office365-Filtering-Correlation-Id: 40b5e862-66d7-47c4-4413-08d43ef5ec77 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001); SRVR:AM5PR0801MB1746; X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1746; 3:gUuNiqRj+dHyxAIeB4hQnBHhpVRDS7PVmp3Oir5SNgKCm7jCPXk2DAXEG+VHbp+LZMmHHy/msp2qd4Gqfyt7tEum+KzaSSmD02AOIyOmcoTtdAp0IUDk36hNnLqQqkS1t0Lheo+70E7k+Erkxx4gWXFE8Sq0b3lJwNATRygIGa9oOpAhubAgdUMZuF28dSEM8fBClsWjmWp5iPw8eGoT2xd5806KU9dxibXBt9Nnwo10/Eg3XxuJBOKzGpHhnsqPChGRYE7Yv6kBtGgtWudiQQ== X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1746; 25:GhtTL2kyPDmO0WE4oxvVTRVlz4utmgmafSdlncDxnHKFVU9iQzWnT35PrdXoJhk+zLY9zPiWcBmwYRLZSvsOCh0vrLuaYikl97f4izown+vTCWtZ35gGW9SJgpjkcpW0JnEEpPDV1XdM2qAutKpWI5dCoqwegCH1Bl7orwX8OCC66rr3rfTgjMYF9BnmW9codPplGcBWuOASNdZufY40NJ1rxkUBecjNxcctWanJn4QrMmTuqlfcPqDOD7u8EmVttv5ZKa226rsNDRE1//EdPScnPvK95pGo4LH9mS2je1InU7CWchhixtTlgGg9lNU8lVXP+WlgDBGAoc8VDJvvoSftcSggyKzkWPQ7u5XLpPQlfIbJ63GWjWTdyNo3rZb3OP95XHH50JfncYDtRJHUHVUG0sZxl2x3pI/lO3jtOxBtsR5SnwC20puDX6T8w763W2l1fjiTVzgdX3cEkK6cKqNeg3G4bY4uGlcMH37U2/8hQTGx/iXakn8auKcmp5RSFj0nMT3lF22eOGhbcDfbVk6EQXpyIWqzCLTyPo/seeIa0fJm5oXx3+G2XasnQ3Ud9JGeM2E2lqIl5Lzrd9HsWFKtcYzTmX28s26wC0eV4P9QC/H1zO/CeoFKrCtOkjzjvfXcgCmUaDObEeNtCQ649K+NhliP4MJycJFDMOUW4H06OxkHTCwVlQVROVUJQ2XnVHoewtOsgbisFzJPSBcUufgblMj5kf0kzXcVENCYyDnX1fobwraA/fJhNStyek9E6zqrHAgWrmIrrWfbX68AuQ== X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1746; 31:X5wlci3SIKWRfoUusY+v4lSauX3QpmBepZueLX+84z+BiCoEHqAEg0iswzFys5Cwom6ROSxcpFB5qBNomnVnfDb/3JCuBO09rFYHmtl92QJNWi0hy6H1xzIndTin+nALDeVdgSqv3rUnbndPVcbgKLlz1S1ZznZy3VX4TM/eofi/k1ITWoL4Tq9z/Huft4ap5g5dg6Ryo1Yz2Nv+znvOSWuXCPkzPk0QEvUCG52pftptcKM9B6/WeyIryUvjA3hC; 20:2kGfigD2rph71Cenog/DvaupwuI6GBB+01L6+9QDfNvH0YA2vn4Qj18yxnnKIqHgNQphJimIRDY7Z0jueny/1VaoGZTLv69fuJ39lGIaTLjKjMJNCGkzO/+/caM12hnSMBjalQh/R0aTCB1f41Lpvkuh83jOjKqZFqxhah09h+U= NoDisclaimer: True X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(180628864354917); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040375)(601004)(2401047)(5005006)(8121501046)(10201501046)(3002001)(6055026)(6041248)(20161123555025)(20161123560025)(20161123564025)(20161123562025)(6072148); SRVR:AM5PR0801MB1746; BCL:0; PCL:0; RULEID:; SRVR:AM5PR0801MB1746; X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1746; 4:mGuFOWWtTdBITbDfxyY0cy/nMFJipS8d9TVviw7ijKQBTrbsLRpz13Ilh+TgfNjC8o+n4fqT1LjxAIIytoYjcag/kq1wZ/DgMo8vILdh+cPXDAKWNo8PCVk1bEolhfv5nH3Wn5/9fBew1gzkLNgSr92NvyNaY0EzR5m4YBTC3S6fnnqHcXATesw2sPuxs9JqFFZ2MRSNTTTHlfbYbLpTmec74siZykmu31XN8VG0FCT+jS8NoQtMJj6BEFJv+FlelbSY7Zg9xE8CSK4I0C8eCp50B4zmEPuLGGYbzjJaX6ogjICxPV5ALry4VygBxghV4y2Lm1cAhXMmmtl2DTXbuqQgMdJuBY0cdaXypvQRYAcacLAISEUgbfDz7Jy7f/qmRKDAu8VatvGBs2rwhpY+rSwGx4qjUYTcI7huLoE0qsT3XLHQI7St+B7vglORvmYK0vsWaU5Oc/HFfGa9Hn7s9TDvZqZxYkNgZP8uUbwrWqmzW+LCUCB1ahyQvSkzbNpv4YtuobbnonQDfQqWlDEzVj/oEbXiStdvKS42cGIfpfQ3MiVavqU/rUVMrNAE3nOadRjuFeEM5rPa6Nzg5tH69htapY+o+fpXypXRVn/W6KOWCZX8lZmN0K4X30GaWRZx X-Forefront-PRVS: 01901B3451 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6009001)(7916002)(39450400003)(39840400002)(39410400002)(39860400002)(39850400002)(199003)(189002)(6666003)(81166006)(8676002)(50226002)(81156014)(305945005)(450100001)(7736002)(38730400001)(2950100002)(6116002)(97736004)(92566002)(6916009)(47776003)(2906002)(3846002)(54906002)(33646002)(66066001)(48376002)(50466002)(50986999)(189998001)(4326007)(76176999)(25786008)(36756003)(6486002)(110136003)(106356001)(105586002)(5660300001)(101416001)(68736007)(42186005)(2351001)(86362001)(5003940100001)(217873001); DIR:OUT; SFP:1101; SCL:1; SRVR:AM5PR0801MB1746; H:e109786-lin.cambridge.arm.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: arm.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; AM5PR0801MB1746; 23:yR/SOzR+ttzy8c9uPUq5AyX6mHmu/BkLUL+d6Bt?= iltv1kxeUW1OVp1R7aPa59t5S02rnYV9WJai0Zp9m+440SSGzBWhT7jsHB7kyPkWTMMchNZJ7rYhWXL3RJKcGqf+mC+9pAgf7Q7uZ7p/p4a7+QCuHN6YT6VkLwN1O7ZzlU+7E5BebhnmKDjnAi9fMR+RldaoSu2S2o8WR5+AJD3dAKA91qdKmQAxV+jCOB1k+Pv5PjVDm8DKRamjuowErfg3zW5GQ/4rhPzV3+h+5yJFFyPxEDmtnzRFyQ46NZzX1p1U4QiyBfcjdNR+ILmcrHs0GaruCIrex15XdeFkzFWSEKKQkmNbzPewpF07oWGQeLaAQCNoLMAH2BAGRoMYpHnQ7SgCuXUlVcdUGEUt8/bR5KznhLLsjUc18g8/17K5+J+9xvY7+2i0cjjFwuOsfw8CLaJUqQ7sL+RqMXXZZ+nJELzqcXTR/+/HgGuSfivb8cN4CUsRfmnfSGpJvy7LzeetHc+F54Cd2TkFWVFnkh3X0XnL3fUtlXa4+4NzDNXX4/GvZEIKwCuECRnzJye9qoNcxscJmLRt+8em/XSDpw4BmCGMmKr53b5CtrhtEJjyA6/yLM9hQPCyl+LbmZtsjU0fMUCqktvOC2jUTHNya/+CpZBg8G8aBV46bLK50b7LCaMduVIKSqtY2B8dB0FSZeVUP/kaN7ux17LkiajXkydUILTWsqfzsysjO32EJvPyzrOHEkIez0Qcor+s0NP1LTkiH7+Fm7ypFdLYiQDrLssAErg9Q6oSpsLhN+i0bjzBZZ0GVxTjcPT8q9ku7Mq7er06sHlcTUYUmiy2VbP3ZOkv2jmzbsH0Cdxz+Au3Ba0WH8QP5IlghfnQJMwC4ppzphP7nLXmEwY9iolspz5FZ33Fm5CSo+9kBxau3Gp9mBXQECTFJMrlhWcmCJ2uszpeara1r3jHTAELQRgHZcTemA3OVowHnYIiCJLY/NdX2iawO7GfsGL72RYP3pGx3a4MqTH7xlAPuI0Hl4cDZ5ZvZY1O7q2JObS13VX4lNb4NqhDJBThBMz3iYHQR7wkpOhPtzwD7nHesanGxNP2kEetf+27RA9peNujajDmak+HrJWhYy7AkwpiamnFBSIrmYfhYswBi7zWl6A5ru8fmuIGBBElPDMkycadu5X0Zm729wjrrzNCfERg6+z7VTTvDxygza5XpdFE0UUtR6+aXUwgbhoTQMA== X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1746; 6:UuustikSJQinzLEi+UDgpQoU/fmcNZto1+gNCSPQYhw48mhUVonAiiL7L2rxmKilFJ72exigznU5DG7tkwxEepXU3+0ra1l+kGZYALcffZgG8VC3gaYeWEm1FOYpakxWuSeFDfOWiWRhR+YIN4EOHS/0XObHTTOfIJY+KxTvId6jmGXRgvkIy9du42LGqYZKCMDZVrEVX3t0kXX0M23bPmHCk5nlbhWxpM2oLDiMOC7EA3gH9RwJ2/IoAtRkFSBF6sTnC8OX3KB2yu3iYtXImOSyfahfqrhkOhvoLCY/E4HlV2pQQh9tOUMtZa8FNC8a1DinU7z5YCuiMJh7haM4fAB4AOtqwcp+mDOY6mg6q9TONesDQ52dvVl3XctRVCJO6lMJc4MIBRPur9JV2h+7hvR8WvEN4IzAYZVMHtGrQAUeqYkRf/SVSaaowwgswD3xETPPIoTQhBSPBNHp+/i4Bw==; 5:wEpit2vYzV7c0Yyc0hTsi6D0OrjYx9asp/QuBhd46V5cazjodhyCciN3RncmqjUYB9yRbSDd5Nt17vpf4FdrUXID+Y5P34tM6Nd9cQFljAJuYUfbwHcpo112u1vLxXJght6KWBtSFS+o6+DsL3OMuQ==; 24:W3A+C+IBHkjT97jJQNBnONbuN28PYUnjLV56mCbGGPtJA/DkYFCW5dKbDklAs0xhxc48ysc8/0Pqo3jsbzAag3msqL6MJkzFu4Gqr61QQl0= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1746; 7:SZ6MWdFth1osvLH4IfMrYaWLxgsWaHgp4KKrE+1E9THB6gLrnQaY4BJZVa2uBonHPfg9zdLcl7pyhZcUUyX4EKjJn48nt5n69G9mj+LcHb27/7OsvVsB3f2f4dJF9rNA2xdCe3mutOSDONATy9G6PA3bsTzDN49RVBdsPdvoZC0YIZqRsVDz1vXAQRrL1XWcopdenj6LksjZ+M0Y4zVBjvXRnrbrJy7lh+H73m1GCLz/UYP5dICieA8fggqbxtFWkwLIqNucbXuIgy85eRb9okk9E2k55UBlnXhjjdKmWNB1I4Y8Ok7kWPbFwv2IHIpLtO9pBXvnK4ml3cUJ6nCmGy1b2ZyaIfoepY9Og/lsCJz104mA+1m4J6nc75g+4Pmt5BqQhA3NtQpuZfohMUitRx3Px7hLmqRTcF/JOtqBAto+TX4uIVbz0rtKTdnwjQT5pS1AF9fQapdB4bFMb90pkw== X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Jan 2017 16:28:51.9209 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM5PR0801MB1746 Cc: nd@arm.com Subject: [lng-odp] [API-NEXT PATCH 4/5] queue: adding depth threshold trigger X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "The OpenDataPlane \(ODP\) List" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: lng-odp-bounces@lists.linaro.org Sender: "lng-odp" This adds an ability to set a depth threshold for a queue. When the threshold is exceeded, an event will be enqueued on another queue as notification of the fact that the threshold has been exceeded. Signed-off-by: Sergei Trofimov --- include/odp/api/spec/queue.h | 33 ++++++ .../linux-generic/include/odp_queue_internal.h | 8 +- platform/linux-generic/odp_queue.c | 117 +++++++++++++++++++++ 3 files changed, 157 insertions(+), 1 deletion(-) -- 1.9.1 diff --git a/include/odp/api/spec/queue.h b/include/odp/api/spec/queue.h index 5af676b..e72ae87 100644 --- a/include/odp/api/spec/queue.h +++ b/include/odp/api/spec/queue.h @@ -445,6 +445,39 @@ int odp_queue_info(odp_queue_t queue, odp_queue_info_t *info); int odp_queue_depth(odp_queue_t queue); /** + * + * Sets the queue depth threshold. When the threshold is reached, a + * notification event (if one has been armed) will be sent to the notification + * queue when the threshold is exceeded. + * + * @param queue Queue whose notification threshold will be set. + * @param threshold Number of the events in the queue on which to trigger. + * @param notifq Notification queue to be triggered on reaching the number + * of events. This queue must be of type ODP_QUEUE_TYPE_NOTIF. + * + */ +int odp_queue_threshold_set(odp_queue_t queue, int threshold, odp_queue_t notifq); + +/** + * + * Reset a previously set queue threshold. + * @param queue Queue whose threshold is to be reset. + * + */ +int odp_queue_threshold_reset(odp_queue_t queue); + +/** + * Resets a notification queue. A notification queue must be "armed" with an event + * before it can be triggered. It is the responsibility of the notification listener to + * reset the notification queue + * + * @param notif Notification queue to be reset This queue must be of + * type ODP_QUEUE_TYPE_NOTIF. + * @param event An event to reset the queue with. + */ +int odp_queue_threshold_arm(odp_queue_t queue, odp_event_t event); + +/** * @} */ diff --git a/platform/linux-generic/include/odp_queue_internal.h b/platform/linux-generic/include/odp_queue_internal.h index fb78124..02bee9f 100644 --- a/platform/linux-generic/include/odp_queue_internal.h +++ b/platform/linux-generic/include/odp_queue_internal.h @@ -79,8 +79,12 @@ struct queue_entry_s { odp_pktout_queue_t pktout; char name[ODP_QUEUE_NAME_LEN]; - int depth; + int depth; + int depth_threshold; + odp_queue_t threshold_queue; + sem_t notif_sem; + odp_event_t notif_event; }; union queue_entry_u { @@ -100,6 +104,8 @@ int queue_deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num); void queue_lock(queue_entry_t *queue); void queue_unlock(queue_entry_t *queue); +int queue_trigger(odp_queue_t handle); + static inline uint32_t queue_to_id(odp_queue_t handle) { return _odp_typeval(handle) - 1; diff --git a/platform/linux-generic/odp_queue.c b/platform/linux-generic/odp_queue.c index 82fe794..83e6545 100644 --- a/platform/linux-generic/odp_queue.c +++ b/platform/linux-generic/odp_queue.c @@ -93,6 +93,8 @@ static int queue_init(queue_entry_t *queue, const char *name, if (param->type == ODP_QUEUE_TYPE_NOTIF) sem_init(&queue->s.notif_sem, 0, 0); + queue->s.notif_event = ODP_EVENT_INVALID; + queue->s.type = queue->s.param.type; queue->s.enqueue = queue_enq; @@ -389,6 +391,32 @@ odp_queue_t odp_queue_lookup(const char *name) return ODP_QUEUE_INVALID; } +int queue_trigger(odp_queue_t handle) +{ + queue_entry_t *queue = queue_to_qentry(handle); + + ODP_ASSERT(queue->s.type == ODP_QUEUE_TYPE_NOTIF); + + LOCK(&queue->s.lock); + + if (queue->s.notif_event == ODP_EVENT_INVALID) { + UNLOCK(&queue->s.lock); + return 0; + } + + odp_event_t event = queue->s.notif_event; + queue->s.notif_event = ODP_EVENT_INVALID; + + UNLOCK(&queue->s.lock); + + int ret = odp_queue_enq(handle, event); + + if (ret != 0) + free(event); + + return ret; +} + static inline int enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num) { @@ -453,6 +481,11 @@ static inline int enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], queue->s.tail = tail; queue->s.depth += num; + if (queue->s.threshold_queue != ODP_QUEUE_INVALID && + queue->s.depth >= queue->s.depth_threshold) { + queue_trigger(queue->s.threshold_queue); + } + if (queue->s.status == QUEUE_STATUS_NOTSCHED) { queue->s.status = QUEUE_STATUS_SCHED; sched = 1; /* retval: schedule queue */ @@ -832,3 +865,87 @@ int odp_queue_depth(odp_queue_t handle) return depth; } + +int odp_queue_threshold_set(odp_queue_t handle, int threshold, odp_queue_t destq) +{ + uint32_t queue_id; + queue_entry_t *queue; + + queue_id = queue_to_id(handle); + + if (odp_unlikely(queue_id >= ODP_CONFIG_QUEUES)) { + ODP_ERR("Invalid queue handle:%" PRIu64 "\n", + odp_queue_to_u64(handle)); + return 0; + } + + queue = get_qentry(queue_id); + + LOCK(&queue->s.lock); + + queue->s.depth_threshold = threshold; + queue->s.threshold_queue = destq; + + UNLOCK(&queue->s.lock); + + return 0; +} + +int odp_queue_threshold_reset(odp_queue_t handle) +{ + uint32_t queue_id; + queue_entry_t *queue; + + queue_id = queue_to_id(handle); + + if (odp_unlikely(queue_id >= ODP_CONFIG_QUEUES)) { + ODP_ERR("Invalid queue handle:%" PRIu64 "\n", + odp_queue_to_u64(handle)); + return -1; + } + + queue = get_qentry(queue_id); + + LOCK(&queue->s.lock); + + queue->s.depth_threshold = 0; + queue->s.threshold_queue = ODP_QUEUE_INVALID; + + if (queue->s.notif_event != ODP_EVENT_INVALID) { + odp_event_free(queue->s.notif_event); + queue->s.notif_event = ODP_EVENT_INVALID; + } + + UNLOCK(&queue->s.lock); + + return 0; +} + +int odp_queue_threshold_arm(odp_queue_t handle, odp_event_t event) +{ + uint32_t queue_id; + queue_entry_t *queue; + + queue_id = queue_to_id(handle); + + if (odp_unlikely(queue_id >= ODP_CONFIG_QUEUES)) { + ODP_ERR("Invalid queue handle:%" PRIu64 "\n", + odp_queue_to_u64(handle)); + return -1; + } + + queue = get_qentry(queue_id); + + if (odp_unlikely(queue->s.type != ODP_QUEUE_TYPE_NOTIF)) + return -1; + + LOCK(&queue->s.lock); + + if (queue->s.notif_event != ODP_EVENT_INVALID) { + odp_event_free(queue->s.notif_event); + } + + queue->s.notif_event = event; + UNLOCK(&queue->s.lock); + return 0; +} From patchwork Tue Jan 17 16:28:41 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergei Trofimov X-Patchwork-Id: 91695 Delivered-To: patch@linaro.org Received: by 10.182.3.34 with SMTP id 2csp523725obz; Tue, 17 Jan 2017 08:33:07 -0800 (PST) X-Received: by 10.36.245.5 with SMTP id k5mr22047764ith.100.1484670787792; Tue, 17 Jan 2017 08:33:07 -0800 (PST) Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id l10si12782141itd.116.2017.01.17.08.33.07; Tue, 17 Jan 2017 08:33:07 -0800 (PST) Received-SPF: pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id 4B43760954; Tue, 17 Jan 2017 16:33:07 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAD_ENC_HEADER,BAYES_00, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id D861D60EE1; Tue, 17 Jan 2017 16:29:22 +0000 (UTC) X-Original-To: lng-odp@lists.linaro.org Delivered-To: lng-odp@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id AFFA360641; Tue, 17 Jan 2017 16:28:58 +0000 (UTC) Received: from EUR01-HE1-obe.outbound.protection.outlook.com (mail-he1eur01on0069.outbound.protection.outlook.com [104.47.0.69]) by lists.linaro.org (Postfix) with ESMTPS id 2870F60951 for ; Tue, 17 Jan 2017 16:28:54 +0000 (UTC) Received: from e109786-lin.cambridge.arm.com (217.140.96.140) by AM5PR0801MB1746.eurprd08.prod.outlook.com (10.169.247.12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.845.12; Tue, 17 Jan 2017 16:28:52 +0000 From: Sergei Trofimov To: Date: Tue, 17 Jan 2017 16:28:41 +0000 Message-ID: <1484670521-28503-6-git-send-email-sergei.trofimov@arm.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1484670521-28503-1-git-send-email-sergei.trofimov@arm.com> References: <1484670521-28503-1-git-send-email-sergei.trofimov@arm.com> MIME-Version: 1.0 X-Originating-IP: [217.140.96.140] X-ClientProxiedBy: DB6PR0301CA0004.eurprd03.prod.outlook.com (10.168.49.14) To AM5PR0801MB1746.eurprd08.prod.outlook.com (10.169.247.12) X-MS-Office365-Filtering-Correlation-Id: 7afb83f3-07c4-4a31-0c76-08d43ef5ecc8 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001); SRVR:AM5PR0801MB1746; X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1746; 3:F7GERp1mfeSV4khLh5gLt8YGw+8wNlhiyoDHeZbDZmhe+fwqyTCrPD/T46oks/FDwk9KfIs3OrF2HkS192PG4BJIBQzV0dT1guD3Fy5gu+bv68eftat7T+l1NU/3onBcfbFwkGM4Nn2z0VevKjhQH9yv1FQf33WQcaH8rMfL+O6hoBJfYb6S7gC+J6yq3KOAo7B9Ox5QaTUSKb7Fm80Ll3lS74qurkpPJYUN5zTvnLG4eDWDBzYkKV22xFS6NXS/qAPKfJxA8TU50grfF67hIA== X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1746; 25:N0l5WrNM6yQsThIxRF6lz08mmJ4DWOe106rqJmfEDYuStNJqhrcHxIvotGnyXa9uShLRfJO3BiiH6Miq3s/3XcpJSXjjyNXbb/eiLez8DywQafH8xP1VAG7dYDVfJC7hd7z70YEtvjv2Z7cwR+VP4BYHlsH1+Cf4vuIK2f0JslMEF3VF54IDHCQfCtOyyCtDU37fLCWbGriigZFMMoAHUG1C76e0qDmKLp4fJkglXbXHBcp+ETCcxAO6X4sYqqSSY0ZNUyUo+ZmWuXCoyBUGGUak7l4lsJFfGQytC5gD948xUSYUUh1uLXUU6tQxv5CvIxeh3YjrVUEdQzmTQiiQCq65s8BzTdaqBUwaG6BLUtnW6hZLaCpCD6FyRtbbs1FZ95F4jruQJ2Ss3LJ1TGNTSMMHDFXScjMWgpLH55r1+A2y0AExL6BEgxKHPxQA8Fpua3TciAJCqYOcE3tMfU7mJMqffB+yis+TiuSql1P3fEVUDMOUk5XOVp/xS/MPvvbmNNfQCOqP7a9Dm9gFYjQADvhpd0T2vAbdljrAxtLwVZiUN/+k47zjLxFVF1jCcxYcedUM3uO0JXv+f5IO6Y3LBK1PLJMNDTtncSGtrgnegJ4oULxeaFd17xW4hQNRGLIoww7tgk7T6PfDRWVXI6ytULDf8UW5kGqyhaVE4MuWRmourgMl2Wi7tCcvxk0cZ8XjzhawluPaKDP1S6XlqOxo3U+/5qdmMEOtdOWf6IAo6TdWKge+lpIPgr4wu2pxNyS2bqxDz8TVAHPUqwg60KHMTOwpJoUdNWs1Tcx1TxDtR4I= X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1746; 31:xq1gU5OwUanVz2Bbcl7sbYHwqvFUVrnEEKiUnmWbKaCQUzFWwlZzHfdceKTdI9jF/+aUY3SX1HQPLJE+8oA3CwhnJFnCPlUv5uViUG5HuZYMW3zFqKfmKzK89li8tMINhh7hXdYtMuIPXVp67cO49uMWPrAdww2X+2d0dcCcGuoc7Yx17o6M5innrPSLSYo4qU0QOYrWL/ErTYz/jPjKJPfRLFOzALdlpuATTPiOnm0p3050jUhjk5hHtM0IFXC/; 20:bXDqcsMC10XMxG0lVT2duGMb1vgIdy5eTETg0lPNwQkXsQAkMsTVEQwjQgJI5k6hbnEaHlJ3qQcnQbvCp7azDPdJC9ZlR/MD8i8r//1IHZ1wk+ReIkkAQsO3ySWaULmymZggzVANnBwhq580jjTzKL+z5wKIVVszy28rDHJz56M= NoDisclaimer: True X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(180628864354917)(72170088055959); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040375)(601004)(2401047)(5005006)(8121501046)(10201501046)(3002001)(6055026)(6041248)(20161123555025)(20161123560025)(20161123564025)(20161123562025)(6072148); SRVR:AM5PR0801MB1746; BCL:0; PCL:0; RULEID:; SRVR:AM5PR0801MB1746; X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1746; 4:LttY2YGmWs1K11DavxqM76sz9rjRIk+l4vy/I/846IR0riCC7aKBx8E/tWl3/CMGz1Az85m7T7CyVnW6Y3bWd1UuGuOA2PWFFG3dYbq/Qim+XYwkBv0PUfix7whYKO6JWHqKIDKaqPnqY1UpcbRG8QLl/LWFvXO9rsSjFOvTGS7CmM9Zb4qDWqgbDqKd0OH1F3f7xf540ZkzIK8MBPtOf2leiYvTX+sUOsKukr1Yf1lTQzxsS/0sALTg6YoaOEFyuXfYla6iu5aDO/Y+5sHkrWHnA+cw4xqGQURMVWNLTacjOJ2EOrNxQe9qnq8dbaSQ0JMsmiCRHuCBAM5xCIOGBXGXTQl39FN1i986UMBjkEvsh22KAcAOHBO3iCnSSPM0w6Z7m6sf3ZoP8z8D6rZ3NS8ml21PI5W1S104/1QXX7O10GJ5lxQfLdXIZZSfGsmPVOXo8RVhewvPt/phcp6WmlaWRfLryifJ1vAfLG1ID8B4BhJ+WBKetYc4FylCIxmB1f80S6phO3aTmX5Hq8zVBj64rya3wbiWcCI2fMKYykqDVMclzAc4N4tu2aODFOkcO+Rba1VU1w88/PYnzL3cLg0MJxePGifj16szEQMLnCBgHF3fClUwlWUDrrlmLfW+CNoEyrD5OzLfHMOwWXY5br2BAPxDs2DvrcLnp0lgPsU= X-Forefront-PRVS: 01901B3451 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6009001)(7916002)(39450400003)(39840400002)(39410400002)(39860400002)(39850400002)(199003)(189002)(6666003)(31430400001)(81166006)(8676002)(50226002)(81156014)(305945005)(450100001)(7736002)(38730400001)(2950100002)(6116002)(97736004)(92566002)(6916009)(47776003)(2906002)(3846002)(54906002)(33646002)(66066001)(48376002)(50466002)(50986999)(189998001)(4326007)(76176999)(25786008)(36756003)(6486002)(110136003)(106356001)(105586002)(5660300001)(575784001)(101416001)(68736007)(42186005)(2351001)(86362001)(5003940100001)(217873001); DIR:OUT; SFP:1101; SCL:1; SRVR:AM5PR0801MB1746; H:e109786-lin.cambridge.arm.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: arm.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; AM5PR0801MB1746; 23:fw3IRz7aYtam166NP3k6cyZLMS54DgE5jkElW/j?= URWZDoPulcabrpCRZ8fEuqZSKtnSecoiXQqrhzHWzu+bt1nyUREha4nE8Zb9HklfXy+nLRBoq5DggZ0Z0eVRQj4Tsp2kvBYrBPwgw9ItuupHaDVvqmdDmZ3EY/YRg7597W5fcY2jZzNnHmP4LtjXkmoiR+XS1wbggy+BA0hkbtuHmxidtugFpT1VrB5NF4OuGGgsL/ZxM6fG9PEggK5NmsqtsZXu5C3DFN4uFfk6vi0DKwX+u1utp1d2pK8GGE/Acu6AMwko49yu8wLqj83KtYoOt75uen9UABBhpHb0oV/WeaAgpJlwpkM9v+QS13alMXDnfUZhnhh8zPm9tPPIvn+G3fy8KpdZfiXIz65bRnzYfceLLWhe6TGDfVGEO29rqvKlpfVC5zFEqGsbloSUYywZdhA5qEhvbi3vgtX/HY/4baaUgJFSUAAKCM/7fflPGk7BxG93aY+qN80a+SDIKcQRVTOBeodpUrBJVxoN3hNNFQfTh/fTy0fOoOHXMyRS5+JD/hoi+ARJaNJ2c5r3gd22rZ5sa16/8dLkH2lISrQkTuCzwkv3dXQyGldARB81UHO4XOFxmB2A9T2fAUyRZT1+1y5CWrTQr5jAYsE8cjjzC6mvZ94lcSElRVhX9uhaDnXEKlDbzCPr1vAytiDEwlc5eenfCPa+/N4NxszektucAdN6F5Btp2EZsE4JzVaxFC0r82xIuhTPoS9pfgKKPiCHxEz1DJ3g1JqoDwWzBk9X3DI69JLinSGvec1llJlP34jQvEDhXzBcnzQrf9EyPLsxMAEW1ToiWQEZT+O0QKI19WBuoi4lqgcwLeTX+s58fZXjvISJmTwHDTOihIGwfw6KssFdwrfrP3S5zJzVLSkczHj0EjIo25uANFrzGjzXDLYb5SZ0hu9ZMjbs/LqsiXI4ulFqx9gZOzOKktl2OQck9DBXI2I1HwMmd8Q3LayzanUwI5jfZdGCPEa6onGihcEcA7gMMOHFfNkxPKfSEkLm08DDc3xfumfVC8vJTWdMEp55JjH+APV1fZAtymVSlqmBxaEAvY3hyi2uiSnbjmRTcizBh/uouu/Nq9s80RuviyzeYvfOaydYxLWgx6aGtDyX4Go3p0Lm+c6yTbk9hFBUlOZJ38YCwrI+Fytpj2FlMtIuM7u3UEhUEDfdhGmuzVjKCfucLdZGmu1i/iBn2iUrxcE1xuSZ2DDgOgNTv2KUjrY2hLxpee/WHS7Qih+MMYIRc9m8klg8DCN+A4kXPwOcgmA== X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1746; 6:Jygvwj+8Glo6GsfeRTi3iDAtqj9TLJETkde9gRPabcCbCrHTIIxMWqvCsqe+qT9lR4kWHjZD8WsRIL3PTE3FmgP7Zp51tbwvVX4cr0ToDcl8jdYndDlcoqDD9Zql1A11DoLoIK2QW4FR9RrjYp6is6iCkep12oSgK4GpPkP/HXP53SP9xTRpVnayGDdFzOOrNdb0/RTvK2nav5NsPKRCfvEcarxXUOWnF8N5W1yxfcjvzUW+M5QPboNxVIJKrgwrWCpILAdZ1K9vSC75trM3OQ7/NEG4Dwl7rqJ/FpBk5hxyH28UI0X88FhkbU+DcgZjLG2EYaj9eVSeK5jfcrc7G4W92QMsMdUAZ0iShRs0rxfqWu4gJKyWVFGynbc3BgUOXMncpybCEphJbNh7phG6m7xx1O4fquE9YINiuNI0q+B8FdRTuNWbgtb7rFib+Xvs6etp2fjrCEdnRpn/J1oQeA==; 5:Rlbe4iW5BjaeiUBx8JYG9Eb81u1CaNe203MNAuAZGjirhaqQ0fqEacdvEqQ/wT+46ny/MP708QitgDvNsZZwSA9Gi8BX1tpsEzrQyqouTlOohF2ZwsRmt4BBw/OHI6YMy3msrceJf0CQhuRhak8d7A==; 24:8DbdmWFLJdYwlnEXGhw7LDCxQWV+dk/YivPwVaZ1DqYDMj43iF+6+UwQAmK2rB4hxqPl+3VIiMPeLpvcCbK6GlaqrqtXrPw2+3fTmbNNtxw= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1746; 7:8rfoSN9IG+vqDf2s2x5xsBGgqSUrloQyly+nwUoBkiDqd8RGtH9D7/OEPGgZl7f2asjI2CZ4pyMpo3XOhe8ssqFvxaLy2JrtHAeRL0QELe3xDYbQPeH/N0A+s64I0tbzf9a94rms1Is3rUzyNF+OGRXtZB99xHjzaQuyzIkxD7BJgIn9OrIoGeZydu2pYVHEWeig7zyohPOFfm8sKpsCKQnFTncW43saU2yIltykyjsU3nqwcFxeCtz7leLmWvDQDdzBcOWhShU5ac4z+L6WCQ10hc+FR7oBBpVh6LXu0oJmPMW7MHT62mK+vjVv5CgK+fZY5pY+Lz2EHB8cEVJtMgynfhPcpYOtcsburbuyayZQMZSGp+K8srx4LX5adqTvxDlp+8w5A5JHOX3UQ5+eRyQOQ52mFVndN/MPIOMncis0RyPoyFPtei42vNQWfsecHgFr3JzDLj4L4cwHXyPSkg== X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Jan 2017 16:28:52.4493 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM5PR0801MB1746 Cc: nd@arm.com Subject: [lng-odp] [API-NEXT PATCH 5/5] power: Adding a power governor implementation X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "The OpenDataPlane \(ODP\) List" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: lng-odp-bounces@lists.linaro.org Sender: "lng-odp" Adding an API for a power governor. A governor will try to optimise power usage within an associated power domains by monitoring packet queue(s) to determine how much "performance" is necessary at a given point in time. This also implements a PoC DVFS governor that will step down the frequency periodically while the queue is under the thershold and jump to max if thershold is exceeded (this a similar behavior to the Linux ondemand cpufreq governor). Signed-off-by: Sergei Trofimov --- doc/users-guide/users-guide.adoc | 7 + include/odp/api/spec/power.h | 37 ++++ platform/linux-generic/Makefile.am | 1 + .../linux-generic/include/odp_config_internal.h | 5 + platform/linux-generic/include/odp_internal.h | 4 + platform/linux-generic/odp_init.c | 12 ++ platform/linux-generic/odp_power_governor.c | 220 +++++++++++++++++++++ 7 files changed, 286 insertions(+) create mode 100644 platform/linux-generic/odp_power_governor.c -- 1.9.1 diff --git a/doc/users-guide/users-guide.adoc b/doc/users-guide/users-guide.adoc index 41c57d1..00299cf 100755 --- a/doc/users-guide/users-guide.adoc +++ b/doc/users-guide/users-guide.adoc @@ -404,6 +404,13 @@ types of atomic variables. The ODP event model also makes use of queues to avoid the need for explicit locking in many cases. This will be discussed in the next section. +=== Power Governor +A power governor will try to minimize power usage of a set of cores while +maintaining QoS on one or more queues. The API define an interface for +initializing a governor for a set of CPUs specified by a mask, and for +registering and unregistering queues that will be monitored for QoS with an +existing governor. + == ODP Components == Building on ODP concepts, ODP offers several components that relate to the flow of work through an ODP application. These include the Classifier, diff --git a/include/odp/api/spec/power.h b/include/odp/api/spec/power.h index 26dd64e..09a4b0a 100644 --- a/include/odp/api/spec/power.h +++ b/include/odp/api/spec/power.h @@ -18,12 +18,20 @@ #include #include + #include +#include +#include +#include #ifdef __cplusplus extern "C" { #endif +typedef ODP_HANDLE_T(odp_power_governor_t); + +#define ODP_POWER_GOVERNOR_INVALID _odp_cast_scalar(odp_power_governor_t, 0) + /** * CPU power domain description. @@ -108,6 +116,35 @@ int odp_power_domain_set_perf_level(odp_power_domain_t *domain, int level); */ uint64_t odp_power_domain_get_perf_level(odp_power_domain_t *domain); +/** + * Initialize a power governor for the specified power domain. + * + * @param domain domain to be governed + * + */ +odp_power_governor_t odp_power_governor_init(odp_cpumask_t *cpus); + +/** + * + * Add a queue to be monitored by the power governor. The governor will be notified when the + * queue hits the specified threshold and will boost performance if possible. + * + * @param governor power governor to which the queue will be added + * @param queue queue who's depth will be monitored to determine when power + * needs to be boosted. + * @param threshold queue depth threshold at which power will be boosted (if possible). + */ +int odp_power_governor_add_queue(odp_power_governor_t governor, odp_queue_t queue, uint64_t threshold); + +/** + * Remove the queue from being monitored by the specified power governor. + * + * @param governor power governor to which the queue will be added + * @param queue queue who's depth will be monitored to determine when power + * needs to be boosted. + */ +int odp_power_governor_remove_queue(odp_power_governor_t governor, odp_queue_t queue); + #ifdef __cplusplus } #endif diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 738c582..16832cd 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -207,6 +207,7 @@ __LIB__libodp_linux_la_SOURCES = \ odp_pkt_queue.c \ odp_pool.c \ odp_power.c \ + odp_power_governor.c \ odp_queue.c \ odp_rwlock.c \ odp_rwlock_recursive.c \ diff --git a/platform/linux-generic/include/odp_config_internal.h b/platform/linux-generic/include/odp_config_internal.h index dadd59e..c0d12dd 100644 --- a/platform/linux-generic/include/odp_config_internal.h +++ b/platform/linux-generic/include/odp_config_internal.h @@ -130,6 +130,11 @@ extern "C" { #define CONFIG_BURST_SIZE 16 /* + * Maximum number of power governors + */ +#define ODP_CONFIG_POWER_GOVERNORS 16 + +/* * Maximum number of events in a pool */ #define CONFIG_POOL_MAX_NUM (1 * 1024 * 1024) diff --git a/platform/linux-generic/include/odp_internal.h b/platform/linux-generic/include/odp_internal.h index b313b1f..c84239d 100644 --- a/platform/linux-generic/include/odp_internal.h +++ b/platform/linux-generic/include/odp_internal.h @@ -69,6 +69,7 @@ enum init_stage { CLASSIFICATION_INIT, TRAFFIC_MNGR_INIT, NAME_TABLE_INIT, + POWER_GOVERNOR_INIT, ALL_INIT /* All init stages completed */ }; @@ -116,6 +117,9 @@ int odp_time_term_global(void); int odp_tm_init_global(void); int odp_tm_term_global(void); +int odp_power_governor_init_global(void); +int odp_power_governor_term_global(void); + int _odp_int_name_tbl_init_global(void); int _odp_int_name_tbl_term_global(void); diff --git a/platform/linux-generic/odp_init.c b/platform/linux-generic/odp_init.c index 06c6143..56df042 100644 --- a/platform/linux-generic/odp_init.c +++ b/platform/linux-generic/odp_init.c @@ -179,6 +179,13 @@ int odp_init_global(odp_instance_t *instance, ODP_ERR("ODP name table init failed\n"); goto init_failed; } + stage = NAME_TABLE_INIT; + + if (odp_power_governor_init_global()) { + ODP_ERR("ODP power governor init failed\n"); + goto init_failed; + } + stage = POWER_GOVERNOR_INIT; *instance = (odp_instance_t)odp_global_data.main_pid; @@ -204,6 +211,11 @@ int _odp_term_global(enum init_stage stage) switch (stage) { case ALL_INIT: + case POWER_GOVERNOR_INIT: + if (odp_power_governor_term_global()) { + ODP_ERR("Power governor term failed.\n"); + rc = -1; + } case NAME_TABLE_INIT: if (_odp_int_name_tbl_term_global()) { ODP_ERR("Name table term failed.\n"); diff --git a/platform/linux-generic/odp_power_governor.c b/platform/linux-generic/odp_power_governor.c new file mode 100644 index 0000000..1f30ffd --- /dev/null +++ b/platform/linux-generic/odp_power_governor.c @@ -0,0 +1,220 @@ +#define _POSIX_C_SOURCE 199309L + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +struct power_governor_entry_s; +typedef struct power_governor_entry_s { + struct power_governor_entry_s *next; + odp_spinlock_t lock; + odp_power_domain_t *domain; + odp_queue_t queue; + int current_perf_level_idx; + int _stop; + timer_t timer; + pthread_t thread; + odp_pool_t pool; + odp_event_t event; +} power_governor_entry_t; + +typedef struct power_governor_table_t { + power_governor_entry_t power_governor[ODP_CONFIG_POWER_GOVERNORS]; + uint32_t num_entries; +} power_governor_table_t; + +static power_governor_table_t *power_governor_tbl; + +static inline odp_power_governor_t power_governor_index_to_handle(uint32_t power_governor_id) +{ + return _odp_cast_scalar(odp_power_governor_t, power_governor_id); +} + +static inline uint32_t power_governor_handle_to_index(odp_power_governor_t power_governor_hdl) +{ + return _odp_typeval(power_governor_hdl); +} + +static inline power_governor_entry_t *get_power_governor_entry(uint32_t index) { + return &power_governor_tbl->power_governor[index]; +} + +static void governor_reset_timer(power_governor_entry_t *the_governor) +{ + struct itimerspec spec; + + spec.it_interval.tv_sec = 0; + spec.it_interval.tv_nsec = 0; + spec.it_value.tv_sec = 0; + spec.it_value.tv_nsec = 10000000; + timer_settime(the_governor->timer, 0, &spec, NULL); +} + +static void governor_spindown_cores(union sigval val) +{ + power_governor_entry_t *the_governor = (power_governor_entry_t *)val.sival_ptr; + odp_spinlock_lock(&the_governor->lock); + odp_power_domain_t *pdom = the_governor->domain; + + if (the_governor->current_perf_level_idx > 0) { + uint64_t next_level = pdom->perf_levels[--the_governor->current_perf_level_idx]; + odp_power_domain_set_perf_level(pdom, next_level); + governor_reset_timer(the_governor); + } + + odp_spinlock_unlock(&the_governor->lock); +} + +static void *governor_monitor(void *arg) +{ + power_governor_entry_t *the_governor = (power_governor_entry_t *)arg; + + while (1) { + odp_event_t event = odp_queue_deq_wait(the_governor->queue); + + if (the_governor->_stop) + break; + + odp_spinlock_lock(&the_governor->lock); + + odp_power_domain_t *pdom = the_governor->domain; + uint64_t max_level = pdom->perf_levels[pdom->num_perf_levels - 1]; + + if (the_governor->current_perf_level_idx < pdom->num_perf_levels - 1) { + odp_power_domain_set_perf_level(pdom, max_level); + the_governor->current_perf_level_idx = pdom->num_perf_levels - 1; + governor_reset_timer(the_governor); + } + + odp_spinlock_unlock(&the_governor->lock); + odp_queue_threshold_arm(the_governor->queue, event); + } + + return NULL; +} + +int odp_power_governor_init_global(void) +{ + odp_shm_t shm; + + shm = odp_shm_reserve("odp_power_governors", + sizeof(power_governor_table_t), + sizeof(power_governor_entry_t), 0); + + power_governor_tbl = odp_shm_addr(shm); + + if (power_governor_tbl == NULL) + return -1; + + memset(power_governor_tbl, 0, sizeof(power_governor_table_t)); + + return 0; +} + +int odp_power_governor_term_global(void) +{ + int ret = odp_shm_free(odp_shm_lookup("odp_power_governors")); + if (ret < 0) { + ODP_ERR("shm free failed for odp_power_governors"); + return ret; + } + + return 0; +} + +odp_power_governor_t odp_power_governor_init(odp_cpumask_t *cpus) +{ + odp_power_domain_info_t cpu_info; + odp_power_domain_info_populate(&cpu_info); + odp_power_domain_t *domain = odp_power_domain_for_cpu(&cpu_info, odp_cpumask_first(cpus)); + + if (power_governor_tbl->num_entries == ODP_CONFIG_POWER_GOVERNORS) { + errno = ENOMEM; + return ODP_POWER_GOVERNOR_INVALID; + } + power_governor_entry_t *the_governor = &power_governor_tbl->power_governor[power_governor_tbl->num_entries++]; + + odp_spinlock_init(&the_governor->lock); + the_governor->next = NULL; + + odp_queue_param_t qparams; + odp_queue_param_init(&qparams); + qparams.type = ODP_QUEUE_TYPE_NOTIF; + the_governor->queue = odp_queue_create("power-governor-queue", &qparams); + if (the_governor->queue == ODP_QUEUE_INVALID) { + errno = EINVAL; + return ODP_POWER_GOVERNOR_INVALID; + } + + the_governor->_stop = 0; + + the_governor->domain = domain; + int current_perf_level = odp_power_domain_get_perf_level(domain); + int i; + for (i =0; i < domain->num_perf_levels; i++) { + if (current_perf_level == domain->perf_levels[i]) { + the_governor->current_perf_level_idx = i; + break; + } + } + + odp_pool_param_t params; + odp_pool_param_init(¶ms); + params.buf.size = sizeof(void *); + params.buf.num = 1; + params.buf.align = 0; + params.type = ODP_POOL_BUFFER; + + the_governor->pool = odp_pool_create("power_governor_pool", ¶ms); + odp_buffer_t buffer = odp_buffer_alloc(the_governor->pool); + *(void **)odp_buffer_addr(buffer) = (void *)&the_governor; + the_governor->event = odp_buffer_to_event(buffer); + + struct sigevent sev; + sev.sigev_notify = SIGEV_THREAD; + sev.sigev_value.sival_ptr = (void *)the_governor; + sev.sigev_notify_function = governor_spindown_cores; + sev.sigev_notify_attributes = NULL; + + int ret = timer_create(CLOCK_MONOTONIC, &sev, &the_governor->timer); + if (ret == -1) { + return ODP_POWER_GOVERNOR_INVALID; + } + + ret = pthread_create(&the_governor->thread, NULL, governor_monitor, the_governor); + if (ret) { + errno = ret; + return ODP_POWER_GOVERNOR_INVALID; + } + + governor_reset_timer(the_governor); + + return power_governor_index_to_handle(power_governor_tbl->num_entries - 1); +} + +int odp_power_governor_add_queue(odp_power_governor_t handle, odp_queue_t targetq, uint64_t threshold) +{ + uint32_t index = power_governor_handle_to_index(handle); + power_governor_entry_t *the_governor = get_power_governor_entry(index); + odp_queue_threshold_arm(the_governor->queue, the_governor->event); + return odp_queue_threshold_set(targetq, threshold, the_governor->queue); +} + +int odp_power_governor_remove_queue(odp_power_governor_t handle ODP_UNUSED, odp_queue_t targetq) +{ + return odp_queue_threshold_reset(targetq); +}