get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/109580/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 109580,
    "url": "http://patches.dpdk.org/api/patches/109580/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20220411110013.18624-2-david.marchand@redhat.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20220411110013.18624-2-david.marchand@redhat.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20220411110013.18624-2-david.marchand@redhat.com",
    "date": "2022-04-11T11:00:06",
    "name": "[RFC,v3,1/8] eal: annotate spinlock and rwlock",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "44126c1ba896462eca12631d860295ef6e8ebcd2",
    "submitter": {
        "id": 1173,
        "url": "http://patches.dpdk.org/api/people/1173/?format=api",
        "name": "David Marchand",
        "email": "david.marchand@redhat.com"
    },
    "delegate": {
        "id": 24651,
        "url": "http://patches.dpdk.org/api/users/24651/?format=api",
        "username": "dmarchand",
        "first_name": "David",
        "last_name": "Marchand",
        "email": "david.marchand@redhat.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20220411110013.18624-2-david.marchand@redhat.com/mbox/",
    "series": [
        {
            "id": 22474,
            "url": "http://patches.dpdk.org/api/series/22474/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=22474",
            "date": "2022-04-11T11:00:05",
            "name": "vhost lock annotations",
            "version": 3,
            "mbox": "http://patches.dpdk.org/series/22474/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/109580/comments/",
    "check": "pending",
    "checks": "http://patches.dpdk.org/api/patches/109580/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 6FC67A0093;\n\tMon, 11 Apr 2022 13:00:35 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 5E39D40F35;\n\tMon, 11 Apr 2022 13:00:35 +0200 (CEST)",
            "from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.133.124])\n by mails.dpdk.org (Postfix) with ESMTP id E400C406B4\n for <dev@dpdk.org>; Mon, 11 Apr 2022 13:00:33 +0200 (CEST)",
            "from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com\n [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS\n (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n us-mta-96-WZmRWY07OXyQ5PyiptD5pQ-1; Mon, 11 Apr 2022 07:00:27 -0400",
            "from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com\n [10.11.54.7])\n (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n (No client certificate requested)\n by mimecast-mx02.redhat.com (Postfix) with ESMTPS id D5A1A1C0BF84;\n Mon, 11 Apr 2022 11:00:26 +0000 (UTC)",
            "from dmarchan.remote.csb (unknown [10.40.192.83])\n by smtp.corp.redhat.com (Postfix) with ESMTP id 816541454538;\n Mon, 11 Apr 2022 11:00:24 +0000 (UTC)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1649674833;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:cc:mime-version:mime-version:content-type:content-type:\n content-transfer-encoding:content-transfer-encoding:\n in-reply-to:in-reply-to:references:references;\n bh=t4dHM24GSyxpEMw7Q+9nkSMr3qkmihsGUhbxGBUm27k=;\n b=B62DqgRapZBv1Os+PpH1gaP2Z2QpWoa+ohhjO6KwDJ/DpHMQsXf8fprKgR64yZDwBVFsk4\n tyDOmYc4lBf2Kia1ZJMYD1O6hP66zZUy7Hhgr40xzp9W5e77+ugPz36aVMMq09sRrBDKrw\n 9ZHToeDCVo0axItff+geLpcpr2300+8=",
        "X-MC-Unique": "WZmRWY07OXyQ5PyiptD5pQ-1",
        "From": "David Marchand <david.marchand@redhat.com>",
        "To": "dev@dpdk.org",
        "Cc": "maxime.coquelin@redhat.com, stephen@networkplumber.org,\n chenbo.xia@intel.com, jiayu.hu@intel.com, yuanx.wang@intel.com,\n xuan.ding@intel.com, Ruifeng Wang <ruifeng.wang@arm.com>,\n Jan Viktorin <viktorin@rehivetech.com>,\n David Christensen <drc@linux.vnet.ibm.com>,\n Bruce Richardson <bruce.richardson@intel.com>,\n Konstantin Ananyev <konstantin.ananyev@intel.com>",
        "Subject": "[RFC PATCH v3 1/8] eal: annotate spinlock and rwlock",
        "Date": "Mon, 11 Apr 2022 13:00:06 +0200",
        "Message-Id": "<20220411110013.18624-2-david.marchand@redhat.com>",
        "In-Reply-To": "<20220411110013.18624-1-david.marchand@redhat.com>",
        "References": "<20220328121758.26632-1-david.marchand@redhat.com>\n <20220411110013.18624-1-david.marchand@redhat.com>",
        "MIME-Version": "1.0",
        "X-Scanned-By": "MIMEDefang 2.85 on 10.11.54.7",
        "Authentication-Results": "relay.mimecast.com;\n auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=david.marchand@redhat.com",
        "X-Mimecast-Spam-Score": "0",
        "X-Mimecast-Originator": "redhat.com",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain; charset=\"US-ASCII\"; x-default=true",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "clang offers some thread safety checks, statically verifying that locks\nare taken and released in the code.\nTo use those checks, the full code leading to taking or releasing locks\nmust be annotated with some attributes.\n\nWrap those attributes into our own set of macros.\n\nrwlock and the \"normal\" spinlock are instrumented.\n\nA component may enable this check by setting annotate_locks = true\nin its meson.build.\n\nNote: those checks might be of interest out of DPDK, but it\nrequires that the including application locks are annotated.\nOn the other hand, applications out there might have been using\nthose same checks.\nTo be on the safe side, keep this instrumentation under a\nRTE_ANNOTATE_LOCKS internal build flag.\n\nSigned-off-by: David Marchand <david.marchand@redhat.com>\n---\nChanges since RFC v2:\n- fixed rwlock trylock,\n- instrumented _tm spinlocks,\n- aligned attribute names to clang,\n\n---\n drivers/meson.build                    |  5 ++\n lib/eal/arm/include/rte_rwlock.h       |  4 ++\n lib/eal/arm/include/rte_spinlock.h     |  6 +++\n lib/eal/include/generic/rte_rwlock.h   | 27 +++++++++--\n lib/eal/include/generic/rte_spinlock.h | 40 ++++++++++-----\n lib/eal/include/meson.build            |  1 +\n lib/eal/include/rte_lock_annotations.h | 67 ++++++++++++++++++++++++++\n lib/eal/ppc/include/rte_rwlock.h       |  4 ++\n lib/eal/ppc/include/rte_spinlock.h     |  9 ++++\n lib/eal/x86/include/rte_rwlock.h       |  4 ++\n lib/eal/x86/include/rte_spinlock.h     |  9 ++++\n lib/meson.build                        |  5 ++\n 12 files changed, 164 insertions(+), 17 deletions(-)\n create mode 100644 lib/eal/include/rte_lock_annotations.h",
    "diff": "diff --git a/drivers/meson.build b/drivers/meson.build\nindex 1d8123b00c..c81c8c0eff 100644\n--- a/drivers/meson.build\n+++ b/drivers/meson.build\n@@ -87,6 +87,7 @@ foreach subpath:subdirs\n         build = true # set to false to disable, e.g. missing deps\n         reason = '<unknown reason>' # set if build == false to explain\n         name = drv\n+        annotate_locks = false\n         sources = []\n         headers = []\n         objs = []\n@@ -152,6 +153,10 @@ foreach subpath:subdirs\n         enabled_drivers += name\n         lib_name = '_'.join(['rte', class, name])\n         cflags += '-DRTE_LOG_DEFAULT_LOGTYPE=' + '.'.join([log_prefix, name])\n+        if annotate_locks and cc.has_argument('-Wthread-safety')\n+            cflags += '-DRTE_ANNOTATE_LOCKS'\n+            cflags += '-Wthread-safety'\n+        endif\n         dpdk_conf.set(lib_name.to_upper(), 1)\n \n         dpdk_extra_ldflags += pkgconfig_extra_libs\ndiff --git a/lib/eal/arm/include/rte_rwlock.h b/lib/eal/arm/include/rte_rwlock.h\nindex 18bb37b036..575f171670 100644\n--- a/lib/eal/arm/include/rte_rwlock.h\n+++ b/lib/eal/arm/include/rte_rwlock.h\n@@ -13,24 +13,28 @@ extern \"C\" {\n \n static inline void\n rte_rwlock_read_lock_tm(rte_rwlock_t *rwl)\n+\t__rte_no_thread_safety_analysis\n {\n \trte_rwlock_read_lock(rwl);\n }\n \n static inline void\n rte_rwlock_read_unlock_tm(rte_rwlock_t *rwl)\n+\t__rte_no_thread_safety_analysis\n {\n \trte_rwlock_read_unlock(rwl);\n }\n \n static inline void\n rte_rwlock_write_lock_tm(rte_rwlock_t *rwl)\n+\t__rte_no_thread_safety_analysis\n {\n \trte_rwlock_write_lock(rwl);\n }\n \n static inline void\n rte_rwlock_write_unlock_tm(rte_rwlock_t *rwl)\n+\t__rte_no_thread_safety_analysis\n {\n \trte_rwlock_write_unlock(rwl);\n }\ndiff --git a/lib/eal/arm/include/rte_spinlock.h b/lib/eal/arm/include/rte_spinlock.h\nindex a973763c23..2970de5c3c 100644\n--- a/lib/eal/arm/include/rte_spinlock.h\n+++ b/lib/eal/arm/include/rte_spinlock.h\n@@ -23,36 +23,42 @@ static inline int rte_tm_supported(void)\n \n static inline void\n rte_spinlock_lock_tm(rte_spinlock_t *sl)\n+\t__rte_no_thread_safety_analysis\n {\n \trte_spinlock_lock(sl); /* fall-back */\n }\n \n static inline int\n rte_spinlock_trylock_tm(rte_spinlock_t *sl)\n+\t__rte_no_thread_safety_analysis\n {\n \treturn rte_spinlock_trylock(sl);\n }\n \n static inline void\n rte_spinlock_unlock_tm(rte_spinlock_t *sl)\n+\t__rte_no_thread_safety_analysis\n {\n \trte_spinlock_unlock(sl);\n }\n \n static inline void\n rte_spinlock_recursive_lock_tm(rte_spinlock_recursive_t *slr)\n+\t__rte_no_thread_safety_analysis\n {\n \trte_spinlock_recursive_lock(slr); /* fall-back */\n }\n \n static inline void\n rte_spinlock_recursive_unlock_tm(rte_spinlock_recursive_t *slr)\n+\t__rte_no_thread_safety_analysis\n {\n \trte_spinlock_recursive_unlock(slr);\n }\n \n static inline int\n rte_spinlock_recursive_trylock_tm(rte_spinlock_recursive_t *slr)\n+\t__rte_no_thread_safety_analysis\n {\n \treturn rte_spinlock_recursive_trylock(slr);\n }\ndiff --git a/lib/eal/include/generic/rte_rwlock.h b/lib/eal/include/generic/rte_rwlock.h\nindex da9bc3e9c0..145851f9c0 100644\n--- a/lib/eal/include/generic/rte_rwlock.h\n+++ b/lib/eal/include/generic/rte_rwlock.h\n@@ -23,6 +23,7 @@ extern \"C\" {\n \n #include <rte_common.h>\n #include <rte_atomic.h>\n+#include <rte_lock_annotations.h>\n #include <rte_pause.h>\n \n /**\n@@ -30,7 +31,7 @@ extern \"C\" {\n  *\n  * cnt is -1 when write lock is held, and > 0 when read locks are held.\n  */\n-typedef struct {\n+typedef struct __rte_lockable {\n \tvolatile int32_t cnt; /**< -1 when W lock held, > 0 when R locks held. */\n } rte_rwlock_t;\n \n@@ -59,6 +60,8 @@ rte_rwlock_init(rte_rwlock_t *rwl)\n  */\n static inline void\n rte_rwlock_read_lock(rte_rwlock_t *rwl)\n+\t__rte_shared_lock_function(rwl)\n+\t__rte_no_thread_safety_analysis\n {\n \tint32_t x;\n \tint success = 0;\n@@ -91,6 +94,8 @@ rte_rwlock_read_lock(rte_rwlock_t *rwl)\n __rte_experimental\n static inline int\n rte_rwlock_read_trylock(rte_rwlock_t *rwl)\n+\t__rte_shared_trylock_function(0, rwl)\n+\t__rte_no_thread_safety_analysis\n {\n \tint32_t x;\n \tint success = 0;\n@@ -115,6 +120,8 @@ rte_rwlock_read_trylock(rte_rwlock_t *rwl)\n  */\n static inline void\n rte_rwlock_read_unlock(rte_rwlock_t *rwl)\n+\t__rte_unlock_function(rwl)\n+\t__rte_no_thread_safety_analysis\n {\n \t__atomic_fetch_sub(&rwl->cnt, 1, __ATOMIC_RELEASE);\n }\n@@ -135,6 +142,8 @@ rte_rwlock_read_unlock(rte_rwlock_t *rwl)\n __rte_experimental\n static inline int\n rte_rwlock_write_trylock(rte_rwlock_t *rwl)\n+\t__rte_exclusive_trylock_function(0, rwl)\n+\t__rte_no_thread_safety_analysis\n {\n \tint32_t x;\n \n@@ -154,6 +163,8 @@ rte_rwlock_write_trylock(rte_rwlock_t *rwl)\n  */\n static inline void\n rte_rwlock_write_lock(rte_rwlock_t *rwl)\n+\t__rte_exclusive_lock_function(rwl)\n+\t__rte_no_thread_safety_analysis\n {\n \tint32_t x;\n \tint success = 0;\n@@ -178,6 +189,8 @@ rte_rwlock_write_lock(rte_rwlock_t *rwl)\n  */\n static inline void\n rte_rwlock_write_unlock(rte_rwlock_t *rwl)\n+\t__rte_unlock_function(rwl)\n+\t__rte_no_thread_safety_analysis\n {\n \t__atomic_store_n(&rwl->cnt, 0, __ATOMIC_RELEASE);\n }\n@@ -196,7 +209,8 @@ rte_rwlock_write_unlock(rte_rwlock_t *rwl)\n  *   A pointer to a rwlock structure.\n  */\n static inline void\n-rte_rwlock_read_lock_tm(rte_rwlock_t *rwl);\n+rte_rwlock_read_lock_tm(rte_rwlock_t *rwl)\n+\t__rte_shared_lock_function(rwl);\n \n /**\n  * Commit hardware memory transaction or release the read lock if the lock is used as a fall-back\n@@ -205,7 +219,8 @@ rte_rwlock_read_lock_tm(rte_rwlock_t *rwl);\n  *   A pointer to the rwlock structure.\n  */\n static inline void\n-rte_rwlock_read_unlock_tm(rte_rwlock_t *rwl);\n+rte_rwlock_read_unlock_tm(rte_rwlock_t *rwl)\n+\t__rte_unlock_function(rwl);\n \n /**\n  * Try to execute critical section in a hardware memory transaction, if it\n@@ -221,7 +236,8 @@ rte_rwlock_read_unlock_tm(rte_rwlock_t *rwl);\n  *   A pointer to a rwlock structure.\n  */\n static inline void\n-rte_rwlock_write_lock_tm(rte_rwlock_t *rwl);\n+rte_rwlock_write_lock_tm(rte_rwlock_t *rwl)\n+\t__rte_exclusive_lock_function(rwl);\n \n /**\n  * Commit hardware memory transaction or release the write lock if the lock is used as a fall-back\n@@ -230,7 +246,8 @@ rte_rwlock_write_lock_tm(rte_rwlock_t *rwl);\n  *   A pointer to a rwlock structure.\n  */\n static inline void\n-rte_rwlock_write_unlock_tm(rte_rwlock_t *rwl);\n+rte_rwlock_write_unlock_tm(rte_rwlock_t *rwl)\n+\t__rte_unlock_function(rwl);\n \n #ifdef __cplusplus\n }\ndiff --git a/lib/eal/include/generic/rte_spinlock.h b/lib/eal/include/generic/rte_spinlock.h\nindex 40fe49d5ad..684bfac96c 100644\n--- a/lib/eal/include/generic/rte_spinlock.h\n+++ b/lib/eal/include/generic/rte_spinlock.h\n@@ -22,12 +22,13 @@\n #ifdef RTE_FORCE_INTRINSICS\n #include <rte_common.h>\n #endif\n+#include <rte_lock_annotations.h>\n #include <rte_pause.h>\n \n /**\n  * The rte_spinlock_t type.\n  */\n-typedef struct {\n+typedef struct __rte_lockable {\n \tvolatile int locked; /**< lock status 0 = unlocked, 1 = locked */\n } rte_spinlock_t;\n \n@@ -55,11 +56,13 @@ rte_spinlock_init(rte_spinlock_t *sl)\n  *   A pointer to the spinlock.\n  */\n static inline void\n-rte_spinlock_lock(rte_spinlock_t *sl);\n+rte_spinlock_lock(rte_spinlock_t *sl)\n+\t__rte_exclusive_lock_function(sl);\n \n #ifdef RTE_FORCE_INTRINSICS\n static inline void\n rte_spinlock_lock(rte_spinlock_t *sl)\n+\t__rte_no_thread_safety_analysis\n {\n \tint exp = 0;\n \n@@ -79,11 +82,13 @@ rte_spinlock_lock(rte_spinlock_t *sl)\n  *   A pointer to the spinlock.\n  */\n static inline void\n-rte_spinlock_unlock (rte_spinlock_t *sl);\n+rte_spinlock_unlock(rte_spinlock_t *sl)\n+\t__rte_unlock_function(sl);\n \n #ifdef RTE_FORCE_INTRINSICS\n static inline void\n-rte_spinlock_unlock (rte_spinlock_t *sl)\n+rte_spinlock_unlock(rte_spinlock_t *sl)\n+\t__rte_no_thread_safety_analysis\n {\n \t__atomic_store_n(&sl->locked, 0, __ATOMIC_RELEASE);\n }\n@@ -98,11 +103,13 @@ rte_spinlock_unlock (rte_spinlock_t *sl)\n  *   1 if the lock is successfully taken; 0 otherwise.\n  */\n static inline int\n-rte_spinlock_trylock (rte_spinlock_t *sl);\n+rte_spinlock_trylock(rte_spinlock_t *sl)\n+\t__rte_exclusive_trylock_function(1, sl);\n \n #ifdef RTE_FORCE_INTRINSICS\n static inline int\n-rte_spinlock_trylock (rte_spinlock_t *sl)\n+rte_spinlock_trylock(rte_spinlock_t *sl)\n+\t__rte_no_thread_safety_analysis\n {\n \tint exp = 0;\n \treturn __atomic_compare_exchange_n(&sl->locked, &exp, 1,\n@@ -146,7 +153,8 @@ static inline int rte_tm_supported(void);\n  *   A pointer to the spinlock.\n  */\n static inline void\n-rte_spinlock_lock_tm(rte_spinlock_t *sl);\n+rte_spinlock_lock_tm(rte_spinlock_t *sl)\n+\t__rte_exclusive_lock_function(sl);\n \n /**\n  * Commit hardware memory transaction or release the spinlock if\n@@ -156,7 +164,8 @@ rte_spinlock_lock_tm(rte_spinlock_t *sl);\n  *   A pointer to the spinlock.\n  */\n static inline void\n-rte_spinlock_unlock_tm(rte_spinlock_t *sl);\n+rte_spinlock_unlock_tm(rte_spinlock_t *sl)\n+\t__rte_unlock_function(sl);\n \n /**\n  * Try to execute critical section in a hardware memory transaction,\n@@ -175,7 +184,8 @@ rte_spinlock_unlock_tm(rte_spinlock_t *sl);\n  *   or lock is successfully taken; 0 otherwise.\n  */\n static inline int\n-rte_spinlock_trylock_tm(rte_spinlock_t *sl);\n+rte_spinlock_trylock_tm(rte_spinlock_t *sl)\n+\t__rte_exclusive_trylock_function(1, sl);\n \n /**\n  * The rte_spinlock_recursive_t type.\n@@ -211,6 +221,7 @@ static inline void rte_spinlock_recursive_init(rte_spinlock_recursive_t *slr)\n  *   A pointer to the recursive spinlock.\n  */\n static inline void rte_spinlock_recursive_lock(rte_spinlock_recursive_t *slr)\n+\t__rte_no_thread_safety_analysis\n {\n \tint id = rte_gettid();\n \n@@ -227,6 +238,7 @@ static inline void rte_spinlock_recursive_lock(rte_spinlock_recursive_t *slr)\n  *   A pointer to the recursive spinlock.\n  */\n static inline void rte_spinlock_recursive_unlock(rte_spinlock_recursive_t *slr)\n+\t__rte_no_thread_safety_analysis\n {\n \tif (--(slr->count) == 0) {\n \t\tslr->user = -1;\n@@ -244,6 +256,7 @@ static inline void rte_spinlock_recursive_unlock(rte_spinlock_recursive_t *slr)\n  *   1 if the lock is successfully taken; 0 otherwise.\n  */\n static inline int rte_spinlock_recursive_trylock(rte_spinlock_recursive_t *slr)\n+\t__rte_no_thread_safety_analysis\n {\n \tint id = rte_gettid();\n \n@@ -271,7 +284,8 @@ static inline int rte_spinlock_recursive_trylock(rte_spinlock_recursive_t *slr)\n  *   A pointer to the recursive spinlock.\n  */\n static inline void rte_spinlock_recursive_lock_tm(\n-\trte_spinlock_recursive_t *slr);\n+\trte_spinlock_recursive_t *slr)\n+\t__rte_no_thread_safety_analysis;\n \n /**\n  * Commit hardware memory transaction or release the recursive spinlock\n@@ -281,7 +295,8 @@ static inline void rte_spinlock_recursive_lock_tm(\n  *   A pointer to the recursive spinlock.\n  */\n static inline void rte_spinlock_recursive_unlock_tm(\n-\trte_spinlock_recursive_t *slr);\n+\trte_spinlock_recursive_t *slr)\n+\t__rte_no_thread_safety_analysis;\n \n /**\n  * Try to execute critical section in a hardware memory transaction,\n@@ -300,6 +315,7 @@ static inline void rte_spinlock_recursive_unlock_tm(\n  *   or lock is successfully taken; 0 otherwise.\n  */\n static inline int rte_spinlock_recursive_trylock_tm(\n-\trte_spinlock_recursive_t *slr);\n+\trte_spinlock_recursive_t *slr)\n+\t__rte_no_thread_safety_analysis;\n \n #endif /* _RTE_SPINLOCK_H_ */\ndiff --git a/lib/eal/include/meson.build b/lib/eal/include/meson.build\nindex 9700494816..a20b8d7e23 100644\n--- a/lib/eal/include/meson.build\n+++ b/lib/eal/include/meson.build\n@@ -27,6 +27,7 @@ headers += files(\n         'rte_keepalive.h',\n         'rte_launch.h',\n         'rte_lcore.h',\n+        'rte_lock_annotations.h',\n         'rte_log.h',\n         'rte_malloc.h',\n         'rte_memory.h',\ndiff --git a/lib/eal/include/rte_lock_annotations.h b/lib/eal/include/rte_lock_annotations.h\nnew file mode 100644\nindex 0000000000..bcaf4193f7\n--- /dev/null\n+++ b/lib/eal/include/rte_lock_annotations.h\n@@ -0,0 +1,67 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2022 Red Hat, Inc.\n+ */\n+\n+#ifndef RTE_LOCK_ANNOTATIONS_H\n+#define RTE_LOCK_ANNOTATIONS_H\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+#endif\n+\n+#ifdef RTE_ANNOTATE_LOCKS\n+\n+#define __rte_lockable \\\n+\t__attribute__((lockable))\n+\n+#define __rte_guarded_by(...) \\\n+\t__attribute__((guarded_by(__VA_ARGS__)))\n+#define __rte_guarded_var \\\n+\t__attribute__((guarded_var))\n+\n+#define __rte_exclusive_locks_required(...) \\\n+\t__attribute__((exclusive_locks_required(__VA_ARGS__)))\n+#define __rte_exclusive_lock_function(...) \\\n+\t__attribute__((exclusive_lock_function(__VA_ARGS__)))\n+#define __rte_exclusive_trylock_function(ret, ...) \\\n+\t__attribute__((exclusive_trylock_function(ret, __VA_ARGS__)))\n+\n+#define __rte_shared_locks_required(...) \\\n+\t__attribute__((shared_locks_required(__VA_ARGS__)))\n+#define __rte_shared_lock_function(...) \\\n+\t__attribute__((shared_lock_function(__VA_ARGS__)))\n+#define __rte_shared_trylock_function(ret, ...) \\\n+\t__attribute__((shared_trylock_function(ret, __VA_ARGS__)))\n+\n+#define __rte_unlock_function(...) \\\n+\t__attribute__((unlock_function(__VA_ARGS__)))\n+\n+#define __rte_no_thread_safety_analysis \\\n+\t__attribute__((no_thread_safety_analysis))\n+\n+#else /* ! RTE_ANNOTATE_LOCKS */\n+\n+#define __rte_lockable\n+\n+#define __rte_guarded_by(...)\n+#define __rte_guarded_var\n+\n+#define __rte_exclusive_locks_required(...)\n+#define __rte_exclusive_lock_function(...)\n+#define __rte_exclusive_trylock_function(...)\n+\n+#define __rte_shared_locks_required(...)\n+#define __rte_shared_lock_function(...)\n+#define __rte_shared_trylock_function(...)\n+\n+#define __rte_unlock_function(...)\n+\n+#define __rte_no_thread_safety_analysis\n+\n+#endif /* RTE_ANNOTATE_LOCKS */\n+\n+#ifdef __cplusplus\n+}\n+#endif\n+\n+#endif /* RTE_LOCK_ANNOTATIONS_H */\ndiff --git a/lib/eal/ppc/include/rte_rwlock.h b/lib/eal/ppc/include/rte_rwlock.h\nindex 9fadc04076..d7a5b61b8e 100644\n--- a/lib/eal/ppc/include/rte_rwlock.h\n+++ b/lib/eal/ppc/include/rte_rwlock.h\n@@ -11,24 +11,28 @@ extern \"C\" {\n \n static inline void\n rte_rwlock_read_lock_tm(rte_rwlock_t *rwl)\n+\t__rte_no_thread_safety_analysis\n {\n \trte_rwlock_read_lock(rwl);\n }\n \n static inline void\n rte_rwlock_read_unlock_tm(rte_rwlock_t *rwl)\n+\t__rte_no_thread_safety_analysis\n {\n \trte_rwlock_read_unlock(rwl);\n }\n \n static inline void\n rte_rwlock_write_lock_tm(rte_rwlock_t *rwl)\n+\t__rte_no_thread_safety_analysis\n {\n \trte_rwlock_write_lock(rwl);\n }\n \n static inline void\n rte_rwlock_write_unlock_tm(rte_rwlock_t *rwl)\n+\t__rte_no_thread_safety_analysis\n {\n \trte_rwlock_write_unlock(rwl);\n }\ndiff --git a/lib/eal/ppc/include/rte_spinlock.h b/lib/eal/ppc/include/rte_spinlock.h\nindex 149ec245c7..979abea16d 100644\n--- a/lib/eal/ppc/include/rte_spinlock.h\n+++ b/lib/eal/ppc/include/rte_spinlock.h\n@@ -20,6 +20,7 @@ extern \"C\" {\n \n static inline void\n rte_spinlock_lock(rte_spinlock_t *sl)\n+\t__rte_no_thread_safety_analysis\n {\n \twhile (__sync_lock_test_and_set(&sl->locked, 1))\n \t\twhile (sl->locked)\n@@ -28,12 +29,14 @@ rte_spinlock_lock(rte_spinlock_t *sl)\n \n static inline void\n rte_spinlock_unlock(rte_spinlock_t *sl)\n+\t__rte_no_thread_safety_analysis\n {\n \t__sync_lock_release(&sl->locked);\n }\n \n static inline int\n rte_spinlock_trylock(rte_spinlock_t *sl)\n+\t__rte_no_thread_safety_analysis\n {\n \treturn __sync_lock_test_and_set(&sl->locked, 1) == 0;\n }\n@@ -47,36 +50,42 @@ static inline int rte_tm_supported(void)\n \n static inline void\n rte_spinlock_lock_tm(rte_spinlock_t *sl)\n+\t__rte_no_thread_safety_analysis\n {\n \trte_spinlock_lock(sl); /* fall-back */\n }\n \n static inline int\n rte_spinlock_trylock_tm(rte_spinlock_t *sl)\n+\t__rte_no_thread_safety_analysis\n {\n \treturn rte_spinlock_trylock(sl);\n }\n \n static inline void\n rte_spinlock_unlock_tm(rte_spinlock_t *sl)\n+\t__rte_no_thread_safety_analysis\n {\n \trte_spinlock_unlock(sl);\n }\n \n static inline void\n rte_spinlock_recursive_lock_tm(rte_spinlock_recursive_t *slr)\n+\t__rte_no_thread_safety_analysis\n {\n \trte_spinlock_recursive_lock(slr); /* fall-back */\n }\n \n static inline void\n rte_spinlock_recursive_unlock_tm(rte_spinlock_recursive_t *slr)\n+\t__rte_no_thread_safety_analysis\n {\n \trte_spinlock_recursive_unlock(slr);\n }\n \n static inline int\n rte_spinlock_recursive_trylock_tm(rte_spinlock_recursive_t *slr)\n+\t__rte_no_thread_safety_analysis\n {\n \treturn rte_spinlock_recursive_trylock(slr);\n }\ndiff --git a/lib/eal/x86/include/rte_rwlock.h b/lib/eal/x86/include/rte_rwlock.h\nindex eec4c7123c..1796b69265 100644\n--- a/lib/eal/x86/include/rte_rwlock.h\n+++ b/lib/eal/x86/include/rte_rwlock.h\n@@ -14,6 +14,7 @@ extern \"C\" {\n \n static inline void\n rte_rwlock_read_lock_tm(rte_rwlock_t *rwl)\n+\t__rte_no_thread_safety_analysis\n {\n \tif (likely(rte_try_tm(&rwl->cnt)))\n \t\treturn;\n@@ -22,6 +23,7 @@ rte_rwlock_read_lock_tm(rte_rwlock_t *rwl)\n \n static inline void\n rte_rwlock_read_unlock_tm(rte_rwlock_t *rwl)\n+\t__rte_no_thread_safety_analysis\n {\n \tif (unlikely(rwl->cnt))\n \t\trte_rwlock_read_unlock(rwl);\n@@ -31,6 +33,7 @@ rte_rwlock_read_unlock_tm(rte_rwlock_t *rwl)\n \n static inline void\n rte_rwlock_write_lock_tm(rte_rwlock_t *rwl)\n+\t__rte_no_thread_safety_analysis\n {\n \tif (likely(rte_try_tm(&rwl->cnt)))\n \t\treturn;\n@@ -39,6 +42,7 @@ rte_rwlock_write_lock_tm(rte_rwlock_t *rwl)\n \n static inline void\n rte_rwlock_write_unlock_tm(rte_rwlock_t *rwl)\n+\t__rte_no_thread_safety_analysis\n {\n \tif (unlikely(rwl->cnt))\n \t\trte_rwlock_write_unlock(rwl);\ndiff --git a/lib/eal/x86/include/rte_spinlock.h b/lib/eal/x86/include/rte_spinlock.h\nindex e2e2b2643c..0b20ddfd73 100644\n--- a/lib/eal/x86/include/rte_spinlock.h\n+++ b/lib/eal/x86/include/rte_spinlock.h\n@@ -23,6 +23,7 @@ extern \"C\" {\n #ifndef RTE_FORCE_INTRINSICS\n static inline void\n rte_spinlock_lock(rte_spinlock_t *sl)\n+\t__rte_no_thread_safety_analysis\n {\n \tint lock_val = 1;\n \tasm volatile (\n@@ -43,6 +44,7 @@ rte_spinlock_lock(rte_spinlock_t *sl)\n \n static inline void\n rte_spinlock_unlock (rte_spinlock_t *sl)\n+\t__rte_no_thread_safety_analysis\n {\n \tint unlock_val = 0;\n \tasm volatile (\n@@ -54,6 +56,7 @@ rte_spinlock_unlock (rte_spinlock_t *sl)\n \n static inline int\n rte_spinlock_trylock (rte_spinlock_t *sl)\n+\t__rte_no_thread_safety_analysis\n {\n \tint lockval = 1;\n \n@@ -121,6 +124,7 @@ rte_try_tm(volatile int *lock)\n \n static inline void\n rte_spinlock_lock_tm(rte_spinlock_t *sl)\n+\t__rte_no_thread_safety_analysis\n {\n \tif (likely(rte_try_tm(&sl->locked)))\n \t\treturn;\n@@ -130,6 +134,7 @@ rte_spinlock_lock_tm(rte_spinlock_t *sl)\n \n static inline int\n rte_spinlock_trylock_tm(rte_spinlock_t *sl)\n+\t__rte_no_thread_safety_analysis\n {\n \tif (likely(rte_try_tm(&sl->locked)))\n \t\treturn 1;\n@@ -139,6 +144,7 @@ rte_spinlock_trylock_tm(rte_spinlock_t *sl)\n \n static inline void\n rte_spinlock_unlock_tm(rte_spinlock_t *sl)\n+\t__rte_no_thread_safety_analysis\n {\n \tif (unlikely(sl->locked))\n \t\trte_spinlock_unlock(sl);\n@@ -148,6 +154,7 @@ rte_spinlock_unlock_tm(rte_spinlock_t *sl)\n \n static inline void\n rte_spinlock_recursive_lock_tm(rte_spinlock_recursive_t *slr)\n+\t__rte_no_thread_safety_analysis\n {\n \tif (likely(rte_try_tm(&slr->sl.locked)))\n \t\treturn;\n@@ -157,6 +164,7 @@ rte_spinlock_recursive_lock_tm(rte_spinlock_recursive_t *slr)\n \n static inline void\n rte_spinlock_recursive_unlock_tm(rte_spinlock_recursive_t *slr)\n+\t__rte_no_thread_safety_analysis\n {\n \tif (unlikely(slr->sl.locked))\n \t\trte_spinlock_recursive_unlock(slr);\n@@ -166,6 +174,7 @@ rte_spinlock_recursive_unlock_tm(rte_spinlock_recursive_t *slr)\n \n static inline int\n rte_spinlock_recursive_trylock_tm(rte_spinlock_recursive_t *slr)\n+\t__rte_no_thread_safety_analysis\n {\n \tif (likely(rte_try_tm(&slr->sl.locked)))\n \t\treturn 1;\ndiff --git a/lib/meson.build b/lib/meson.build\nindex 24adbe44c9..909133ea64 100644\n--- a/lib/meson.build\n+++ b/lib/meson.build\n@@ -112,6 +112,7 @@ foreach l:libraries\n     reason = '<unknown reason>' # set if build == false to explain why\n     name = l\n     use_function_versioning = false\n+    annotate_locks = false\n     sources = []\n     headers = []\n     indirect_headers = [] # public headers not directly included by apps\n@@ -184,6 +185,10 @@ foreach l:libraries\n         cflags += '-DRTE_USE_FUNCTION_VERSIONING'\n     endif\n     cflags += '-DRTE_LOG_DEFAULT_LOGTYPE=lib.' + l\n+    if annotate_locks and cc.has_argument('-Wthread-safety')\n+        cflags += '-DRTE_ANNOTATE_LOCKS'\n+        cflags += '-Wthread-safety'\n+    endif\n \n     # first build static lib\n     static_lib = static_library(libname,\n",
    "prefixes": [
        "RFC",
        "v3",
        "1/8"
    ]
}