From patchwork Thu Aug 3 05:00:08 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Github ODP bot X-Patchwork-Id: 109297 Delivered-To: patch@linaro.org Received: by 10.140.101.6 with SMTP id t6csp305255qge; Wed, 2 Aug 2017 22:01:23 -0700 (PDT) X-Received: by 10.55.201.202 with SMTP id m71mr870685qkl.140.1501736483749; Wed, 02 Aug 2017 22:01:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1501736483; cv=none; d=google.com; s=arc-20160816; b=d0OFEd4VeRMEWHiUAUDTgZzTXCSaGDcdDMSfMUDxAq+bKwnIlaPCnMAYUYQqjESbgB uTSD9HMdeuvM2+Fdz9192O8nnjU7d1aMYdSchkqsz5KApFJ+j1occfWuaiZ4HCxW3FgI TSu1Cl2SttleQmisR3UUWz4x5A2SD83Lsv8EV04TIIogQNuQdN2gYXBlHgSaBpHvRQlW pGAHI7xg7v+cxEPIsMsc+KiD3K1olxt/FX8gVrQz9M4T24KYGF/Fx+QL9+SZwzvyBpNx QpPOJ3OjgZ6XOKuS8N2TzqChxjax3dJvlxlfeEOa02+M0PKI6zjrv6QEFBg5Tj4OcG72 zsWA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:github-pr-num :references:in-reply-to:message-id:date:to:from:delivered-to :arc-authentication-results; bh=7eEHuIZ1JNvJ6xDHQ3dQvS2uujZnRXIgaGe4LkSh5uk=; b=wE3u5fhnD+WTALz7y/mH7mcoiYJyRjgmGeUJZxu68ImRMNXfw3X49dS1Uymhjl2YMc 9E4N5U477fiZB4hm6/CZv0xzZ1nSXCLnN9R810M7PJPB1/qgRK4lHOXi1qKEZHmrbvYJ x7dIoJvfXaRGyb9DPSBQqLFuReKcJ4YtNhakQp2yVweVIoE/IikJeyaDsp3OvLZCJ/bI DH0BbpYth/gC2Q0bz4cz9JhPBo5TMgf0fB1jU+Hb5vl3XbAqSi8np71G72uslB1SCS7R 2uKRa52ZkPdUwtTWx9wL+9Cddu5TiI/LL4TnZglH/yPN2QlGMbVnuN26PJ2qfpeLD7bw 51zg== ARC-Authentication-Results: i=1; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id 49si957153qtq.306.2017.08.02.22.01.23; Wed, 02 Aug 2017 22:01:23 -0700 (PDT) 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Received: by lists.linaro.org (Postfix, from userid 109) id 77C3F60C79; Thu, 3 Aug 2017 05:01:23 +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=-2.6 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_LOW,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 7483260666; Thu, 3 Aug 2017 05:01: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 6B5A060C5E; Thu, 3 Aug 2017 05:01:12 +0000 (UTC) Received: from forward3j.cmail.yandex.net (forward3j.cmail.yandex.net [5.255.227.21]) by lists.linaro.org (Postfix) with ESMTPS id 0424860666 for ; Thu, 3 Aug 2017 05:00:41 +0000 (UTC) Received: from smtp4o.mail.yandex.net (smtp4o.mail.yandex.net [37.140.190.29]) by forward3j.cmail.yandex.net (Yandex) with ESMTP id 8D895206BA for ; Thu, 3 Aug 2017 08:00:39 +0300 (MSK) Received: from smtp4o.mail.yandex.net (localhost.localdomain [127.0.0.1]) by smtp4o.mail.yandex.net (Yandex) with ESMTP id 5A5D96C01145 for ; Thu, 3 Aug 2017 08:00:21 +0300 (MSK) Received: by smtp4o.mail.yandex.net (nwsmtp/Yandex) with ESMTPSA id xjXRCJHRIW-0JRSkON4; Thu, 03 Aug 2017 08:00:19 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (Client certificate not present) X-Yandex-Suid-Status: 1 0 From: Github ODP bot To: lng-odp@lists.linaro.org Date: Thu, 3 Aug 2017 08:00:08 +0300 Message-Id: <1501736410-15618-2-git-send-email-odpbot@yandex.ru> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1501736410-15618-1-git-send-email-odpbot@yandex.ru> References: <1501736410-15618-1-git-send-email-odpbot@yandex.ru> Github-pr-num: 65 Subject: [lng-odp] [PATCH CLOUD-DEV v4 1/3] example: ddf_app: add .gitignore 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" From: Yi He Signed-off-by: Yi He --- /** Email created from pull request 65 (heyi-linaro:modular-framework) ** https://github.com/Linaro/odp/pull/65 ** Patch: https://github.com/Linaro/odp/pull/65.patch ** Base sha: 1ba26aa5650c05718c177842178de6d0f70b7fc1 ** Merge commit sha: bf1d072772b57f96a842e5d2b57e3f9f9eed0107 **/ example/ddf_app/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 example/ddf_app/.gitignore diff --git a/example/ddf_app/.gitignore b/example/ddf_app/.gitignore new file mode 100644 index 00000000..f79a1409 --- /dev/null +++ b/example/ddf_app/.gitignore @@ -0,0 +1 @@ +odp_ddf_app From patchwork Thu Aug 3 05:00:09 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Github ODP bot X-Patchwork-Id: 109298 Delivered-To: patch@linaro.org Received: by 10.140.101.6 with SMTP id t6csp305635qge; Wed, 2 Aug 2017 22:01:49 -0700 (PDT) X-Received: by 10.55.209.86 with SMTP id s83mr738061qki.171.1501736509283; Wed, 02 Aug 2017 22:01:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1501736509; cv=none; d=google.com; s=arc-20160816; b=A29xwWp8XVTa4er8MZQWm3O0e3acN04WmatF/rJi4OLFY+AynyZq5dbv+SoqeWqnsT jutTPDQ43p1JOs5U37OodJ0G8Z7dTZ23+L+DvwCDYwHo/mqHXJCSK5Ycziv/9zO2lBUE S16SZrVOm5OgT+dXL+JdzaZnc39bu2dGM+ZNa9/sjJCFo6YPIvxvHpMGIpEZtLNlrFTK 97gvY1/i7A98DHyp857v29J1fP80ZD9ULEt8sB3c1qM4Fg+FKBS0U+7oncU059LBsWd2 ByF4LoknX+dHjVcrK1Mzxw9PXqXA5DrxHpUOktlFA+v1UbHATOaBUS64DgjmoEk7+f8O S+WA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:github-pr-num :references:in-reply-to:message-id:date:to:from:delivered-to :arc-authentication-results; bh=bgsnSOXq6YoBnwNK3fXoT0Ufz+XIWL12vbuZfSAoWTw=; b=DDeUbdjjdFBoZ59ZRKdlRfLC4+GMieluXwUGlJVpFLD/qMWhVHU5FvMzoSaA2ORUzQ 0p0vdRPAdakCkAzzstlYCvh19ATbxPPJ0gq6fFJUWtoIJPIpvzVFUHz+JOcqlmpBhVZp R3wgPFR+633sbVo+dH2D6t0tFD0EI+W9bXGytoz/1KgYwvHQyTMdK1rHAZbqhN5aNfNu JKjvaVo9M3OPvP93WdMHoqznxmmJxl+y7m2xkRZMR1PdSG/aNPkvUcPSKJwjEX/h6mm8 LOU9S1YQoeOeM8IDZI1+OFWBMTvKlJWq8cpnx719MsFHVxXhq/y4oWFpIk19CxeO1Nce XBig== ARC-Authentication-Results: i=1; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id q3si3090724qtq.264.2017.08.02.22.01.49; Wed, 02 Aug 2017 22:01:49 -0700 (PDT) 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Received: by lists.linaro.org (Postfix, from userid 109) id F3E6260C6A; Thu, 3 Aug 2017 05:01:48 +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=-2.6 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_LOW,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 D611F606D0; Thu, 3 Aug 2017 05:01:18 +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 AAB4560696; Thu, 3 Aug 2017 05:01:12 +0000 (UTC) Received: from forward4p.cmail.yandex.net (forward4p.cmail.yandex.net [77.88.31.19]) by lists.linaro.org (Postfix) with ESMTPS id BB91960A58 for ; Thu, 3 Aug 2017 05:00:37 +0000 (UTC) Received: from smtp4o.mail.yandex.net (smtp4o.mail.yandex.net [IPv6:2a02:6b8:0:1a2d::28]) by forward4p.cmail.yandex.net (Yandex) with ESMTP id AED1220C7C for ; Thu, 3 Aug 2017 08:00:35 +0300 (MSK) Received: from smtp4o.mail.yandex.net (localhost.localdomain [127.0.0.1]) by smtp4o.mail.yandex.net (Yandex) with ESMTP id C9B916C01183 for ; Thu, 3 Aug 2017 08:00:23 +0300 (MSK) Received: by smtp4o.mail.yandex.net (nwsmtp/Yandex) with ESMTPSA id xjXRCJHRIW-0MRmnQWb; Thu, 03 Aug 2017 08:00:22 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (Client certificate not present) X-Yandex-Suid-Status: 1 0 From: Github ODP bot To: lng-odp@lists.linaro.org Date: Thu, 3 Aug 2017 08:00:09 +0300 Message-Id: <1501736410-15618-3-git-send-email-odpbot@yandex.ru> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1501736410-15618-1-git-send-email-odpbot@yandex.ru> References: <1501736410-15618-1-git-send-email-odpbot@yandex.ru> Github-pr-num: 65 Subject: [lng-odp] [PATCH CLOUD-DEV v4 2/3] validation: pktio: disable socket mmsg pktio 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" From: Yi He It was not working already, the problem are obscured in make check because with static pktio_if_ops array socket mmap pktio always take precedence over socket mmsg pktio. Signed-off-by: Yi He --- /** Email created from pull request 65 (heyi-linaro:modular-framework) ** https://github.com/Linaro/odp/pull/65 ** Patch: https://github.com/Linaro/odp/pull/65.patch ** Base sha: 1ba26aa5650c05718c177842178de6d0f70b7fc1 ** Merge commit sha: bf1d072772b57f96a842e5d2b57e3f9f9eed0107 **/ test/linux-generic/validation/api/pktio/pktio_env | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/linux-generic/validation/api/pktio/pktio_env b/test/linux-generic/validation/api/pktio/pktio_env index 345b5bd5..3a6f9e89 100644 --- a/test/linux-generic/validation/api/pktio/pktio_env +++ b/test/linux-generic/validation/api/pktio/pktio_env @@ -103,6 +103,9 @@ setup_pktio_env() return 5 fi done + + # disable socket mmsg pktio since it was not working already + export ODP_PKTIO_DISABLE_SOCKET_MMSG=1 } cleanup_pktio_env() From patchwork Thu Aug 3 05:00:10 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Github ODP bot X-Patchwork-Id: 109299 Delivered-To: patch@linaro.org Received: by 10.140.101.6 with SMTP id t6csp306093qge; Wed, 2 Aug 2017 22:02:24 -0700 (PDT) X-Received: by 10.237.42.55 with SMTP id c52mr507450qtd.311.1501736544371; Wed, 02 Aug 2017 22:02:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1501736544; cv=none; d=google.com; s=arc-20160816; b=vyvXSLiCPye/YU2EWqMO3ttYx58MSDffL9qRLVPvZZhzs7VNIe1CVIPaXJCSzRwlo+ zwvSezyWf4VCuEj/fhE0WyuL8s4MQ/fyyEEuigBM7lOk7NAIvzgFeYdx9StVKmY3rkb8 lpTRI9KbAU50DNre0Aawn3kh6Z3/TNLjgm4OUkYnYx4ZcM4wol3spllFgDI7fZ6KgOcM R/ec7X43N0/eopufGGGY3E5/dEDebpWqqPHD1f/ziIHCxTOCbbMOjFsFi8GxxDINzqQD JkmpKiw4gYnaEsQwIHdHFVr35BjrXDS3JULhInKUIUjnUKG+/fiLLRi6GnZsP3FC9c/l Dzdw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:github-pr-num :references:in-reply-to:message-id:date:to:from:delivered-to :arc-authentication-results; bh=Hw8dsWcHxJvmvu+5ry+gSDQlklIfYKLeOKK/6w4EYDQ=; b=z78PR1IXvqugFHLSWaqeEX2k0VUvDowwiBf0pI6fUE06WdX1CFvKqRuOms7H0P/Z8h 0etfmJmJhGCmV+GDYX0f+pl15Ixbslm0L96z9rYyC+h7CxkLzl2EZ6mce+comLHfiiv1 jky9FVEZLS+3gsbAW6YKklC5vjPDSm+nXurMfloy3AopdpXtYQHK++hOTcVQ/fTkLyQG xLNMD8RMzIOWLLZXVcs2pzrDICw+MchgZ8gPUr9cK1jGH2WCCZjM5qPkn3zGWWF0n08Q aN1S2Ay1I2iS3yhKT4aH7qlh8D9F5o3IrJ6ZcnpqXlFq6uh4tvXDmXahvLcmGsUfuvGg ZUQQ== ARC-Authentication-Results: i=1; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id f7si30825007qte.231.2017.08.02.22.02.24; Wed, 02 Aug 2017 22:02:24 -0700 (PDT) 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Received: by lists.linaro.org (Postfix, from userid 109) id 1122A60BEA; Thu, 3 Aug 2017 05:02:24 +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=-0.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, URIBL_BLOCKED, URIBL_SBL, URIBL_SBL_A 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 60DE960CA0; Thu, 3 Aug 2017 05:01:33 +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 8C54660C6A; Thu, 3 Aug 2017 05:01:20 +0000 (UTC) Received: from forward1m.cmail.yandex.net (forward1m.cmail.yandex.net [5.255.216.2]) by lists.linaro.org (Postfix) with ESMTPS id 0310B60BEA for ; Thu, 3 Aug 2017 05:00:39 +0000 (UTC) Received: from smtp4o.mail.yandex.net (smtp4o.mail.yandex.net [37.140.190.29]) by forward1m.cmail.yandex.net (Yandex) with ESMTP id 6C1A621071 for ; Thu, 3 Aug 2017 08:00:36 +0300 (MSK) Received: from smtp4o.mail.yandex.net (localhost.localdomain [127.0.0.1]) by smtp4o.mail.yandex.net (Yandex) with ESMTP id 25E2B6C0113F for ; Thu, 3 Aug 2017 08:00:25 +0300 (MSK) Received: by smtp4o.mail.yandex.net (nwsmtp/Yandex) with ESMTPSA id xjXRCJHRIW-0ORC3mit; Thu, 03 Aug 2017 08:00:24 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (Client certificate not present) X-Yandex-Suid-Status: 1 0 From: Github ODP bot To: lng-odp@lists.linaro.org Date: Thu, 3 Aug 2017 08:00:10 +0300 Message-Id: <1501736410-15618-4-git-send-email-odpbot@yandex.ru> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1501736410-15618-1-git-send-email-odpbot@yandex.ru> References: <1501736410-15618-1-git-send-email-odpbot@yandex.ru> Github-pr-num: 65 Subject: [lng-odp] [PATCH CLOUD-DEV v4 3/3] odp: add modular framework 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" From: Yi He Add modular programming framework to support selectable implementations for variant software subsystems. Signed-off-by: Yi He --- /** Email created from pull request 65 (heyi-linaro:modular-framework) ** https://github.com/Linaro/odp/pull/65 ** Patch: https://github.com/Linaro/odp/pull/65.patch ** Base sha: 1ba26aa5650c05718c177842178de6d0f70b7fc1 ** Merge commit sha: bf1d072772b57f96a842e5d2b57e3f9f9eed0107 **/ frameworks/modular/list.h | 271 +++++++++++++++++++ frameworks/modular/odp_module.c | 179 +++++++++++++ frameworks/modular/odp_module.h | 296 +++++++++++++++++++++ include/odp/api/spec/atomic.h | 6 + include/odp/api/spec/rwlock.h | 5 + platform/linux-generic/Makefile.am | 8 + .../include/odp/api/plat/atomic_types.h | 2 + .../include/odp/api/plat/rwlock_types.h | 2 + 8 files changed, 769 insertions(+) create mode 100644 frameworks/modular/list.h create mode 100644 frameworks/modular/odp_module.c create mode 100644 frameworks/modular/odp_module.h diff --git a/frameworks/modular/list.h b/frameworks/modular/list.h new file mode 100644 index 00000000..cc42b714 --- /dev/null +++ b/frameworks/modular/list.h @@ -0,0 +1,271 @@ +/* Adopted and modified Rusty Russell CCAN Project + * https://github.com/rustyrussell/ccan + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2017, ARM Limited. All rights reserved. + * + * Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CCAN_LIST_H +#define CCAN_LIST_H + +#include +#include + +/* Always assume the availabilities of typeof or __typeof__ */ +#if defined(__STDC__) +#define typeof __typeof__ +#endif + +/** + * struct list_node - an entry in a doubly-linked list + * @next: next entry (self if empty) + * @prev: previous entry (self if empty) + * + * This is used as an entry in a linked list. + * Example: + * struct child { + * const char *name; + * // Linked list of all us children. + * struct list_node list; + * }; + */ +struct list_node { + struct list_node *next, *prev; +}; + +/** + * struct list_head - the head of a doubly-linked list + * @node: the head node + * + * This is used as the head of a linked list. + * Example: + * struct parent { + * const char *name; + * struct list_head children; + * unsigned int num_children; + * }; + */ +struct list_head { + struct list_node node; +}; + +/** + * LIST_HEAD_INIT - initializer for an empty list_head + * @name: the name of the list. + * + * Explicit initializer for an empty list. + * + * See also: + * LIST_HEAD, list_head_init() + * + * Example: + * static struct list_head my_list = LIST_HEAD_INIT(my_list); + */ +#define LIST_HEAD_INIT(name) { { &(name).node, &(name).node } } + +/** + * list_head_init - initialize a list_head + * @h: the list_head to set to the empty list + * + * Example: + * ... + * struct parent *parent = malloc(sizeof(*parent)); + * + * list_head_init(&parent->children); + * parent->num_children = 0; + */ +static inline void list_head_init(struct list_head *h) +{ + h->node.next = &h->node; + h->node.prev = &h->node; +} + +/** + * list_node_init - initialize a list_node + * @n: the list_node to link to itself. + * + * You don't need to use this normally! But it lets you list_del(@n) + * safely. + */ +static inline void list_node_init(struct list_node *n) +{ + n->next = n; + n->prev = n; +} + +/** + * list_add_after - add an entry after an existing node in a linked list + * @p: the existing list_node to add the node after + * @n: the new list_node to add to the list. + * + * The existing list_node must already be a member of the list. + * The new list_node does not need to be initialized; it will be overwritten. + * + * Example: + * struct child c1, c2, c3; + * LIST_HEAD(h); + * + * list_add_tail(&h, &c1.list); + * list_add_tail(&h, &c3.list); + * list_add_after(&c1.list, &c2.list); + */ +static inline void list_add_after(struct list_node *p, + struct list_node *n) +{ + n->next = p->next; + n->prev = p; + p->next->prev = n; + p->next = n; +} + +/** + * list_add - add an entry at the start of a linked list. + * @h: the list_head to add the node to + * @n: the list_node to add to the list. + * + * The list_node does not need to be initialized; it will be overwritten. + * Example: + * struct child *child = malloc(sizeof(*child)); + * + * child->name = "marvin"; + * list_add(&parent->children, &child->list); + * parent->num_children++; + */ +static inline void list_add(struct list_head *h, + struct list_node *n) +{ + list_add_after(&h->node, n); +} + +/** + * list_add_before - add an entry before an existing node in a linked list + * @p: the existing list_node to add the node before + * @n: the new list_node to add to the list. + * + * The existing list_node must already be a member of the list. + * The new list_node does not need to be initialized; it will be overwritten. + * + * Example: + * list_head_init(&h); + * list_add_tail(&h, &c1.list); + * list_add_tail(&h, &c3.list); + * list_add_before(&c3.list, &c2.list); + */ +static inline void list_add_before(struct list_node *p, + struct list_node *n) +{ + n->next = p; + n->prev = p->prev; + p->prev->next = n; + p->prev = n; +} + +/** + * list_add_tail - add an entry at the end of a linked list. + * @h: the list_head to add the node to + * @n: the list_node to add to the list. + * + * The list_node does not need to be initialized; it will be overwritten. + * Example: + * list_add_tail(&parent->children, &child->list); + * parent->num_children++; + */ +static inline void list_add_tail(struct list_head *h, + struct list_node *n) +{ + list_add_before(&h->node, n); +} + +/** + * list_empty - is a list empty? + * @h: the list_head + * + * If the list is empty, returns true. + * + * Example: + * assert(list_empty(&parent->children) == (parent->num_children == 0)); + */ +static inline bool list_empty(const struct list_head *h) +{ + return (h->node.next == &h->node); +} + +/** + * list_node_detached - is a node detached from any lists? + * @n: the list_node + * + * If the list node is initialized and detached, return true. + * Always use list_node_init() and list_del_init() on list nodes. + */ +static inline bool list_node_detached(const struct list_node *n) +{ + return (n->next == n); +} + +/** + * list_del - delete an entry from an (unknown) linked list. + * @n: the list_node to delete from the list. + * + * Note that this leaves @n in an undefined state; it can be added to + * another list, but not deleted again. + * + * See also: + * list_del_from(), list_del_init() + * + * Example: + * list_del(&child->list); + * parent->num_children--; + */ +static inline void list_del(struct list_node *n) +{ + n->next->prev = n->prev; + n->prev->next = n->next; + + /* Catch use-after-del. */ + n->next = NULL; + n->prev = NULL; +} + +/** + * list_del_init - delete a node, and reset it so it can be deleted again. + * @n: the list_node to be deleted. + * + * list_del(@n) or list_del_init() again after this will be safe, + * which can be useful in some cases. + * + * See also: + * list_del_from(), list_del() + * + * Example: + * list_del_init(&child->list); + * parent->num_children--; + */ +static inline void list_del_init(struct list_node *n) +{ + list_del(n); + list_node_init(n); +} + +#endif /* CCAN_LIST_H */ diff --git a/frameworks/modular/odp_module.c b/frameworks/modular/odp_module.c new file mode 100644 index 00000000..89b7cb0d --- /dev/null +++ b/frameworks/modular/odp_module.c @@ -0,0 +1,179 @@ +/* Copyright (c) 2017, ARM Limited. All rights reserved. + * + * Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include "odp_module.h" + +#define MODULE_FRAMEWORK_VERSION 0x00010000UL +ODP_SUBSYSTEM_DEFINE(module, "module framework", MODULE_FRAMEWORK_VERSION); + +/* Bootstrap log facility, enable if ODP_DEBUG_PRINT flag is set. */ +#define DBG(format, ...) \ + do { \ + if (ODP_DEBUG_PRINT == 1) \ + fprintf(stderr, format, ##__VA_ARGS__); \ + } while (0) + +/* Keep it simple, allow one registration session at a time. */ +static struct { + odp_rwlock_t lock; + odp_subsystem_t *subsystem; + odp_module_base_t *module; +} registration = { + .lock = ODP_RWLOCK_UNLOCKED, + .subsystem = NULL, + .module = NULL, +}; + +static inline int registration_sanity_check( + odp_subsystem_t *subsystem, odp_module_base_t *module) +{ + if (subsystem == NULL || module == NULL) + return -ENOENT; + + if (!list_node_detached(&module->list)) { + DBG("module %s was already registered.\n", module->name); + return -EAGAIN; + } + + return 0; +} + +/* Module is linked statically or dynamically, and are loaded by + * program loader (execve) or dynamic linker/loader (ld.so) + * + * subsystem_register_module() should complete the whole registration + * session and link the module into subsystem's module array. + */ +static int linker_register_module( + odp_subsystem_t *subsystem, odp_module_base_t *module) +{ + int sanity = registration_sanity_check(subsystem, module); + + if (sanity < 0) /* sanity check errors */ + return sanity; + + /* Allow one registration session at a time */ + odp_rwlock_write_lock(®istration.lock); + + /* Block the subsystem API calls in load new + * implementation modules. */ + odp_rwlock_write_lock(&subsystem->lock); + module->handler = NULL; /* no DSO handler */ + list_add_tail(&subsystem->modules, &module->list); + odp_rwlock_write_unlock(&subsystem->lock); + + odp_rwlock_write_unlock(®istration.lock); + return 0; +} + +static int (*do_register_module)(odp_subsystem_t *, odp_module_base_t *) + = &linker_register_module; + +static int loader_register_module( + odp_subsystem_t *subsystem, odp_module_base_t *module) +{ + int sanity = registration_sanity_check(subsystem, module); + + if (sanity < 0) /* sanity check errors */ + return sanity; + + /* Registration session lock must be held by + * module_loader_start(). */ + if (odp_rwlock_write_trylock(®istration.lock) == 0) { + registration.subsystem = subsystem; + registration.module = module; + return 0; + } + + odp_rwlock_write_unlock(®istration.lock); + return -EACCES; +} + +void odp_module_loader_start(void) +{ + odp_rwlock_write_lock(®istration.lock); + + if (registration.module != NULL || + registration.subsystem != NULL) { + DBG("module loader start warn, A previous " + "registration did not complete yet.\n"); + } + + registration.module = NULL; + registration.subsystem = NULL; + do_register_module = &loader_register_module; +} + +void odp_module_loader_end(void) +{ + if (registration.module != NULL || + registration.subsystem != NULL) { + DBG("module loader end warn, A previous " + "registration did not complete yet.\n"); + } + + registration.module = NULL; + registration.subsystem = NULL; + do_register_module = &linker_register_module; + + odp_rwlock_write_unlock(®istration.lock); +} + +int odp_module_install(void *dso, bool active) +{ + /* Bottom halves of the registration, context exclusion + * is guaranteed by module_loader_start() + */ + if (odp_rwlock_write_trylock(®istration.lock) == 0) { + odp_subsystem_t *subsystem = registration.subsystem; + odp_module_base_t *module = registration.module; + + if (subsystem != NULL && module != NULL) { + odp_rwlock_write_lock(&subsystem->lock); + + module->handler = dso; + list_add_tail(&subsystem->modules, &module->list); + + /* install as active implementation */ + if (active) /* warn: replaceable */ + subsystem->active = module; + + odp_rwlock_write_unlock(&subsystem->lock); + } + + registration.subsystem = NULL; + registration.module = NULL; + return 0; + } + + odp_rwlock_write_unlock(®istration.lock); + return -EACCES; +} + +int odp_module_abandon(void) +{ + /* Bottom halves of the registration, context exclusion + * is guaranteed by module_loader_start() + */ + if (odp_rwlock_write_trylock(®istration.lock) == 0) { + registration.subsystem = NULL; + registration.module = NULL; + return 0; + } + + odp_rwlock_write_unlock(®istration.lock); + return -EACCES; +} + +int __subsystem_register_module( + odp_subsystem_t *subsystem, odp_module_base_t *module) +{ + return do_register_module(subsystem, module); +} diff --git a/frameworks/modular/odp_module.h b/frameworks/modular/odp_module.h new file mode 100644 index 00000000..1a9e178c --- /dev/null +++ b/frameworks/modular/odp_module.h @@ -0,0 +1,296 @@ +/* Copyright (c) 2017, ARM Limited. All rights reserved. + * + * Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * Modular framework solves the problem of choosing a module + * from multiple modules of a subsystem. + * + * The choice is available during compile time or during runtime + * or initialization. The runtime choice could be using shared + * libraries or dynamic loadable libraries. + * + * Multiple modules of the same subsystem can be built into + * individual static libraries(.a), shared libraries(.so) to be + * dynamically linked or loaded, and use constructor functions + * to register themselves. + * + * A subsystem can choose one active module and provide APIs to + * switch between modules. + * + * Alternatively, subsystem can load multiple modules and + * determine the APIs route in runtime. + * + * In order to gain full possible performance, the subsystem + * allows for choosing a specific module at compile time. + * This eliminates the need to choose the module using function + * pointer table. + * + * This framework tries to minimizes dependencies to the linked + * list and rwlock facilities only. + */ + +#ifndef ODP_MODULE_H_ +#define ODP_MODULE_H_ + +#include +#include +#include "list.h" + +/* Forward declaration */ +typedef struct odp_module_base odp_module_base_t; + +/* Subsystem */ +typedef struct odp_subsystem { + odp_rwlock_t lock; + uint32_t version; + const char *name; + const char *description; + struct list_head modules; + odp_module_base_t *active; +} odp_subsystem_t; + +/* Internally construct subsystem instance name */ +#define __subsystem(name) odp_ ## name ## _subsystem + +/* Declare an ODP subsystem in header file */ +#define ODP_SUBSYSTEM_DECLARE(name) \ + extern odp_subsystem_t __subsystem(name) + +/* Define an ODP subsystem in source file */ +#define ODP_SUBSYSTEM_DEFINE(_name, _description, _version) \ + odp_subsystem_t __subsystem(_name) = \ + { \ + .lock = ODP_RWLOCK_UNLOCKED, \ + .name = # _name, \ + .version = _version, \ + .description = _description, \ + } + +/* Internally construct subsystem API name */ +#define __odp_api(subsystem, api) odp_ ## subsystem ##_## api + +/* Subsystem API prototype name */ +#define odp_api_proto(subsystem, api) __odp_api(subsystem, api ## _proto_t) + +/* Subsystem API declaration */ +#define ODP_SUBSYSTEM_API(name, _return, api, ...) \ + extern _return __odp_api(name, api)(__VA_ARGS__); \ + typedef _return (*odp_api_proto(name, api))(__VA_ARGS__) + +/* Subsystem API stubs are weak */ +#define ODP_SUBSYSTEM_API_STUB(name, api) \ + __attribute__((weak)) __odp_api(name, api) + +/* In case a subsystem module are built as static libraries(.a) + * or preload dynamic libraries(.so), the module can use this + * macro to override the APIs weak stubs. + */ +#define ODP_SUBSYSTEM_API_OVERRIDE(name, api, _alias) \ + __attribute__((alias(#_alias))) __odp_api(name, api) + +#define odp_subsystem_constructor(name) \ + do { \ + odp_rwlock_init(&__subsystem(name).lock); \ + list_head_init(&__subsystem(name).modules); \ + __subsystem(name).active = NULL; \ + } while (0) + +#define ODP_SUBSYSTEM_CONSTRUCTOR(name) \ + static void __attribute__((constructor(101))) \ + odp_ ## name ## _subsystem_constructor(void) + +#define odp_subsystem_lock(access, name) \ + odp_rwlock_ ## access ## _lock(&__subsystem(name).lock) + +#define odp_subsystem_unlock(access, name) \ + odp_rwlock_ ## access ## _unlock(&__subsystem(name).lock) + +/* Base class to all inherited subsystem module classes */ +struct odp_module_base { + struct list_node list; + const char *name; + void *handler; /* DSO */ + int (*init_local)(void); + int (*term_local)(void); + int (*init_global)(void); + int (*term_global)(void); +}; + +/* It is required to define subsystem module class with the + * base class as its 1st member and named as "base", and also + * use ODP_MODULE_CLASS(subsystem) to create the association + * between module class name and subsystem name, like: + * + * typedef ODP_MODULE_CLASS(subsystem) { + * odp_module_base_t base; + * ...new members... + * } new_module_t; // Here pick the name you like freely + * + * It also supports forward declaration like: + * + * // Forward declaration + * typedef ODP_MODULE_CLASS(subsystem) new_module_t; + * // Laterly comes the definition + * ODP_MODULE_CLASS(subsystem) { + * odp_module_base_t base; + * ...new members... + * } + * + * Then in preprocessor macros when we have the subsystem name + * we can recover the module class type information, like: + * + * #define MACRO(subsystem) + * do { + * ODP_MODULE_CLASS(subsystem) *mod = NULL; + * odp_subsystem_foreach_module(subsystem, mod) { + * mod->xxx; // access the module class + * } + * } while(0) + */ +#define ODP_MODULE_CLASS(subsystem) struct odp_ ## subsystem ## _module + +/* Below macros assume that all subsystem module classes have + * odp_module_base_t as their 1st member named "base". + * + * This greatly reduces the complexity for module list iteration + * and module pointer recovery from its list_node member by a forced + * type conversion instead of complex calls to container_of() etc. + */ +#define __force_cast(module, node) \ + ((typeof(module))((void *)(node))) + +#define __foreach_module(pos, head) \ + for (pos = __force_cast(pos, (head)->node.next); \ + pos != __force_cast(pos, head); \ + pos = __force_cast(pos, (pos)->base.list.next)) + +#define __foreach_module_safe(pos, n, head) \ + for (pos = __force_cast(pos, (head)->node.next), \ + n = __force_cast(pos, (pos)->base.list.next); \ + pos != __force_cast(pos, head); \ + pos = n, n = __force_cast(next, (next)->base.list.next)) + +#define odp_subsystem_active_module(name, mod) \ + __force_cast(mod, __subsystem(name).active) + +#define odp_subsystem_foreach_module(name, mod) \ + __foreach_module(mod, &__subsystem(name).modules) + +#define odp_subsystem_foreach_module_safe(name, mod, next) \ + __foreach_module_safe(mod, next, &__subsystem(name).modules) + +#define odp_module_constructor(mod) list_node_init(&(mod)->base.list) + +/* Module constructors should be later than subsystem constructors, + * in statically linked scenarios (both subsystems and modules are + * linked statically). thus the priority 102 compared to the above + * subsystem constructor priority 101. + */ +#define ODP_MODULE_CONSTRUCTOR(name) \ + static void __attribute__((constructor(102))) \ + odp_ ## name ## _module_constructor(void) + +/* All subsystems' initialization and termination routines are + * the same, provide template to help generate similar routines + * automatically, examples: + * + * ODP_SUBSYSTEM_FOREACH_TEMPLATE(subsystem, init_global, DBG) + * will generate a function walk through all the modules of the + * subsystem and invoke init_global method for each. + */ +#define ODP_SUBSYSTEM_FOREACH_TEMPLATE(subs, method, print) \ +static int odp_ ## subs ##_## method(bool continue_on_errors) \ +{ \ + int result = 0; \ + ODP_MODULE_CLASS(subs) * mod = NULL; \ + \ + odp_subsystem_lock(read, subs); \ + odp_subsystem_foreach_module(subs, mod) { \ + result = mod->base.method ? \ + mod->base.method() : 0; \ + if (result < 0) { \ + print("error %d to %s subsystem %s " \ + "module %s.\n", result, #method, \ + __subsystem(subs).name, \ + mod->base.name); \ + \ + if (continue_on_errors) \ + continue; \ + else \ + goto done; \ + } \ + } \ +done: \ + odp_subsystem_unlock(read, subs); \ + return result; \ +} + +/* Subsystem Modules Registration + * + * odp_subsystem_register_module() are called by all modules in their + * constructors, whereas the modules could be: + * + * 1) built as static libraries(.a) and linked statically, or + * built as shared libraries(.so) and linked dynamically. + * + * odp_subsystem_register_module() should complete the whole + * registration session and link the module into subsystem's + * module array. + * + * 2) built as shared libraries(.so) and loaded by a module loader + * in runtime with libdl APIs + * + * The whole registration session needs to be split to aim the + * module loader to properly handle dlopen() returns, and save + * the DSO handler into module's data structure. + * + * The module loader should program in this way: + * odp_module_loader_start(); + * ...... + * for each module + * handler = dlopen(module); + * // The module constructor runs before dlopen() returns + * // which in turn calls odp_subsystem_register_module() + * if (handler is valid) + * odp_module_install(handler); + * else + * odp_module_abandon(); + * ...... + * odp_module_loader_end(); + */ + +void odp_module_loader_start(void); +void odp_module_loader_end(void); + +int odp_module_install(void *, bool active); +int odp_module_abandon(void); + +#define __maybe_unused __attribute__((unused)) +static inline void __subsystem_set_active( + odp_subsystem_t *subsystem __maybe_unused, + odp_module_base_t *module __maybe_unused) +{ +#if defined(IM_ACTIVE_MODULE) + subsystem->active = module; +#endif +} + +int __subsystem_register_module( + odp_subsystem_t *, odp_module_base_t *); + +/* Macro to allow polymorphism on module classes */ +#define odp_subsystem_register_module(name, module) \ +({ \ + odp_module_base_t *base = &(module)->base; \ + __subsystem_register_module(&__subsystem(name), base); \ + __subsystem_set_active(&__subsystem(name), base); \ +}) + +#endif diff --git a/include/odp/api/spec/atomic.h b/include/odp/api/spec/atomic.h index 408829df..54a174ea 100644 --- a/include/odp/api/spec/atomic.h +++ b/include/odp/api/spec/atomic.h @@ -59,6 +59,12 @@ extern "C" { * Atomic 32-bit unsigned integer */ +/** + * @def ODP_ATOMIC_INIT + * Compile-time atomic initializer: + * odp_atomic_xx_t atomic = ODP_ATOMIC_INIT(v); + */ + /* * 32-bit operations in RELAXED memory ordering * -------------------------------------------- diff --git a/include/odp/api/spec/rwlock.h b/include/odp/api/spec/rwlock.h index ff8a3f27..8816b6e7 100644 --- a/include/odp/api/spec/rwlock.h +++ b/include/odp/api/spec/rwlock.h @@ -36,6 +36,11 @@ extern "C" { * ODP reader/writer lock */ +/** + * @def ODP_RWLOCK_UNLOCKED + * Compile-time RW lock initializer: + * odp_rwlock_t lock = ODP_RWLOCK_UNLOCKED; + */ /** * Initialize a reader/writer lock. diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index ba4a31ea..4a7b77b8 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -6,6 +6,7 @@ include $(top_srcdir)/platform/@with_platform@/Makefile.inc AM_CFLAGS += -I$(srcdir)/include AM_CFLAGS += -I$(top_srcdir)/include +AM_CFLAGS += -I$(top_srcdir)/frameworks/modular AM_CFLAGS += -I$(top_srcdir)/include/odp/arch/@ARCH_ABI@ AM_CFLAGS += -I$(top_builddir)/include AM_CFLAGS += -Iinclude @@ -292,6 +293,13 @@ if HAVE_PCAP __LIB__libodp_linux_la_SOURCES += pktio/pcap.c endif +# Build modular framework into odp-linux library +modularframeworkdir = $(top_srcdir)/frameworks/modular +noinst_HEADERS += $(modularframeworkdir)/list.h \ + $(modularframeworkdir)/odp_module.h + +__LIB__libodp_linux_la_SOURCES += ../../frameworks/modular/odp_module.c + __LIB__libodp_linux_la_LIBADD = $(ATOMIC_LIBS) # Create symlink for ABI header files. Application does not need to use the arch diff --git a/platform/linux-generic/include/odp/api/plat/atomic_types.h b/platform/linux-generic/include/odp/api/plat/atomic_types.h index a674ac99..86c9e5b0 100644 --- a/platform/linux-generic/include/odp/api/plat/atomic_types.h +++ b/platform/linux-generic/include/odp/api/plat/atomic_types.h @@ -81,6 +81,8 @@ typedef struct odp_atomic_u64_s odp_atomic_u64_t; typedef struct odp_atomic_u32_s odp_atomic_u32_t; +#define ODP_ATOMIC_INIT(a) { .v = a } + #ifdef __cplusplus } #endif diff --git a/platform/linux-generic/include/odp/api/plat/rwlock_types.h b/platform/linux-generic/include/odp/api/plat/rwlock_types.h index f7dc0449..2c1f3660 100644 --- a/platform/linux-generic/include/odp/api/plat/rwlock_types.h +++ b/platform/linux-generic/include/odp/api/plat/rwlock_types.h @@ -30,6 +30,8 @@ struct odp_rwlock_s { typedef struct odp_rwlock_s odp_rwlock_t; +#define ODP_RWLOCK_UNLOCKED { .cnt = ODP_ATOMIC_INIT(0) } + #ifdef __cplusplus } #endif