From: Shiji Yang Date: Tue, 2 Jun 2026 00:50:19 +0000 (+0800) Subject: kernel: bump 6.12 to 6.12.92 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=d0520b880d5bb5273993e151c6fcc891c86efe0b;p=thirdparty%2Fopenwrt.git kernel: bump 6.12 to 6.12.92 Changelog: https://cdn.kernel.org/pub/linux/kernel/v6.x/ChangeLog-6.12.92 Remove upstreamed patches: - generic/backport-6.12/216-01-revert-perf-cgroup-update-metric-leader-in-evlist__e.patch[1] - generic/backport-6.12/216-02-revert-perf-tool_pmu-fix-aggregation-on-duration_tim.patch[2] - generic/backport-6.12/216-03-revert-perf-python-add-parse_events-function.patch[3] - generic/backport-6.12/216-04-revert-perf-tool_pmu-factor-tool-events-into-their-o.patch[4] - ath79/patches-6.12/301-irqchip-irq-ath79-cpu-drop-OF-init-helper.patch[5] All other patches are automatically refreshed. [1] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v6.12.92&id=546fc0fe44797e07dfb17898e019e0b543628f53 [2] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v6.12.92&id=9fdca4c4d7eb942e83c81ef0e097303730ef72a6 [3] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v6.12.92&id=94fc25a1f82aeaf7777478234ad38d90adb9d94f [4] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v6.12.92&id=709575a6ab20da63b2183ec4ac89a8e284ddbc1d [5] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v6.12.92&id=c6211c8832d542d93f4e030e6e6f79c45b219e13 Signed-off-by: Shiji Yang Link: https://github.com/openwrt/openwrt/pull/23621 Signed-off-by: Jonas Jelonek --- diff --git a/target/linux/airoha/patches-6.12/048-06-v6.15-net-dsa-mt7530-Enable-Rx-sptag-for-EN7581-SoC.patch b/target/linux/airoha/patches-6.12/048-06-v6.15-net-dsa-mt7530-Enable-Rx-sptag-for-EN7581-SoC.patch index 27956d553af..71822d69d9d 100644 --- a/target/linux/airoha/patches-6.12/048-06-v6.15-net-dsa-mt7530-Enable-Rx-sptag-for-EN7581-SoC.patch +++ b/target/linux/airoha/patches-6.12/048-06-v6.15-net-dsa-mt7530-Enable-Rx-sptag-for-EN7581-SoC.patch @@ -19,7 +19,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2588,6 +2588,11 @@ mt7531_setup_common(struct dsa_switch *d +@@ -2599,6 +2599,11 @@ mt7531_setup_common(struct dsa_switch *d /* Allow mirroring frames received on the local port (monitor port). */ mt7530_set(priv, MT753X_AGC, LOCAL_EN); diff --git a/target/linux/airoha/patches-6.12/401-02-v6.16-net-dsa-mt7530-Add-AN7583-support.patch b/target/linux/airoha/patches-6.12/401-02-v6.16-net-dsa-mt7530-Add-AN7583-support.patch index 547687cb563..bca3d7b3f10 100644 --- a/target/linux/airoha/patches-6.12/401-02-v6.16-net-dsa-mt7530-Add-AN7583-support.patch +++ b/target/linux/airoha/patches-6.12/401-02-v6.16-net-dsa-mt7530-Add-AN7583-support.patch @@ -31,7 +31,7 @@ Signed-off-by: Jakub Kicinski { /* sentinel */ }, --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -1153,7 +1153,7 @@ mt753x_cpu_port_enable(struct dsa_switch +@@ -1160,7 +1160,7 @@ mt753x_cpu_port_enable(struct dsa_switch * is affine to the inbound user port. */ if (priv->id == ID_MT7531 || priv->id == ID_MT7988 || @@ -40,7 +40,7 @@ Signed-off-by: Jakub Kicinski mt7530_set(priv, MT7531_CFC, MT7531_CPU_PMAP(BIT(port))); /* CPU port gets connected to all user ports of -@@ -2589,7 +2589,7 @@ mt7531_setup_common(struct dsa_switch *d +@@ -2600,7 +2600,7 @@ mt7531_setup_common(struct dsa_switch *d mt7530_set(priv, MT753X_AGC, LOCAL_EN); /* Enable Special Tag for rx frames */ @@ -49,7 +49,7 @@ Signed-off-by: Jakub Kicinski mt7530_write(priv, MT753X_CPORT_SPTAG_CFG, CPORT_SW2FE_STAG_EN | CPORT_FE2SW_STAG_EN); -@@ -3157,6 +3157,16 @@ static int mt7988_setup(struct dsa_switc +@@ -3168,6 +3168,16 @@ static int mt7988_setup(struct dsa_switc reset_control_deassert(priv->rstc); usleep_range(20, 50); @@ -66,7 +66,7 @@ Signed-off-by: Jakub Kicinski /* Reset the switch PHYs */ mt7530_write(priv, MT7530_SYS_CTRL, SYS_CTRL_PHY_RST); -@@ -3253,6 +3263,16 @@ const struct mt753x_info mt753x_table[] +@@ -3264,6 +3274,16 @@ const struct mt753x_info mt753x_table[] .pcs_ops = &mt7530_pcs_ops, .sw_setup = mt7988_setup, .phy_read_c22 = mt7531_ind_c22_phy_read, diff --git a/target/linux/ath79/patches-6.12/301-irqchip-irq-ath79-cpu-drop-OF-init-helper.patch b/target/linux/ath79/patches-6.12/301-irqchip-irq-ath79-cpu-drop-OF-init-helper.patch deleted file mode 100644 index 13117d9a8e6..00000000000 --- a/target/linux/ath79/patches-6.12/301-irqchip-irq-ath79-cpu-drop-OF-init-helper.patch +++ /dev/null @@ -1,23 +0,0 @@ -From e029f998594f151008ecbfa024e2957edd2a5189 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Tue, 6 Mar 2018 09:58:19 +0100 -Subject: [PATCH 08/33] irqchip/irq-ath79-cpu: drop !OF init helper - -Signed-off-by: John Crispin ---- - drivers/irqchip/irq-ath79-cpu.c | 7 ------- - 1 file changed, 7 deletions(-) - ---- a/drivers/irqchip/irq-ath79-cpu.c -+++ b/drivers/irqchip/irq-ath79-cpu.c -@@ -85,10 +85,3 @@ static int __init ar79_cpu_intc_of_init( - } - IRQCHIP_DECLARE(ar79_cpu_intc, "qca,ar7100-cpu-intc", - ar79_cpu_intc_of_init); -- --void __init ath79_cpu_irq_init(unsigned irq_wb_chan2, unsigned irq_wb_chan3) --{ -- irq_wb_chan[2] = irq_wb_chan2; -- irq_wb_chan[3] = irq_wb_chan3; -- mips_cpu_irq_init(); --} diff --git a/target/linux/ath79/patches-6.12/900-unaligned_access_hacks.patch b/target/linux/ath79/patches-6.12/900-unaligned_access_hacks.patch index ab0cf0a8ab1..ae78d711acb 100644 --- a/target/linux/ath79/patches-6.12/900-unaligned_access_hacks.patch +++ b/target/linux/ath79/patches-6.12/900-unaligned_access_hacks.patch @@ -312,7 +312,7 @@ SVN-Revision: 35130 case IPV6_2292HOPOPTS: --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c -@@ -993,7 +993,7 @@ static bool ipv6_hop_jumbo(struct sk_buf +@@ -1004,7 +1004,7 @@ static bool ipv6_hop_jumbo(struct sk_buf goto drop; } diff --git a/target/linux/bcm27xx/patches-6.12/950-0122-bcmgenet-Better-coalescing-parameter-defaults.patch b/target/linux/bcm27xx/patches-6.12/950-0122-bcmgenet-Better-coalescing-parameter-defaults.patch index b2e6cbf0440..c521f1ecedb 100644 --- a/target/linux/bcm27xx/patches-6.12/950-0122-bcmgenet-Better-coalescing-parameter-defaults.patch +++ b/target/linux/bcm27xx/patches-6.12/950-0122-bcmgenet-Better-coalescing-parameter-defaults.patch @@ -18,7 +18,7 @@ Signed-off-by: Phil Elwell --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c -@@ -2675,7 +2675,7 @@ static void bcmgenet_init_tx_ring(struct +@@ -2674,7 +2674,7 @@ static void bcmgenet_init_tx_ring(struct bcmgenet_tdma_ring_writel(priv, index, 0, TDMA_PROD_INDEX); bcmgenet_tdma_ring_writel(priv, index, 0, TDMA_CONS_INDEX); @@ -27,7 +27,7 @@ Signed-off-by: Phil Elwell /* Disable rate control for now */ bcmgenet_tdma_ring_writel(priv, index, flow_period_val, TDMA_FLOW_PERIOD); -@@ -4074,8 +4074,10 @@ static int bcmgenet_probe(struct platfor +@@ -4073,8 +4073,10 @@ static int bcmgenet_probe(struct platfor netif_set_real_num_rx_queues(priv->dev, priv->hw_params->rx_queues + 1); /* Set default coalescing parameters */ diff --git a/target/linux/bcm27xx/patches-6.12/950-0133-net-bcmgenet-Workaround-2-for-Pi4-Ethernet-fail.patch b/target/linux/bcm27xx/patches-6.12/950-0133-net-bcmgenet-Workaround-2-for-Pi4-Ethernet-fail.patch index 7718ce07d30..c044b2ae2e1 100644 --- a/target/linux/bcm27xx/patches-6.12/950-0133-net-bcmgenet-Workaround-2-for-Pi4-Ethernet-fail.patch +++ b/target/linux/bcm27xx/patches-6.12/950-0133-net-bcmgenet-Workaround-2-for-Pi4-Ethernet-fail.patch @@ -37,7 +37,7 @@ Signed-off-by: Phil Elwell static inline void bcmgenet_writel(u32 value, void __iomem *offset) { -@@ -2513,6 +2516,11 @@ static void reset_umac(struct bcmgenet_p +@@ -2512,6 +2515,11 @@ static void reset_umac(struct bcmgenet_p bcmgenet_rbuf_ctrl_set(priv, 0); udelay(10); diff --git a/target/linux/bcm27xx/patches-6.12/950-0297-net-bcmgenet-Add-eee-module-parameter.patch b/target/linux/bcm27xx/patches-6.12/950-0297-net-bcmgenet-Add-eee-module-parameter.patch index ec4d648668d..4b8942dddef 100644 --- a/target/linux/bcm27xx/patches-6.12/950-0297-net-bcmgenet-Add-eee-module-parameter.patch +++ b/target/linux/bcm27xx/patches-6.12/950-0297-net-bcmgenet-Add-eee-module-parameter.patch @@ -26,7 +26,7 @@ Signed-off-by: Phil Elwell static inline void bcmgenet_writel(u32 value, void __iomem *offset) { -@@ -3360,6 +3363,17 @@ static int bcmgenet_open(struct net_devi +@@ -3359,6 +3362,17 @@ static int bcmgenet_open(struct net_devi bcmgenet_phy_pause_set(dev, priv->rx_pause, priv->tx_pause); diff --git a/target/linux/generic/backport-6.12/216-01-revert-perf-cgroup-update-metric-leader-in-evlist__e.patch b/target/linux/generic/backport-6.12/216-01-revert-perf-cgroup-update-metric-leader-in-evlist__e.patch deleted file mode 100644 index c877f61cc20..00000000000 --- a/target/linux/generic/backport-6.12/216-01-revert-perf-cgroup-update-metric-leader-in-evlist__e.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 5c9ceee75a90cd5db0d38d9dbfde6659194a9b5b Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Sun, 24 May 2026 10:29:50 -0400 -Subject: Revert "perf cgroup: Update metric leader in evlist__expand_cgroup" - -This reverts commit d26e31446c0fa96feca0b7701243b42447225d33. - -Signed-off-by: Sasha Levin ---- - tools/perf/util/cgroup.c | 30 +++++++----------------------- - 1 file changed, 7 insertions(+), 23 deletions(-) - ---- a/tools/perf/util/cgroup.c -+++ b/tools/perf/util/cgroup.c -@@ -417,6 +417,7 @@ int evlist__expand_cgroup(struct evlist - struct rblist *metric_events, bool open_cgroup) - { - struct evlist *orig_list, *tmp_list; -+ struct evsel *pos, *evsel, *leader; - struct rblist orig_metric_events; - struct cgroup *cgrp = NULL; - struct cgroup_name *cn; -@@ -455,7 +456,6 @@ int evlist__expand_cgroup(struct evlist - goto out_err; - - list_for_each_entry(cn, &cgroup_list, list) { -- struct evsel *pos; - char *name; - - if (!cn->used) -@@ -471,37 +471,21 @@ int evlist__expand_cgroup(struct evlist - if (cgrp == NULL) - continue; - -- /* copy the list and set to the new cgroup. */ -+ leader = NULL; - evlist__for_each_entry(orig_list, pos) { -- struct evsel *evsel = evsel__clone(/*dest=*/NULL, pos); -- -+ evsel = evsel__clone(/*dest=*/NULL, pos); - if (evsel == NULL) - goto out_err; - -- /* stash the copy during the copying. */ -- pos->priv = evsel; - cgroup__put(evsel->cgrp); - evsel->cgrp = cgroup__get(cgrp); - -- evlist__add(tmp_list, evsel); -- } -- /* update leader information using stashed pointer to copy. */ -- evlist__for_each_entry(orig_list, pos) { -- struct evsel *evsel = pos->priv; -- -- if (evsel__leader(pos)) -- evsel__set_leader(evsel, evsel__leader(pos)->priv); -- -- if (pos->metric_leader) -- evsel->metric_leader = pos->metric_leader->priv; -+ if (evsel__is_group_leader(pos)) -+ leader = evsel; -+ evsel__set_leader(evsel, leader); - -- if (pos->first_wildcard_match) -- evsel->first_wildcard_match = pos->first_wildcard_match->priv; -+ evlist__add(tmp_list, evsel); - } -- /* the stashed copy is no longer used. */ -- evlist__for_each_entry(orig_list, pos) -- pos->priv = NULL; -- - /* cgroup__new() has a refcount, release it here */ - cgroup__put(cgrp); - nr_cgroups++; diff --git a/target/linux/generic/backport-6.12/216-02-revert-perf-tool_pmu-fix-aggregation-on-duration_tim.patch b/target/linux/generic/backport-6.12/216-02-revert-perf-tool_pmu-fix-aggregation-on-duration_tim.patch deleted file mode 100644 index b9b3c63a42e..00000000000 --- a/target/linux/generic/backport-6.12/216-02-revert-perf-tool_pmu-fix-aggregation-on-duration_tim.patch +++ /dev/null @@ -1,30 +0,0 @@ -From f126428e706b7c6eb9aa1c79ced284b195d4e392 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Sun, 24 May 2026 10:36:48 -0400 -Subject: Revert "perf tool_pmu: Fix aggregation on duration_time" - -This reverts commit 310be445ab1028315627b326516f193511cb1c97. - -Signed-off-by: Sasha Levin ---- - tools/perf/util/tool_pmu.c | 8 +------- - 1 file changed, 1 insertion(+), 7 deletions(-) - ---- a/tools/perf/util/tool_pmu.c -+++ b/tools/perf/util/tool_pmu.c -@@ -392,14 +392,8 @@ int evsel__read_tool(struct evsel *evsel - delta_start *= 1000000000 / ticks_per_sec; - } - count->val = delta_start; -+ count->ena = count->run = delta_start; - count->lost = 0; -- /* -- * The values of enabled and running must make a ratio of 100%. The -- * exact values don't matter as long as they are non-zero to avoid -- * issues with evsel__count_has_error. -- */ -- count->ena++; -- count->run++; - return 0; - } - diff --git a/target/linux/generic/backport-6.12/216-03-revert-perf-python-add-parse_events-function.patch b/target/linux/generic/backport-6.12/216-03-revert-perf-python-add-parse_events-function.patch deleted file mode 100644 index 2932c5bdde0..00000000000 --- a/target/linux/generic/backport-6.12/216-03-revert-perf-python-add-parse_events-function.patch +++ /dev/null @@ -1,163 +0,0 @@ -From 8a11c59a5aab9423777ee1ead5e66174896c7adb Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Sun, 24 May 2026 10:36:48 -0400 -Subject: Revert "perf python: Add parse_events function" - -This reverts commit 9cd264079fab9867dbc9fbc8a1e521996e3d7212. - -Signed-off-by: Sasha Levin ---- - tools/perf/util/cgroup.c | 2 +- - tools/perf/util/evsel.c | 19 +++++-------- - tools/perf/util/evsel.h | 2 +- - tools/perf/util/python.c | 61 ---------------------------------------- - 4 files changed, 9 insertions(+), 75 deletions(-) - ---- a/tools/perf/util/cgroup.c -+++ b/tools/perf/util/cgroup.c -@@ -473,7 +473,7 @@ int evlist__expand_cgroup(struct evlist - - leader = NULL; - evlist__for_each_entry(orig_list, pos) { -- evsel = evsel__clone(/*dest=*/NULL, pos); -+ evsel = evsel__clone(pos); - if (evsel == NULL) - goto out_err; - ---- a/tools/perf/util/evsel.c -+++ b/tools/perf/util/evsel.c -@@ -332,7 +332,7 @@ static int evsel__copy_config_terms(stru - * The assumption is that @orig is not configured nor opened yet. - * So we only care about the attributes that can be set while it's parsed. - */ --struct evsel *evsel__clone(struct evsel *dest, struct evsel *orig) -+struct evsel *evsel__clone(struct evsel *orig) - { - struct evsel *evsel; - -@@ -345,11 +345,7 @@ struct evsel *evsel__clone(struct evsel - if (orig->bpf_obj) - return NULL; - -- if (dest) -- evsel = dest; -- else -- evsel = evsel__new(&orig->core.attr); -- -+ evsel = evsel__new(&orig->core.attr); - if (evsel == NULL) - return NULL; - -@@ -399,12 +395,11 @@ struct evsel *evsel__clone(struct evsel - evsel->core.leader = orig->core.leader; - - evsel->max_events = orig->max_events; -- zfree(&evsel->unit); -- if (orig->unit) { -- evsel->unit = strdup(orig->unit); -- if (evsel->unit == NULL) -- goto out_err; -- } -+ free((char *)evsel->unit); -+ evsel->unit = strdup(orig->unit); -+ if (evsel->unit == NULL) -+ goto out_err; -+ - evsel->scale = orig->scale; - evsel->snapshot = orig->snapshot; - evsel->per_pkg = orig->per_pkg; ---- a/tools/perf/util/evsel.h -+++ b/tools/perf/util/evsel.h -@@ -241,7 +241,7 @@ static inline struct evsel *evsel__new(s - return evsel__new_idx(attr, 0); - } - --struct evsel *evsel__clone(struct evsel *dest, struct evsel *orig); -+struct evsel *evsel__clone(struct evsel *orig); - - int copy_config_terms(struct list_head *dst, struct list_head *src); - void free_config_terms(struct list_head *config_terms); ---- a/tools/perf/util/python.c -+++ b/tools/perf/util/python.c -@@ -13,7 +13,6 @@ - #include "evsel.h" - #include "event.h" - #include "print_binary.h" --#include "strbuf.h" - #include "thread_map.h" - #include "trace-event.h" - #include "mmap.h" -@@ -1248,60 +1247,6 @@ static PyObject *pyrf__tracepoint(struct - #endif // HAVE_LIBTRACEEVENT - } - --static PyObject *pyrf_evsel__from_evsel(struct evsel *evsel) --{ -- struct pyrf_evsel *pevsel = PyObject_New(struct pyrf_evsel, &pyrf_evsel__type); -- -- if (!pevsel) -- return NULL; -- -- memset(&pevsel->evsel, 0, sizeof(pevsel->evsel)); -- evsel__init(&pevsel->evsel, &evsel->core.attr, evsel->core.idx); -- -- evsel__clone(&pevsel->evsel, evsel); -- return (PyObject *)pevsel; --} -- --static PyObject *pyrf_evlist__from_evlist(struct evlist *evlist) --{ -- struct pyrf_evlist *pevlist = PyObject_New(struct pyrf_evlist, &pyrf_evlist__type); -- struct evsel *pos; -- -- if (!pevlist) -- return NULL; -- -- memset(&pevlist->evlist, 0, sizeof(pevlist->evlist)); -- evlist__init(&pevlist->evlist, evlist->core.all_cpus, evlist->core.threads); -- evlist__for_each_entry(evlist, pos) { -- struct pyrf_evsel *pevsel = (void *)pyrf_evsel__from_evsel(pos); -- -- evlist__add(&pevlist->evlist, &pevsel->evsel); -- } -- return (PyObject *)pevlist; --} -- --static PyObject *pyrf__parse_events(PyObject *self, PyObject *args) --{ -- const char *input; -- struct evlist evlist = {}; -- struct parse_events_error err; -- PyObject *result; -- -- if (!PyArg_ParseTuple(args, "s", &input)) -- return NULL; -- -- parse_events_error__init(&err); -- evlist__init(&evlist, NULL, NULL); -- if (parse_events(&evlist, input, &err)) { -- parse_events_error__print(&err, input); -- PyErr_SetFromErrno(PyExc_OSError); -- return NULL; -- } -- result = pyrf_evlist__from_evlist(&evlist); -- evlist__exit(&evlist); -- return result; --} -- - static PyMethodDef perf__methods[] = { - { - .ml_name = "tracepoint", -@@ -1309,12 +1254,6 @@ static PyMethodDef perf__methods[] = { - .ml_flags = METH_VARARGS | METH_KEYWORDS, - .ml_doc = PyDoc_STR("Get tracepoint config.") - }, -- { -- .ml_name = "parse_events", -- .ml_meth = (PyCFunction) pyrf__parse_events, -- .ml_flags = METH_VARARGS, -- .ml_doc = PyDoc_STR("Parse a string of events and return an evlist.") -- }, - { .ml_name = NULL, } - }; - diff --git a/target/linux/generic/backport-6.12/216-04-revert-perf-tool_pmu-factor-tool-events-into-their-o.patch b/target/linux/generic/backport-6.12/216-04-revert-perf-tool_pmu-factor-tool-events-into-their-o.patch deleted file mode 100644 index 5613508ef00..00000000000 --- a/target/linux/generic/backport-6.12/216-04-revert-perf-tool_pmu-factor-tool-events-into-their-o.patch +++ /dev/null @@ -1,1387 +0,0 @@ -From 0a56a56da306fbc202f01e7373295d6239716451 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Sun, 24 May 2026 10:36:48 -0400 -Subject: Revert "perf tool_pmu: Factor tool events into their own PMU" - -This reverts commit 7cfcd01f33fc3400c60f923d2896a8cdc60cecc4. - -Signed-off-by: Sasha Levin ---- - tools/perf/builtin-list.c | 13 +- - tools/perf/builtin-stat.c | 1 - - tools/perf/util/Build | 1 - - tools/perf/util/evsel.c | 272 ++++++++++++++++++++-- - tools/perf/util/evsel.h | 28 ++- - tools/perf/util/metricgroup.c | 1 - - tools/perf/util/parse-events.c | 39 ++++ - tools/perf/util/parse-events.h | 3 + - tools/perf/util/parse-events.l | 11 + - tools/perf/util/parse-events.y | 16 ++ - tools/perf/util/pmu.c | 20 +- - tools/perf/util/pmu.h | 2 - - tools/perf/util/pmus.c | 9 - - tools/perf/util/print-events.c | 36 ++- - tools/perf/util/print-events.h | 1 + - tools/perf/util/stat-display.c | 6 +- - tools/perf/util/stat-shadow.c | 1 - - tools/perf/util/tool_pmu.c | 411 --------------------------------- - tools/perf/util/tool_pmu.h | 51 ---- - 19 files changed, 392 insertions(+), 530 deletions(-) - delete mode 100644 tools/perf/util/tool_pmu.c - delete mode 100644 tools/perf/util/tool_pmu.h - ---- a/tools/perf/builtin-list.c -+++ b/tools/perf/builtin-list.c -@@ -19,7 +19,6 @@ - #include "util/string2.h" - #include "util/strlist.h" - #include "util/strbuf.h" --#include "util/tool_pmu.h" - #include - #include - #include -@@ -615,18 +614,9 @@ int cmd_list(int argc, const char **argv - event_symbols_hw, PERF_COUNT_HW_MAX); - else if (strcmp(argv[i], "sw") == 0 || - strcmp(argv[i], "software") == 0) { -- char *old_pmu_glob = default_ps.pmu_glob; -- - print_symbol_events(&print_cb, ps, PERF_TYPE_SOFTWARE, - event_symbols_sw, PERF_COUNT_SW_MAX); -- default_ps.pmu_glob = strdup("tool"); -- if (!default_ps.pmu_glob) { -- ret = -1; -- goto out; -- } -- perf_pmus__print_pmu_events(&print_cb, ps); -- zfree(&default_ps.pmu_glob); -- default_ps.pmu_glob = old_pmu_glob; -+ print_tool_events(&print_cb, ps); - } else if (strcmp(argv[i], "cache") == 0 || - strcmp(argv[i], "hwcache") == 0) - print_hwcache_events(&print_cb, ps); -@@ -674,6 +664,7 @@ int cmd_list(int argc, const char **argv - event_symbols_hw, PERF_COUNT_HW_MAX); - print_symbol_events(&print_cb, ps, PERF_TYPE_SOFTWARE, - event_symbols_sw, PERF_COUNT_SW_MAX); -+ print_tool_events(&print_cb, ps); - print_hwcache_events(&print_cb, ps); - perf_pmus__print_pmu_events(&print_cb, ps); - print_tracepoint_events(&print_cb, ps); ---- a/tools/perf/builtin-stat.c -+++ b/tools/perf/builtin-stat.c -@@ -46,7 +46,6 @@ - #include "util/parse-events.h" - #include "util/pmus.h" - #include "util/pmu.h" --#include "util/tool_pmu.h" - #include "util/event.h" - #include "util/evlist.h" - #include "util/evsel.h" ---- a/tools/perf/util/Build -+++ b/tools/perf/util/Build -@@ -83,7 +83,6 @@ perf-util-y += pmu.o - perf-util-y += pmus.o - perf-util-y += pmu-flex.o - perf-util-y += pmu-bison.o --perf-util-y += tool_pmu.o - perf-util-y += svghelper.o - perf-util-$(CONFIG_LIBTRACEEVENT) += trace-event-info.o - perf-util-y += trace-event-scripting.o ---- a/tools/perf/util/evsel.c -+++ b/tools/perf/util/evsel.c -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -50,7 +51,6 @@ - #include "off_cpu.h" - #include "pmu.h" - #include "pmus.h" --#include "tool_pmu.h" - #include "rlimit.h" - #include "../perf-sys.h" - #include "util/parse-branch-options.h" -@@ -71,6 +71,33 @@ struct perf_missing_features perf_missin - - static clockid_t clockid; - -+static const char *const perf_tool_event__tool_names[PERF_TOOL_MAX] = { -+ NULL, -+ "duration_time", -+ "user_time", -+ "system_time", -+}; -+ -+const char *perf_tool_event__to_str(enum perf_tool_event ev) -+{ -+ if (ev > PERF_TOOL_NONE && ev < PERF_TOOL_MAX) -+ return perf_tool_event__tool_names[ev]; -+ -+ return NULL; -+} -+ -+enum perf_tool_event perf_tool_event__from_str(const char *str) -+{ -+ int i; -+ -+ perf_tool_event__for_each_event(i) { -+ if (!strcmp(str, perf_tool_event__tool_names[i])) -+ return i; -+ } -+ return PERF_TOOL_NONE; -+} -+ -+ - static int evsel__no_extra_init(struct evsel *evsel __maybe_unused) - { - return 0; -@@ -395,6 +422,7 @@ struct evsel *evsel__clone(struct evsel - evsel->core.leader = orig->core.leader; - - evsel->max_events = orig->max_events; -+ evsel->tool_event = orig->tool_event; - free((char *)evsel->unit); - evsel->unit = strdup(orig->unit); - if (evsel->unit == NULL) -@@ -592,6 +620,11 @@ static int evsel__sw_name(struct evsel * - return r + evsel__add_modifiers(evsel, bf + r, size - r); - } - -+static int evsel__tool_name(enum perf_tool_event ev, char *bf, size_t size) -+{ -+ return scnprintf(bf, size, "%s", perf_tool_event__to_str(ev)); -+} -+ - static int __evsel__bp_name(char *bf, size_t size, u64 addr, u64 type) - { - int r; -@@ -742,7 +775,10 @@ const char *evsel__name(struct evsel *ev - break; - - case PERF_TYPE_SOFTWARE: -- evsel__sw_name(evsel, bf, sizeof(bf)); -+ if (evsel__is_tool(evsel)) -+ evsel__tool_name(evsel__tool_event(evsel), bf, sizeof(bf)); -+ else -+ evsel__sw_name(evsel, bf, sizeof(bf)); - break; - - case PERF_TYPE_TRACEPOINT: -@@ -753,10 +789,6 @@ const char *evsel__name(struct evsel *ev - evsel__bp_name(evsel, bf, sizeof(bf)); - break; - -- case PERF_PMU_TYPE_TOOL: -- scnprintf(bf, sizeof(bf), "%s", evsel__tool_pmu_event_name(evsel)); -- break; -- - default: - scnprintf(bf, sizeof(bf), "unknown attr type: %d", - evsel->core.attr.type); -@@ -782,7 +814,7 @@ const char *evsel__metric_id(const struc - return evsel->metric_id; - - if (evsel__is_tool(evsel)) -- return evsel__tool_pmu_event_name(evsel); -+ return perf_tool_event__to_str(evsel__tool_event(evsel)); - - return "unknown"; - } -@@ -1666,6 +1698,167 @@ static int evsel__read_group(struct evse - return evsel__process_group_data(leader, cpu_map_idx, thread, data); - } - -+static bool read_until_char(struct io *io, char e) -+{ -+ int c; -+ -+ do { -+ c = io__get_char(io); -+ if (c == -1) -+ return false; -+ } while (c != e); -+ return true; -+} -+ -+static int read_stat_field(int fd, struct perf_cpu cpu, int field, __u64 *val) -+{ -+ char buf[256]; -+ struct io io; -+ int i; -+ -+ io__init(&io, fd, buf, sizeof(buf)); -+ -+ /* Skip lines to relevant CPU. */ -+ for (i = -1; i < cpu.cpu; i++) { -+ if (!read_until_char(&io, '\n')) -+ return -EINVAL; -+ } -+ /* Skip to "cpu". */ -+ if (io__get_char(&io) != 'c') return -EINVAL; -+ if (io__get_char(&io) != 'p') return -EINVAL; -+ if (io__get_char(&io) != 'u') return -EINVAL; -+ -+ /* Skip N of cpuN. */ -+ if (!read_until_char(&io, ' ')) -+ return -EINVAL; -+ -+ i = 1; -+ while (true) { -+ if (io__get_dec(&io, val) != ' ') -+ break; -+ if (field == i) -+ return 0; -+ i++; -+ } -+ return -EINVAL; -+} -+ -+static int read_pid_stat_field(int fd, int field, __u64 *val) -+{ -+ char buf[256]; -+ struct io io; -+ int c, i; -+ -+ io__init(&io, fd, buf, sizeof(buf)); -+ if (io__get_dec(&io, val) != ' ') -+ return -EINVAL; -+ if (field == 1) -+ return 0; -+ -+ /* Skip comm. */ -+ if (io__get_char(&io) != '(' || !read_until_char(&io, ')')) -+ return -EINVAL; -+ if (field == 2) -+ return -EINVAL; /* String can't be returned. */ -+ -+ /* Skip state */ -+ if (io__get_char(&io) != ' ' || io__get_char(&io) == -1) -+ return -EINVAL; -+ if (field == 3) -+ return -EINVAL; /* String can't be returned. */ -+ -+ /* Loop over numeric fields*/ -+ if (io__get_char(&io) != ' ') -+ return -EINVAL; -+ -+ i = 4; -+ while (true) { -+ c = io__get_dec(&io, val); -+ if (c == -1) -+ return -EINVAL; -+ if (c == -2) { -+ /* Assume a -ve was read */ -+ c = io__get_dec(&io, val); -+ *val *= -1; -+ } -+ if (c != ' ') -+ return -EINVAL; -+ if (field == i) -+ return 0; -+ i++; -+ } -+ return -EINVAL; -+} -+ -+static int evsel__read_tool(struct evsel *evsel, int cpu_map_idx, int thread) -+{ -+ __u64 *start_time, cur_time, delta_start; -+ int fd, err = 0; -+ struct perf_counts_values *count; -+ bool adjust = false; -+ -+ count = perf_counts(evsel->counts, cpu_map_idx, thread); -+ -+ switch (evsel__tool_event(evsel)) { -+ case PERF_TOOL_DURATION_TIME: -+ /* -+ * Pretend duration_time is only on the first CPU and thread, or -+ * else aggregation will scale duration_time by the number of -+ * CPUs/threads. -+ */ -+ start_time = &evsel->start_time; -+ if (cpu_map_idx == 0 && thread == 0) -+ cur_time = rdclock(); -+ else -+ cur_time = *start_time; -+ break; -+ case PERF_TOOL_USER_TIME: -+ case PERF_TOOL_SYSTEM_TIME: { -+ bool system = evsel__tool_event(evsel) == PERF_TOOL_SYSTEM_TIME; -+ -+ start_time = xyarray__entry(evsel->start_times, cpu_map_idx, thread); -+ fd = FD(evsel, cpu_map_idx, thread); -+ lseek(fd, SEEK_SET, 0); -+ if (evsel->pid_stat) { -+ /* The event exists solely on 1 CPU. */ -+ if (cpu_map_idx == 0) -+ err = read_pid_stat_field(fd, system ? 15 : 14, &cur_time); -+ else -+ cur_time = 0; -+ } else { -+ /* The event is for all threads. */ -+ if (thread == 0) { -+ struct perf_cpu cpu = perf_cpu_map__cpu(evsel->core.cpus, -+ cpu_map_idx); -+ -+ err = read_stat_field(fd, cpu, system ? 3 : 1, &cur_time); -+ } else { -+ cur_time = 0; -+ } -+ } -+ adjust = true; -+ break; -+ } -+ case PERF_TOOL_NONE: -+ case PERF_TOOL_MAX: -+ default: -+ err = -EINVAL; -+ } -+ if (err) -+ return err; -+ -+ delta_start = cur_time - *start_time; -+ if (adjust) { -+ __u64 ticks_per_sec = sysconf(_SC_CLK_TCK); -+ -+ delta_start *= 1000000000 / ticks_per_sec; -+ } -+ count->val = delta_start; -+ count->ena = count->run = delta_start; -+ count->lost = 0; -+ return 0; -+} -+ - bool __evsel__match(const struct evsel *evsel, u32 type, u64 config) - { - -@@ -1881,7 +2074,6 @@ static struct perf_thread_map *empty_thr - static int __evsel__prepare_open(struct evsel *evsel, struct perf_cpu_map *cpus, - struct perf_thread_map *threads) - { -- int ret = 0; - int nthreads = perf_thread_map__nr(threads); - - if ((perf_missing_features.write_backward && evsel->core.attr.write_backward) || -@@ -1912,14 +2104,19 @@ static int __evsel__prepare_open(struct - perf_evsel__alloc_fd(&evsel->core, perf_cpu_map__nr(cpus), nthreads) < 0) - return -ENOMEM; - -- if (evsel__is_tool(evsel)) -- ret = evsel__tool_pmu_prepare_open(evsel, cpus, nthreads); -+ if ((evsel__tool_event(evsel) == PERF_TOOL_SYSTEM_TIME || -+ evsel__tool_event(evsel) == PERF_TOOL_USER_TIME) && -+ !evsel->start_times) { -+ evsel->start_times = xyarray__new(perf_cpu_map__nr(cpus), nthreads, sizeof(__u64)); -+ if (!evsel->start_times) -+ return -ENOMEM; -+ } - - evsel->open_flags = PERF_FLAG_FD_CLOEXEC; - if (evsel->cgrp) - evsel->open_flags |= PERF_FLAG_PID_CGROUP; - -- return ret; -+ return 0; - } - - static void evsel__disable_missing_features(struct evsel *evsel) -@@ -2097,6 +2294,13 @@ static int evsel__open_cpu(struct evsel - int pid = -1, err, old_errno; - enum rlimit_action set_rlimit = NO_CHANGE; - -+ if (evsel__tool_event(evsel) == PERF_TOOL_DURATION_TIME) { -+ if (evsel->core.attr.sample_period) /* no sampling */ -+ return -EINVAL; -+ evsel->start_time = rdclock(); -+ return 0; -+ } -+ - if (evsel__is_retire_lat(evsel)) - return tpebs_start(evsel->evlist); - -@@ -2121,12 +2325,6 @@ fallback_missing_features: - pr_debug3("Opening: %s\n", evsel__name(evsel)); - display_attr(&evsel->core.attr); - -- if (evsel__is_tool(evsel)) { -- return evsel__tool_pmu_open(evsel, threads, -- start_cpu_map_idx, -- end_cpu_map_idx); -- } -- - for (idx = start_cpu_map_idx; idx < end_cpu_map_idx; idx++) { - - for (thread = 0; thread < nthreads; thread++) { -@@ -2138,6 +2336,46 @@ retry_open: - if (!evsel->cgrp && !evsel->core.system_wide) - pid = perf_thread_map__pid(threads, thread); - -+ if (evsel__tool_event(evsel) == PERF_TOOL_USER_TIME || -+ evsel__tool_event(evsel) == PERF_TOOL_SYSTEM_TIME) { -+ bool system = evsel__tool_event(evsel) == PERF_TOOL_SYSTEM_TIME; -+ __u64 *start_time = NULL; -+ -+ if (evsel->core.attr.sample_period) { -+ /* no sampling */ -+ err = -EINVAL; -+ goto out_close; -+ } -+ if (pid > -1) { -+ char buf[64]; -+ -+ snprintf(buf, sizeof(buf), "/proc/%d/stat", pid); -+ fd = open(buf, O_RDONLY); -+ evsel->pid_stat = true; -+ } else { -+ fd = open("/proc/stat", O_RDONLY); -+ } -+ FD(evsel, idx, thread) = fd; -+ if (fd < 0) { -+ err = -errno; -+ goto out_close; -+ } -+ start_time = xyarray__entry(evsel->start_times, idx, thread); -+ if (pid > -1) { -+ err = read_pid_stat_field(fd, system ? 15 : 14, -+ start_time); -+ } else { -+ struct perf_cpu cpu; -+ -+ cpu = perf_cpu_map__cpu(evsel->core.cpus, idx); -+ err = read_stat_field(fd, cpu, system ? 3 : 1, -+ start_time); -+ } -+ if (err) -+ goto out_close; -+ continue; -+ } -+ - group_fd = get_group_fd(evsel, idx, thread); - - if (group_fd == -2) { ---- a/tools/perf/util/evsel.h -+++ b/tools/perf/util/evsel.h -@@ -11,7 +11,6 @@ - #include - #include "symbol_conf.h" - #include "pmus.h" --#include "pmu.h" - - struct bpf_object; - struct cgroup; -@@ -23,9 +22,25 @@ struct target; - struct hashmap; - struct bperf_leader_bpf; - struct bperf_follower_bpf; -+struct perf_pmu; - - typedef int (evsel__sb_cb_t)(union perf_event *event, void *data); - -+enum perf_tool_event { -+ PERF_TOOL_NONE = 0, -+ PERF_TOOL_DURATION_TIME = 1, -+ PERF_TOOL_USER_TIME = 2, -+ PERF_TOOL_SYSTEM_TIME = 3, -+ -+ PERF_TOOL_MAX, -+}; -+ -+const char *perf_tool_event__to_str(enum perf_tool_event ev); -+enum perf_tool_event perf_tool_event__from_str(const char *str); -+ -+#define perf_tool_event__for_each_event(ev) \ -+ for ((ev) = PERF_TOOL_DURATION_TIME; (ev) < PERF_TOOL_MAX; ev++) -+ - /** struct evsel - event selector - * - * @evlist - evlist this evsel is in, if it is in one. -@@ -68,6 +83,7 @@ struct evsel { - const char *unit; - struct cgroup *cgrp; - const char *metric_id; -+ enum perf_tool_event tool_event; - /* parse modifier helper */ - int exclude_GH; - int sample_read; -@@ -307,11 +323,21 @@ const char *evsel__name(struct evsel *ev - bool evsel__name_is(struct evsel *evsel, const char *name); - const char *evsel__metric_id(const struct evsel *evsel); - -+static inline bool evsel__is_tool(const struct evsel *evsel) -+{ -+ return evsel->tool_event != PERF_TOOL_NONE; -+} -+ - static inline bool evsel__is_retire_lat(const struct evsel *evsel) - { - return evsel->retire_lat; - } - -+static inline enum perf_tool_event evsel__tool_event(const struct evsel *evsel) -+{ -+ return evsel->tool_event; -+} -+ - const char *evsel__group_name(struct evsel *evsel); - int evsel__group_desc(struct evsel *evsel, char *buf, size_t size); - ---- a/tools/perf/util/metricgroup.c -+++ b/tools/perf/util/metricgroup.c -@@ -14,7 +14,6 @@ - #include "pmus.h" - #include "print-events.h" - #include "smt.h" --#include "tool_pmu.h" - #include "expr.h" - #include "rblist.h" - #include ---- a/tools/perf/util/parse-events.c -+++ b/tools/perf/util/parse-events.c -@@ -302,6 +302,38 @@ static int add_event(struct list_head *l - alternate_hw_config) ? 0 : -ENOMEM; - } - -+static int add_event_tool(struct list_head *list, int *idx, -+ enum perf_tool_event tool_event) -+{ -+ struct evsel *evsel; -+ struct perf_event_attr attr = { -+ .type = PERF_TYPE_SOFTWARE, -+ .config = PERF_COUNT_SW_DUMMY, -+ }; -+ struct perf_cpu_map *cpu_list = NULL; -+ -+ if (tool_event == PERF_TOOL_DURATION_TIME) { -+ /* Duration time is gathered globally, pretend it is only on CPU0. */ -+ cpu_list = perf_cpu_map__new("0"); -+ } -+ evsel = __add_event(list, idx, &attr, /*init_attr=*/true, /*name=*/NULL, -+ /*metric_id=*/NULL, /*pmu=*/NULL, -+ /*config_terms=*/NULL, /*auto_merge_stats=*/false, -+ cpu_list, -+ /*alternate_hw_config=*/PERF_COUNT_HW_MAX); -+ perf_cpu_map__put(cpu_list); -+ if (!evsel) -+ return -ENOMEM; -+ evsel->tool_event = tool_event; -+ if (tool_event == PERF_TOOL_DURATION_TIME -+ || tool_event == PERF_TOOL_USER_TIME -+ || tool_event == PERF_TOOL_SYSTEM_TIME) { -+ free((char *)evsel->unit); -+ evsel->unit = strdup("ns"); -+ } -+ return 0; -+} -+ - /** - * parse_aliases - search names for entries beginning or equalling str ignoring - * case. If mutliple entries in names match str then the longest -@@ -1398,6 +1430,13 @@ int parse_events_add_numeric(struct pars - type, /*extended_type=*/0, config, head_config); - } - -+int parse_events_add_tool(struct parse_events_state *parse_state, -+ struct list_head *list, -+ int tool_event) -+{ -+ return add_event_tool(list, &parse_state->idx, tool_event); -+} -+ - static bool config_term_percore(struct list_head *config_terms) - { - struct evsel_config_term *term; ---- a/tools/perf/util/parse-events.h -+++ b/tools/perf/util/parse-events.h -@@ -227,6 +227,9 @@ int parse_events_add_numeric(struct pars - u32 type, u64 config, - const struct parse_events_terms *head_config, - bool wildcard); -+int parse_events_add_tool(struct parse_events_state *parse_state, -+ struct list_head *list, -+ int tool_event); - int parse_events_add_cache(struct list_head *list, int *idx, const char *name, - struct parse_events_state *parse_state, - struct parse_events_terms *parsed_terms); ---- a/tools/perf/util/parse-events.l -+++ b/tools/perf/util/parse-events.l -@@ -121,6 +121,14 @@ static int sym(yyscan_t scanner, int typ - return type == PERF_TYPE_HARDWARE ? PE_VALUE_SYM_HW : PE_VALUE_SYM_SW; - } - -+static int tool(yyscan_t scanner, enum perf_tool_event event) -+{ -+ YYSTYPE *yylval = parse_events_get_lval(scanner); -+ -+ yylval->num = event; -+ return PE_VALUE_SYM_TOOL; -+} -+ - static int term(yyscan_t scanner, enum parse_events__term_type type) - { - YYSTYPE *yylval = parse_events_get_lval(scanner); -@@ -396,6 +404,9 @@ cpu-migrations|migrations { return sym - alignment-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_ALIGNMENT_FAULTS); } - emulation-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS); } - dummy { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_DUMMY); } -+duration_time { return tool(yyscanner, PERF_TOOL_DURATION_TIME); } -+user_time { return tool(yyscanner, PERF_TOOL_USER_TIME); } -+system_time { return tool(yyscanner, PERF_TOOL_SYSTEM_TIME); } - bpf-output { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_BPF_OUTPUT); } - cgroup-switches { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CGROUP_SWITCHES); } - ---- a/tools/perf/util/parse-events.y -+++ b/tools/perf/util/parse-events.y -@@ -56,6 +56,7 @@ static void free_list_evsel(struct list_ - - %token PE_START_EVENTS PE_START_TERMS - %token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_TERM -+%token PE_VALUE_SYM_TOOL - %token PE_EVENT_NAME - %token PE_RAW PE_NAME - %token PE_MODIFIER_EVENT PE_MODIFIER_BP PE_BP_COLON PE_BP_SLASH -@@ -67,6 +68,7 @@ static void free_list_evsel(struct list_ - %type PE_VALUE - %type PE_VALUE_SYM_HW - %type PE_VALUE_SYM_SW -+%type PE_VALUE_SYM_TOOL - %type PE_MODIFIER_EVENT - %type PE_TERM - %type value_sym -@@ -348,6 +350,20 @@ value_sym sep_slash_slash_dc - PE_ABORT(err); - $$ = list; - } -+| -+PE_VALUE_SYM_TOOL sep_slash_slash_dc -+{ -+ struct list_head *list; -+ int err; -+ -+ list = alloc_list(); -+ if (!list) -+ YYNOMEM; -+ err = parse_events_add_tool(_parse_state, list, $1); -+ if (err) -+ YYNOMEM; -+ $$ = list; -+} - - event_legacy_cache: - PE_LEGACY_CACHE opt_event_config ---- a/tools/perf/util/pmu.c -+++ b/tools/perf/util/pmu.c -@@ -19,7 +19,6 @@ - #include "evsel.h" - #include "pmu.h" - #include "pmus.h" --#include "tool_pmu.h" - #include - #include - #include "parse-events.h" -@@ -1512,9 +1511,6 @@ int perf_pmu__config(struct perf_pmu *pm - { - bool zero = !!pmu->perf_event_attr_init_default; - -- if (perf_pmu__is_tool(pmu)) -- return tool_pmu__config_terms(attr, head_terms, err); -- - /* Fake PMU doesn't have proper terms so nothing to configure in attr. */ - if (perf_pmu__is_fake(pmu)) - return 0; -@@ -1627,8 +1623,8 @@ int perf_pmu__check_alias(struct perf_pm - info->scale = 0.0; - info->snapshot = false; - -- /* Tool/fake PMU doesn't rewrite terms. */ -- if (perf_pmu__is_tool(pmu) || perf_pmu__is_fake(pmu)) -+ /* Fake PMU doesn't rewrite terms. */ -+ if (perf_pmu__is_fake(pmu)) - goto out; - - list_for_each_entry_safe(term, h, &head_terms->terms, list) { -@@ -1798,8 +1794,6 @@ bool perf_pmu__have_event(struct perf_pm - { - if (!name) - return false; -- if (perf_pmu__is_tool(pmu)) -- return perf_tool_event__from_str(name) != PERF_TOOL_NONE; - if (perf_pmu__find_alias(pmu, name, /*load=*/ true) != NULL) - return true; - if (pmu->cpu_aliases_added || !pmu->events_table) -@@ -1811,9 +1805,6 @@ size_t perf_pmu__num_events(struct perf_ - { - size_t nr; - -- if (perf_pmu__is_tool(pmu)) -- return tool_pmu__num_events(); -- - pmu_aliases_parse(pmu); - nr = pmu->sysfs_aliases + pmu->sys_json_aliases; - -@@ -1875,9 +1866,6 @@ int perf_pmu__for_each_event(struct perf - int ret = 0; - struct strbuf sb; - -- if (perf_pmu__is_tool(pmu)) -- return tool_pmu__for_each_event_cb(pmu, state, cb); -- - strbuf_init(&sb, /*hint=*/ 0); - pmu_aliases_parse(pmu); - pmu_add_cpu_aliases(pmu); -@@ -1966,7 +1954,6 @@ bool perf_pmu__is_software(const struct - case PERF_TYPE_HW_CACHE: return false; - case PERF_TYPE_RAW: return false; - case PERF_TYPE_BREAKPOINT: return true; -- case PERF_PMU_TYPE_TOOL: return true; - default: break; - } - for (size_t i = 0; i < ARRAY_SIZE(known_sw_pmus); i++) { -@@ -2294,9 +2281,6 @@ const char *perf_pmu__name_from_config(s - if (!pmu) - return NULL; - -- if (perf_pmu__is_tool(pmu)) -- return perf_tool_event__to_str(config); -- - pmu_aliases_parse(pmu); - pmu_add_cpu_aliases(pmu); - list_for_each_entry(event, &pmu->aliases, list) { ---- a/tools/perf/util/pmu.h -+++ b/tools/perf/util/pmu.h -@@ -37,7 +37,6 @@ struct perf_pmu_caps { - }; - - enum { -- PERF_PMU_TYPE_TOOL = 0xFFFFFFFE, - PERF_PMU_TYPE_FAKE = 0xFFFFFFFF, - }; - -@@ -286,7 +285,6 @@ struct perf_pmu *perf_pmu__lookup(struct - struct perf_pmu *perf_pmu__create_placeholder_core_pmu(struct list_head *core_pmus); - void perf_pmu__delete(struct perf_pmu *pmu); - struct perf_pmu *perf_pmus__find_core_pmu(void); -- - const char *perf_pmu__name_from_config(struct perf_pmu *pmu, u64 config); - - #endif /* __PMU_H */ ---- a/tools/perf/util/pmus.c -+++ b/tools/perf/util/pmus.c -@@ -15,7 +15,6 @@ - #include "evsel.h" - #include "pmus.h" - #include "pmu.h" --#include "tool_pmu.h" - #include "print-events.h" - #include "strbuf.h" - -@@ -201,7 +200,6 @@ static void pmu_read_sysfs(bool core_onl - int fd; - DIR *dir; - struct dirent *dent; -- struct perf_pmu *tool_pmu; - - if (read_sysfs_all_pmus || (core_only && read_sysfs_core_pmus)) - return; -@@ -231,10 +229,6 @@ static void pmu_read_sysfs(bool core_onl - pr_err("Failure to set up any core PMUs\n"); - } - list_sort(NULL, &core_pmus, pmus_cmp); -- if (!core_only) { -- tool_pmu = perf_pmus__tool_pmu(); -- list_add_tail(&tool_pmu->list, &other_pmus); -- } - list_sort(NULL, &other_pmus, pmus_cmp); - if (!list_empty(&core_pmus)) { - read_sysfs_core_pmus = true; -@@ -590,9 +584,6 @@ void perf_pmus__print_raw_pmu_events(con - int len = pmu_name_len_no_suffix(pmu->name); - const char *desc = "(see 'man perf-list' or 'man perf-record' on how to encode it)"; - -- if (perf_pmu__is_tool(pmu)) -- continue; -- - if (!pmu->is_core) - desc = NULL; - ---- a/tools/perf/util/print-events.c -+++ b/tools/perf/util/print-events.c -@@ -29,7 +29,6 @@ - #include "tracepoint.h" - #include "pfm.h" - #include "thread_map.h" --#include "tool_pmu.h" - #include "util.h" - - #define MAX_NAME_LEN 100 -@@ -44,6 +43,21 @@ static const char * const event_type_des - "Hardware breakpoint", - }; - -+static const struct event_symbol event_symbols_tool[PERF_TOOL_MAX] = { -+ [PERF_TOOL_DURATION_TIME] = { -+ .symbol = "duration_time", -+ .alias = "", -+ }, -+ [PERF_TOOL_USER_TIME] = { -+ .symbol = "user_time", -+ .alias = "", -+ }, -+ [PERF_TOOL_SYSTEM_TIME] = { -+ .symbol = "system_time", -+ .alias = "", -+ }, -+}; -+ - /* - * Print the events from /tracing/events - */ -@@ -328,6 +342,24 @@ int print_hwcache_events(const struct pr - return 0; - } - -+void print_tool_events(const struct print_callbacks *print_cb, void *print_state) -+{ -+ // Start at 1 because the first enum entry means no tool event. -+ for (int i = 1; i < PERF_TOOL_MAX; ++i) { -+ print_cb->print_event(print_state, -+ "tool", -+ /*pmu_name=*/NULL, -+ event_symbols_tool[i].symbol, -+ event_symbols_tool[i].alias, -+ /*scale_unit=*/NULL, -+ /*deprecated=*/false, -+ "Tool event", -+ /*desc=*/NULL, -+ /*long_desc=*/NULL, -+ /*encoding_desc=*/NULL); -+ } -+} -+ - void print_symbol_events(const struct print_callbacks *print_cb, void *print_state, - unsigned int type, const struct event_symbol *syms, - unsigned int max) -@@ -391,6 +423,8 @@ void print_events(const struct print_cal - print_symbol_events(print_cb, print_state, PERF_TYPE_SOFTWARE, - event_symbols_sw, PERF_COUNT_SW_MAX); - -+ print_tool_events(print_cb, print_state); -+ - print_hwcache_events(print_cb, print_state); - - perf_pmus__print_pmu_events(print_cb, print_state); ---- a/tools/perf/util/print-events.h -+++ b/tools/perf/util/print-events.h -@@ -36,6 +36,7 @@ void print_sdt_events(const struct print - void print_symbol_events(const struct print_callbacks *print_cb, void *print_state, - unsigned int type, const struct event_symbol *syms, - unsigned int max); -+void print_tool_events(const struct print_callbacks *print_cb, void *print_state); - void print_tracepoint_events(const struct print_callbacks *print_cb, void *print_state); - bool is_event_supported(u8 type, u64 config); - ---- a/tools/perf/util/stat-display.c -+++ b/tools/perf/util/stat-display.c -@@ -21,7 +21,6 @@ - #include "iostat.h" - #include "pmu.h" - #include "pmus.h" --#include "tool_pmu.h" - - #define CNTR_NOT_SUPPORTED "" - #define CNTR_NOT_COUNTED "" -@@ -947,10 +946,7 @@ static bool should_skip_zero_counter(str - if (config->aggr_mode == AGGR_THREAD && config->system_wide) - return true; - -- /* -- * Many tool events are only gathered on the first index, skip other -- * zero values. -- */ -+ /* Tool events have the software PMU but are only gathered on 1. */ - if (evsel__is_tool(counter)) - return true; - ---- a/tools/perf/util/stat-shadow.c -+++ b/tools/perf/util/stat-shadow.c -@@ -15,7 +15,6 @@ - #include - #include "iostat.h" - #include "util/hashmap.h" --#include "tool_pmu.h" - - struct stats walltime_nsecs_stats; - struct rusage_stats ru_stats; ---- a/tools/perf/util/tool_pmu.c -+++ /dev/null -@@ -1,411 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0-only --#include "cgroup.h" --#include "counts.h" --#include "evsel.h" --#include "pmu.h" --#include "print-events.h" --#include "time-utils.h" --#include "tool_pmu.h" --#include --#include --#include --#include --#include -- --static const char *const tool_pmu__event_names[PERF_TOOL_MAX] = { -- NULL, -- "duration_time", -- "user_time", -- "system_time", --}; -- -- --const char *perf_tool_event__to_str(enum perf_tool_event ev) --{ -- if (ev > PERF_TOOL_NONE && ev < PERF_TOOL_MAX) -- return tool_pmu__event_names[ev]; -- -- return NULL; --} -- --enum perf_tool_event perf_tool_event__from_str(const char *str) --{ -- int i; -- -- perf_tool_event__for_each_event(i) { -- if (!strcasecmp(str, tool_pmu__event_names[i])) -- return i; -- } -- return PERF_TOOL_NONE; --} -- --static int tool_pmu__config_term(struct perf_event_attr *attr, -- struct parse_events_term *term, -- struct parse_events_error *err) --{ -- if (term->type_term == PARSE_EVENTS__TERM_TYPE_USER) { -- enum perf_tool_event ev = perf_tool_event__from_str(term->config); -- -- if (ev == PERF_TOOL_NONE) -- goto err_out; -- -- attr->config = ev; -- return 0; -- } --err_out: -- if (err) { -- char *err_str; -- -- parse_events_error__handle(err, term->err_val, -- asprintf(&err_str, -- "unexpected tool event term (%s) %s", -- parse_events__term_type_str(term->type_term), -- term->config) < 0 -- ? strdup("unexpected tool event term") -- : err_str, -- NULL); -- } -- return -EINVAL; --} -- --int tool_pmu__config_terms(struct perf_event_attr *attr, -- struct parse_events_terms *terms, -- struct parse_events_error *err) --{ -- struct parse_events_term *term; -- -- list_for_each_entry(term, &terms->terms, list) { -- if (tool_pmu__config_term(attr, term, err)) -- return -EINVAL; -- } -- -- return 0; -- --} -- --int tool_pmu__for_each_event_cb(struct perf_pmu *pmu, void *state, pmu_event_callback cb) --{ -- struct pmu_event_info info = { -- .pmu = pmu, -- .event_type_desc = "Tool event", -- }; -- int i; -- -- perf_tool_event__for_each_event(i) { -- int ret; -- -- info.name = perf_tool_event__to_str(i); -- info.alias = NULL; -- info.scale_unit = NULL; -- info.desc = NULL; -- info.long_desc = NULL; -- info.encoding_desc = NULL; -- info.topic = NULL; -- info.pmu_name = pmu->name; -- info.deprecated = false; -- ret = cb(state, &info); -- if (ret) -- return ret; -- } -- return 0; --} -- --bool perf_pmu__is_tool(const struct perf_pmu *pmu) --{ -- return pmu && pmu->type == PERF_PMU_TYPE_TOOL; --} -- --bool evsel__is_tool(const struct evsel *evsel) --{ -- return perf_pmu__is_tool(evsel->pmu); --} -- --enum perf_tool_event evsel__tool_event(const struct evsel *evsel) --{ -- if (!evsel__is_tool(evsel)) -- return PERF_TOOL_NONE; -- -- return (enum perf_tool_event)evsel->core.attr.config; --} -- --const char *evsel__tool_pmu_event_name(const struct evsel *evsel) --{ -- return perf_tool_event__to_str(evsel->core.attr.config); --} -- --static bool read_until_char(struct io *io, char e) --{ -- int c; -- -- do { -- c = io__get_char(io); -- if (c == -1) -- return false; -- } while (c != e); -- return true; --} -- --static int read_stat_field(int fd, struct perf_cpu cpu, int field, __u64 *val) --{ -- char buf[256]; -- struct io io; -- int i; -- -- io__init(&io, fd, buf, sizeof(buf)); -- -- /* Skip lines to relevant CPU. */ -- for (i = -1; i < cpu.cpu; i++) { -- if (!read_until_char(&io, '\n')) -- return -EINVAL; -- } -- /* Skip to "cpu". */ -- if (io__get_char(&io) != 'c') return -EINVAL; -- if (io__get_char(&io) != 'p') return -EINVAL; -- if (io__get_char(&io) != 'u') return -EINVAL; -- -- /* Skip N of cpuN. */ -- if (!read_until_char(&io, ' ')) -- return -EINVAL; -- -- i = 1; -- while (true) { -- if (io__get_dec(&io, val) != ' ') -- break; -- if (field == i) -- return 0; -- i++; -- } -- return -EINVAL; --} -- --static int read_pid_stat_field(int fd, int field, __u64 *val) --{ -- char buf[256]; -- struct io io; -- int c, i; -- -- io__init(&io, fd, buf, sizeof(buf)); -- if (io__get_dec(&io, val) != ' ') -- return -EINVAL; -- if (field == 1) -- return 0; -- -- /* Skip comm. */ -- if (io__get_char(&io) != '(' || !read_until_char(&io, ')')) -- return -EINVAL; -- if (field == 2) -- return -EINVAL; /* String can't be returned. */ -- -- /* Skip state */ -- if (io__get_char(&io) != ' ' || io__get_char(&io) == -1) -- return -EINVAL; -- if (field == 3) -- return -EINVAL; /* String can't be returned. */ -- -- /* Loop over numeric fields*/ -- if (io__get_char(&io) != ' ') -- return -EINVAL; -- -- i = 4; -- while (true) { -- c = io__get_dec(&io, val); -- if (c == -1) -- return -EINVAL; -- if (c == -2) { -- /* Assume a -ve was read */ -- c = io__get_dec(&io, val); -- *val *= -1; -- } -- if (c != ' ') -- return -EINVAL; -- if (field == i) -- return 0; -- i++; -- } -- return -EINVAL; --} -- --int evsel__tool_pmu_prepare_open(struct evsel *evsel, -- struct perf_cpu_map *cpus, -- int nthreads) --{ -- if ((evsel__tool_event(evsel) == PERF_TOOL_SYSTEM_TIME || -- evsel__tool_event(evsel) == PERF_TOOL_USER_TIME) && -- !evsel->start_times) { -- evsel->start_times = xyarray__new(perf_cpu_map__nr(cpus), -- nthreads, -- sizeof(__u64)); -- if (!evsel->start_times) -- return -ENOMEM; -- } -- return 0; --} -- --#define FD(e, x, y) (*(int *)xyarray__entry(e->core.fd, x, y)) -- --int evsel__tool_pmu_open(struct evsel *evsel, -- struct perf_thread_map *threads, -- int start_cpu_map_idx, int end_cpu_map_idx) --{ -- enum perf_tool_event ev = evsel__tool_event(evsel); -- int pid = -1, idx = 0, thread = 0, nthreads, err = 0, old_errno; -- -- if (ev == PERF_TOOL_DURATION_TIME) { -- if (evsel->core.attr.sample_period) /* no sampling */ -- return -EINVAL; -- evsel->start_time = rdclock(); -- return 0; -- } -- -- if (evsel->cgrp) -- pid = evsel->cgrp->fd; -- -- nthreads = perf_thread_map__nr(threads); -- for (idx = start_cpu_map_idx; idx < end_cpu_map_idx; idx++) { -- for (thread = 0; thread < nthreads; thread++) { -- if (thread >= nthreads) -- break; -- -- if (!evsel->cgrp && !evsel->core.system_wide) -- pid = perf_thread_map__pid(threads, thread); -- -- if (ev == PERF_TOOL_USER_TIME || ev == PERF_TOOL_SYSTEM_TIME) { -- bool system = ev == PERF_TOOL_SYSTEM_TIME; -- __u64 *start_time = NULL; -- int fd; -- -- if (evsel->core.attr.sample_period) { -- /* no sampling */ -- err = -EINVAL; -- goto out_close; -- } -- if (pid > -1) { -- char buf[64]; -- -- snprintf(buf, sizeof(buf), "/proc/%d/stat", pid); -- fd = open(buf, O_RDONLY); -- evsel->pid_stat = true; -- } else { -- fd = open("/proc/stat", O_RDONLY); -- } -- FD(evsel, idx, thread) = fd; -- if (fd < 0) { -- err = -errno; -- goto out_close; -- } -- start_time = xyarray__entry(evsel->start_times, idx, thread); -- if (pid > -1) { -- err = read_pid_stat_field(fd, system ? 15 : 14, -- start_time); -- } else { -- struct perf_cpu cpu; -- -- cpu = perf_cpu_map__cpu(evsel->core.cpus, idx); -- err = read_stat_field(fd, cpu, system ? 3 : 1, -- start_time); -- } -- if (err) -- goto out_close; -- } -- -- } -- } -- return 0; --out_close: -- if (err) -- threads->err_thread = thread; -- -- old_errno = errno; -- do { -- while (--thread >= 0) { -- if (FD(evsel, idx, thread) >= 0) -- close(FD(evsel, idx, thread)); -- FD(evsel, idx, thread) = -1; -- } -- thread = nthreads; -- } while (--idx >= 0); -- errno = old_errno; -- return err; --} -- --int evsel__read_tool(struct evsel *evsel, int cpu_map_idx, int thread) --{ -- __u64 *start_time, cur_time, delta_start; -- int fd, err = 0; -- struct perf_counts_values *count; -- bool adjust = false; -- -- count = perf_counts(evsel->counts, cpu_map_idx, thread); -- -- switch (evsel__tool_event(evsel)) { -- case PERF_TOOL_DURATION_TIME: -- /* -- * Pretend duration_time is only on the first CPU and thread, or -- * else aggregation will scale duration_time by the number of -- * CPUs/threads. -- */ -- start_time = &evsel->start_time; -- if (cpu_map_idx == 0 && thread == 0) -- cur_time = rdclock(); -- else -- cur_time = *start_time; -- break; -- case PERF_TOOL_USER_TIME: -- case PERF_TOOL_SYSTEM_TIME: { -- bool system = evsel__tool_event(evsel) == PERF_TOOL_SYSTEM_TIME; -- -- start_time = xyarray__entry(evsel->start_times, cpu_map_idx, thread); -- fd = FD(evsel, cpu_map_idx, thread); -- lseek(fd, SEEK_SET, 0); -- if (evsel->pid_stat) { -- /* The event exists solely on 1 CPU. */ -- if (cpu_map_idx == 0) -- err = read_pid_stat_field(fd, system ? 15 : 14, &cur_time); -- else -- cur_time = 0; -- } else { -- /* The event is for all threads. */ -- if (thread == 0) { -- struct perf_cpu cpu = perf_cpu_map__cpu(evsel->core.cpus, -- cpu_map_idx); -- -- err = read_stat_field(fd, cpu, system ? 3 : 1, &cur_time); -- } else { -- cur_time = 0; -- } -- } -- adjust = true; -- break; -- } -- case PERF_TOOL_NONE: -- case PERF_TOOL_MAX: -- default: -- err = -EINVAL; -- } -- if (err) -- return err; -- -- delta_start = cur_time - *start_time; -- if (adjust) { -- __u64 ticks_per_sec = sysconf(_SC_CLK_TCK); -- -- delta_start *= 1000000000 / ticks_per_sec; -- } -- count->val = delta_start; -- count->ena = count->run = delta_start; -- count->lost = 0; -- return 0; --} -- --struct perf_pmu *perf_pmus__tool_pmu(void) --{ -- static struct perf_pmu tool = { -- .name = "tool", -- .type = PERF_PMU_TYPE_TOOL, -- .aliases = LIST_HEAD_INIT(tool.aliases), -- .caps = LIST_HEAD_INIT(tool.caps), -- .format = LIST_HEAD_INIT(tool.format), -- }; -- -- return &tool; --} ---- a/tools/perf/util/tool_pmu.h -+++ /dev/null -@@ -1,51 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --#ifndef __TOOL_PMU_H --#define __TOOL_PMU_H -- --#include "pmu.h" -- --struct evsel; --struct perf_thread_map; --struct print_callbacks; -- --enum perf_tool_event { -- PERF_TOOL_NONE = 0, -- PERF_TOOL_DURATION_TIME = 1, -- PERF_TOOL_USER_TIME = 2, -- PERF_TOOL_SYSTEM_TIME = 3, -- -- PERF_TOOL_MAX, --}; -- --#define perf_tool_event__for_each_event(ev) \ -- for ((ev) = PERF_TOOL_DURATION_TIME; (ev) < PERF_TOOL_MAX; ev++) -- --static inline size_t tool_pmu__num_events(void) --{ -- return PERF_TOOL_MAX - 1; --} -- --const char *perf_tool_event__to_str(enum perf_tool_event ev); --enum perf_tool_event perf_tool_event__from_str(const char *str); --int tool_pmu__config_terms(struct perf_event_attr *attr, -- struct parse_events_terms *terms, -- struct parse_events_error *err); --int tool_pmu__for_each_event_cb(struct perf_pmu *pmu, void *state, pmu_event_callback cb); -- --bool perf_pmu__is_tool(const struct perf_pmu *pmu); -- -- --bool evsel__is_tool(const struct evsel *evsel); --enum perf_tool_event evsel__tool_event(const struct evsel *evsel); --const char *evsel__tool_pmu_event_name(const struct evsel *evsel); --int evsel__tool_pmu_prepare_open(struct evsel *evsel, -- struct perf_cpu_map *cpus, -- int nthreads); --int evsel__tool_pmu_open(struct evsel *evsel, -- struct perf_thread_map *threads, -- int start_cpu_map_idx, int end_cpu_map_idx); --int evsel__read_tool(struct evsel *evsel, int cpu_map_idx, int thread); -- --struct perf_pmu *perf_pmus__tool_pmu(void); -- --#endif /* __TOOL_PMU_H */ diff --git a/target/linux/generic/backport-6.12/720-09-v6.14-net-phy-Constify-struct-mdio_device_id.patch b/target/linux/generic/backport-6.12/720-09-v6.14-net-phy-Constify-struct-mdio_device_id.patch index 7cd13deda86..1081663db16 100644 --- a/target/linux/generic/backport-6.12/720-09-v6.14-net-phy-Constify-struct-mdio_device_id.patch +++ b/target/linux/generic/backport-6.12/720-09-v6.14-net-phy-Constify-struct-mdio_device_id.patch @@ -304,7 +304,7 @@ Signed-off-by: Jakub Kicinski { } --- a/drivers/net/phy/dp83tc811.c +++ b/drivers/net/phy/dp83tc811.c -@@ -403,7 +403,7 @@ static struct phy_driver dp83811_driver[ +@@ -404,7 +404,7 @@ static struct phy_driver dp83811_driver[ }; module_phy_driver(dp83811_driver); diff --git a/target/linux/generic/kernel-6.12 b/target/linux/generic/kernel-6.12 index d051e365111..7c860e73950 100644 --- a/target/linux/generic/kernel-6.12 +++ b/target/linux/generic/kernel-6.12 @@ -1,2 +1,2 @@ -LINUX_VERSION-6.12 = .91 -LINUX_KERNEL_HASH-6.12.91 = 0ff2ab9e169f9f1948557471fbb450d3018f8c5b77caf288e1a3982582597969 +LINUX_VERSION-6.12 = .92 +LINUX_KERNEL_HASH-6.12.92 = 0fe376b7db3cac4456b38291bee4faa7091cb8befaa6f9870314f5d1282f9e3e diff --git a/target/linux/generic/pending-6.12/834-ledtrig-libata.patch b/target/linux/generic/pending-6.12/834-ledtrig-libata.patch index f4458afb127..72abaeab992 100644 --- a/target/linux/generic/pending-6.12/834-ledtrig-libata.patch +++ b/target/linux/generic/pending-6.12/834-ledtrig-libata.patch @@ -132,7 +132,7 @@ Signed-off-by: Daniel Golle /* * Define if arch has non-standard setup. This is a _PCI_ standard -@@ -937,6 +940,10 @@ struct ata_port { +@@ -938,6 +941,10 @@ struct ata_port { #ifdef CONFIG_ATA_ACPI struct ata_acpi_gtm __acpi_init_gtm; /* use ata_acpi_init_gtm() */ #endif