From 41eb1be1dc060f219f493f064c6f5cff1a1ad3cb Mon Sep 17 00:00:00 2001 From: Mohammad Abdul Awal Date: Wed, 5 Aug 2026 16:36:15 +0100 Subject: [PATCH] ipm: add patches for dpdk 25.11 Also rebased the older DPDK LTS patches to latest stable version as below. The 25.11/ directory contains patches that add the busyness telemetry to DPDK 25.11.2 The 24.11/ directory contains patches that add the busyness telemetry to DPDK 24.11.5 The 23.11/ directory contains patches that add the busyness telemetry to DPDK 23.11.6 The 22.11/ directory contains patches that add the busyness telemetry to DPDK 22.11.11 The 21.11/ directory contains patches that add the busyness telemetry to DPDK 21.11.9 The 20.11/ directory contains patches that add the busyness telemetry to DPDK 20.11.10 Signed-off-by: Mohammad Abdul Awal --- ...001-eal-add-lcore-busyness-telemetry.patch | 70 +- ...l-add-cpuset-lcore-telemetry-entries.patch | 6 +- ...apacity-endpoint-to-telemetry-thread.patch | 10 +- ...001-eal-add-lcore-busyness-telemetry.patch | 72 +- ...l-add-cpuset-lcore-telemetry-entries.patch | 6 +- ...apacity-endpoint-to-telemetry-thread.patch | 10 +- ...001-eal-add-lcore-busyness-telemetry.patch | 70 +- ...l-add-cpuset-lcore-telemetry-entries.patch | 4 +- ...apacity-endpoint-to-telemetry-thread.patch | 8 +- ...001-eal-add-lcore-busyness-telemetry.patch | 877 ++++++++++++++++++ ...l-add-cpuset-lcore-telemetry-entries.patch | 79 ++ ...apacity-endpoint-to-telemetry-thread.patch | 346 +++++++ ipm/patches/dpdk/README.md | 11 +- 13 files changed, 1436 insertions(+), 133 deletions(-) create mode 100644 ipm/patches/dpdk/25.11/0001-eal-add-lcore-busyness-telemetry.patch create mode 100644 ipm/patches/dpdk/25.11/0002-eal-add-cpuset-lcore-telemetry-entries.patch create mode 100644 ipm/patches/dpdk/25.11/0003-add-capacity-endpoint-to-telemetry-thread.patch diff --git a/ipm/patches/dpdk/22.11/0001-eal-add-lcore-busyness-telemetry.patch b/ipm/patches/dpdk/22.11/0001-eal-add-lcore-busyness-telemetry.patch index 7e8d5c4..9e5a994 100644 --- a/ipm/patches/dpdk/22.11/0001-eal-add-lcore-busyness-telemetry.patch +++ b/ipm/patches/dpdk/22.11/0001-eal-add-lcore-busyness-telemetry.patch @@ -1,6 +1,6 @@ -From 5129fb19501eecce2410efc58548951ffb02c226 Mon Sep 17 00:00:00 2001 -From: Anatoly Burakov -Date: Mon, 11 Nov 2024 09:25:29 +0000 +From 82605211da6a3e7fc45ef254c1dc5da81c88f2e6 Mon Sep 17 00:00:00 2001 +From: Kevin Laatz +Date: Wed, 22 Apr 2026 11:06:33 +0000 Subject: [PATCH 1/3] eal: add lcore busyness telemetry Currently, there is no way to measure lcore busyness in a passive way, @@ -72,7 +72,7 @@ Signed-off-by: Anatoly Burakov create mode 100644 lib/eal/common/eal_common_lcore_telemetry.c diff --git a/config/rte_config.h b/config/rte_config.h -index 7b8c85e948..1193d936f6 100644 +index 7b8c85e..1193d93 100644 --- a/config/rte_config.h +++ b/config/rte_config.h @@ -38,6 +38,8 @@ @@ -85,7 +85,7 @@ index 7b8c85e948..1193d936f6 100644 /* bsd module defines */ #define RTE_CONTIGMEM_MAX_NUM_BUFS 64 diff --git a/lib/bbdev/rte_bbdev.h b/lib/bbdev/rte_bbdev.h -index 52f6ed9b01..9f337ee4d1 100644 +index 52f6ed9..9f337ee 100644 --- a/lib/bbdev/rte_bbdev.h +++ b/lib/bbdev/rte_bbdev.h @@ -29,6 +29,7 @@ extern "C" { @@ -141,7 +141,7 @@ index 52f6ed9b01..9f337ee4d1 100644 /** diff --git a/lib/compressdev/rte_compressdev.c b/lib/compressdev/rte_compressdev.c -index cf2c20a704..04a854a935 100644 +index cf2c20a..04a854a 100644 --- a/lib/compressdev/rte_compressdev.c +++ b/lib/compressdev/rte_compressdev.c @@ -587,6 +587,8 @@ rte_compressdev_dequeue_burst(uint8_t dev_id, uint16_t qp_id, @@ -154,7 +154,7 @@ index cf2c20a704..04a854a935 100644 } diff --git a/lib/cryptodev/rte_cryptodev.h b/lib/cryptodev/rte_cryptodev.h -index cef9f2b3cb..82fc21d24d 100644 +index cef9f2b..82fc21d 100644 --- a/lib/cryptodev/rte_cryptodev.h +++ b/lib/cryptodev/rte_cryptodev.h @@ -1874,6 +1874,8 @@ rte_cryptodev_dequeue_burst(uint8_t dev_id, uint16_t qp_id, @@ -167,7 +167,7 @@ index cef9f2b3cb..82fc21d24d 100644 } diff --git a/lib/distributor/rte_distributor.c b/lib/distributor/rte_distributor.c -index 3969b2ea7e..6136547e9a 100644 +index 3969b2e..6136547 100644 --- a/lib/distributor/rte_distributor.c +++ b/lib/distributor/rte_distributor.c @@ -57,6 +57,8 @@ rte_distributor_request_pkt(struct rte_distributor *d, @@ -217,7 +217,7 @@ index 3969b2ea7e..6136547e9a 100644 } diff --git a/lib/distributor/rte_distributor_single.c b/lib/distributor/rte_distributor_single.c -index 2c77ac454a..4c3bb1b5c1 100644 +index 2c77ac4..4c3bb1b 100644 --- a/lib/distributor/rte_distributor_single.c +++ b/lib/distributor/rte_distributor_single.c @@ -31,8 +31,13 @@ rte_distributor_request_pkt_single(struct rte_distributor_single *d, @@ -250,10 +250,10 @@ index 2c77ac454a..4c3bb1b5c1 100644 } diff --git a/lib/dmadev/rte_dmadev.h b/lib/dmadev/rte_dmadev.h -index e61d71959e..754e10b95d 100644 +index 2360560..40fc8bc 100644 --- a/lib/dmadev/rte_dmadev.h +++ b/lib/dmadev/rte_dmadev.h -@@ -149,6 +149,7 @@ +@@ -150,6 +150,7 @@ #include #include #include @@ -261,7 +261,7 @@ index e61d71959e..754e10b95d 100644 #ifdef __cplusplus extern "C" { -@@ -1031,7 +1032,7 @@ rte_dma_completed(int16_t dev_id, uint16_t vchan, const uint16_t nb_cpls, +@@ -1032,7 +1033,7 @@ rte_dma_completed(int16_t dev_id, uint16_t vchan, const uint16_t nb_cpls, uint16_t *last_idx, bool *has_error) { struct rte_dma_fp_object *obj = &rte_dma_fp_objs[dev_id]; @@ -270,7 +270,7 @@ index e61d71959e..754e10b95d 100644 bool err; #ifdef RTE_DMADEV_DEBUG -@@ -1055,8 +1056,10 @@ rte_dma_completed(int16_t dev_id, uint16_t vchan, const uint16_t nb_cpls, +@@ -1056,8 +1057,10 @@ rte_dma_completed(int16_t dev_id, uint16_t vchan, const uint16_t nb_cpls, has_error = &err; *has_error = false; @@ -283,7 +283,7 @@ index e61d71959e..754e10b95d 100644 } /** -@@ -1095,7 +1098,7 @@ rte_dma_completed_status(int16_t dev_id, uint16_t vchan, +@@ -1096,7 +1099,7 @@ rte_dma_completed_status(int16_t dev_id, uint16_t vchan, enum rte_dma_status_code *status) { struct rte_dma_fp_object *obj = &rte_dma_fp_objs[dev_id]; @@ -292,7 +292,7 @@ index e61d71959e..754e10b95d 100644 #ifdef RTE_DMADEV_DEBUG if (!rte_dma_is_valid(dev_id) || nb_cpls == 0 || status == NULL) -@@ -1107,8 +1110,10 @@ rte_dma_completed_status(int16_t dev_id, uint16_t vchan, +@@ -1108,8 +1111,10 @@ rte_dma_completed_status(int16_t dev_id, uint16_t vchan, if (last_idx == NULL) last_idx = &idx; @@ -306,7 +306,7 @@ index e61d71959e..754e10b95d 100644 /** diff --git a/lib/eal/common/eal_common_lcore_telemetry.c b/lib/eal/common/eal_common_lcore_telemetry.c new file mode 100644 -index 0000000000..1478e5a48a +index 0000000..1478e5a --- /dev/null +++ b/lib/eal/common/eal_common_lcore_telemetry.c @@ -0,0 +1,319 @@ @@ -630,7 +630,7 @@ index 0000000000..1478e5a48a + +#endif diff --git a/lib/eal/common/meson.build b/lib/eal/common/meson.build -index 917758cc65..a743e66a7d 100644 +index 917758c..a743e66 100644 --- a/lib/eal/common/meson.build +++ b/lib/eal/common/meson.build @@ -17,6 +17,7 @@ sources += files( @@ -642,19 +642,19 @@ index 917758cc65..a743e66a7d 100644 'eal_common_log.c', 'eal_common_mcfg.c', diff --git a/lib/eal/freebsd/eal.c b/lib/eal/freebsd/eal.c -index 122daf6c1f..a7be6ab285 100644 +index 3da8dec..dc5fa8e 100644 --- a/lib/eal/freebsd/eal.c +++ b/lib/eal/freebsd/eal.c -@@ -906,6 +906,7 @@ rte_eal_cleanup(void) - eal_bus_cleanup(); +@@ -911,6 +911,7 @@ rte_eal_cleanup(void) + rte_eal_alarm_cleanup(); rte_trace_save(); eal_trace_fini(); + eal_lcore_telemetry_free(); - rte_eal_alarm_cleanup(); /* after this point, any DPDK pointers will become dangling */ rte_eal_memory_detach(); + eal_cleanup_config(internal_conf); diff --git a/lib/eal/include/rte_lcore.h b/lib/eal/include/rte_lcore.h -index 6938c3fd7b..9f4bd6e22f 100644 +index 6938c3f..9f4bd6e 100644 --- a/lib/eal/include/rte_lcore.h +++ b/lib/eal/include/rte_lcore.h @@ -418,6 +418,90 @@ rte_ctrl_thread_create(pthread_t *thread, const char *name, @@ -749,19 +749,19 @@ index 6938c3fd7b..9f4bd6e22f 100644 } #endif diff --git a/lib/eal/linux/eal.c b/lib/eal/linux/eal.c -index 336698379f..2bff37791e 100644 +index de30e52..7fa21f0 100644 --- a/lib/eal/linux/eal.c +++ b/lib/eal/linux/eal.c -@@ -1382,6 +1382,7 @@ rte_eal_cleanup(void) - eal_bus_cleanup(); +@@ -1386,6 +1386,7 @@ rte_eal_cleanup(void) + rte_eal_alarm_cleanup(); rte_trace_save(); eal_trace_fini(); + eal_lcore_telemetry_free(); eal_mp_dev_hotplug_cleanup(); - rte_eal_alarm_cleanup(); /* after this point, any DPDK pointers will become dangling */ + rte_eal_memory_detach(); diff --git a/lib/eal/meson.build b/lib/eal/meson.build -index 056beb9461..7199aa03c2 100644 +index 056beb9..7199aa0 100644 --- a/lib/eal/meson.build +++ b/lib/eal/meson.build @@ -25,6 +25,9 @@ subdir(arch_subdir) @@ -775,7 +775,7 @@ index 056beb9461..7199aa03c2 100644 if dpdk_conf.has('RTE_USE_LIBBSD') ext_deps += libbsd diff --git a/lib/eal/version.map b/lib/eal/version.map -index 7ad12a7dc9..7791f59314 100644 +index 7ad12a7..7791f59 100644 --- a/lib/eal/version.map +++ b/lib/eal/version.map @@ -440,6 +440,13 @@ EXPERIMENTAL { @@ -793,10 +793,10 @@ index 7ad12a7dc9..7791f59314 100644 INTERNAL { diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h -index e73244822a..17fabfa5b0 100644 +index 913ff2a..9c8f2bf 100644 --- a/lib/ethdev/rte_ethdev.h +++ b/lib/ethdev/rte_ethdev.h -@@ -5913,6 +5913,8 @@ rte_eth_rx_burst(uint16_t port_id, uint16_t queue_id, +@@ -5919,6 +5919,8 @@ rte_eth_rx_burst(uint16_t port_id, uint16_t queue_id, #endif rte_ethdev_trace_rx_burst(port_id, queue_id, (void **)rx_pkts, nb_rx); @@ -806,7 +806,7 @@ index e73244822a..17fabfa5b0 100644 } diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h -index d0e2463bb8..b4f677c46d 100644 +index d0e2463..b4f677c 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h @@ -2194,6 +2194,7 @@ rte_event_dequeue_burst(uint8_t dev_id, uint8_t port_id, struct rte_event ev[], @@ -835,7 +835,7 @@ index d0e2463bb8..b4f677c46d 100644 #define RTE_EVENT_DEV_MAINT_OP_FLUSH (1 << 0) diff --git a/lib/rawdev/rte_rawdev.c b/lib/rawdev/rte_rawdev.c -index dcebe4f653..0faae13c9c 100644 +index 4805e14..470ae23 100644 --- a/lib/rawdev/rte_rawdev.c +++ b/lib/rawdev/rte_rawdev.c @@ -237,13 +237,16 @@ rte_rawdev_dequeue_buffers(uint16_t dev_id, @@ -857,7 +857,7 @@ index dcebe4f653..0faae13c9c 100644 int diff --git a/lib/regexdev/rte_regexdev.h b/lib/regexdev/rte_regexdev.h -index 25476f1f73..31fd293e48 100644 +index 25476f1..31fd293 100644 --- a/lib/regexdev/rte_regexdev.h +++ b/lib/regexdev/rte_regexdev.h @@ -1534,6 +1534,7 @@ rte_regexdev_dequeue_burst(uint8_t dev_id, uint16_t qp_id, @@ -880,7 +880,7 @@ index 25476f1f73..31fd293e48 100644 #ifdef __cplusplus diff --git a/lib/ring/rte_ring_elem_pvt.h b/lib/ring/rte_ring_elem_pvt.h -index 4b80f58980..e2a72e3ea7 100644 +index 4b80f58..e2a72e3 100644 --- a/lib/ring/rte_ring_elem_pvt.h +++ b/lib/ring/rte_ring_elem_pvt.h @@ -385,6 +385,7 @@ __rte_ring_do_dequeue_elem(struct rte_ring *r, void *obj_table, @@ -892,5 +892,5 @@ index 4b80f58980..e2a72e3ea7 100644 } -- -2.25.1 +2.43.0 diff --git a/ipm/patches/dpdk/22.11/0002-eal-add-cpuset-lcore-telemetry-entries.patch b/ipm/patches/dpdk/22.11/0002-eal-add-cpuset-lcore-telemetry-entries.patch index 2a02775..c5485c0 100644 --- a/ipm/patches/dpdk/22.11/0002-eal-add-cpuset-lcore-telemetry-entries.patch +++ b/ipm/patches/dpdk/22.11/0002-eal-add-cpuset-lcore-telemetry-entries.patch @@ -1,4 +1,4 @@ -From 810d87bf69d79351cfa3089df920e4b726f269a5 Mon Sep 17 00:00:00 2001 +From 209a9711579aa81084211ac1895a8d01d0902642 Mon Sep 17 00:00:00 2001 From: Anatoly Burakov Date: Fri, 15 Jul 2022 13:12:45 +0000 Subject: [PATCH 2/3] eal: add cpuset lcore telemetry entries @@ -11,7 +11,7 @@ Signed-off-by: Anatoly Burakov 1 file changed, 46 insertions(+) diff --git a/lib/eal/common/eal_common_lcore_telemetry.c b/lib/eal/common/eal_common_lcore_telemetry.c -index 1478e5a48a..f01ccd9a65 100644 +index 1478e5a..f01ccd9 100644 --- a/lib/eal/common/eal_common_lcore_telemetry.c +++ b/lib/eal/common/eal_common_lcore_telemetry.c @@ -263,6 +263,49 @@ lcore_handle_busyness(const char *cmd __rte_unused, @@ -75,5 +75,5 @@ index 1478e5a48a..f01ccd9a65 100644 } -- -2.25.1 +2.43.0 diff --git a/ipm/patches/dpdk/22.11/0003-add-capacity-endpoint-to-telemetry-thread.patch b/ipm/patches/dpdk/22.11/0003-add-capacity-endpoint-to-telemetry-thread.patch index df6cbd4..9925a0f 100644 --- a/ipm/patches/dpdk/22.11/0003-add-capacity-endpoint-to-telemetry-thread.patch +++ b/ipm/patches/dpdk/22.11/0003-add-capacity-endpoint-to-telemetry-thread.patch @@ -1,4 +1,4 @@ -From ea2762b20c60cd66378758559af90bb48c9a8ee5 Mon Sep 17 00:00:00 2001 +From 84a7755e2cac79d509f00d216765bf83df723e88 Mon Sep 17 00:00:00 2001 From: David Hunt Date: Fri, 23 Aug 2024 09:07:08 +0100 Subject: [PATCH 3/3] add capacity endpoint to telemetry thread @@ -19,7 +19,7 @@ Signed-off-by: David Hunt 3 files changed, 262 insertions(+) diff --git a/lib/eal/common/eal_common_lcore_telemetry.c b/lib/eal/common/eal_common_lcore_telemetry.c -index f01ccd9a65..18dcc40b1e 100644 +index f01ccd9..18dcc40 100644 --- a/lib/eal/common/eal_common_lcore_telemetry.c +++ b/lib/eal/common/eal_common_lcore_telemetry.c @@ -10,9 +10,18 @@ @@ -308,7 +308,7 @@ index f01ccd9a65..18dcc40b1e 100644 { return -ENOTSUP; diff --git a/lib/eal/include/rte_lcore.h b/lib/eal/include/rte_lcore.h -index 9f4bd6e22f..132cdb9139 100644 +index 9f4bd6e..132cdb9 100644 --- a/lib/eal/include/rte_lcore.h +++ b/lib/eal/include/rte_lcore.h @@ -437,6 +437,27 @@ __rte_experimental @@ -340,7 +340,7 @@ index 9f4bd6e22f..132cdb9139 100644 * @warning * @b EXPERIMENTAL: this API may change without prior notice. diff --git a/lib/eal/version.map b/lib/eal/version.map -index 7791f59314..5bb8429b29 100644 +index 7791f59..5bb8429 100644 --- a/lib/eal/version.map +++ b/lib/eal/version.map @@ -444,6 +444,7 @@ EXPERIMENTAL { @@ -352,5 +352,5 @@ index 7791f59314..5bb8429b29 100644 rte_lcore_busyness_enabled; rte_lcore_busyness_enabled_set; -- -2.25.1 +2.43.0 diff --git a/ipm/patches/dpdk/23.11/0001-eal-add-lcore-busyness-telemetry.patch b/ipm/patches/dpdk/23.11/0001-eal-add-lcore-busyness-telemetry.patch index 79354fa..296d251 100644 --- a/ipm/patches/dpdk/23.11/0001-eal-add-lcore-busyness-telemetry.patch +++ b/ipm/patches/dpdk/23.11/0001-eal-add-lcore-busyness-telemetry.patch @@ -1,6 +1,6 @@ -From 80cd70f677c7747f0f930c6212bbd42bcd58c02c Mon Sep 17 00:00:00 2001 -From: Anatoly Burakov -Date: Fri, 20 Sep 2024 09:08:28 +0100 +From 4d68af72818fe1f49c824f128dd8a58525b6187c Mon Sep 17 00:00:00 2001 +From: Kevin Laatz +Date: Wed, 22 Apr 2026 10:34:35 +0000 Subject: [PATCH 1/3] eal: add lcore busyness telemetry Currently, there is no way to measure lcore busyness in a passive way, @@ -73,7 +73,7 @@ Signed-off-by: Anatoly Burakov create mode 100644 lib/eal/common/eal_common_lcore_telemetry.c diff --git a/config/rte_config.h b/config/rte_config.h -index da265d7dd2..7e0083abf3 100644 +index da265d7..7e0083a 100644 --- a/config/rte_config.h +++ b/config/rte_config.h @@ -38,6 +38,8 @@ @@ -86,7 +86,7 @@ index da265d7dd2..7e0083abf3 100644 /* bsd module defines */ #define RTE_CONTIGMEM_MAX_NUM_BUFS 64 diff --git a/lib/bbdev/rte_bbdev.h b/lib/bbdev/rte_bbdev.h -index 0cbfdd1c95..536f3a79d3 100644 +index 0cbfdd1..536f3a7 100644 --- a/lib/bbdev/rte_bbdev.h +++ b/lib/bbdev/rte_bbdev.h @@ -29,6 +29,7 @@ extern "C" { @@ -142,7 +142,7 @@ index 0cbfdd1c95..536f3a79d3 100644 /** diff --git a/lib/compressdev/rte_compressdev.c b/lib/compressdev/rte_compressdev.c -index cf2c20a704..04a854a935 100644 +index cf2c20a..04a854a 100644 --- a/lib/compressdev/rte_compressdev.c +++ b/lib/compressdev/rte_compressdev.c @@ -587,6 +587,8 @@ rte_compressdev_dequeue_burst(uint8_t dev_id, uint16_t qp_id, @@ -155,7 +155,7 @@ index cf2c20a704..04a854a935 100644 } diff --git a/lib/cryptodev/rte_cryptodev.h b/lib/cryptodev/rte_cryptodev.h -index a42a4fc04e..12e986c6e4 100644 +index a42a4fc..12e986c 100644 --- a/lib/cryptodev/rte_cryptodev.h +++ b/lib/cryptodev/rte_cryptodev.h @@ -1933,6 +1933,8 @@ rte_cryptodev_dequeue_burst(uint8_t dev_id, uint16_t qp_id, @@ -168,7 +168,7 @@ index a42a4fc04e..12e986c6e4 100644 } diff --git a/lib/distributor/rte_distributor.c b/lib/distributor/rte_distributor.c -index 2ecb95c3e5..0c8f9a1dea 100644 +index 2ecb95c..0c8f9a1 100644 --- a/lib/distributor/rte_distributor.c +++ b/lib/distributor/rte_distributor.c @@ -57,6 +57,8 @@ rte_distributor_request_pkt(struct rte_distributor *d, @@ -218,7 +218,7 @@ index 2ecb95c3e5..0c8f9a1dea 100644 } diff --git a/lib/distributor/rte_distributor_single.c b/lib/distributor/rte_distributor_single.c -index d4b3e12648..3c18805ecd 100644 +index d4b3e12..3c18805 100644 --- a/lib/distributor/rte_distributor_single.c +++ b/lib/distributor/rte_distributor_single.c @@ -31,8 +31,13 @@ rte_distributor_request_pkt_single(struct rte_distributor_single *d, @@ -251,10 +251,10 @@ index d4b3e12648..3c18805ecd 100644 } diff --git a/lib/dmadev/rte_dmadev.h b/lib/dmadev/rte_dmadev.h -index 450b81c307..e32d089a48 100644 +index 54a65cc..4903622 100644 --- a/lib/dmadev/rte_dmadev.h +++ b/lib/dmadev/rte_dmadev.h -@@ -148,6 +148,8 @@ +@@ -149,6 +149,8 @@ #include #include @@ -263,7 +263,7 @@ index 450b81c307..e32d089a48 100644 #ifdef __cplusplus extern "C" { -@@ -995,7 +997,7 @@ rte_dma_completed(int16_t dev_id, uint16_t vchan, const uint16_t nb_cpls, +@@ -996,7 +998,7 @@ rte_dma_completed(int16_t dev_id, uint16_t vchan, const uint16_t nb_cpls, uint16_t *last_idx, bool *has_error) { struct rte_dma_fp_object *obj = &rte_dma_fp_objs[dev_id]; @@ -272,7 +272,7 @@ index 450b81c307..e32d089a48 100644 bool err; #ifdef RTE_DMADEV_DEBUG -@@ -1019,8 +1021,10 @@ rte_dma_completed(int16_t dev_id, uint16_t vchan, const uint16_t nb_cpls, +@@ -1020,8 +1022,10 @@ rte_dma_completed(int16_t dev_id, uint16_t vchan, const uint16_t nb_cpls, has_error = &err; *has_error = false; @@ -285,7 +285,7 @@ index 450b81c307..e32d089a48 100644 } /** -@@ -1055,7 +1059,7 @@ rte_dma_completed_status(int16_t dev_id, uint16_t vchan, +@@ -1056,7 +1060,7 @@ rte_dma_completed_status(int16_t dev_id, uint16_t vchan, enum rte_dma_status_code *status) { struct rte_dma_fp_object *obj = &rte_dma_fp_objs[dev_id]; @@ -294,7 +294,7 @@ index 450b81c307..e32d089a48 100644 #ifdef RTE_DMADEV_DEBUG if (!rte_dma_is_valid(dev_id) || nb_cpls == 0 || status == NULL) -@@ -1067,8 +1071,10 @@ rte_dma_completed_status(int16_t dev_id, uint16_t vchan, +@@ -1068,8 +1072,10 @@ rte_dma_completed_status(int16_t dev_id, uint16_t vchan, if (last_idx == NULL) last_idx = &idx; @@ -308,7 +308,7 @@ index 450b81c307..e32d089a48 100644 /** diff --git a/lib/eal/common/eal_common_lcore_telemetry.c b/lib/eal/common/eal_common_lcore_telemetry.c new file mode 100644 -index 0000000000..1478e5a48a +index 0000000..1478e5a --- /dev/null +++ b/lib/eal/common/eal_common_lcore_telemetry.c @@ -0,0 +1,319 @@ @@ -632,7 +632,7 @@ index 0000000000..1478e5a48a + +#endif diff --git a/lib/eal/common/meson.build b/lib/eal/common/meson.build -index 22a626ba6f..1ca6f9a420 100644 +index 22a626b..1ca6f9a 100644 --- a/lib/eal/common/meson.build +++ b/lib/eal/common/meson.build @@ -17,6 +17,7 @@ sources += files( @@ -644,19 +644,19 @@ index 22a626ba6f..1ca6f9a420 100644 'eal_common_mcfg.c', 'eal_common_memalloc.c', diff --git a/lib/eal/freebsd/eal.c b/lib/eal/freebsd/eal.c -index 568e06e9ed..1c27688e39 100644 +index 2c9eb3d..a91ad04 100644 --- a/lib/eal/freebsd/eal.c +++ b/lib/eal/freebsd/eal.c -@@ -929,6 +929,7 @@ rte_eal_cleanup(void) - eal_bus_cleanup(); +@@ -934,6 +934,7 @@ rte_eal_cleanup(void) + rte_eal_alarm_cleanup(); rte_trace_save(); eal_trace_fini(); + eal_lcore_telemetry_free(); - rte_eal_alarm_cleanup(); /* after this point, any DPDK pointers will become dangling */ rte_eal_memory_detach(); + eal_cleanup_config(internal_conf); diff --git a/lib/eal/include/rte_lcore.h b/lib/eal/include/rte_lcore.h -index 7deae47af3..3c64774bcb 100644 +index 7deae47..3c64774 100644 --- a/lib/eal/include/rte_lcore.h +++ b/lib/eal/include/rte_lcore.h @@ -407,6 +407,90 @@ rte_thread_register(void); @@ -751,19 +751,19 @@ index 7deae47af3..3c64774bcb 100644 } #endif diff --git a/lib/eal/linux/eal.c b/lib/eal/linux/eal.c -index 57da058cec..7734b4b8a4 100644 +index 07a5a93..64e4533 100644 --- a/lib/eal/linux/eal.c +++ b/lib/eal/linux/eal.c -@@ -1373,6 +1373,7 @@ rte_eal_cleanup(void) - eal_bus_cleanup(); +@@ -1377,6 +1377,7 @@ rte_eal_cleanup(void) + rte_eal_alarm_cleanup(); rte_trace_save(); eal_trace_fini(); + eal_lcore_telemetry_free(); eal_mp_dev_hotplug_cleanup(); - rte_eal_alarm_cleanup(); /* after this point, any DPDK pointers will become dangling */ + rte_eal_memory_detach(); diff --git a/lib/eal/meson.build b/lib/eal/meson.build -index e1d6c4cf17..833d33138c 100644 +index e1d6c4c..833d331 100644 --- a/lib/eal/meson.build +++ b/lib/eal/meson.build @@ -17,6 +17,9 @@ subdir(arch_subdir) @@ -777,7 +777,7 @@ index e1d6c4cf17..833d33138c 100644 if dpdk_conf.has('RTE_USE_LIBBSD') ext_deps += libbsd diff --git a/lib/eal/version.map b/lib/eal/version.map -index 5e0cd47c82..a4451d58eb 100644 +index 5e0cd47..a4451d5 100644 --- a/lib/eal/version.map +++ b/lib/eal/version.map @@ -385,6 +385,64 @@ EXPERIMENTAL { @@ -846,10 +846,10 @@ index 5e0cd47c82..a4451d58eb 100644 # added in 23.03 rte_lcore_register_usage_cb; diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h -index 545799c341..e89eef37ee 100644 +index df162ab..2654724 100644 --- a/lib/ethdev/rte_ethdev.h +++ b/lib/ethdev/rte_ethdev.h -@@ -6099,6 +6099,8 @@ rte_eth_rx_burst(uint16_t port_id, uint16_t queue_id, +@@ -6105,6 +6105,8 @@ rte_eth_rx_burst(uint16_t port_id, uint16_t queue_id, #endif rte_ethdev_trace_rx_burst(port_id, queue_id, (void **)rx_pkts, nb_rx); @@ -859,7 +859,7 @@ index 545799c341..e89eef37ee 100644 } diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h -index 7fd9016ca7..ce4e57b60d 100644 +index 7fd9016..ce4e57b 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h @@ -2408,6 +2408,7 @@ rte_event_dequeue_burst(uint8_t dev_id, uint8_t port_id, struct rte_event ev[], @@ -887,7 +887,7 @@ index 7fd9016ca7..ce4e57b60d 100644 #define RTE_EVENT_DEV_MAINT_OP_FLUSH (1 << 0) diff --git a/lib/rawdev/rte_rawdev.c b/lib/rawdev/rte_rawdev.c -index 4f8897b639..2403c78925 100644 +index bf81c9b..4c9518e 100644 --- a/lib/rawdev/rte_rawdev.c +++ b/lib/rawdev/rte_rawdev.c @@ -237,13 +237,16 @@ rte_rawdev_dequeue_buffers(uint16_t dev_id, @@ -909,7 +909,7 @@ index 4f8897b639..2403c78925 100644 int diff --git a/lib/regexdev/rte_regexdev.h b/lib/regexdev/rte_regexdev.h -index d50af775b5..7b243a0866 100644 +index d50af77..7b243a0 100644 --- a/lib/regexdev/rte_regexdev.h +++ b/lib/regexdev/rte_regexdev.h @@ -1530,6 +1530,7 @@ rte_regexdev_dequeue_burst(uint8_t dev_id, uint16_t qp_id, @@ -932,7 +932,7 @@ index d50af775b5..7b243a0866 100644 #ifdef __cplusplus diff --git a/lib/ring/rte_ring.h b/lib/ring/rte_ring.h -index c709f30497..057542dcb0 100644 +index c709f30..057542d 100644 --- a/lib/ring/rte_ring.h +++ b/lib/ring/rte_ring.h @@ -411,8 +411,10 @@ static __rte_always_inline unsigned int @@ -960,7 +960,7 @@ index c709f30497..057542dcb0 100644 #ifdef __cplusplus diff --git a/lib/ring/rte_ring_elem_pvt.h b/lib/ring/rte_ring_elem_pvt.h -index 4b80f58980..e2a72e3ea7 100644 +index 4b80f58..e2a72e3 100644 --- a/lib/ring/rte_ring_elem_pvt.h +++ b/lib/ring/rte_ring_elem_pvt.h @@ -385,6 +385,7 @@ __rte_ring_do_dequeue_elem(struct rte_ring *r, void *obj_table, @@ -972,5 +972,5 @@ index 4b80f58980..e2a72e3ea7 100644 } -- -2.25.1 +2.43.0 diff --git a/ipm/patches/dpdk/23.11/0002-eal-add-cpuset-lcore-telemetry-entries.patch b/ipm/patches/dpdk/23.11/0002-eal-add-cpuset-lcore-telemetry-entries.patch index c2bac0e..2cb9f9e 100644 --- a/ipm/patches/dpdk/23.11/0002-eal-add-cpuset-lcore-telemetry-entries.patch +++ b/ipm/patches/dpdk/23.11/0002-eal-add-cpuset-lcore-telemetry-entries.patch @@ -1,4 +1,4 @@ -From f689846f602caddf6a0f6c013c3dbb6f0974dec2 Mon Sep 17 00:00:00 2001 +From 96b8900caad0edf9476027e7848995a82f805006 Mon Sep 17 00:00:00 2001 From: Hoang Nguyen Date: Thu, 1 Aug 2024 16:11:56 +0000 Subject: [PATCH 2/3] eal: add cpuset lcore telemetry entries @@ -11,7 +11,7 @@ Signed-off-by: Anatoly Burakov 1 file changed, 46 insertions(+) diff --git a/lib/eal/common/eal_common_lcore_telemetry.c b/lib/eal/common/eal_common_lcore_telemetry.c -index 1478e5a48a..f01ccd9a65 100644 +index 1478e5a..f01ccd9 100644 --- a/lib/eal/common/eal_common_lcore_telemetry.c +++ b/lib/eal/common/eal_common_lcore_telemetry.c @@ -263,6 +263,49 @@ lcore_handle_busyness(const char *cmd __rte_unused, @@ -75,5 +75,5 @@ index 1478e5a48a..f01ccd9a65 100644 } -- -2.25.1 +2.43.0 diff --git a/ipm/patches/dpdk/23.11/0003-add-capacity-endpoint-to-telemetry-thread.patch b/ipm/patches/dpdk/23.11/0003-add-capacity-endpoint-to-telemetry-thread.patch index 6be6861..3fdaf56 100644 --- a/ipm/patches/dpdk/23.11/0003-add-capacity-endpoint-to-telemetry-thread.patch +++ b/ipm/patches/dpdk/23.11/0003-add-capacity-endpoint-to-telemetry-thread.patch @@ -1,4 +1,4 @@ -From 2a8e1d477157e299f02fb9e64aa5d197d2caee16 Mon Sep 17 00:00:00 2001 +From df16c36f9740fe7f204e3ecc4bb985d63992a26c Mon Sep 17 00:00:00 2001 From: David Hunt Date: Fri, 20 Sep 2024 09:11:45 +0100 Subject: [PATCH 3/3] add capacity endpoint to telemetry thread @@ -19,7 +19,7 @@ Signed-off-by: David Hunt 3 files changed, 263 insertions(+) diff --git a/lib/eal/common/eal_common_lcore_telemetry.c b/lib/eal/common/eal_common_lcore_telemetry.c -index f01ccd9a65..1c6d085a55 100644 +index f01ccd9..1c6d085 100644 --- a/lib/eal/common/eal_common_lcore_telemetry.c +++ b/lib/eal/common/eal_common_lcore_telemetry.c @@ -10,9 +10,18 @@ @@ -309,7 +309,7 @@ index f01ccd9a65..1c6d085a55 100644 { return -ENOTSUP; diff --git a/lib/eal/include/rte_lcore.h b/lib/eal/include/rte_lcore.h -index 3c64774bcb..dffb7d1ab5 100644 +index 3c64774..dffb7d1 100644 --- a/lib/eal/include/rte_lcore.h +++ b/lib/eal/include/rte_lcore.h @@ -426,6 +426,27 @@ __rte_experimental @@ -341,7 +341,7 @@ index 3c64774bcb..dffb7d1ab5 100644 * @warning * @b EXPERIMENTAL: this API may change without prior notice. diff --git a/lib/eal/version.map b/lib/eal/version.map -index a4451d58eb..a2a3ba045f 100644 +index a4451d5..a2a3ba0 100644 --- a/lib/eal/version.map +++ b/lib/eal/version.map @@ -440,6 +440,7 @@ EXPERIMENTAL { @@ -353,5 +353,5 @@ index a4451d58eb..a2a3ba045f 100644 rte_lcore_busyness_enabled; rte_lcore_busyness_enabled_set; -- -2.25.1 +2.43.0 diff --git a/ipm/patches/dpdk/24.11/0001-eal-add-lcore-busyness-telemetry.patch b/ipm/patches/dpdk/24.11/0001-eal-add-lcore-busyness-telemetry.patch index 41e037a..d693149 100644 --- a/ipm/patches/dpdk/24.11/0001-eal-add-lcore-busyness-telemetry.patch +++ b/ipm/patches/dpdk/24.11/0001-eal-add-lcore-busyness-telemetry.patch @@ -1,6 +1,6 @@ -From 79bf3a1bbf2a1d4b5327c1278bfd05eaaa325d96 Mon Sep 17 00:00:00 2001 -From: Anatoly Burakov -Date: Fri, 20 Sep 2024 09:08:28 +0100 +From c6e891ddb9141325b65fbf2d94a8afb2fc5f9f5a Mon Sep 17 00:00:00 2001 +From: Kevin Laatz +Date: Wed, 22 Apr 2026 11:17:49 +0000 Subject: [PATCH 1/3] eal: add lcore busyness telemetry Currently, there is no way to measure lcore busyness in a passive way, @@ -73,7 +73,7 @@ Signed-off-by: Anatoly Burakov create mode 100644 lib/eal/common/eal_common_lcore_telemetry.c diff --git a/config/rte_config.h b/config/rte_config.h -index 3734db6bdc..11feae586c 100644 +index 3734db6..11feae5 100644 --- a/config/rte_config.h +++ b/config/rte_config.h @@ -51,6 +51,8 @@ @@ -86,7 +86,7 @@ index 3734db6bdc..11feae586c 100644 /* bsd module defines */ #define RTE_CONTIGMEM_MAX_NUM_BUFS 64 diff --git a/lib/bbdev/rte_bbdev.h b/lib/bbdev/rte_bbdev.h -index 6d5cdc7b8c..80dc3b075b 100644 +index 6d5cdc7..80dc3b0 100644 --- a/lib/bbdev/rte_bbdev.h +++ b/lib/bbdev/rte_bbdev.h @@ -25,6 +25,7 @@ @@ -142,7 +142,7 @@ index 6d5cdc7b8c..80dc3b075b 100644 /** diff --git a/lib/compressdev/rte_compressdev.c b/lib/compressdev/rte_compressdev.c -index cf2c20a704..04a854a935 100644 +index cf2c20a..04a854a 100644 --- a/lib/compressdev/rte_compressdev.c +++ b/lib/compressdev/rte_compressdev.c @@ -587,6 +587,8 @@ rte_compressdev_dequeue_burst(uint8_t dev_id, uint16_t qp_id, @@ -155,10 +155,10 @@ index cf2c20a704..04a854a935 100644 } diff --git a/lib/cryptodev/rte_cryptodev.h b/lib/cryptodev/rte_cryptodev.h -index c64d2f83a0..da4b7fffbf 100644 +index 071ff3d..b6ec34a 100644 --- a/lib/cryptodev/rte_cryptodev.h +++ b/lib/cryptodev/rte_cryptodev.h -@@ -2007,6 +2007,8 @@ rte_cryptodev_dequeue_burst(uint8_t dev_id, uint16_t qp_id, +@@ -2016,6 +2016,8 @@ rte_cryptodev_dequeue_burst(uint8_t dev_id, uint16_t qp_id, rte_rcu_qsbr_thread_offline(list->qsbr, 0); } #endif @@ -168,7 +168,7 @@ index c64d2f83a0..da4b7fffbf 100644 } diff --git a/lib/distributor/rte_distributor.c b/lib/distributor/rte_distributor.c -index e58727cdc2..9396a62edd 100644 +index e58727c..9396a62 100644 --- a/lib/distributor/rte_distributor.c +++ b/lib/distributor/rte_distributor.c @@ -58,6 +58,8 @@ rte_distributor_request_pkt(struct rte_distributor *d, @@ -218,7 +218,7 @@ index e58727cdc2..9396a62edd 100644 } diff --git a/lib/distributor/rte_distributor_single.c b/lib/distributor/rte_distributor_single.c -index d4b3e12648..3c18805ecd 100644 +index d4b3e12..3c18805 100644 --- a/lib/distributor/rte_distributor_single.c +++ b/lib/distributor/rte_distributor_single.c @@ -31,8 +31,13 @@ rte_distributor_request_pkt_single(struct rte_distributor_single *d, @@ -251,10 +251,10 @@ index d4b3e12648..3c18805ecd 100644 } diff --git a/lib/dmadev/rte_dmadev.h b/lib/dmadev/rte_dmadev.h -index 2f9304a9db..3876cf1556 100644 +index e2c8615..5da6a29 100644 --- a/lib/dmadev/rte_dmadev.h +++ b/lib/dmadev/rte_dmadev.h -@@ -148,6 +148,8 @@ +@@ -149,6 +149,8 @@ #include #include @@ -263,7 +263,7 @@ index 2f9304a9db..3876cf1556 100644 #ifdef __cplusplus extern "C" { -@@ -1068,6 +1070,7 @@ rte_dma_completed(int16_t dev_id, uint16_t vchan, const uint16_t nb_cpls, +@@ -1069,6 +1071,7 @@ rte_dma_completed(int16_t dev_id, uint16_t vchan, const uint16_t nb_cpls, has_error); rte_dma_trace_completed(dev_id, vchan, nb_cpls, last_idx, has_error, ret); @@ -271,7 +271,7 @@ index 2f9304a9db..3876cf1556 100644 return ret; } -@@ -1120,6 +1123,7 @@ rte_dma_completed_status(int16_t dev_id, uint16_t vchan, +@@ -1121,6 +1124,7 @@ rte_dma_completed_status(int16_t dev_id, uint16_t vchan, last_idx, status); rte_dma_trace_completed_status(dev_id, vchan, nb_cpls, last_idx, status, ret); @@ -281,7 +281,7 @@ index 2f9304a9db..3876cf1556 100644 } diff --git a/lib/eal/common/eal_common_lcore_telemetry.c b/lib/eal/common/eal_common_lcore_telemetry.c new file mode 100644 -index 0000000000..1478e5a48a +index 0000000..1478e5a --- /dev/null +++ b/lib/eal/common/eal_common_lcore_telemetry.c @@ -0,0 +1,319 @@ @@ -605,7 +605,7 @@ index 0000000000..1478e5a48a + +#endif diff --git a/lib/eal/common/meson.build b/lib/eal/common/meson.build -index e273745e93..96afcd7825 100644 +index e273745..96afcd7 100644 --- a/lib/eal/common/meson.build +++ b/lib/eal/common/meson.build @@ -17,6 +17,7 @@ sources += files( @@ -617,19 +617,19 @@ index e273745e93..96afcd7825 100644 'eal_common_lcore_var.c', 'eal_common_mcfg.c', diff --git a/lib/eal/freebsd/eal.c b/lib/eal/freebsd/eal.c -index a96bbf5836..26d6b6a703 100644 +index 7aec419..237d911 100644 --- a/lib/eal/freebsd/eal.c +++ b/lib/eal/freebsd/eal.c -@@ -901,6 +901,7 @@ rte_eal_cleanup(void) - eal_bus_cleanup(); +@@ -908,6 +908,7 @@ rte_eal_cleanup(void) + rte_eal_alarm_cleanup(); rte_trace_save(); eal_trace_fini(); + eal_lcore_telemetry_free(); - rte_eal_alarm_cleanup(); /* after this point, any DPDK pointers will become dangling */ rte_eal_memory_detach(); + eal_cleanup_config(internal_conf); diff --git a/lib/eal/include/rte_lcore.h b/lib/eal/include/rte_lcore.h -index 549b9e68c5..6fb5a679be 100644 +index 549b9e6..6fb5a67 100644 --- a/lib/eal/include/rte_lcore.h +++ b/lib/eal/include/rte_lcore.h @@ -403,6 +403,90 @@ rte_thread_register(void); @@ -724,19 +724,19 @@ index 549b9e68c5..6fb5a679be 100644 } #endif diff --git a/lib/eal/linux/eal.c b/lib/eal/linux/eal.c -index a6220524a4..9389e24d70 100644 +index a1e95c5..c626336 100644 --- a/lib/eal/linux/eal.c +++ b/lib/eal/linux/eal.c -@@ -1323,6 +1323,7 @@ rte_eal_cleanup(void) - eal_bus_cleanup(); +@@ -1329,6 +1329,7 @@ rte_eal_cleanup(void) + rte_eal_alarm_cleanup(); rte_trace_save(); eal_trace_fini(); + eal_lcore_telemetry_free(); eal_mp_dev_hotplug_cleanup(); - rte_eal_alarm_cleanup(); /* after this point, any DPDK pointers will become dangling */ + rte_eal_memory_detach(); diff --git a/lib/eal/meson.build b/lib/eal/meson.build -index e1d6c4cf17..833d33138c 100644 +index e1d6c4c..833d331 100644 --- a/lib/eal/meson.build +++ b/lib/eal/meson.build @@ -17,6 +17,9 @@ subdir(arch_subdir) @@ -750,7 +750,7 @@ index e1d6c4cf17..833d33138c 100644 if dpdk_conf.has('RTE_USE_LIBBSD') ext_deps += libbsd diff --git a/lib/eal/version.map b/lib/eal/version.map -index a20c713eb1..459194b45a 100644 +index e2a622c..701da62 100644 --- a/lib/eal/version.map +++ b/lib/eal/version.map @@ -388,6 +388,65 @@ EXPERIMENTAL { @@ -820,7 +820,7 @@ index a20c713eb1..459194b45a 100644 # added in 23.03 __rte_eal_trace_generic_blob; diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h -index 1f71cad244..4e011384c2 100644 +index ea3487d..cbad062 100644 --- a/lib/ethdev/rte_ethdev.h +++ b/lib/ethdev/rte_ethdev.h @@ -6314,6 +6314,8 @@ rte_eth_rx_burst(uint16_t port_id, uint16_t queue_id, @@ -833,10 +833,10 @@ index 1f71cad244..4e011384c2 100644 } diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h -index fabd1490db..df0de1ae9a 100644 +index 7649882..f802c82 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h -@@ -2829,6 +2829,7 @@ rte_event_dequeue_burst(uint8_t dev_id, uint8_t port_id, struct rte_event ev[], +@@ -2830,6 +2830,7 @@ rte_event_dequeue_burst(uint8_t dev_id, uint8_t port_id, struct rte_event ev[], uint16_t nb_events, uint64_t timeout_ticks) { const struct rte_event_fp_ops *fp_ops; @@ -844,7 +844,7 @@ index fabd1490db..df0de1ae9a 100644 void *port; fp_ops = &rte_event_fp_ops[dev_id]; -@@ -2847,7 +2848,10 @@ rte_event_dequeue_burst(uint8_t dev_id, uint8_t port_id, struct rte_event ev[], +@@ -2848,7 +2849,10 @@ rte_event_dequeue_burst(uint8_t dev_id, uint8_t port_id, struct rte_event ev[], #endif rte_eventdev_trace_deq_burst(dev_id, port_id, ev, nb_events); @@ -857,7 +857,7 @@ index fabd1490db..df0de1ae9a 100644 #define RTE_EVENT_DEV_MAINT_OP_FLUSH (1 << 0) diff --git a/lib/rawdev/rte_rawdev.c b/lib/rawdev/rte_rawdev.c -index 4f8897b639..2403c78925 100644 +index bf81c9b..4c9518e 100644 --- a/lib/rawdev/rte_rawdev.c +++ b/lib/rawdev/rte_rawdev.c @@ -237,13 +237,16 @@ rte_rawdev_dequeue_buffers(uint16_t dev_id, @@ -879,7 +879,7 @@ index 4f8897b639..2403c78925 100644 int diff --git a/lib/regexdev/rte_regexdev.h b/lib/regexdev/rte_regexdev.h -index b18a1d4251..5d4a84eab5 100644 +index b18a1d4..5d4a84e 100644 --- a/lib/regexdev/rte_regexdev.h +++ b/lib/regexdev/rte_regexdev.h @@ -1531,6 +1531,7 @@ rte_regexdev_dequeue_burst(uint8_t dev_id, uint16_t qp_id, @@ -902,7 +902,7 @@ index b18a1d4251..5d4a84eab5 100644 #ifdef __cplusplus diff --git a/lib/ring/rte_ring.h b/lib/ring/rte_ring.h -index 11ca69c73d..7f612dbb71 100644 +index 11ca69c..7f612db 100644 --- a/lib/ring/rte_ring.h +++ b/lib/ring/rte_ring.h @@ -411,8 +411,10 @@ static __rte_always_inline unsigned int @@ -930,7 +930,7 @@ index 11ca69c73d..7f612dbb71 100644 #ifdef __cplusplus diff --git a/lib/ring/rte_ring_elem_pvt.h b/lib/ring/rte_ring_elem_pvt.h -index 4b80f58980..e2a72e3ea7 100644 +index 4b80f58..e2a72e3 100644 --- a/lib/ring/rte_ring_elem_pvt.h +++ b/lib/ring/rte_ring_elem_pvt.h @@ -385,6 +385,7 @@ __rte_ring_do_dequeue_elem(struct rte_ring *r, void *obj_table, diff --git a/ipm/patches/dpdk/24.11/0002-eal-add-cpuset-lcore-telemetry-entries.patch b/ipm/patches/dpdk/24.11/0002-eal-add-cpuset-lcore-telemetry-entries.patch index 4107bf2..1c4ebab 100644 --- a/ipm/patches/dpdk/24.11/0002-eal-add-cpuset-lcore-telemetry-entries.patch +++ b/ipm/patches/dpdk/24.11/0002-eal-add-cpuset-lcore-telemetry-entries.patch @@ -1,4 +1,4 @@ -From e0ee93d040b11b07825074d988ad8e8ba6ce08d5 Mon Sep 17 00:00:00 2001 +From 7b040278389eeb241e81cda448597c8341cc4b03 Mon Sep 17 00:00:00 2001 From: Hoang Nguyen Date: Thu, 1 Aug 2024 16:11:56 +0000 Subject: [PATCH 2/3] eal: add cpuset lcore telemetry entries @@ -11,7 +11,7 @@ Signed-off-by: Anatoly Burakov 1 file changed, 46 insertions(+) diff --git a/lib/eal/common/eal_common_lcore_telemetry.c b/lib/eal/common/eal_common_lcore_telemetry.c -index 1478e5a48a..f01ccd9a65 100644 +index 1478e5a..f01ccd9 100644 --- a/lib/eal/common/eal_common_lcore_telemetry.c +++ b/lib/eal/common/eal_common_lcore_telemetry.c @@ -263,6 +263,49 @@ lcore_handle_busyness(const char *cmd __rte_unused, diff --git a/ipm/patches/dpdk/24.11/0003-add-capacity-endpoint-to-telemetry-thread.patch b/ipm/patches/dpdk/24.11/0003-add-capacity-endpoint-to-telemetry-thread.patch index 2beab13..6a0cd7c 100644 --- a/ipm/patches/dpdk/24.11/0003-add-capacity-endpoint-to-telemetry-thread.patch +++ b/ipm/patches/dpdk/24.11/0003-add-capacity-endpoint-to-telemetry-thread.patch @@ -1,4 +1,4 @@ -From 1b43ac9e21b34064e508bf5c489722c0fc208f8c Mon Sep 17 00:00:00 2001 +From 4add769c8ac877b842cb5d5e5b6def5d6095b381 Mon Sep 17 00:00:00 2001 From: David Hunt Date: Fri, 20 Sep 2024 09:11:45 +0100 Subject: [PATCH 3/3] add capacity endpoint to telemetry thread @@ -19,7 +19,7 @@ Signed-off-by: David Hunt 3 files changed, 263 insertions(+) diff --git a/lib/eal/common/eal_common_lcore_telemetry.c b/lib/eal/common/eal_common_lcore_telemetry.c -index f01ccd9a65..1c6d085a55 100644 +index f01ccd9..1c6d085 100644 --- a/lib/eal/common/eal_common_lcore_telemetry.c +++ b/lib/eal/common/eal_common_lcore_telemetry.c @@ -10,9 +10,18 @@ @@ -309,7 +309,7 @@ index f01ccd9a65..1c6d085a55 100644 { return -ENOTSUP; diff --git a/lib/eal/include/rte_lcore.h b/lib/eal/include/rte_lcore.h -index 6fb5a679be..4838e3e02b 100644 +index 6fb5a67..4838e3e 100644 --- a/lib/eal/include/rte_lcore.h +++ b/lib/eal/include/rte_lcore.h @@ -422,6 +422,27 @@ __rte_experimental @@ -341,7 +341,7 @@ index 6fb5a679be..4838e3e02b 100644 * @warning * @b EXPERIMENTAL: this API may change without prior notice. diff --git a/lib/eal/version.map b/lib/eal/version.map -index 459194b45a..33292379eb 100644 +index 701da62..7f21a83 100644 --- a/lib/eal/version.map +++ b/lib/eal/version.map @@ -444,6 +444,7 @@ EXPERIMENTAL { diff --git a/ipm/patches/dpdk/25.11/0001-eal-add-lcore-busyness-telemetry.patch b/ipm/patches/dpdk/25.11/0001-eal-add-lcore-busyness-telemetry.patch new file mode 100644 index 0000000..9c2afc5 --- /dev/null +++ b/ipm/patches/dpdk/25.11/0001-eal-add-lcore-busyness-telemetry.patch @@ -0,0 +1,877 @@ +From 7361218c9389379265828d7d5e0e440da78fc873 Mon Sep 17 00:00:00 2001 +From: Anatoly Burakov +Date: Fri, 20 Sep 2024 09:08:28 +0100 +Subject: [PATCH 1/3] eal: add lcore busyness telemetry + +Currently, there is no way to measure lcore busyness in a passive way, +without any modifications to the application. This patch adds a new EAL +API that will be able to passively track core busyness. + +The busyness is calculated by relying on the fact that most DPDK API's +will poll for packets. Empty polls can be counted as "idle", while +non-empty polls can be counted as busy. To measure lcore busyness, we +simply call the telemetry timestamping function with the number of polls +a particular code section has processed, and count the number of cycles +we've spent processing empty bursts. The more empty bursts we encounter, +the less cycles we spend in "busy" state, and the less core busyness +will be reported. + +In order for all of the above to work without modifications to the +application, the library code needs to be instrumented with calls to +the lcore telemetry busyness timestamping function. The following parts +of DPDK are instrumented with lcore telemetry calls: + +- All major driver API's: + - ethdev + - cryptodev + - compressdev + - regexdev + - bbdev + - rawdev + - eventdev + - dmadev +- Some additional libraries: + - ring + - distributor + +To avoid performance impact from having lcore telemetry support, a +global variable is exported by EAL, and a call to timestamping function +is wrapped into a macro, so that whenever telemetry is disabled, it only +takes one additional branch and no function calls are performed. It is +also possible to disable it at compile time by commenting out +RTE_LCORE_BUSYNESS from build config. + +This patch also adds a telemetry endpoint to report lcore busyness, as +well as telemetry endpoints to enable/disable lcore telemetry. + +Signed-off-by: Kevin Laatz +Signed-off-by: Conor Walsh +Signed-off-by: David Hunt +Signed-off-by: Anatoly Burakov +--- + config/rte_config.h | 2 + + lib/bbdev/rte_bbdev.h | 5 + + lib/compressdev/rte_compressdev.c | 6 +- + lib/cryptodev/rte_cryptodev.h | 2 + + lib/distributor/rte_distributor.c | 21 +- + lib/distributor/rte_distributor_single.c | 14 +- + lib/dmadev/rte_dmadev.h | 4 + + lib/eal/common/eal_common_lcore_telemetry.c | 329 ++++++++++++++++++++ + lib/eal/common/meson.build | 1 + + lib/eal/freebsd/eal.c | 1 + + lib/eal/include/rte_lcore.h | 84 +++++ + lib/eal/linux/eal.c | 1 + + lib/eal/meson.build | 3 + + lib/ethdev/rte_ethdev.h | 2 + + lib/eventdev/rte_eventdev.h | 6 +- + lib/rawdev/rte_rawdev.c | 5 +- + lib/regexdev/rte_regexdev.h | 5 +- + lib/ring/rte_ring.h | 8 +- + lib/ring/rte_ring_elem_pvt.h | 1 + + 19 files changed, 484 insertions(+), 16 deletions(-) + create mode 100644 lib/eal/common/eal_common_lcore_telemetry.c + +diff --git a/config/rte_config.h b/config/rte_config.h +index a2609fa403..0f2502baa2 100644 +--- a/config/rte_config.h ++++ b/config/rte_config.h +@@ -51,6 +51,8 @@ + #define RTE_LOG_DP_LEVEL RTE_LOG_INFO + #define RTE_MAX_VFIO_CONTAINERS 64 + #define RTE_TRACE 1 ++#define RTE_LCORE_BUSYNESS 1 ++#define RTE_LCORE_BUSYNESS_PERIOD 4000000ULL + + /* bsd module defines */ + #define RTE_CONTIGMEM_MAX_NUM_BUFS 64 +diff --git a/lib/bbdev/rte_bbdev.h b/lib/bbdev/rte_bbdev.h +index 4912bc7b6f..3dcaa746a3 100644 +--- a/lib/bbdev/rte_bbdev.h ++++ b/lib/bbdev/rte_bbdev.h +@@ -25,6 +25,7 @@ + + #include + #include ++#include + + #include "rte_bbdev_op.h" + +@@ -768,6 +769,7 @@ rte_bbdev_dequeue_enc_ops(uint16_t dev_id, uint16_t queue_id, + if (num_ops_dequeued > 0) + rte_bbdev_trace_dequeue(dev_id, queue_id, (void **)ops, num_ops, + num_ops_dequeued, rte_bbdev_op_type_str(RTE_BBDEV_OP_TURBO_ENC)); ++ RTE_LCORE_TELEMETRY_TIMESTAMP(num_ops_dequeued); + return num_ops_dequeued; + } + +@@ -804,6 +806,7 @@ rte_bbdev_dequeue_dec_ops(uint16_t dev_id, uint16_t queue_id, + if (num_ops_dequeued > 0) + rte_bbdev_trace_dequeue(dev_id, queue_id, (void **)ops, num_ops, + num_ops_dequeued, rte_bbdev_op_type_str(RTE_BBDEV_OP_TURBO_DEC)); ++ RTE_LCORE_TELEMETRY_TIMESTAMP(num_ops_dequeued); + return num_ops_dequeued; + } + +@@ -839,6 +842,7 @@ rte_bbdev_dequeue_ldpc_enc_ops(uint16_t dev_id, uint16_t queue_id, + if (num_ops_dequeued > 0) + rte_bbdev_trace_dequeue(dev_id, queue_id, (void **)ops, num_ops, + num_ops_dequeued, rte_bbdev_op_type_str(RTE_BBDEV_OP_LDPC_ENC)); ++ RTE_LCORE_TELEMETRY_TIMESTAMP(num_ops_dequeued); + return num_ops_dequeued; + } + +@@ -873,6 +877,7 @@ rte_bbdev_dequeue_ldpc_dec_ops(uint16_t dev_id, uint16_t queue_id, + if (num_ops_dequeued > 0) + rte_bbdev_trace_dequeue(dev_id, queue_id, (void **)ops, num_ops, + num_ops_dequeued, rte_bbdev_op_type_str(RTE_BBDEV_OP_LDPC_DEC)); ++ RTE_LCORE_TELEMETRY_TIMESTAMP(num_ops_dequeued); + return num_ops_dequeued; + } + +diff --git a/lib/compressdev/rte_compressdev.c b/lib/compressdev/rte_compressdev.c +index 790b2cd658..36930b339a 100644 +--- a/lib/compressdev/rte_compressdev.c ++++ b/lib/compressdev/rte_compressdev.c +@@ -612,7 +612,11 @@ rte_compressdev_dequeue_burst(uint8_t dev_id, uint16_t qp_id, + { + struct rte_compressdev *dev = &rte_comp_devices[dev_id]; + +- return dev->dequeue_burst(dev->data->queue_pairs[qp_id], ops, nb_ops); ++ nb_ops = dev->dequeue_burst(dev->data->queue_pairs[qp_id], ops, nb_ops); ++ ++ RTE_LCORE_TELEMETRY_TIMESTAMP(nb_ops); ++ ++ return nb_ops; + } + + RTE_EXPORT_SYMBOL(rte_compressdev_enqueue_burst) +diff --git a/lib/cryptodev/rte_cryptodev.h b/lib/cryptodev/rte_cryptodev.h +index 37a6a5e49b..34b1a8a93a 100644 +--- a/lib/cryptodev/rte_cryptodev.h ++++ b/lib/cryptodev/rte_cryptodev.h +@@ -2026,6 +2026,8 @@ rte_cryptodev_dequeue_burst(uint8_t dev_id, uint16_t qp_id, + rte_rcu_qsbr_thread_offline(list->qsbr, 0); + } + #endif ++ ++ RTE_LCORE_TELEMETRY_TIMESTAMP(nb_ops); + return nb_ops; + } + +diff --git a/lib/distributor/rte_distributor.c b/lib/distributor/rte_distributor.c +index dde7ce2677..3b874334f7 100644 +--- a/lib/distributor/rte_distributor.c ++++ b/lib/distributor/rte_distributor.c +@@ -60,6 +60,8 @@ rte_distributor_request_pkt(struct rte_distributor *d, + + while (rte_rdtsc() < t) + rte_pause(); ++ /* this was an empty poll */ ++ RTE_LCORE_TELEMETRY_TIMESTAMP(0); + } + + /* +@@ -140,24 +142,29 @@ rte_distributor_get_pkt(struct rte_distributor *d, + + if (unlikely(d->alg_type == RTE_DIST_ALG_SINGLE)) { + if (return_count <= 1) { ++ uint16_t cnt; + pkts[0] = rte_distributor_get_pkt_single(d->d_single, +- worker_id, return_count ? oldpkt[0] : NULL); +- return (pkts[0]) ? 1 : 0; +- } else +- return -EINVAL; ++ worker_id, ++ return_count ? oldpkt[0] : NULL); ++ cnt = (pkts[0] != NULL) ? 1 : 0; ++ RTE_LCORE_TELEMETRY_TIMESTAMP(cnt); ++ return cnt; ++ } ++ return -EINVAL; + } + + rte_distributor_request_pkt(d, worker_id, oldpkt, return_count); + +- count = rte_distributor_poll_pkt(d, worker_id, pkts); +- while (count == -1) { ++ while ((count = rte_distributor_poll_pkt(d, worker_id, pkts)) == -1) { + uint64_t t = rte_rdtsc() + 100; + + while (rte_rdtsc() < t) + rte_pause(); + +- count = rte_distributor_poll_pkt(d, worker_id, pkts); ++ /* this was an empty poll */ ++ RTE_LCORE_TELEMETRY_TIMESTAMP(0); + } ++ RTE_LCORE_TELEMETRY_TIMESTAMP(count); + return count; + } + +diff --git a/lib/distributor/rte_distributor_single.c b/lib/distributor/rte_distributor_single.c +index d4b3e12648..3c18805ecd 100644 +--- a/lib/distributor/rte_distributor_single.c ++++ b/lib/distributor/rte_distributor_single.c +@@ -31,8 +31,13 @@ rte_distributor_request_pkt_single(struct rte_distributor_single *d, + union rte_distributor_buffer_single *buf = &d->bufs[worker_id]; + int64_t req = (((int64_t)(uintptr_t)oldpkt) << RTE_DISTRIB_FLAG_BITS) + | RTE_DISTRIB_GET_BUF; +- RTE_WAIT_UNTIL_MASKED(&buf->bufptr64, RTE_DISTRIB_FLAGS_MASK, +- ==, 0, rte_memory_order_relaxed); ++ ++ while ((__atomic_load_n(&buf->bufptr64, __ATOMIC_RELAXED) ++ & RTE_DISTRIB_FLAGS_MASK) != 0) { ++ rte_pause(); ++ /* this was an empty poll */ ++ RTE_LCORE_TELEMETRY_TIMESTAMP(0); ++ } + + /* Sync with distributor on GET_BUF flag. */ + rte_atomic_store_explicit(&buf->bufptr64, req, rte_memory_order_release); +@@ -59,8 +64,11 @@ rte_distributor_get_pkt_single(struct rte_distributor_single *d, + { + struct rte_mbuf *ret; + rte_distributor_request_pkt_single(d, worker_id, oldpkt); +- while ((ret = rte_distributor_poll_pkt_single(d, worker_id)) == NULL) ++ while ((ret = rte_distributor_poll_pkt_single(d, worker_id)) == NULL) { + rte_pause(); ++ /* this was an empty poll */ ++ RTE_LCORE_TELEMETRY_TIMESTAMP(0); ++ } + return ret; + } + +diff --git a/lib/dmadev/rte_dmadev.h b/lib/dmadev/rte_dmadev.h +index 81dfe187e2..96aa01b478 100644 +--- a/lib/dmadev/rte_dmadev.h ++++ b/lib/dmadev/rte_dmadev.h +@@ -150,6 +150,8 @@ + #include + #include + #include ++#include ++#include + + #ifdef __cplusplus + extern "C" { +@@ -1380,6 +1382,7 @@ rte_dma_completed(int16_t dev_id, uint16_t vchan, const uint16_t nb_cpls, + ret = obj->completed(obj->dev_private, vchan, nb_cpls, last_idx, has_error); + rte_dma_trace_completed(dev_id, vchan, nb_cpls, last_idx, has_error, + ret); ++ RTE_LCORE_TELEMETRY_TIMESTAMP(ret); + + return ret; + } +@@ -1431,6 +1434,7 @@ rte_dma_completed_status(int16_t dev_id, uint16_t vchan, + ret = obj->completed_status(obj->dev_private, vchan, nb_cpls, last_idx, status); + rte_dma_trace_completed_status(dev_id, vchan, nb_cpls, last_idx, status, + ret); ++ RTE_LCORE_TELEMETRY_TIMESTAMP(ret); + + return ret; + } +diff --git a/lib/eal/common/eal_common_lcore_telemetry.c b/lib/eal/common/eal_common_lcore_telemetry.c +new file mode 100644 +index 0000000000..df7eab1fd4 +--- /dev/null ++++ b/lib/eal/common/eal_common_lcore_telemetry.c +@@ -0,0 +1,329 @@ ++/* SPDX-License-Identifier: BSD-3-Clause ++ * Copyright(c) 2022 Intel Corporation ++ */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef RTE_LCORE_BUSYNESS ++#include ++#endif ++ ++RTE_EXPORT_EXPERIMENTAL_SYMBOL(__rte_lcore_telemetry_enabled, 20.11); ++int __rte_lcore_telemetry_enabled; ++ ++#ifdef RTE_LCORE_BUSYNESS ++ ++#include "eal_private.h" ++ ++struct lcore_telemetry { ++ int busyness; ++ /**< Calculated busyness (gets set/returned by the API) */ ++ int raw_busyness; ++ /**< Calculated busyness times 100. */ ++ uint64_t interval_ts; ++ /**< when previous telemetry interval started */ ++ uint64_t empty_cycles; ++ /**< empty cycle count since last interval */ ++ uint64_t last_poll_ts; ++ /**< last poll timestamp */ ++ bool last_empty; ++ /**< if last poll was empty */ ++ unsigned int contig_poll_cnt; ++ /**< contiguous (always empty/non empty) poll counter */ ++} __rte_cache_aligned; ++ ++static struct lcore_telemetry *telemetry_data; ++ ++#define LCORE_BUSYNESS_MAX 100 ++#define LCORE_BUSYNESS_NOT_SET -1 ++#define LCORE_BUSYNESS_MIN 0 ++ ++#define SMOOTH_COEFF 5 ++#define STATE_CHANGE_OPT 32 ++ ++/* Helper function to check if the lcore is enabled. ++ * Cannot use rte_lcore_is_enabled since it only catches ROLE_RTE threads which ++ * does not include ROLE_NON_EAL threads which some application threads, for ++ * example OvS polling threads, are marked as. ++ */ ++static int ++lcore_enabled(unsigned int lcore_id) ++{ ++ enum rte_lcore_role_t role = rte_eal_lcore_role(lcore_id); ++ ++ return role == ROLE_RTE || role == ROLE_NON_EAL; ++} ++ ++static void lcore_config_init(void) ++{ ++ struct lcore_telemetry *td; ++ int lcore_id; ++ ++ /* Foreach lcore - can't use macro since it excludes ROLE_NON_EAL */ ++ for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { ++ if (!lcore_enabled(lcore_id)) ++ continue; ++ ++ td = &telemetry_data[lcore_id]; ++ ++ td->interval_ts = 0; ++ td->last_poll_ts = 0; ++ td->empty_cycles = 0; ++ td->last_empty = true; ++ td->contig_poll_cnt = 0; ++ td->busyness = LCORE_BUSYNESS_NOT_SET; ++ td->raw_busyness = 0; ++ } ++} ++ ++RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_lcore_busyness, 20.11); ++int rte_lcore_busyness(unsigned int lcore_id) ++{ ++ const uint64_t active_thresh = RTE_LCORE_BUSYNESS_PERIOD * 1000; ++ struct lcore_telemetry *tdata; ++ ++ if (lcore_id >= RTE_MAX_LCORE) ++ return -EINVAL; ++ tdata = &telemetry_data[lcore_id]; ++ ++ /* if the lcore is not active */ ++ if (tdata->interval_ts == 0) ++ return LCORE_BUSYNESS_NOT_SET; ++ /* if the core hasn't been active in a while */ ++ else if ((rte_rdtsc() - tdata->interval_ts) > active_thresh) ++ return LCORE_BUSYNESS_NOT_SET; ++ ++ /* this core is active, report its busyness */ ++ return telemetry_data[lcore_id].busyness; ++} ++ ++RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_lcore_busyness_enabled, 20.11); ++int rte_lcore_busyness_enabled(void) ++{ ++ return __rte_lcore_telemetry_enabled; ++} ++ ++RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_lcore_busyness_enabled_set, 20.11); ++void rte_lcore_busyness_enabled_set(int enable) ++{ ++ __rte_lcore_telemetry_enabled = !!enable; ++ ++ if (!enable) ++ lcore_config_init(); ++} ++ ++static inline int calc_raw_busyness(const struct lcore_telemetry *tdata, ++ const uint64_t empty, const uint64_t total) ++{ ++ /* ++ * we don't want to use floating point math here, but we want for our ++ * busyness to react smoothly to sudden changes, while still keeping the ++ * accuracy and making sure that over time the average follows busyness ++ * as measured just-in-time. therefore, we will calculate the average ++ * busyness using integer math, but shift the decimal point two places ++ * to the right, so that 100.0 becomes 10000. this allows us to report ++ * integer values (0..100) while still allowing ourselves to follow the ++ * just-in-time measurements when we calculate our averages. ++ */ ++ const int max_raw_idle = LCORE_BUSYNESS_MAX * 100; ++ ++ const int prev_raw_idle = max_raw_idle - tdata->raw_busyness; ++ ++ /* calculate rate of idle cycles, times 100 */ ++ const int cur_raw_idle = (int)((empty * max_raw_idle) / total); ++ ++ /* smoothen the idleness */ ++ const int smoothened_idle = ++ (cur_raw_idle + prev_raw_idle * (SMOOTH_COEFF - 1)) / SMOOTH_COEFF; ++ ++ /* convert idleness back to busyness */ ++ return max_raw_idle - smoothened_idle; ++} ++ ++RTE_EXPORT_EXPERIMENTAL_SYMBOL(__rte_lcore_telemetry_timestamp, 20.11); ++void __rte_lcore_telemetry_timestamp(uint16_t nb_rx) ++{ ++ const unsigned int lcore_id = rte_lcore_id(); ++ uint64_t interval_ts, empty_cycles, cur_tsc, last_poll_ts; ++ struct lcore_telemetry *tdata; ++ const bool empty = nb_rx == 0; ++ uint64_t diff_int, diff_last; ++ bool last_empty; ++ ++ /* This telemetry is not supported for unregistered non-EAL threads */ ++ if (lcore_id >= RTE_MAX_LCORE) { ++ RTE_LOG(DEBUG, EAL, ++ "Lcore telemetry not supported on unregistered non-EAL thread %d", ++ lcore_id); ++ return; ++ } ++ ++ tdata = &telemetry_data[lcore_id]; ++ last_empty = tdata->last_empty; ++ ++ /* optimization: don't do anything if status hasn't changed */ ++ if (last_empty == empty && tdata->contig_poll_cnt++ < STATE_CHANGE_OPT) ++ return; ++ /* status changed or we're waiting for too long, reset counter */ ++ tdata->contig_poll_cnt = 0; ++ ++ cur_tsc = rte_rdtsc(); ++ ++ interval_ts = tdata->interval_ts; ++ empty_cycles = tdata->empty_cycles; ++ last_poll_ts = tdata->last_poll_ts; ++ ++ diff_int = cur_tsc - interval_ts; ++ diff_last = cur_tsc - last_poll_ts; ++ ++ /* is this the first time we're here? */ ++ if (interval_ts == 0) { ++ tdata->busyness = LCORE_BUSYNESS_MIN; ++ tdata->raw_busyness = 0; ++ tdata->interval_ts = cur_tsc; ++ tdata->empty_cycles = 0; ++ tdata->contig_poll_cnt = 0; ++ goto end; ++ } ++ ++ /* update the empty counter if we got an empty poll earlier */ ++ if (last_empty) ++ empty_cycles += diff_last; ++ ++ /* have we passed the interval? */ ++ if (diff_int > RTE_LCORE_BUSYNESS_PERIOD) { ++ int raw_busyness; ++ ++ /* get updated busyness value */ ++ raw_busyness = calc_raw_busyness(tdata, empty_cycles, diff_int); ++ ++ /* set a new interval, reset empty counter */ ++ tdata->interval_ts = cur_tsc; ++ tdata->empty_cycles = 0; ++ tdata->raw_busyness = raw_busyness; ++ /* bring busyness back to 0..100 range, biased to round up */ ++ tdata->busyness = (raw_busyness + 50) / 100; ++ } else ++ /* we may have updated empty counter */ ++ tdata->empty_cycles = empty_cycles; ++ ++end: ++ /* update status for next poll */ ++ tdata->last_poll_ts = cur_tsc; ++ tdata->last_empty = empty; ++} ++ ++static int ++lcore_busyness_enable(const char *cmd __rte_unused, ++ const char *params __rte_unused, ++ struct rte_tel_data *d) ++{ ++ rte_lcore_busyness_enabled_set(1); ++ ++ rte_tel_data_start_dict(d); ++ ++ rte_tel_data_add_dict_int(d, "busyness_enabled", 1); ++ ++ return 0; ++} ++ ++static int ++lcore_busyness_disable(const char *cmd __rte_unused, ++ const char *params __rte_unused, ++ struct rte_tel_data *d) ++{ ++ rte_lcore_busyness_enabled_set(0); ++ ++ rte_tel_data_start_dict(d); ++ ++ rte_tel_data_add_dict_int(d, "busyness_enabled", 0); ++ ++ return 0; ++} ++ ++static int ++lcore_handle_busyness(const char *cmd __rte_unused, ++ const char *params __rte_unused, struct rte_tel_data *d) ++{ ++ char corenum[64]; ++ int i; ++ ++ rte_tel_data_start_dict(d); ++ ++ /* Foreach lcore - can't use macro since it excludes ROLE_NON_EAL */ ++ for (i = 0; i < RTE_MAX_LCORE; i++) { ++ if (!lcore_enabled(i)) ++ continue; ++ snprintf(corenum, sizeof(corenum), "%d", i); ++ rte_tel_data_add_dict_int(d, corenum, rte_lcore_busyness(i)); ++ } ++ ++ return 0; ++} ++ ++void ++eal_lcore_telemetry_free(void) ++{ ++ if (telemetry_data != NULL) { ++ free(telemetry_data); ++ telemetry_data = NULL; ++ } ++} ++ ++RTE_INIT(lcore_init_telemetry) ++{ ++ telemetry_data = calloc(RTE_MAX_LCORE, sizeof(telemetry_data[0])); ++ if (telemetry_data == NULL) ++ rte_panic("Could not init lcore telemetry data: Out of memory\n"); ++ ++ lcore_config_init(); ++ ++ rte_telemetry_register_cmd("/eal/lcore/busyness", lcore_handle_busyness, ++ "return percentage busyness of cores"); ++ ++ rte_telemetry_register_cmd("/eal/lcore/busyness_enable", lcore_busyness_enable, ++ "enable lcore busyness measurement"); ++ ++ rte_telemetry_register_cmd("/eal/lcore/busyness_disable", lcore_busyness_disable, ++ "disable lcore busyness measurement"); ++ ++ __rte_lcore_telemetry_enabled = true; ++} ++ ++#else ++ ++RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_lcore_busyness, 20.11); ++int rte_lcore_busyness(unsigned int lcore_id __rte_unused) ++{ ++ return -ENOTSUP; ++} ++ ++RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_lcore_busyness_enabled, 20.11); ++int rte_lcore_busyness_enabled(void) ++{ ++ return -ENOTSUP; ++} ++ ++RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_lcore_busyness_enabled_set, 20.11); ++void rte_lcore_busyness_enabled_set(int enable __rte_unused) ++{ ++} ++ ++RTE_EXPORT_EXPERIMENTAL_SYMBOL(__rte_lcore_telemetry_timestamp, 20.11); ++void __rte_lcore_telemetry_timestamp(uint16_t nb_rx __rte_unused) ++{ ++} ++ ++void eal_lcore_telemetry_free(void) ++{ ++} ++ ++#endif +diff --git a/lib/eal/common/meson.build b/lib/eal/common/meson.build +index e273745e93..96afcd7825 100644 +--- a/lib/eal/common/meson.build ++++ b/lib/eal/common/meson.build +@@ -17,6 +17,7 @@ sources += files( + 'eal_common_hexdump.c', + 'eal_common_interrupts.c', + 'eal_common_launch.c', ++ 'eal_common_lcore_telemetry.c', + 'eal_common_lcore.c', + 'eal_common_lcore_var.c', + 'eal_common_mcfg.c', +diff --git a/lib/eal/freebsd/eal.c b/lib/eal/freebsd/eal.c +index 6215245ad5..f03ea2e801 100644 +--- a/lib/eal/freebsd/eal.c ++++ b/lib/eal/freebsd/eal.c +@@ -783,6 +783,7 @@ rte_eal_cleanup(void) + rte_eal_alarm_cleanup(); + rte_trace_save(); + eal_trace_fini(); ++ eal_lcore_telemetry_free(); + /* after this point, any DPDK pointers will become dangling */ + rte_eal_memory_detach(); + eal_cleanup_config(internal_conf); +diff --git a/lib/eal/include/rte_lcore.h b/lib/eal/include/rte_lcore.h +index 10f965b4f0..1d0a5a22f6 100644 +--- a/lib/eal/include/rte_lcore.h ++++ b/lib/eal/include/rte_lcore.h +@@ -402,6 +402,90 @@ rte_thread_register(void); + void + rte_thread_unregister(void); + ++/** ++ * @warning ++ * @b EXPERIMENTAL: this API may change without prior notice. ++ * ++ * Read busyness value corresponding to an lcore. ++ * ++ * @param lcore_id ++ * Lcore to read busyness value for. ++ * @return ++ * - value between 0 and 100 on success ++ * - -1 if lcore is not active ++ * - -EINVAL if lcore is invalid ++ * - -ENOMEM if not enough memory available ++ * - -ENOTSUP if not supported ++ */ ++__rte_experimental ++int ++rte_lcore_busyness(unsigned int lcore_id); ++ ++/** ++ * @warning ++ * @b EXPERIMENTAL: this API may change without prior notice. ++ * ++ * Check if lcore busyness telemetry is enabled. ++ * ++ * @return ++ * - 1 if lcore telemetry is enabled ++ * - 0 if lcore telemetry is disabled ++ * - -ENOTSUP if not lcore telemetry supported ++ */ ++__rte_experimental ++int ++rte_lcore_busyness_enabled(void); ++ ++/** ++ * @warning ++ * @b EXPERIMENTAL: this API may change without prior notice. ++ * ++ * Enable or disable busyness telemetry. ++ * ++ * @param enable ++ * 1 to enable, 0 to disable ++ */ ++__rte_experimental ++void ++rte_lcore_busyness_enabled_set(int enable); ++ ++/** ++ * @warning ++ * @b EXPERIMENTAL: this API may change without prior notice. ++ * ++ * Lcore telemetry timestamping function. ++ * ++ * @param nb_rx ++ * Number of buffers processed by lcore. ++ */ ++__rte_experimental ++void ++__rte_lcore_telemetry_timestamp(uint16_t nb_rx); ++ ++/** @internal lcore telemetry enabled status */ ++extern int __rte_lcore_telemetry_enabled; ++ ++/** @internal free memory allocated for lcore telemetry */ ++void ++eal_lcore_telemetry_free(void); ++ ++/** ++ * Call lcore telemetry timestamp function. ++ * ++ * @param nb_rx ++ * Number of buffers processed by lcore. ++ */ ++#ifdef RTE_LCORE_BUSYNESS ++#define RTE_LCORE_TELEMETRY_TIMESTAMP(nb_rx) \ ++ do { \ ++ if (__rte_lcore_telemetry_enabled) \ ++ __rte_lcore_telemetry_timestamp(nb_rx); \ ++ } while (0) ++#else ++#define RTE_LCORE_TELEMETRY_TIMESTAMP(nb_rx) \ ++ while (0) {} ++#endif ++ + #ifdef __cplusplus + } + #endif +diff --git a/lib/eal/linux/eal.c b/lib/eal/linux/eal.c +index b12f325ddd..ad18f5fb05 100644 +--- a/lib/eal/linux/eal.c ++++ b/lib/eal/linux/eal.c +@@ -983,6 +983,7 @@ rte_eal_cleanup(void) + rte_eal_alarm_cleanup(); + rte_trace_save(); + eal_trace_fini(); ++ eal_lcore_telemetry_free(); + eal_mp_dev_hotplug_cleanup(); + /* after this point, any DPDK pointers will become dangling */ + rte_eal_memory_detach(); +diff --git a/lib/eal/meson.build b/lib/eal/meson.build +index f9fcee24ee..6a205ddb9f 100644 +--- a/lib/eal/meson.build ++++ b/lib/eal/meson.build +@@ -17,6 +17,9 @@ subdir(arch_subdir) + deps += ['argparse', 'kvargs'] + if not is_windows + deps += ['telemetry'] ++else ++ # core busyness telemetry depends on telemetry library ++ dpdk_conf.set('RTE_LCORE_BUSYNESS', false) + endif + if dpdk_conf.has('RTE_USE_LIBBSD') + ext_deps += libbsd +diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h +index a66c2abbdb..7ef326e23b 100644 +--- a/lib/ethdev/rte_ethdev.h ++++ b/lib/ethdev/rte_ethdev.h +@@ -6402,6 +6402,8 @@ rte_eth_rx_burst(uint16_t port_id, uint16_t queue_id, + rte_ethdev_trace_rx_burst_nonempty(port_id, queue_id, (void **)rx_pkts, nb_rx); + else + rte_ethdev_trace_rx_burst_empty(port_id, queue_id, (void **)rx_pkts); ++ ++ RTE_LCORE_TELEMETRY_TIMESTAMP(nb_rx); + return nb_rx; + } + +diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h +index 88c52a5520..3d7bdc1ffa 100644 +--- a/lib/eventdev/rte_eventdev.h ++++ b/lib/eventdev/rte_eventdev.h +@@ -2844,6 +2844,7 @@ rte_event_dequeue_burst(uint8_t dev_id, uint8_t port_id, struct rte_event ev[], + uint16_t nb_events, uint64_t timeout_ticks) + { + const struct rte_event_fp_ops *fp_ops; ++ uint16_t nb_evts; + void *port; + + fp_ops = &rte_event_fp_ops[dev_id]; +@@ -2862,7 +2863,10 @@ rte_event_dequeue_burst(uint8_t dev_id, uint8_t port_id, struct rte_event ev[], + #endif + rte_eventdev_trace_deq_burst(dev_id, port_id, ev, nb_events); + +- return (fp_ops->dequeue_burst)(port, ev, nb_events, timeout_ticks); ++ nb_evts = (fp_ops->dequeue_burst)(port, ev, nb_events, timeout_ticks); ++ RTE_LCORE_TELEMETRY_TIMESTAMP(nb_evts); ++ ++ return nb_evts; + } + + #define RTE_EVENT_DEV_MAINT_OP_FLUSH (1 << 0) +diff --git a/lib/rawdev/rte_rawdev.c b/lib/rawdev/rte_rawdev.c +index d193061842..c96e803dbe 100644 +--- a/lib/rawdev/rte_rawdev.c ++++ b/lib/rawdev/rte_rawdev.c +@@ -249,13 +249,16 @@ rte_rawdev_dequeue_buffers(uint16_t dev_id, + rte_rawdev_obj_t context) + { + struct rte_rawdev *dev; ++ int nb_ops; + + RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); + dev = &rte_rawdevs[dev_id]; + + if (dev->dev_ops->dequeue_bufs == NULL) + return -ENOTSUP; +- return dev->dev_ops->dequeue_bufs(dev, buffers, count, context); ++ nb_ops = dev->dev_ops->dequeue_bufs(dev, buffers, count, context); ++ RTE_LCORE_TELEMETRY_TIMESTAMP(nb_ops); ++ return nb_ops; + } + + RTE_EXPORT_SYMBOL(rte_rawdev_dump) +diff --git a/lib/regexdev/rte_regexdev.h b/lib/regexdev/rte_regexdev.h +index 1534e9f84a..ce01d99b12 100644 +--- a/lib/regexdev/rte_regexdev.h ++++ b/lib/regexdev/rte_regexdev.h +@@ -1531,6 +1531,7 @@ rte_regexdev_dequeue_burst(uint8_t dev_id, uint16_t qp_id, + struct rte_regex_ops **ops, uint16_t nb_ops) + { + struct rte_regexdev *dev = &rte_regex_devices[dev_id]; ++ uint16_t deq_ops; + #ifdef RTE_LIBRTE_REGEXDEV_DEBUG + RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL); + if (dev->dequeue == NULL) +@@ -1540,7 +1541,9 @@ rte_regexdev_dequeue_burst(uint8_t dev_id, uint16_t qp_id, + return -EINVAL; + } + #endif +- return dev->dequeue(dev, qp_id, ops, nb_ops); ++ deq_ops = dev->dequeue(dev, qp_id, ops, nb_ops); ++ RTE_LCORE_TELEMETRY_TIMESTAMP(deq_ops); ++ return deq_ops; + } + + #ifdef __cplusplus +diff --git a/lib/ring/rte_ring.h b/lib/ring/rte_ring.h +index 3382a8e2f2..509beabe99 100644 +--- a/lib/ring/rte_ring.h ++++ b/lib/ring/rte_ring.h +@@ -431,8 +431,10 @@ static __rte_always_inline unsigned int + rte_ring_dequeue_bulk(struct rte_ring *r, void **obj_table, unsigned int n, + unsigned int *available) + { +- return rte_ring_dequeue_bulk_elem(r, obj_table, sizeof(void *), ++ uint32_t nb_rx = rte_ring_dequeue_bulk_elem(r, obj_table, sizeof(void *), + n, available); ++ RTE_LCORE_TELEMETRY_TIMESTAMP(nb_rx); ++ return nb_rx; + } + + /** +@@ -831,8 +833,10 @@ static __rte_always_inline unsigned int + rte_ring_dequeue_burst(struct rte_ring *r, void **obj_table, + unsigned int n, unsigned int *available) + { +- return rte_ring_dequeue_burst_elem(r, obj_table, sizeof(void *), ++ uint32_t nb_rx = rte_ring_dequeue_burst_elem(r, obj_table, sizeof(void *), + n, available); ++ RTE_LCORE_TELEMETRY_TIMESTAMP(nb_rx); ++ return nb_rx; + } + + #ifdef __cplusplus +diff --git a/lib/ring/rte_ring_elem_pvt.h b/lib/ring/rte_ring_elem_pvt.h +index 6eafae121f..884f142914 100644 +--- a/lib/ring/rte_ring_elem_pvt.h ++++ b/lib/ring/rte_ring_elem_pvt.h +@@ -470,6 +470,7 @@ __rte_ring_do_dequeue_elem(struct rte_ring *r, void *obj_table, + end: + if (available != NULL) + *available = entries - n; ++ RTE_LCORE_TELEMETRY_TIMESTAMP(n); + return n; + } + +-- +2.43.0 + diff --git a/ipm/patches/dpdk/25.11/0002-eal-add-cpuset-lcore-telemetry-entries.patch b/ipm/patches/dpdk/25.11/0002-eal-add-cpuset-lcore-telemetry-entries.patch new file mode 100644 index 0000000..9dc0fa1 --- /dev/null +++ b/ipm/patches/dpdk/25.11/0002-eal-add-cpuset-lcore-telemetry-entries.patch @@ -0,0 +1,79 @@ +From f75258c3bde7aa97dcae97a01e6fb8eb59138099 Mon Sep 17 00:00:00 2001 +From: Hoang Nguyen +Date: Thu, 1 Aug 2024 16:11:56 +0000 +Subject: [PATCH 2/3] eal: add cpuset lcore telemetry entries + +Expose per-lcore cpuset information to telemetry. + +Signed-off-by: Anatoly Burakov +--- + lib/eal/common/eal_common_lcore_telemetry.c | 46 +++++++++++++++++++++ + 1 file changed, 46 insertions(+) + +diff --git a/lib/eal/common/eal_common_lcore_telemetry.c b/lib/eal/common/eal_common_lcore_telemetry.c +index df7eab1fd4..8a6d13c57c 100644 +--- a/lib/eal/common/eal_common_lcore_telemetry.c ++++ b/lib/eal/common/eal_common_lcore_telemetry.c +@@ -269,6 +269,49 @@ lcore_handle_busyness(const char *cmd __rte_unused, + return 0; + } + ++static int ++lcore_handle_cpuset(const char *cmd __rte_unused, ++ const char *params __rte_unused, ++ struct rte_tel_data *d) ++{ ++ char corenum[64]; ++ int i; ++ ++ rte_tel_data_start_dict(d); ++ ++ /* Foreach lcore - can't use macro since it excludes ROLE_NON_EAL */ ++ for (i = 0; i < RTE_MAX_LCORE; i++) { ++ const struct lcore_config *cfg = &lcore_config[i]; ++ const rte_cpuset_t *cpuset = &cfg->cpuset; ++ struct rte_tel_data *ld; ++ unsigned int cpu; ++ ++ if (!lcore_enabled(i)) ++ continue; ++ ++ /* create an array of integers */ ++ ld = rte_tel_data_alloc(); ++ if (ld == NULL) ++ return -ENOMEM; ++ rte_tel_data_start_array(ld, RTE_TEL_INT_VAL); ++ ++ /* add cpu ID's from cpuset to the array */ ++ for (cpu = 0; cpu < CPU_SETSIZE; cpu++) { ++ if (!CPU_ISSET(cpu, cpuset)) ++ continue; ++ rte_tel_data_add_array_int(ld, cpu); ++ } ++ ++ /* add array to the per-lcore container */ ++ snprintf(corenum, sizeof(corenum), "%d", i); ++ ++ /* tell telemetry library to free this array automatically */ ++ rte_tel_data_add_dict_container(d, corenum, ld, 0); ++ } ++ ++ return 0; ++} ++ + void + eal_lcore_telemetry_free(void) + { +@@ -295,6 +338,9 @@ RTE_INIT(lcore_init_telemetry) + rte_telemetry_register_cmd("/eal/lcore/busyness_disable", lcore_busyness_disable, + "disable lcore busyness measurement"); + ++ rte_telemetry_register_cmd("/eal/lcore/cpuset", lcore_handle_cpuset, ++ "list physical core affinity for each lcore"); ++ + __rte_lcore_telemetry_enabled = true; + } + +-- +2.43.0 + diff --git a/ipm/patches/dpdk/25.11/0003-add-capacity-endpoint-to-telemetry-thread.patch b/ipm/patches/dpdk/25.11/0003-add-capacity-endpoint-to-telemetry-thread.patch new file mode 100644 index 0000000..4bacd1c --- /dev/null +++ b/ipm/patches/dpdk/25.11/0003-add-capacity-endpoint-to-telemetry-thread.patch @@ -0,0 +1,346 @@ +From e9e3baf4a86cbd4f4e7eb03fc17d04b07b6cef82 Mon Sep 17 00:00:00 2001 +From: David Hunt +Date: Fri, 20 Sep 2024 09:11:45 +0100 +Subject: [PATCH 3/3] add capacity endpoint to telemetry thread + +Busyness is calculated on how busy the current core is, ignoring the +current frequency. So a core that's 50% busy at P1 (e.g. 2GHz), shows +as 100% busy at 1GHz. + +This patch adds a new 'capacity' metric that shows a percentage based on +the P1 (base) freqency of the core, so that if the core is 50% busy at +P1, it should show 50% regardless of what the current frequency is. + +Signed-off-by: David Hunt +--- + lib/eal/common/eal_common_lcore_telemetry.c | 243 ++++++++++++++++++++ + lib/eal/include/rte_lcore.h | 21 ++ + 2 files changed, 264 insertions(+) + +diff --git a/lib/eal/common/eal_common_lcore_telemetry.c b/lib/eal/common/eal_common_lcore_telemetry.c +index 8a6d13c57c..54d826069c 100644 +--- a/lib/eal/common/eal_common_lcore_telemetry.c ++++ b/lib/eal/common/eal_common_lcore_telemetry.c +@@ -11,9 +11,18 @@ + #include + #include + #include ++#include ++#include ++#include + + #ifdef RTE_LCORE_BUSYNESS + #include ++#define MSR_PLATFORM_INFO 0xCE ++#define POWER_SYSFS_CUR_PATH "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_cur_freq" ++#define POWER_SYSFS_BASE_FREQ_PATH "/sys/devices/system/cpu/cpu%u/cpufreq/base_frequency" ++#define POWER_SYSFS_SCALING_DRIVER_PATH "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_driver" ++#define POWER_SYSFS_SCALING_MAX_FREQ_PATH "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_max_freq" ++#define POWER_SYSFS_MSR_PATH "/dev/cpu/%u/msr" + #endif + + RTE_EXPORT_EXPERIMENTAL_SYMBOL(__rte_lcore_telemetry_enabled, 20.11); +@@ -49,6 +58,183 @@ static struct lcore_telemetry *telemetry_data; + #define SMOOTH_COEFF 5 + #define STATE_CHANGE_OPT 32 + ++static int p1_freq[RTE_MAX_LCORE] = {0}; ++ ++static int ++try_read_base_frequency(unsigned int lcore_id) ++{ ++ char path[PATH_MAX]; ++ int fd; ++ snprintf(path, sizeof(path), POWER_SYSFS_BASE_FREQ_PATH, rte_lcore_to_cpu_id(lcore_id)); ++ ++ fd = open(path, O_RDONLY); ++ if (fd == -1) { ++ return -1; ++ } ++ char buffer[16]; ++ ssize_t bytesRead = pread(fd, buffer, sizeof(buffer) - 1, 0); ++ if (bytesRead == -1) { ++ close(fd); ++ return -1; ++ } ++ buffer[bytesRead] = '\0'; // Null-terminate the buffer ++ close(fd); ++ ++ p1_freq[lcore_id] = atoi(buffer); ++ return p1_freq[lcore_id]; ++ ++ ++} ++ ++static int ++try_read_scaling_max_freq(unsigned int lcore_id) ++{ ++ char path[PATH_MAX]; ++ int freq; ++ int fd; ++ ++ /* ++ * If the driver is acpi_cpufreq, we can read the scaling_max_freq file ++ */ ++ ++ snprintf(path, sizeof(path), POWER_SYSFS_SCALING_DRIVER_PATH, rte_lcore_to_cpu_id(lcore_id)); ++ fd = open(path, O_RDONLY); ++ if (fd == -1) { ++ return -1; ++ } ++ char buffer[16]; ++ ssize_t bytesRead = pread(fd, buffer, sizeof(buffer) - 1, 0); ++ if (bytesRead == -1) { ++ close(fd); ++ return -1; ++ } ++ buffer[bytesRead] = '\0'; // Null-terminate the buffer ++ ++ close(fd); ++ ++ if (strncmp(buffer, "acpi-cpufreq", 12) == 0) { ++ /* we can use the scaling_max_freq to get the p1 */ ++ snprintf(path, sizeof(path), POWER_SYSFS_SCALING_MAX_FREQ_PATH, rte_lcore_to_cpu_id(lcore_id)); ++ fd = open(path, O_RDONLY); ++ if (fd == -1) { ++ return -1; ++ } ++ ssize_t bytesRead = pread(fd, buffer, sizeof(buffer) - 1, 0); ++ if (bytesRead == -1) { ++ close(fd); ++ return -1; ++ } ++ buffer[bytesRead] = '\0'; // Null-terminate the buffer ++ close(fd); ++ freq = atoi(buffer) / 1000; /* convert to KHz */ ++ ++ /* ++ * If the freq value ends with '1', then, turbo is enabled. ++ * Round it down to the nearest 100. Otherwuse use the value. ++ */ ++ return (freq & ~1) * 1000; /* convert to Hz */ ++ } ++ return -1; ++} ++ ++static int ++try_read_msr(unsigned int lcore_id) ++{ ++ char path[PATH_MAX]; ++ int fd; ++ int freq; ++ uint64_t data; ++ ++ /* ++ * If the msr driver is present, we can read p1 from MSR_PLATFORM_INFO register ++ */ ++ snprintf(path, sizeof(path), POWER_SYSFS_MSR_PATH, rte_lcore_to_cpu_id(lcore_id)); ++ fd = open(path, O_RDONLY); ++ if (fd < 0) { ++ return -1; ++ } ++ ++ if (pread(fd, &data, sizeof(data), MSR_PLATFORM_INFO) != sizeof(data)) { ++ close(fd); ++ return -1; ++ } ++ ++ close(fd); ++ ++ freq = ((data >> 8) & 0xff) * 100 * 1000; ++ ++ return freq; ++} ++ ++ ++static ++int read_sysfs_p1_freq(unsigned int lcore_id) { ++ int freq; ++ ++ /* We've previously got the p1 frequency. */ ++ if (p1_freq[lcore_id] != 0) ++ return p1_freq[lcore_id]; ++ ++ /* ++ * Check the base_frequency file, if it's there ++ */ ++ freq = try_read_base_frequency(lcore_id); ++ if (freq != -1) { ++ p1_freq[lcore_id] = freq; ++ return freq; ++ } ++ ++ /* ++ * Check the scaling_max_freq file for the acpi-freq driver ++ */ ++ freq = try_read_scaling_max_freq(lcore_id); ++ if (freq != -1) { ++ p1_freq[lcore_id] = freq; ++ return freq; ++ } ++ ++ /* ++ * Try reading from the MSR register ++ */ ++ freq = try_read_msr(lcore_id); ++ if (freq != -1) { ++ p1_freq[lcore_id] = freq; ++ return freq; ++ } ++ ++ RTE_LOG(ERR, EAL, "Capacity telemetry for lcore %d not supported: no p1 frequency found", ++ lcore_id); ++ ++ return -1; ++} ++ ++ ++int current_fds[RTE_MAX_LCORE] = {0}; ++ ++static ++int read_sysfs_cur_freq(unsigned int lcore_id) { ++ char path[PATH_MAX]; ++ ++ if (current_fds[lcore_id] == 0) { ++ snprintf(path, sizeof(path), POWER_SYSFS_CUR_PATH, rte_lcore_to_cpu_id(lcore_id)); ++ current_fds[lcore_id] = open(path, O_RDONLY); ++ if (current_fds[lcore_id] == -1) { ++ return -1; ++ } ++ } ++ ++ char buffer[16]; ++ ssize_t bytesRead = pread(current_fds[lcore_id], buffer, sizeof(buffer) - 1, 0); ++ if (bytesRead == -1) { ++ return -1; ++ } ++ ++ buffer[bytesRead] = '\0'; // Null-terminate the buffer ++ ++ int value = atoi(buffer); ++ return value; ++} ++ + /* Helper function to check if the lcore is enabled. + * Cannot use rte_lcore_is_enabled since it only catches ROLE_RTE threads which + * does not include ROLE_NON_EAL threads which some application threads, for +@@ -105,6 +291,34 @@ int rte_lcore_busyness(unsigned int lcore_id) + return telemetry_data[lcore_id].busyness; + } + ++RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_lcore_capacity, 20.11); ++int rte_lcore_capacity(unsigned int lcore_id) ++{ ++ const uint64_t active_thresh = RTE_LCORE_BUSYNESS_PERIOD * 1000; ++ struct lcore_telemetry *tdata; ++ ++ if (lcore_id >= RTE_MAX_LCORE) ++ return -EINVAL; ++ tdata = &telemetry_data[lcore_id]; ++ ++ /* if the lcore is not active */ ++ if (tdata->interval_ts == 0) ++ return LCORE_BUSYNESS_NOT_SET; ++ /* if the core hasn't been active in a while */ ++ else if ((rte_rdtsc() - tdata->interval_ts) > active_thresh) ++ return LCORE_BUSYNESS_NOT_SET; ++ ++ int cur_freq = read_sysfs_cur_freq(rte_lcore_to_cpu_id(lcore_id)); ++ int busy = telemetry_data[lcore_id].busyness; ++ int p1 = read_sysfs_p1_freq(lcore_id) ; ++ ++ if ((busy == -1) || (p1 <= 0)) { ++ return -1; ++ } else { ++ return busy * cur_freq / p1; ++ } ++} ++ + RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_lcore_busyness_enabled, 20.11); + int rte_lcore_busyness_enabled(void) + { +@@ -269,6 +483,26 @@ lcore_handle_busyness(const char *cmd __rte_unused, + return 0; + } + ++static int ++lcore_handle_capacity(const char *cmd __rte_unused, ++ const char *params __rte_unused, struct rte_tel_data *d) ++{ ++ char corenum[64]; ++ int i; ++ ++ rte_tel_data_start_dict(d); ++ ++ /* Foreach lcore - can't use macro since it excludes ROLE_NON_EAL */ ++ for (i = 0; i < RTE_MAX_LCORE; i++) { ++ if (!lcore_enabled(i)) ++ continue; ++ snprintf(corenum, sizeof(corenum), "%d", i); ++ rte_tel_data_add_dict_int(d, corenum, rte_lcore_capacity(i)); ++ } ++ ++ return 0; ++} ++ + static int + lcore_handle_cpuset(const char *cmd __rte_unused, + const char *params __rte_unused, +@@ -332,6 +566,9 @@ RTE_INIT(lcore_init_telemetry) + rte_telemetry_register_cmd("/eal/lcore/busyness", lcore_handle_busyness, + "return percentage busyness of cores"); + ++ rte_telemetry_register_cmd("/eal/lcore/capacity_used", lcore_handle_capacity, ++ "return percentage capacity of cores"); ++ + rte_telemetry_register_cmd("/eal/lcore/busyness_enable", lcore_busyness_enable, + "enable lcore busyness measurement"); + +@@ -346,6 +583,12 @@ RTE_INIT(lcore_init_telemetry) + + #else + ++RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_lcore_capacity, 20.11); ++int rte_lcore_capacity(unsigned int lcore_id __rte_unused) ++{ ++ return -ENOTSUP; ++} ++ + RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_lcore_busyness, 20.11); + int rte_lcore_busyness(unsigned int lcore_id __rte_unused) + { +diff --git a/lib/eal/include/rte_lcore.h b/lib/eal/include/rte_lcore.h +index 1d0a5a22f6..7af3532b17 100644 +--- a/lib/eal/include/rte_lcore.h ++++ b/lib/eal/include/rte_lcore.h +@@ -421,6 +421,27 @@ __rte_experimental + int + rte_lcore_busyness(unsigned int lcore_id); + ++/** ++ * @warning ++ * @b EXPERIMENTAL: this API may change without prior notice. ++ * ++ * Read capacity value corresponding to an lcore. ++ * This differs from busyness in that it is related to the current usage ++ * of the lcore compared to P1 frequency, not the current frequency. ++ * ++ * @param lcore_id ++ * Lcore to read capacity value for. ++ * @return ++ * - value between 0 and 100 on success ++ * - -1 if lcore is not active ++ * - -EINVAL if lcore is invalid ++ * - -ENOMEM if not enough memory available ++ * - -ENOTSUP if not supported ++ */ ++__rte_experimental ++int ++rte_lcore_capacity(unsigned int lcore_id); ++ + /** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. +-- +2.43.0 + diff --git a/ipm/patches/dpdk/README.md b/ipm/patches/dpdk/README.md index 18d6546..ca50441 100644 --- a/ipm/patches/dpdk/README.md +++ b/ipm/patches/dpdk/README.md @@ -1,8 +1,9 @@ # DPDK Patches Apply the patches using ```git am {patch}.patch```. -1. ```20.11 directory``` are a set of patches that add the busyness telemetry to DPDK 20.11.9 -2. ```21.11 directory``` are a set of patches that add the busyness telemetry to DPDK 21.11.8 -3. ```22.11 directory``` are a set of patches that add the busyness telemetry to DPDK 22.11.6 -4. ```23.11 directory``` are a set of patches that add the busyness telemetry to DPDK 23.11.2 -5. ```24.11 directory``` are a set of patches that add the busyness telemetry to DPDK 24.11.2 +- The ```25.11/``` directory contains patches that add the busyness telemetry to DPDK 25.11.2 +- The ```24.11/``` directory contains patches that add the busyness telemetry to DPDK 24.11.5 +- The ```23.11/``` directory contains patches that add the busyness telemetry to DPDK 23.11.6 +- The ```22.11/``` directory contains patches that add the busyness telemetry to DPDK 22.11.11 +- The ```21.11/``` directory contains patches that add the busyness telemetry to DPDK 21.11.9 +- The ```20.11/``` directory contains patches that add the busyness telemetry to DPDK 20.11.10