get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 138768,
    "url": "https://patches.dpdk.org/api/patches/138768/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20240325155354.770676-2-rjarry@redhat.com/",
    "project": {
        "id": 1,
        "url": "https://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": "<20240325155354.770676-2-rjarry@redhat.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20240325155354.770676-2-rjarry@redhat.com",
    "date": "2024-03-25T15:53:55",
    "name": "graph: avoid id collisions",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "8b93585acd773353ab02d4a6185fc0b7026108af",
    "submitter": {
        "id": 2850,
        "url": "https://patches.dpdk.org/api/people/2850/?format=api",
        "name": "Robin Jarry",
        "email": "rjarry@redhat.com"
    },
    "delegate": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20240325155354.770676-2-rjarry@redhat.com/mbox/",
    "series": [
        {
            "id": 31613,
            "url": "https://patches.dpdk.org/api/series/31613/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=31613",
            "date": "2024-03-25T15:53:55",
            "name": "graph: avoid id collisions",
            "version": 1,
            "mbox": "https://patches.dpdk.org/series/31613/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/138768/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/138768/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 31C6D43D47;\n\tMon, 25 Mar 2024 16:54:21 +0100 (CET)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 2391C40A79;\n\tMon, 25 Mar 2024 16:54:21 +0100 (CET)",
            "from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.129.124])\n by mails.dpdk.org (Postfix) with ESMTP id 73FD640A77\n for <dev@dpdk.org>; Mon, 25 Mar 2024 16:54:19 +0100 (CET)",
            "from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com\n [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS\n (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n us-mta-323-N5LFCUvCO2K8dIyKiuV1Ug-1; Mon, 25 Mar 2024 11:54:14 -0400",
            "from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com\n [10.11.54.5])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n (No client certificate requested)\n by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 47008185A786;\n Mon, 25 Mar 2024 15:54:14 +0000 (UTC)",
            "from localhost.localdomain (unknown [10.39.208.19])\n by smtp.corp.redhat.com (Postfix) with ESMTP id E5F6510E47;\n Mon, 25 Mar 2024 15:54:12 +0000 (UTC)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1711382059;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:mime-version:mime-version:content-type:content-type:\n content-transfer-encoding:content-transfer-encoding;\n bh=g+6Jl8WxduhGWl/wkZtWM9Ql8JciOSk93HaJOUGzNvE=;\n b=ME6byyjPqsP4kz4hXuxNszPpTAawQ7hFL8dWFjNLEVJl378oCaOOoT9ZR9N2lXxvFVbe3f\n Rid8N4EDwmH+gFBWlkw+5FB6RSC++f4sce2LIzUoX6So2nz4npvBjPRKicfKyBqwPSZt2L\n l6jdkopw9oeUK8FveLrNfevq+kmdBEc=",
        "X-MC-Unique": "N5LFCUvCO2K8dIyKiuV1Ug-1",
        "From": "Robin Jarry <rjarry@redhat.com>",
        "To": "dev@dpdk.org, Jerin Jacob <jerinj@marvell.com>,\n Kiran Kumar K <kirankumark@marvell.com>,\n Nithin Dabilpuram <ndabilpuram@marvell.com>,\n Zhirun Yan <yanzhirun_163@163.com>",
        "Subject": "[PATCH] graph: avoid id collisions",
        "Date": "Mon, 25 Mar 2024 16:53:55 +0100",
        "Message-ID": "<20240325155354.770676-2-rjarry@redhat.com>",
        "MIME-Version": "1.0",
        "X-Scanned-By": "MIMEDefang 3.4.1 on 10.11.54.5",
        "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": "The graph id is determined based on a global variable that is\nincremented every time a graph is created, and decremented every time\na graph is destroyed. This only works if graphs are destroyed in the\nreverse order in which they have been created.\n\nThe following code produces duplicate graph IDs which can lead to\nuse-after-free bugs and other undefined behaviours:\n\n  a = rte_graph_create(...); // id=0 graph_id=1\n  b = rte_graph_create(...); // id=1 graph_id=2\n  rte_graph_destroy(a);      // graph_id=1\n  c = rte_graph_create(...); // id=1 graph_id=2 (duplicate with b)\n  rte_graph_destroy(c);      // frees memory still used by b\n\nRemove the global counter. Make sure that the graph list is always\nordered by increasing graph ids. When creating a new graph, pick a free\nid which is not allocated.\n\nSigned-off-by: Robin Jarry <rjarry@redhat.com>\n---\n lib/graph/graph.c | 86 +++++++++++++++++++++++++++++++++++++----------\n 1 file changed, 69 insertions(+), 17 deletions(-)",
    "diff": "diff --git a/lib/graph/graph.c b/lib/graph/graph.c\nindex 147bc6c685c5..50616580d06b 100644\n--- a/lib/graph/graph.c\n+++ b/lib/graph/graph.c\n@@ -19,11 +19,54 @@\n \n static struct graph_head graph_list = STAILQ_HEAD_INITIALIZER(graph_list);\n static rte_spinlock_t graph_lock = RTE_SPINLOCK_INITIALIZER;\n-static rte_graph_t graph_id;\n-\n-#define GRAPH_ID_CHECK(id) ID_CHECK(id, graph_id)\n \n /* Private functions */\n+static struct graph *\n+graph_from_id(rte_graph_t id)\n+{\n+\tstruct graph *graph;\n+\tSTAILQ_FOREACH(graph, &graph_list, next) {\n+\t\tif (graph->id == id)\n+\t\t\treturn graph;\n+\t}\n+\trte_errno = EINVAL;\n+\treturn NULL;\n+}\n+\n+static rte_graph_t\n+graph_next_free_id(void)\n+{\n+\tstruct graph *graph;\n+\trte_graph_t id = 0;\n+\n+\tSTAILQ_FOREACH(graph, &graph_list, next) {\n+\t\tif (id < graph->id)\n+\t\t\tbreak;\n+\t\tid = graph->id + 1;\n+\t}\n+\n+\treturn id;\n+}\n+\n+static void\n+graph_insert_ordered(struct graph *graph)\n+{\n+\tstruct graph *after, *g;\n+\n+\tafter = NULL;\n+\tSTAILQ_FOREACH(g, &graph_list, next) {\n+\t\tif (g->id < graph->id) {\n+\t\t\tafter = g;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\tif (after == NULL) {\n+\t\tSTAILQ_INSERT_TAIL(&graph_list, graph, next);\n+\t} else {\n+\t\tSTAILQ_INSERT_AFTER(&graph_list, after, graph, next);\n+\t}\n+}\n+\n struct graph_head *\n graph_list_head_get(void)\n {\n@@ -279,7 +322,8 @@ rte_graph_model_mcore_dispatch_core_bind(rte_graph_t id, int lcore)\n {\n \tstruct graph *graph;\n \n-\tGRAPH_ID_CHECK(id);\n+\tif (graph_from_id(id) == NULL)\n+\t\tgoto fail;\n \tif (!rte_lcore_is_enabled(lcore))\n \t\tSET_ERR_JMP(ENOLINK, fail, \"lcore %d not enabled\", lcore);\n \n@@ -309,7 +353,8 @@ rte_graph_model_mcore_dispatch_core_unbind(rte_graph_t id)\n {\n \tstruct graph *graph;\n \n-\tGRAPH_ID_CHECK(id);\n+\tif (graph_from_id(id) == NULL)\n+\t\tgoto fail;\n \tSTAILQ_FOREACH(graph, &graph_list, next)\n \t\tif (graph->id == id)\n \t\t\tbreak;\n@@ -406,7 +451,7 @@ rte_graph_create(const char *name, struct rte_graph_param *prm)\n \tgraph->socket = prm->socket_id;\n \tgraph->src_node_count = src_node_count;\n \tgraph->node_count = graph_nodes_count(graph);\n-\tgraph->id = graph_id;\n+\tgraph->id = graph_next_free_id();\n \tgraph->parent_id = RTE_GRAPH_ID_INVALID;\n \tgraph->lcore_id = RTE_MAX_LCORE;\n \tgraph->num_pkt_to_capture = prm->num_pkt_to_capture;\n@@ -422,8 +467,7 @@ rte_graph_create(const char *name, struct rte_graph_param *prm)\n \t\tgoto graph_mem_destroy;\n \n \t/* All good, Lets add the graph to the list */\n-\tgraph_id++;\n-\tSTAILQ_INSERT_TAIL(&graph_list, graph, next);\n+\tgraph_insert_ordered(graph);\n \n \tgraph_spinlock_unlock();\n \treturn graph->id;\n@@ -467,7 +511,6 @@ rte_graph_destroy(rte_graph_t id)\n \t\t\tgraph_cleanup(graph);\n \t\t\tSTAILQ_REMOVE(&graph_list, graph, graph, next);\n \t\t\tfree(graph);\n-\t\t\tgraph_id--;\n \t\t\tgoto done;\n \t\t}\n \t\tgraph = tmp;\n@@ -520,7 +563,7 @@ graph_clone(struct graph *parent_graph, const char *name, struct rte_graph_param\n \tgraph->parent_id = parent_graph->id;\n \tgraph->lcore_id = parent_graph->lcore_id;\n \tgraph->socket = parent_graph->socket;\n-\tgraph->id = graph_id;\n+\tgraph->id = graph_next_free_id();\n \n \t/* Allocate the Graph fast path memory and populate the data */\n \tif (graph_fp_mem_create(graph))\n@@ -539,8 +582,7 @@ graph_clone(struct graph *parent_graph, const char *name, struct rte_graph_param\n \t\tgoto graph_mem_destroy;\n \n \t/* All good, Lets add the graph to the list */\n-\tgraph_id++;\n-\tSTAILQ_INSERT_TAIL(&graph_list, graph, next);\n+\tgraph_insert_ordered(graph);\n \n \tgraph_spinlock_unlock();\n \treturn graph->id;\n@@ -561,7 +603,8 @@ rte_graph_clone(rte_graph_t id, const char *name, struct rte_graph_param *prm)\n {\n \tstruct graph *graph;\n \n-\tGRAPH_ID_CHECK(id);\n+\tif (graph_from_id(id) == NULL)\n+\t\tgoto fail;\n \tSTAILQ_FOREACH(graph, &graph_list, next)\n \t\tif (graph->id == id)\n \t\t\treturn graph_clone(graph, name, prm);\n@@ -587,7 +630,8 @@ rte_graph_id_to_name(rte_graph_t id)\n {\n \tstruct graph *graph;\n \n-\tGRAPH_ID_CHECK(id);\n+\tif (graph_from_id(id) == NULL)\n+\t\tgoto fail;\n \tSTAILQ_FOREACH(graph, &graph_list, next)\n \t\tif (graph->id == id)\n \t\t\treturn graph->name;\n@@ -604,7 +648,8 @@ rte_graph_node_get(rte_graph_t gid, uint32_t nid)\n \trte_graph_off_t off;\n \trte_node_t count;\n \n-\tGRAPH_ID_CHECK(gid);\n+\tif (graph_from_id(gid) == NULL)\n+\t\tgoto fail;\n \tSTAILQ_FOREACH(graph, &graph_list, next)\n \t\tif (graph->id == gid) {\n \t\t\trte_graph_foreach_node(count, off, graph->graph,\n@@ -747,7 +792,8 @@ graph_scan_dump(FILE *f, rte_graph_t id, bool all)\n \tstruct graph *graph;\n \n \tRTE_VERIFY(f);\n-\tGRAPH_ID_CHECK(id);\n+\tif (graph_from_id(id) == NULL)\n+\t\tgoto fail;\n \n \tSTAILQ_FOREACH(graph, &graph_list, next) {\n \t\tif (all == true) {\n@@ -776,7 +822,13 @@ rte_graph_list_dump(FILE *f)\n rte_graph_t\n rte_graph_max_count(void)\n {\n-\treturn graph_id;\n+\tstruct graph *graph;\n+\trte_graph_t count = 0;\n+\n+\tSTAILQ_FOREACH(graph, &graph_list, next)\n+\t\tcount++;\n+\n+\treturn count;\n }\n \n RTE_LOG_REGISTER_DEFAULT(rte_graph_logtype, INFO);\n",
    "prefixes": []
}