DPDK patches and discussions
 help / color / mirror / Atom feed
From: Kiran Kumar Kokkilagadda <kirankumark@marvell.com>
To: David Marchand <david.marchand@redhat.com>,
	"dev@dpdk.org" <dev@dpdk.org>
Cc: "stable@dpdk.org" <stable@dpdk.org>,
	Jerin Jacob <jerinj@marvell.com>,
	Nithin Kumar Dabilpuram <ndabilpuram@marvell.com>,
	Zhirun Yan <yanzhirun_163@163.com>,
	Pavan Nikhilesh Bhagavatula <pbhagavatula@marvell.com>
Subject: Re: [EXTERNAL] [PATCH v3 14/18] graph: fix unaligned access in stats
Date: Tue, 15 Jul 2025 05:27:29 +0000	[thread overview]
Message-ID: <DM3PPF17CE793AB04170AB53A7026EA684BAC57A@DM3PPF17CE793AB.namprd18.prod.outlook.com> (raw)
In-Reply-To: <20250708122823.3406288-15-david.marchand@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 14909 bytes --]



Get Outlook for Mac <https://aka.ms/GetOutlookForMac>

From: David Marchand <david.marchand@redhat.com>
Date: Tuesday, 8 July 2025 at 6:01 PM
To: dev@dpdk.org <dev@dpdk.org>
Cc: stable@dpdk.org <stable@dpdk.org>, Jerin Jacob <jerinj@marvell.com>, Kiran Kumar Kokkilagadda <kirankumark@marvell.com>, Nithin Kumar Dabilpuram <ndabilpuram@marvell.com>, Zhirun Yan <yanzhirun_163@163.com>, Pavan Nikhilesh Bhagavatula <pbhagavatula@marvell.com>
Subject: [EXTERNAL] [PATCH v3 14/18] graph: fix unaligned access in stats
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: 
ZjQcmQRYFpfptBannerStart
Prioritize security for external emails:
Confirm sender and content safety before clicking links or opening attachments
<https://us-phishalarm-ewt.proofpoint.com/EWT/v1/CRVmXkqW!to3Z1f8UAnU69Q-c-ZxaLqw4Hrf0nRhoZPfYuYT9mJ7YnAXilGrf--fL-Zm7l1VQHd3bjUXwIMnvcu_suMpHO0hzN2TUxcSNBPH6eYM8qA$>
Report Suspicious <https://us-phishalarm-ewt.proofpoint.com/EWT/v1/CRVmXkqW!to3Z1f8UAnU69Q-c-ZxaLqw4Hrf0nRhoZPfYuYT9mJ7YnAXilGrf--fL-Zm7l1VQHd3bjUXwIMnvcu_suMpHO0hzN2TUxcSNBPH6eYM8qA$>


ZjQcmQRYFpfptBannerEnd

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")

Cc: stable@dpdk.org



Signed-off-by: David Marchand <david.marchand@redhat.com>





Acked-by: Kiran Kumar Kokkilagadda <kirankumark@marvell.com<mailto:kirankumark@marvell.com>>



 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 583ad8dbd5..e9b183bf13 100644

--- a/lib/graph/graph_stats.c

+++ b/lib/graph/graph_stats.c

@@ -37,7 +37,6 @@ struct __rte_cache_aligned rte_graph_cluster_stats {

               int socket_id;

               bool dispatch;

               void *cookie;

-              size_t sz;



               struct cluster_node clusters[];

 };

@@ -178,15 +177,55 @@ graph_cluster_stats_cb_dispatch(bool is_first, bool is_last, void *cookie,

               return graph_cluster_stats_cb(true, is_first, is_last, cookie, stat);

 };



+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) {

+                                            unsigned int n;

+

+                                            for (n = 0; n < max_nodes; n++) {

+                                                           if (nodes[n] != graph_node->node->id)

+                                                                          continue;

+                                                           break;

+                                            }

+                                            if (n == max_nodes) {

+                                                           rte_node_t *new_nodes;

+

+                                                           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 */

               fn = prm->fn;

@@ -203,25 +242,23 @@ stats_mem_init(struct cluster *cluster,

               cluster_node_size += cluster->nb_graphs * sizeof(struct rte_node *);

               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;

                               stats->max_nodes = 0;

                               stats->socket_id = socket_id;

                               stats->cookie = prm->cookie;

-                             stats->sz = sz;

               }



               return stats;

 }



 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;

               struct rte_node *node;

@@ -247,21 +284,12 @@ stats_mem_populate(struct rte_graph_cluster_stats **stats_in,

                               cluster = RTE_PTR_ADD(cluster, stats->cluster_node_size);

               }



-              /* 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;

               cluster->stat.hz = rte_get_timer_hz();

               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;

               if (graph_node->node->xstats) {

@@ -270,7 +298,7 @@ stats_mem_populate(struct rte_graph_cluster_stats **stats_in,

                                              sizeof(uint64_t) * graph_node->node->xstats->nb_xstats,

                                              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);



                               cluster->stat.xstat_desc = rte_zmalloc_socket(NULL,

@@ -278,7 +306,7 @@ stats_mem_populate(struct rte_graph_cluster_stats **stats_in,

                                              RTE_CACHE_LINE_SIZE, stats->socket_id);

                               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,30 +316,20 @@ stats_mem_populate(struct rte_graph_cluster_stats **stats_in,

                                                                            RTE_NODE_XSTAT_DESC_SIZE) < 0) {

                                                             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);

                                              }

                               }

               }



-              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)

 {

@@ -381,10 +399,7 @@ struct rte_graph_cluster_stats *

 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;



               /* Sanity checks */

@@ -402,37 +417,36 @@ rte_graph_cluster_stats_create(const struct rte_graph_cluster_stats_param *prm)

               graph_spinlock_lock();

               /* 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;

               }



               /* Alloc the stats memory */

               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;

                               }

                               if (graph->graph->model == RTE_GRAPH_MODEL_MCORE_DISPATCH)

                                              stats->dispatch = true;

               }



-              /* 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();

               cluster_fini(&cluster);

--

2.50.0



[-- Attachment #2: Type: text/html, Size: 70736 bytes --]

  reply	other threads:[~2025-07-15  5:27 UTC|newest]

Thread overview: 88+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-06-19  7:10 [PATCH 00/10] Run with UBSan in GHA David Marchand
2025-06-19  7:10 ` [PATCH 01/10] ci: save ccache on failure David Marchand
2025-06-25 12:16   ` Aaron Conole
2025-06-19  7:10 ` [PATCH 02/10] test/telemetry: fix test calling all commands David Marchand
2025-06-20  9:16   ` Bruce Richardson
2025-06-23  9:54   ` David Marchand
2025-06-19  7:10 ` [PATCH 03/10] test/mempool: fix test without stack driver David Marchand
2025-06-20  8:54   ` Andrew Rybchenko
2025-06-19  7:10 ` [PATCH 04/10] eal: fix plugin dir walk David Marchand
2025-06-20  9:19   ` Bruce Richardson
2025-06-23  9:41     ` David Marchand
2025-06-19  7:10 ` [PATCH 05/10] cmdline: fix port list parsing David Marchand
2025-06-20  9:58   ` Bruce Richardson
2025-06-23  9:40     ` David Marchand
2025-06-23 10:41       ` Bruce Richardson
2025-06-19  7:10 ` [PATCH 06/10] cmdline: fix highest bit " David Marchand
2025-06-20  9:21   ` Bruce Richardson
2025-06-23  9:32     ` David Marchand
2025-06-19  7:10 ` [PATCH 07/10] tailq: fix cast macro for null pointer David Marchand
2025-06-20  9:23   ` Bruce Richardson
2025-06-19  7:10 ` [PATCH 08/10] hash: fix unaligned access in predictable RSS David Marchand
2025-06-19  7:10 ` [PATCH 09/10] stack: fix unaligned accesses on 128-bit David Marchand
2025-06-19  7:10 ` [PATCH 10/10] build: support Undefined Behavior Sanitizer David Marchand
2025-06-25 12:17   ` Aaron Conole
2025-06-23 13:52 ` [PATCH v2 00/10] Run with UBSan in GHA David Marchand
2025-06-23 13:52   ` [PATCH v2 01/10] ci: save ccache on failure David Marchand
2025-06-23 13:52   ` [PATCH v2 02/10] test/telemetry: fix test calling all commands David Marchand
2025-06-24 15:59     ` Marat Khalili
2025-06-26  8:32       ` David Marchand
2025-06-26  9:51         ` Marat Khalili
2025-07-03 14:09           ` David Marchand
2025-07-03 15:08             ` Marat Khalili
2025-06-23 13:52   ` [PATCH v2 03/10] test/mempool: fix test without stack driver David Marchand
2025-06-24 16:21     ` Marat Khalili
2025-06-23 13:52   ` [PATCH v2 04/10] eal: fix plugin dir walk David Marchand
2025-06-25  8:43     ` Marat Khalili
2025-07-03 14:27       ` David Marchand
2025-06-23 13:52   ` [PATCH v2 05/10] cmdline: fix port list parsing David Marchand
2025-06-23 14:00     ` Bruce Richardson
2025-06-26  9:32     ` Marat Khalili
2025-06-23 13:52   ` [PATCH v2 06/10] cmdline: fix highest bit " David Marchand
2025-06-30 15:25     ` Marat Khalili
2025-06-23 13:52   ` [PATCH v2 07/10] tailq: fix cast macro for null pointer David Marchand
2025-06-30 16:06     ` Marat Khalili
2025-06-23 13:52   ` [PATCH v2 08/10] hash: fix unaligned access in predictable RSS David Marchand
2025-06-30 15:32     ` Bruce Richardson
2025-07-01  8:36     ` Konstantin Ananyev
2025-07-08  7:32       ` David Marchand
2025-07-08 17:58         ` Konstantin Ananyev
2025-07-15 11:57           ` David Marchand
2025-07-15 13:32             ` Konstantin Ananyev
2025-07-15 14:54               ` David Marchand
2025-06-23 13:52   ` [PATCH v2 09/10] stack: fix unaligned accesses on 128-bit David Marchand
2025-06-30 15:33     ` Bruce Richardson
2025-06-23 13:52   ` [PATCH v2 10/10] build: support Undefined Behavior Sanitizer David Marchand
2025-07-08 12:28 ` [PATCH v3 00/18] Run with UBSan in GHA David Marchand
2025-07-08 12:28   ` [PATCH v3 01/18] ci: save ccache on failure David Marchand
2025-07-08 12:28   ` [PATCH v3 02/18] test/telemetry: fix test calling all commands David Marchand
2025-07-08 12:28   ` [PATCH v3 03/18] test/mempool: fix test without stack driver David Marchand
2025-07-08 15:15     ` Morten Brørup
2025-07-08 12:28   ` [PATCH v3 04/18] eal: fix plugin dir walk David Marchand
2025-07-08 12:28   ` [PATCH v3 05/18] cmdline: fix port list parsing David Marchand
2025-07-08 12:28   ` [PATCH v3 06/18] cmdline: fix highest bit " David Marchand
2025-07-08 12:28   ` [PATCH v3 07/18] tailq: fix cast macro for null pointer David Marchand
2025-07-08 12:28   ` [PATCH v3 08/18] hash: fix unaligned access in predictable RSS David Marchand
2025-07-08 12:35     ` Medvedkin, Vladimir
2025-07-08 12:28   ` [PATCH v3 09/18] stack: fix unaligned accesses on 128-bit David Marchand
2025-07-08 15:41     ` Morten Brørup
2025-07-09  8:23     ` Konstantin Ananyev
2025-07-08 12:28   ` [PATCH v3 10/18] build: support Undefined Behavior Sanitizer David Marchand
2025-07-11 12:19     ` Aaron Conole
2025-07-08 12:28   ` [PATCH v3 11/18] test/telemetry: catch errors in subshell David Marchand
2025-07-08 12:28   ` [PATCH v3 12/18] malloc: fix mp message alignment David Marchand
2025-07-08 12:44     ` Bruce Richardson
2025-07-08 12:46       ` David Marchand
2025-07-08 13:25         ` Bruce Richardson
2025-07-08 13:33           ` David Marchand
2025-07-08 12:28   ` [PATCH v3 13/18] graph: fix stats query with no node xstats David Marchand
2025-07-08 12:28   ` [PATCH v3 14/18] graph: fix unaligned access in stats David Marchand
2025-07-15  5:27     ` Kiran Kumar Kokkilagadda [this message]
2025-07-08 12:28   ` [PATCH v3 15/18] eventdev: fix listing timer adapters with telemetry David Marchand
2025-07-08 12:28   ` [PATCH v3 16/18] test/power: fix tests without power drivers David Marchand
2025-07-08 12:47     ` Bruce Richardson
2025-07-08 12:53       ` David Marchand
2025-07-08 13:26         ` Bruce Richardson
2025-07-08 12:28   ` [PATCH v3 17/18] test/raw: fix test without skeleton driver David Marchand
2025-07-08 12:48     ` Bruce Richardson
2025-07-08 12:28   ` [PATCH v3 18/18] ci: extend coverage with UBSan David Marchand

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=DM3PPF17CE793AB04170AB53A7026EA684BAC57A@DM3PPF17CE793AB.namprd18.prod.outlook.com \
    --to=kirankumark@marvell.com \
    --cc=david.marchand@redhat.com \
    --cc=dev@dpdk.org \
    --cc=jerinj@marvell.com \
    --cc=ndabilpuram@marvell.com \
    --cc=pbhagavatula@marvell.com \
    --cc=stable@dpdk.org \
    --cc=yanzhirun_163@163.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).