From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 8379B48A44 for ; Fri, 31 Oct 2025 15:35:35 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 7C36D40150; Fri, 31 Oct 2025 15:35:35 +0100 (CET) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by mails.dpdk.org (Postfix) with ESMTP id 285CD40150 for ; Fri, 31 Oct 2025 15:35:34 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1761921333; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ZOop6myC4nLy/91mL+ai4fPxZEanZtOwuozbTIrG7gs=; b=SV0Uhk0cWe0VCENFvS/CvUbxpdY4M3Xkpw1U4PyXr1mQfXgAA/68XbS3x6J8f2aQEIptvq fi4cv41PXFRBQ5IafzwyU9weAU1uaN//HxwSidkYKEYBivQnRuqZ+MEjaRelISdsmBQS5V t7rqk3JmHrKhGQeoV5eRhjx9d590HGs= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-15-1HP9Hgv9MqGr60lx-vj62g-1; Fri, 31 Oct 2025 10:35:31 -0400 X-MC-Unique: 1HP9Hgv9MqGr60lx-vj62g-1 X-Mimecast-MFC-AGG-ID: 1HP9Hgv9MqGr60lx-vj62g_1761921331 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id E0426180A27B; Fri, 31 Oct 2025 14:35:30 +0000 (UTC) Received: from rh.redhat.com (unknown [10.44.32.50]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 45BE5180029B; Fri, 31 Oct 2025 14:35:28 +0000 (UTC) From: Kevin Traynor To: David Marchand Cc: Kiran Kumar K , dpdk stable Subject: patch 'graph: fix unaligned access in stats' has been queued to stable release 24.11.4 Date: Fri, 31 Oct 2025 14:32:09 +0000 Message-ID: <20251031143421.324432-7-ktraynor@redhat.com> In-Reply-To: <20251031143421.324432-1-ktraynor@redhat.com> References: <20251031143421.324432-1-ktraynor@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: qwCeS3OI12KJFpcC7BScuB6ssskxqo-M2bJjPg9_1ak_1761921331 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit content-type: text/plain; charset="US-ASCII"; x-default=true X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: stable-bounces@dpdk.org Hi, FYI, your patch has been queued to stable release 24.11.4 Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet. It will be pushed if I get no objections before 11/05/25. So please shout if anyone has objections. Also note that after the patch there's a diff of the upstream commit vs the patch applied to the branch. This will indicate if there was any rebasing needed to apply to the stable branch. If there were code changes for rebasing (ie: not only metadata diffs), please double check that the rebase was correctly done. Queued patches are on a temporary branch at: https://github.com/kevintraynor/dpdk-stable This queued commit can be viewed at: https://github.com/kevintraynor/dpdk-stable/commit/18222a6c7b4e674a7a5cd173caedac636537ef26 Thanks. Kevin --- >From 18222a6c7b4e674a7a5cd173caedac636537ef26 Mon Sep 17 00:00:00 2001 From: David Marchand Date: Fri, 4 Jul 2025 11:15:03 +0200 Subject: [PATCH] graph: fix unaligned access in stats [ upstream commit 826af93a68f358f8eb4f363e42d114b93fde0d69 ] UBSan reports: ../lib/graph/graph_stats.c:208:13: runtime error: member access within misaligned address 0x000054742c50 for type 'struct rte_graph_cluster_stats', which requires 64 byte alignment ../lib/graph/graph_stats.c:257:12: runtime error: member access within misaligned address 0x00002219fd30 for type 'struct rte_graph_cluster_stats', which requires 64 byte alignment The current code goes into various complex (non aligned) reallocations / memset / memcpy. Simplify this by computing how many nodes are present in the cluster of graphes. Then directly call rte_malloc for the whole stats object. As a bonus, this change also fixes leaks: - if any error occurred before call to rte_malloc, since the xstats objects stored in the glibc allocated stats object were not freed, - if an allocation failure occurs, with constructs using ptr = realloc(ptr, sz), since the original ptr is lost, Fixes: af1ae8b6a32c ("graph: implement stats") Signed-off-by: David Marchand Acked-by: Kiran Kumar K --- lib/graph/graph_stats.c | 102 +++++++++++++++++++++++----------------- 1 file changed, 58 insertions(+), 44 deletions(-) diff --git a/lib/graph/graph_stats.c b/lib/graph/graph_stats.c index e955ee5e06..80f6d1eae3 100644 --- a/lib/graph/graph_stats.c +++ b/lib/graph/graph_stats.c @@ -37,5 +37,4 @@ struct __rte_cache_aligned rte_graph_cluster_stats { bool dispatch; void *cookie; - size_t sz; struct cluster_node clusters[]; @@ -178,13 +177,53 @@ graph_cluster_stats_cb_dispatch(bool is_first, bool is_last, void *cookie, }; +static uint32_t +cluster_count_nodes(const struct cluster *cluster) +{ + rte_node_t *nodes = NULL; + uint32_t max_nodes = 0; + + for (unsigned int i = 0; i < cluster->nb_graphs; i++) { + struct graph_node *graph_node; + + STAILQ_FOREACH(graph_node, &cluster->graphs[i]->node_list, next) { + rte_node_t *new_nodes; + unsigned int n; + + for (n = 0; n < max_nodes; n++) { + if (nodes[n] != graph_node->node->id) + continue; + break; + } + if (n != max_nodes) + continue; + + max_nodes++; + new_nodes = realloc(nodes, max_nodes * sizeof(nodes[0])); + if (new_nodes == NULL) { + free(nodes); + return 0; + } + nodes = new_nodes; + nodes[n] = graph_node->node->id; + } + } + free(nodes); + + return max_nodes; +} + static struct rte_graph_cluster_stats * stats_mem_init(struct cluster *cluster, const struct rte_graph_cluster_stats_param *prm) { - size_t sz = sizeof(struct rte_graph_cluster_stats); struct rte_graph_cluster_stats *stats; rte_graph_cluster_stats_cb_t fn; int socket_id = prm->socket_id; uint32_t cluster_node_size; + uint32_t max_nodes; + + max_nodes = cluster_count_nodes(cluster); + if (max_nodes == 0) + return NULL; /* Fix up callback */ @@ -203,7 +242,7 @@ stats_mem_init(struct cluster *cluster, cluster_node_size = RTE_ALIGN(cluster_node_size, RTE_CACHE_LINE_SIZE); - stats = realloc(NULL, sz); + stats = rte_zmalloc_socket(NULL, sizeof(struct rte_graph_cluster_stats) + + max_nodes * cluster_node_size, 0, socket_id); if (stats) { - memset(stats, 0, sz); stats->fn = fn; stats->cluster_node_size = cluster_node_size; @@ -211,5 +250,4 @@ stats_mem_init(struct cluster *cluster, stats->socket_id = socket_id; stats->cookie = prm->cookie; - stats->sz = sz; } @@ -218,8 +256,7 @@ stats_mem_init(struct cluster *cluster, static int -stats_mem_populate(struct rte_graph_cluster_stats **stats_in, +stats_mem_populate(struct rte_graph_cluster_stats *stats, struct rte_graph *graph, struct graph_node *graph_node) { - struct rte_graph_cluster_stats *stats = *stats_in; rte_node_t id = graph_node->node->id; struct cluster_node *cluster; @@ -247,13 +284,4 @@ stats_mem_populate(struct rte_graph_cluster_stats **stats_in, } - /* Hey, it is a new node, allocate space for it in the reel */ - stats = realloc(stats, stats->sz + stats->cluster_node_size); - if (stats == NULL) - SET_ERR_JMP(ENOMEM, err, "Realloc failed"); - *stats_in = NULL; - - /* Clear the new struct cluster_node area */ - cluster = RTE_PTR_ADD(stats, stats->sz), - memset(cluster, 0, stats->cluster_node_size); memcpy(cluster->stat.name, graph_node->node->name, RTE_NODE_NAMESIZE); cluster->stat.id = graph_node->node->id; @@ -261,5 +289,5 @@ stats_mem_populate(struct rte_graph_cluster_stats **stats_in, node = graph_node_id_to_ptr(graph, id); if (node == NULL) - SET_ERR_JMP(ENOENT, free, "Failed to find node %s in graph %s", + SET_ERR_JMP(ENOENT, err, "Failed to find node %s in graph %s", graph_node->node->name, graph->name); cluster->nodes[cluster->nb_nodes++] = node; @@ -270,5 +298,5 @@ stats_mem_populate(struct rte_graph_cluster_stats **stats_in, RTE_CACHE_LINE_SIZE, stats->socket_id); if (cluster->stat.xstat_count == NULL) - SET_ERR_JMP(ENOMEM, free, "Failed to allocate memory node %s graph %s", + SET_ERR_JMP(ENOMEM, err, "Failed to allocate memory node %s graph %s", graph_node->node->name, graph->name); @@ -278,5 +306,5 @@ stats_mem_populate(struct rte_graph_cluster_stats **stats_in, if (cluster->stat.xstat_desc == NULL) { rte_free(cluster->stat.xstat_count); - SET_ERR_JMP(ENOMEM, free, "Failed to allocate memory node %s graph %s", + SET_ERR_JMP(ENOMEM, err, "Failed to allocate memory node %s graph %s", graph_node->node->name, graph->name); } @@ -288,5 +316,5 @@ stats_mem_populate(struct rte_graph_cluster_stats **stats_in, rte_free(cluster->stat.xstat_count); rte_free(cluster->stat.xstat_desc); - SET_ERR_JMP(E2BIG, free, + SET_ERR_JMP(E2BIG, err, "Error description overflow node %s graph %s", graph_node->node->name, graph->name); @@ -295,21 +323,11 @@ stats_mem_populate(struct rte_graph_cluster_stats **stats_in, } - stats->sz += stats->cluster_node_size; stats->max_nodes++; - *stats_in = stats; return 0; -free: - free(stats); err: return -rte_errno; } -static void -stats_mem_fini(struct rte_graph_cluster_stats *stats) -{ - free(stats); -} - static void cluster_init(struct cluster *cluster) @@ -380,8 +398,5 @@ rte_graph_cluster_stats_create(const struct rte_graph_cluster_stats_param *prm) { struct rte_graph_cluster_stats *stats, *rc = NULL; - struct graph_node *graph_node; struct cluster cluster; - struct graph *graph; - const char *pattern; rte_graph_t i; @@ -401,6 +416,5 @@ rte_graph_cluster_stats_create(const struct rte_graph_cluster_stats_param *prm) /* Expand graph pattern and add the graph to the cluster */ for (i = 0; i < prm->nb_graph_patterns; i++) { - pattern = prm->graph_patterns[i]; - if (expand_pattern_to_cluster(&cluster, pattern)) + if (expand_pattern_to_cluster(&cluster, prm->graph_patterns[i])) goto bad_pattern; } @@ -409,12 +423,15 @@ rte_graph_cluster_stats_create(const struct rte_graph_cluster_stats_param *prm) stats = stats_mem_init(&cluster, prm); if (stats == NULL) - SET_ERR_JMP(ENOMEM, bad_pattern, "Failed alloc stats memory"); + SET_ERR_JMP(ENOMEM, bad_pattern, "Failed rte_malloc for stats memory"); /* Iterate over M(Graph) x N (Nodes in graph) */ for (i = 0; i < cluster.nb_graphs; i++) { + struct graph_node *graph_node; + struct graph *graph; + graph = cluster.graphs[i]; STAILQ_FOREACH(graph_node, &graph->node_list, next) { struct rte_graph *graph_fp = graph->graph; - if (stats_mem_populate(&stats, graph_fp, graph_node)) + if (stats_mem_populate(stats, graph_fp, graph_node)) goto realloc_fail; } @@ -423,13 +440,10 @@ rte_graph_cluster_stats_create(const struct rte_graph_cluster_stats_param *prm) } - /* Finally copy to hugepage memory to avoid pressure on rte_realloc */ - rc = rte_malloc_socket(NULL, stats->sz, 0, stats->socket_id); - if (rc) - rte_memcpy(rc, stats, stats->sz); - else - SET_ERR_JMP(ENOMEM, realloc_fail, "rte_malloc failed"); + rc = stats; + stats = NULL; realloc_fail: - stats_mem_fini(stats); + if (stats != NULL) + rte_graph_cluster_stats_destroy(stats); bad_pattern: graph_spinlock_unlock(); -- 2.51.0 --- Diff of the applied patch vs upstream commit (please double-check if non-empty: --- --- - 2025-10-31 13:53:52.520133323 +0000 +++ 0007-graph-fix-unaligned-access-in-stats.patch 2025-10-31 13:53:52.009452742 +0000 @@ -1 +1 @@ -From 826af93a68f358f8eb4f363e42d114b93fde0d69 Mon Sep 17 00:00:00 2001 +From 18222a6c7b4e674a7a5cd173caedac636537ef26 Mon Sep 17 00:00:00 2001 @@ -5,0 +6,2 @@ +[ upstream commit 826af93a68f358f8eb4f363e42d114b93fde0d69 ] + @@ -32 +33,0 @@ -Cc: stable@dpdk.org @@ -41 +42 @@ -index 583ad8dbd5..e0fc8fd25c 100644 +index e955ee5e06..80f6d1eae3 100644 @@ -44 +45 @@ -@@ -38,5 +38,4 @@ struct __rte_cache_aligned rte_graph_cluster_stats { +@@ -37,5 +37,4 @@ struct __rte_cache_aligned rte_graph_cluster_stats { @@ -50 +51 @@ -@@ -179,13 +178,53 @@ graph_cluster_stats_cb_dispatch(bool is_first, bool is_last, void *cookie, +@@ -178,13 +177,53 @@ graph_cluster_stats_cb_dispatch(bool is_first, bool is_last, void *cookie, @@ -105 +106 @@ -@@ -204,7 +243,7 @@ stats_mem_init(struct cluster *cluster, +@@ -203,7 +242,7 @@ stats_mem_init(struct cluster *cluster, @@ -115 +116 @@ -@@ -212,5 +251,4 @@ stats_mem_init(struct cluster *cluster, +@@ -211,5 +250,4 @@ stats_mem_init(struct cluster *cluster, @@ -121 +122 @@ -@@ -219,8 +257,7 @@ stats_mem_init(struct cluster *cluster, +@@ -218,8 +256,7 @@ stats_mem_init(struct cluster *cluster, @@ -131 +132 @@ -@@ -248,13 +285,4 @@ stats_mem_populate(struct rte_graph_cluster_stats **stats_in, +@@ -247,13 +284,4 @@ stats_mem_populate(struct rte_graph_cluster_stats **stats_in, @@ -145 +146 @@ -@@ -262,5 +290,5 @@ stats_mem_populate(struct rte_graph_cluster_stats **stats_in, +@@ -261,5 +289,5 @@ stats_mem_populate(struct rte_graph_cluster_stats **stats_in, @@ -152 +153 @@ -@@ -271,5 +299,5 @@ stats_mem_populate(struct rte_graph_cluster_stats **stats_in, +@@ -270,5 +298,5 @@ stats_mem_populate(struct rte_graph_cluster_stats **stats_in, @@ -159 +160 @@ -@@ -279,5 +307,5 @@ stats_mem_populate(struct rte_graph_cluster_stats **stats_in, +@@ -278,5 +306,5 @@ stats_mem_populate(struct rte_graph_cluster_stats **stats_in, @@ -166 +167 @@ -@@ -289,5 +317,5 @@ stats_mem_populate(struct rte_graph_cluster_stats **stats_in, +@@ -288,5 +316,5 @@ stats_mem_populate(struct rte_graph_cluster_stats **stats_in, @@ -173 +174 @@ -@@ -296,21 +324,11 @@ stats_mem_populate(struct rte_graph_cluster_stats **stats_in, +@@ -295,21 +323,11 @@ stats_mem_populate(struct rte_graph_cluster_stats **stats_in, @@ -195 +196 @@ -@@ -382,8 +400,5 @@ rte_graph_cluster_stats_create(const struct rte_graph_cluster_stats_param *prm) +@@ -380,8 +398,5 @@ rte_graph_cluster_stats_create(const struct rte_graph_cluster_stats_param *prm) @@ -204 +205 @@ -@@ -403,6 +418,5 @@ rte_graph_cluster_stats_create(const struct rte_graph_cluster_stats_param *prm) +@@ -401,6 +416,5 @@ rte_graph_cluster_stats_create(const struct rte_graph_cluster_stats_param *prm) @@ -212 +213 @@ -@@ -411,12 +425,15 @@ rte_graph_cluster_stats_create(const struct rte_graph_cluster_stats_param *prm) +@@ -409,12 +423,15 @@ rte_graph_cluster_stats_create(const struct rte_graph_cluster_stats_param *prm) @@ -230 +231 @@ -@@ -425,13 +442,10 @@ rte_graph_cluster_stats_create(const struct rte_graph_cluster_stats_param *prm) +@@ -423,13 +440,10 @@ rte_graph_cluster_stats_create(const struct rte_graph_cluster_stats_param *prm)