* [PATCH v4 0/3] PCI Controller event and LTSSM tracepoint support
From: Shawn Lin @ 2026-01-22 2:02 UTC (permalink / raw)
To: Manivannan Sadhasivam, Bjorn Helgaas
Cc: linux-rockchip, linux-pci, linux-trace-kernel, linux-doc,
Steven Rostedt, Masami Hiramatsu, Shawn Lin
This patch-set adds new pci controller event and LTSSM tracepoint used by host drivers
which provide LTSSM trace functionality. The first user is pcie-dw-rockchip with a 256
Bytes FIFO for recording LTSSM transition.
Testing
=========
This series was tested on RK3588/RK3588s EVB1 with NVMe SSD connected to PCIe3 and PCIe2
root ports.
echo 1 > /sys/kernel/debug/tracing/events/pci_controller/pcie_ltssm_state_transition/enable
cat /sys/kernel/debug/tracing/trace_pipe
# tracer: nop
#
# entries-in-buffer/entries-written: 64/64 #P:8
#
# _-----=> irqs-off/BH-disabled
# / _----=> need-resched
# | / _---=> hardirq/softirq
# || / _--=> preempt-depth
# ||| / _-=> migrate-disable
# |||| / delay
# TASK-PID CPU# ||||| TIMESTAMP FUNCTION
# | | | ||||| | |
kworker/0:0-9 [000] ..... 5.600194: pcie_ltssm_state_transition: dev: a40000000.pcie state: DETECT_ACT rate: Unknown
kworker/0:0-9 [000] ..... 5.600198: pcie_ltssm_state_transition: dev: a40000000.pcie state: DETECT_WAIT rate: Unknown
kworker/0:0-9 [000] ..... 5.600199: pcie_ltssm_state_transition: dev: a40000000.pcie state: DETECT_ACT rate: Unknown
kworker/0:0-9 [000] ..... 5.600201: pcie_ltssm_state_transition: dev: a40000000.pcie state: POLL_ACTIVE rate: Unknown
kworker/0:0-9 [000] ..... 5.600202: pcie_ltssm_state_transition: dev: a40000000.pcie state: POLL_CONFIG rate: Unknown
kworker/0:0-9 [000] ..... 5.600204: pcie_ltssm_state_transition: dev: a40000000.pcie state: CFG_LINKWD_START rate: Unknown
kworker/0:0-9 [000] ..... 5.600206: pcie_ltssm_state_transition: dev: a40000000.pcie state: CFG_LINKWD_ACEPT rate: Unknown
kworker/0:0-9 [000] ..... 5.600207: pcie_ltssm_state_transition: dev: a40000000.pcie state: CFG_LANENUM_WAI rate: Unknown
kworker/0:0-9 [000] ..... 5.600208: pcie_ltssm_state_transition: dev: a40000000.pcie state: CFG_LANENUM_ACEPT rate: Unknown
kworker/0:0-9 [000] ..... 5.600210: pcie_ltssm_state_transition: dev: a40000000.pcie state: CFG_COMPLETE rate: Unknown
kworker/0:0-9 [000] ..... 5.600212: pcie_ltssm_state_transition: dev: a40000000.pcie state: CFG_IDLE rate: Unknown
kworker/0:0-9 [000] ..... 5.600213: pcie_ltssm_state_transition: dev: a40000000.pcie state: L0 rate: 2.5 GT/s
kworker/0:0-9 [000] ..... 5.600214: pcie_ltssm_state_transition: dev: a40000000.pcie state: RCVRY_LOCK rate: Unknown
kworker/0:0-9 [000] ..... 5.600216: pcie_ltssm_state_transition: dev: a40000000.pcie state: RCVRY_RCVRCFG rate: Unknown
kworker/0:0-9 [000] ..... 5.600217: pcie_ltssm_state_transition: dev: a40000000.pcie state: RCVRY_SPEED rate: Unknown
kworker/0:0-9 [000] ..... 5.600218: pcie_ltssm_state_transition: dev: a40000000.pcie state: RCVRY_LOCK rate: Unknown
kworker/0:0-9 [000] ..... 5.600220: pcie_ltssm_state_transition: dev: a40000000.pcie state: RCVRY_EQ1 rate: Unknown
kworker/0:0-9 [000] ..... 5.600221: pcie_ltssm_state_transition: dev: a40000000.pcie state: RCVRY_EQ2 rate: 8.0 GT/s
kworker/0:0-9 [000] ..... 5.600222: pcie_ltssm_state_transition: dev: a40000000.pcie state: RCVRY_EQ3 rate: 8.0 GT/s
kworker/0:0-9 [000] ..... 5.600224: pcie_ltssm_state_transition: dev: a40000000.pcie state: RCVRY_LOCK rate: 8.0 GT/s
kworker/0:0-9 [000] ..... 5.600225: pcie_ltssm_state_transition: dev: a40000000.pcie state: RCVRY_RCVRCFG rate: 8.0 GT/s
kworker/0:0-9 [000] ..... 5.600226: pcie_ltssm_state_transition: dev: a40000000.pcie state: RCVRY_IDLE rate: 8.0 GT/s
kworker/0:0-9 [000] ..... 5.600227: pcie_ltssm_state_transition: dev: a40000000.pcie state: L0 rate: 8.0 GT/s
kworker/0:0-9 [000] ..... 5.600228: pcie_ltssm_state_transition: dev: a40000000.pcie state: RCVRY_LOCK rate: 8.0 GT/s
kworker/0:0-9 [000] ..... 5.600229: pcie_ltssm_state_transition: dev: a40000000.pcie state: RCVRY_RCVRCFG rate: 8.0 GT/s
kworker/0:0-9 [000] ..... 5.600231: pcie_ltssm_state_transition: dev: a40000000.pcie state: RCVRY_IDLE rate: 8.0 GT/s
kworker/0:0-9 [000] ..... 5.600232: pcie_ltssm_state_transition: dev: a40000000.pcie state: L0 rate: 8.0 GT/s
kworker/0:0-9 [000] ..... 5.600233: pcie_ltssm_state_transition: dev: a40000000.pcie state: L123_SEND_EIDLE rate: 8.0 GT/s
kworker/0:0-9 [000] ..... 5.600234: pcie_ltssm_state_transition: dev: a40000000.pcie state: L1_IDLE rate: 8.0 GT/s
kworker/0:0-9 [000] ..... 5.600236: pcie_ltssm_state_transition: dev: a40000000.pcie state: RCVRY_LOCK rate: 8.0 GT/s
kworker/0:0-9 [000] ..... 5.600237: pcie_ltssm_state_transition: dev: a40000000.pcie state: RCVRY_RCVRCFG rate: 8.0 GT/s
kworker/0:0-9 [000] ..... 5.600238: pcie_ltssm_state_transition: dev: a40000000.pcie state: RCVRY_IDLE rate: 8.0 GT/s
kworker/0:0-9 [000] ..... 5.600239: pcie_ltssm_state_transition: dev: a40000000.pcie state: L0 rate: 8.0 GT/s
Changes in v4:
- use TRACE_EVENT_FN to notify when to start and stop the tracepoint,
and export pci_ltssm_tp_enabled() for host drivers to use
- skip trace if pci_ltssm_tp_enabled() is false.(Steven)
- wrap into 80 columns(Bjorn)
Changes in v3:
- add TRACE_DEFINE_ENUM for all enums(Steven Rostedt)
- Add toctree entry in Documentation/trace/index.rst(Bagas Sanjaya)
- fix mismatch section underline length(Bagas Sanjaya)
- Make example snippets in code block(Bagas Sanjaya)
- warp context into 80 columns and fix the file name(Bjorn)
- reorder variables(Mani)
- rename loop to i; rename en to enable(Mani)
- use FIELD_GET(Mani)
- add comment about how the FIFO works(Mani)
Changes in v2:
- use tracepoint
Shawn Lin (3):
PCI: trace: Add PCI controller LTSSM transition tracepoint
Documentation: tracing: Add PCI controller event documentation
PCI: dw-rockchip: Add pcie_ltssm_state_transition trace support
Documentation/trace/events-pci-controller.rst | 42 ++++++++++
Documentation/trace/index.rst | 1 +
drivers/pci/controller/dwc/pcie-dw-rockchip.c | 111 ++++++++++++++++++++++++++
drivers/pci/trace.c | 20 +++++
include/linux/pci.h | 4 +
include/trace/events/pci_controller.h | 57 +++++++++++++
6 files changed, 235 insertions(+)
create mode 100644 Documentation/trace/events-pci-controller.rst
create mode 100644 include/trace/events/pci_controller.h
--
2.7.4
^ permalink raw reply
* [PATCH v4 1/3] PCI: trace: Add PCI controller LTSSM transition tracepoint
From: Shawn Lin @ 2026-01-22 2:02 UTC (permalink / raw)
To: Manivannan Sadhasivam, Bjorn Helgaas
Cc: linux-rockchip, linux-pci, linux-trace-kernel, linux-doc,
Steven Rostedt, Masami Hiramatsu, Shawn Lin
In-Reply-To: <1769047340-113287-1-git-send-email-shawn.lin@rock-chips.com>
Some platforms may provide LTSSM trace functionality, recording historical
LTSSM state transition information. This is very useful for debugging, such
as when certain devices cannot be recognized or link broken during test.
Implement the pci controller tracepoint for recording LTSSM and rate.
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---
Changes in v4:
- use TRACE_EVENT_FN to notify when to start and stop the tracepoint,
and export pci_ltssm_tp_enabled() for host drivers to use
Changes in v3:
- add TRACE_DEFINE_ENUM for all enums(Steven Rostedt)
Changes in v2: None
drivers/pci/trace.c | 20 ++++++++++++
include/linux/pci.h | 4 +++
include/trace/events/pci_controller.h | 57 +++++++++++++++++++++++++++++++++++
3 files changed, 81 insertions(+)
create mode 100644 include/trace/events/pci_controller.h
diff --git a/drivers/pci/trace.c b/drivers/pci/trace.c
index cf11abc..d351a51 100644
--- a/drivers/pci/trace.c
+++ b/drivers/pci/trace.c
@@ -9,3 +9,23 @@
#define CREATE_TRACE_POINTS
#include <trace/events/pci.h>
+#include <trace/events/pci_controller.h>
+
+static atomic_t pcie_ltssm_tp_enabled = ATOMIC_INIT(0);
+
+bool pci_ltssm_tp_enabled(void)
+{
+ return atomic_read(&pcie_ltssm_tp_enabled) > 0;
+}
+EXPORT_SYMBOL(pci_ltssm_tp_enabled);
+
+int pci_ltssm_tp_reg(void)
+{
+ atomic_inc(&pcie_ltssm_tp_enabled);
+ return 0;
+}
+
+void pci_ltssm_tp_unreg(void)
+{
+ atomic_dec(&pcie_ltssm_tp_enabled);
+}
diff --git a/include/linux/pci.h b/include/linux/pci.h
index e7cb527..ac25a3e 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -2770,6 +2770,10 @@ static inline struct eeh_dev *pci_dev_to_eeh_dev(struct pci_dev *pdev)
}
#endif
+#ifdef CONFIG_TRACING
+bool pci_ltssm_tp_enabled(void);
+#endif
+
void pci_add_dma_alias(struct pci_dev *dev, u8 devfn_from, unsigned nr_devfns);
bool pci_devs_are_dma_aliases(struct pci_dev *dev1, struct pci_dev *dev2);
int pci_for_each_dma_alias(struct pci_dev *pdev,
diff --git a/include/trace/events/pci_controller.h b/include/trace/events/pci_controller.h
new file mode 100644
index 0000000..db4a960
--- /dev/null
+++ b/include/trace/events/pci_controller.h
@@ -0,0 +1,57 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM pci_controller
+
+#if !defined(_TRACE_HW_EVENT_PCI_CONTROLLER_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_HW_EVENT_PCI_CONTROLLER_H
+
+#include <uapi/linux/pci_regs.h>
+#include <linux/tracepoint.h>
+
+TRACE_DEFINE_ENUM(PCIE_SPEED_2_5GT);
+TRACE_DEFINE_ENUM(PCIE_SPEED_5_0GT);
+TRACE_DEFINE_ENUM(PCIE_SPEED_8_0GT);
+TRACE_DEFINE_ENUM(PCIE_SPEED_16_0GT);
+TRACE_DEFINE_ENUM(PCIE_SPEED_32_0GT);
+TRACE_DEFINE_ENUM(PCIE_SPEED_64_0GT);
+TRACE_DEFINE_ENUM(PCI_SPEED_UNKNOWN);
+
+extern int pci_ltssm_tp_reg(void);
+extern void pci_ltssm_tp_unreg(void);
+
+TRACE_EVENT_FN(pcie_ltssm_state_transition,
+ TP_PROTO(const char *dev_name, const char *state, u32 rate),
+ TP_ARGS(dev_name, state, rate),
+
+ TP_STRUCT__entry(
+ __string(dev_name, dev_name)
+ __string(state, state)
+ __field(u32, rate)
+ ),
+
+ TP_fast_assign(
+ __assign_str(dev_name);
+ __assign_str(state);
+ __entry->rate = rate;
+ ),
+
+ TP_printk("dev: %s state: %s rate: %s",
+ __get_str(dev_name), __get_str(state),
+ __print_symbolic(__entry->rate,
+ { PCIE_SPEED_2_5GT, "2.5 GT/s" },
+ { PCIE_SPEED_5_0GT, "5.0 GT/s" },
+ { PCIE_SPEED_8_0GT, "8.0 GT/s" },
+ { PCIE_SPEED_16_0GT, "16.0 GT/s" },
+ { PCIE_SPEED_32_0GT, "32.0 GT/s" },
+ { PCIE_SPEED_64_0GT, "64.0 GT/s" },
+ { PCI_SPEED_UNKNOWN, "Unknown" }
+ )
+ ),
+
+ pci_ltssm_tp_reg, pci_ltssm_tp_unreg
+);
+
+#endif /* _TRACE_HW_EVENT_PCI_CONTROLLER_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
--
2.7.4
^ permalink raw reply related
* [PATCH v4 3/3] PCI: dw-rockchip: Add pcie_ltssm_state_transition trace support
From: Shawn Lin @ 2026-01-22 2:02 UTC (permalink / raw)
To: Manivannan Sadhasivam, Bjorn Helgaas
Cc: linux-rockchip, linux-pci, linux-trace-kernel, linux-doc,
Steven Rostedt, Masami Hiramatsu, Shawn Lin
In-Reply-To: <1769047340-113287-1-git-send-email-shawn.lin@rock-chips.com>
Rockchip platforms provide a 64x4 bytes debug FIFO to trace the
LTSSM history. Any LTSSM change will be recorded. It's useful
for debug purpose, for example link failure, etc.
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---
Changes in v4:
- skip trace if pci_ltssm_tp_enabled() is false.(Steven)
- wrap into 80 columns(Bjorn)
Changes in v3:
- reorder variables(Mani)
- rename loop to i; rename en to enable(Mani)
- use FIELD_GET(Mani)
- add comment about how the FIFO works(Mani)
Changes in v2:
- use tracepoint
drivers/pci/controller/dwc/pcie-dw-rockchip.c | 111 ++++++++++++++++++++++++++
1 file changed, 111 insertions(+)
diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
index 0fd7bb9..135326c 100644
--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
+++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
@@ -22,6 +22,8 @@
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/reset.h>
+#include <linux/workqueue.h>
+#include <trace/events/pci_controller.h>
#include "../../pci.h"
#include "pcie-designware.h"
@@ -73,6 +75,20 @@
#define PCIE_CLIENT_CDM_RASDES_TBA_L1_1 BIT(4)
#define PCIE_CLIENT_CDM_RASDES_TBA_L1_2 BIT(5)
+/* Debug FIFO information */
+#define PCIE_CLIENT_DBG_FIFO_MODE_CON 0x310
+#define PCIE_CLIENT_DBG_EN 0xffff0007
+#define PCIE_CLIENT_DBG_DIS 0xffff0000
+#define PCIE_CLIENT_DBG_FIFO_PTN_HIT_D0 0x320
+#define PCIE_CLIENT_DBG_FIFO_PTN_HIT_D1 0x324
+#define PCIE_CLIENT_DBG_FIFO_TRN_HIT_D0 0x328
+#define PCIE_CLIENT_DBG_FIFO_TRN_HIT_D1 0x32c
+#define PCIE_CLIENT_DBG_TRANSITION_DATA 0xffff0000
+#define PCIE_CLIENT_DBG_FIFO_STATUS 0x350
+#define PCIE_DBG_FIFO_RATE_MASK GENMASK(22, 20)
+#define PCIE_DBG_FIFO_L1SUB_MASK GENMASK(10, 8)
+#define PCIE_DBG_LTSSM_HISTORY_CNT 64
+
/* Hot Reset Control Register */
#define PCIE_CLIENT_HOT_RESET_CTRL 0x180
#define PCIE_LTSSM_APP_DLY2_EN BIT(1)
@@ -98,6 +114,7 @@ struct rockchip_pcie {
struct irq_domain *irq_domain;
const struct rockchip_pcie_of_data *data;
bool supports_clkreq;
+ struct delayed_work trace_work;
};
struct rockchip_pcie_of_data {
@@ -208,6 +225,96 @@ static enum dw_pcie_ltssm rockchip_pcie_get_ltssm(struct dw_pcie *pci)
return rockchip_pcie_get_ltssm_reg(rockchip) & PCIE_LTSSM_STATUS_MASK;
}
+#ifdef CONFIG_TRACING
+static void rockchip_pcie_ltssm_trace_work(struct work_struct *work)
+{
+ struct rockchip_pcie *rockchip = container_of(work,
+ struct rockchip_pcie,
+ trace_work.work);
+ struct dw_pcie *pci = &rockchip->pci;
+ enum dw_pcie_ltssm state;
+ u32 i, l1ss, prev_val = DW_PCIE_LTSSM_UNKNOWN, rate, val;
+
+ if (!pci_ltssm_tp_enabled())
+ goto skip_trace;
+
+ for (i = 0; i < PCIE_DBG_LTSSM_HISTORY_CNT; i++) {
+ val = rockchip_pcie_readl_apb(rockchip,
+ PCIE_CLIENT_DBG_FIFO_STATUS);
+ rate = FIELD_GET(PCIE_DBG_FIFO_RATE_MASK, val);
+ l1ss = FIELD_GET(PCIE_DBG_FIFO_L1SUB_MASK, val);
+ val = FIELD_GET(PCIE_LTSSM_STATUS_MASK, val);
+
+ /*
+ * Hardware Mechanism: The ring FIFO employs two tracking
+ * counters:
+ * - 'last-read-point': maintains the user's last read position
+ * - 'last-valid-point': tracks the HW's last state update
+ *
+ * Software Handling: When two consecutive LTSSM states are
+ * identical, it indicates invalid subsequent data in the FIFO.
+ * In this case, we skip the remaining entries. The dual counter
+ * design ensures that on the next state transition, reading can
+ * resume from the last user position.
+ */
+ if ((i > 0 && val == prev_val) || val > DW_PCIE_LTSSM_RCVRY_EQ3)
+ break;
+
+ state = prev_val = val;
+ if (val == DW_PCIE_LTSSM_L1_IDLE) {
+ if (l1ss == 2)
+ state = DW_PCIE_LTSSM_L1_2;
+ else if (l1ss == 1)
+ state = DW_PCIE_LTSSM_L1_1;
+ }
+
+ trace_pcie_ltssm_state_transition(dev_name(pci->dev),
+ dw_pcie_ltssm_status_string(state),
+ ((rate + 1) > pci->max_link_speed) ?
+ PCI_SPEED_UNKNOWN : PCIE_SPEED_2_5GT + rate);
+ }
+
+skip_trace:
+ schedule_delayed_work(&rockchip->trace_work, msecs_to_jiffies(5000));
+}
+
+static void rockchip_pcie_ltssm_trace(struct rockchip_pcie *rockchip,
+ bool enable)
+{
+ if (enable) {
+ rockchip_pcie_writel_apb(rockchip,
+ PCIE_CLIENT_DBG_TRANSITION_DATA,
+ PCIE_CLIENT_DBG_FIFO_PTN_HIT_D0);
+ rockchip_pcie_writel_apb(rockchip,
+ PCIE_CLIENT_DBG_TRANSITION_DATA,
+ PCIE_CLIENT_DBG_FIFO_PTN_HIT_D1);
+ rockchip_pcie_writel_apb(rockchip,
+ PCIE_CLIENT_DBG_TRANSITION_DATA,
+ PCIE_CLIENT_DBG_FIFO_TRN_HIT_D0);
+ rockchip_pcie_writel_apb(rockchip,
+ PCIE_CLIENT_DBG_TRANSITION_DATA,
+ PCIE_CLIENT_DBG_FIFO_TRN_HIT_D1);
+ rockchip_pcie_writel_apb(rockchip,
+ PCIE_CLIENT_DBG_EN,
+ PCIE_CLIENT_DBG_FIFO_MODE_CON);
+
+ INIT_DELAYED_WORK(&rockchip->trace_work,
+ rockchip_pcie_ltssm_trace_work);
+ schedule_delayed_work(&rockchip->trace_work, 0);
+ } else {
+ rockchip_pcie_writel_apb(rockchip,
+ PCIE_CLIENT_DBG_DIS,
+ PCIE_CLIENT_DBG_FIFO_MODE_CON);
+ cancel_delayed_work_sync(&rockchip->trace_work);
+ }
+}
+#else
+static void rockchip_pcie_ltssm_trace(struct rockchip_pcie *rockchip,
+ bool enable)
+{
+}
+#endif
+
static void rockchip_pcie_enable_ltssm(struct rockchip_pcie *rockchip)
{
rockchip_pcie_writel_apb(rockchip, PCIE_CLIENT_ENABLE_LTSSM,
@@ -291,6 +398,9 @@ static int rockchip_pcie_start_link(struct dw_pcie *pci)
* 100us as we don't know how long should the device need to reset.
*/
msleep(PCIE_T_PVPERL_MS);
+
+ rockchip_pcie_ltssm_trace(rockchip, true);
+
gpiod_set_value_cansleep(rockchip->rst_gpio, 1);
return 0;
@@ -301,6 +411,7 @@ static void rockchip_pcie_stop_link(struct dw_pcie *pci)
struct rockchip_pcie *rockchip = to_rockchip_pcie(pci);
rockchip_pcie_disable_ltssm(rockchip);
+ rockchip_pcie_ltssm_trace(rockchip, false);
}
static int rockchip_pcie_host_init(struct dw_pcie_rp *pp)
--
2.7.4
^ permalink raw reply related
* [PATCH v4 2/3] Documentation: tracing: Add PCI controller event documentation
From: Shawn Lin @ 2026-01-22 2:02 UTC (permalink / raw)
To: Manivannan Sadhasivam, Bjorn Helgaas
Cc: linux-rockchip, linux-pci, linux-trace-kernel, linux-doc,
Steven Rostedt, Masami Hiramatsu, Shawn Lin
In-Reply-To: <1769047340-113287-1-git-send-email-shawn.lin@rock-chips.com>
The available tracepoint, pcie_ltssm_state_transition, monitors the LTSSM state
transition for debugging purpose. Add description about it.
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---
Changes in v4: None
Changes in v3:
- Add toctree entry in Documentation/trace/index.rst(Bagas Sanjaya)
- fix mismatch section underline length(Bagas Sanjaya)
- Make example snippets in code block(Bagas Sanjaya)
- warp context into 80 columns and fix the file name(Bjorn)
Changes in v2: None
Documentation/trace/events-pci-controller.rst | 42 +++++++++++++++++++++++++++
Documentation/trace/index.rst | 1 +
2 files changed, 43 insertions(+)
create mode 100644 Documentation/trace/events-pci-controller.rst
diff --git a/Documentation/trace/events-pci-controller.rst b/Documentation/trace/events-pci-controller.rst
new file mode 100644
index 0000000..cb9f715
--- /dev/null
+++ b/Documentation/trace/events-pci-controller.rst
@@ -0,0 +1,42 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+======================================
+Subsystem Trace Points: PCI Controller
+======================================
+
+Overview
+========
+The PCI controller tracing system provides tracepoints to monitor controller
+level information for debugging purpose. The events normally show up here:
+
+ /sys/kernel/tracing/events/pci_controller
+
+Cf. include/trace/events/pci_controller.h for the events definitions.
+
+Available Tracepoints
+=====================
+
+pcie_ltssm_state_transition
+---------------------------
+
+Monitors PCIe LTSSM state transition including state and rate information
+::
+
+ pcie_ltssm_state_transition "dev: %s state: %s rate: %s\n"
+
+**Parameters**:
+
+* ``dev`` - PCIe controller instance
+* ``state`` - PCIe LTSSM state
+* ``rate`` - PCIe date rate
+
+**Example Usage**:
+
+.. code-block:: shell
+
+ # Enable the tracepoint
+ echo 1 > /sys/kernel/debug/tracing/events/pci_controller/pcie_ltssm_state_transition/enable
+
+ # Monitor events (the following output is generated when a device is linking)
+ cat /sys/kernel/debug/tracing/trace_pipe
+ kworker/0:0-9 [000] ..... 5.600221: pcie_ltssm_state_transition: dev: a40000000.pcie state: RCVRY_EQ2 rate: 8.0 GT/s
diff --git a/Documentation/trace/index.rst b/Documentation/trace/index.rst
index 0a40bfa..6101317 100644
--- a/Documentation/trace/index.rst
+++ b/Documentation/trace/index.rst
@@ -55,6 +55,7 @@ applications.
events-nmi
events-msr
events-pci
+ events-pci-controller
boottime-trace
histogram
histogram-design
--
2.7.4
^ permalink raw reply related
* [PATCH 0/3] Tracing: Accelerate Kernel Boot by Asynchronizing
From: Yaxiong Tian @ 2026-01-22 3:20 UTC (permalink / raw)
To: axboe, rostedt, mhiramat, mathieu.desnoyers
Cc: linux-kernel, linux-block, linux-trace-kernel, Yaxiong Tian
On my ARM64 platform, I observed that certain tracing module
initializations run for up to 200ms—for example, init_kprobe_trace().
Analysis reveals the root cause: the execution flow eval_map_work_func()
→trace_event_update_with_eval_map()→trace_event_update_all()
is highly time-consuming. Although this flow is placed in eval_map_wq
for asynchronous execution, it holds the trace_event_sem lock, causing
other modules to be blocked either directly or indirectly.
To resolve this issue, I exported eval_map_wq and moved other
initialization functions under the tracing subsystem that are related
to this lock to run asynchronously on this workqueue. After this
optimization, boot time is reduced by approximately 200ms.
Yaxiong Tian (3):
tracing: Export eval_map_wq for asynchronous use by other modules
tracing/kprobes: Make setup_boot_kprobe_events() asynchronous
blktrace: Make init_blk_tracer() asynchronous
kernel/trace/blktrace.c | 23 ++++++++++++++++++++++-
kernel/trace/trace.c | 2 +-
kernel/trace/trace.h | 2 ++
kernel/trace/trace_kprobe.c | 14 +++++++++++++-
4 files changed, 38 insertions(+), 3 deletions(-)
--
2.25.1
^ permalink raw reply
* [PATCH 1/3] tracing: Export eval_map_wq for asynchronous use by other modules
From: Yaxiong Tian @ 2026-01-22 3:24 UTC (permalink / raw)
To: axboe, rostedt, mhiramat, mathieu.desnoyers
Cc: linux-block, linux-kernel, linux-trace-kernel, Yaxiong Tian
In-Reply-To: <20260122032051.386331-1-tianyaxiong@kylinos.cn>
The eval_map_work_func() function, though queued in eval_map_wq,
holds the trace_event_sem read-write lock for a long time during
kernel boot. This causes blocking issues for other functions.
Making eval_map_wq extern allows other modules to schedule their
work asynchronously on this queue, preventing it from blocking
the main boot thread.
Signed-off-by: Yaxiong Tian <tianyaxiong@kylinos.cn>
---
kernel/trace/trace.c | 2 +-
kernel/trace/trace.h | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index e18005807395..cb073d0c86a6 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -10774,7 +10774,7 @@ int tracing_init_dentry(void)
extern struct trace_eval_map *__start_ftrace_eval_maps[];
extern struct trace_eval_map *__stop_ftrace_eval_maps[];
-static struct workqueue_struct *eval_map_wq __initdata;
+struct workqueue_struct *eval_map_wq __initdata;
static struct work_struct eval_map_work __initdata;
static struct work_struct tracerfs_init_work __initdata;
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index de4e6713b84e..44aaabc46a7a 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -770,6 +770,8 @@ extern unsigned long nsecs_to_usecs(unsigned long nsecs);
extern unsigned long tracing_thresh;
+extern struct workqueue_struct *eval_map_wq __initdata;
+
/* PID filtering */
bool trace_find_filtered_pid(struct trace_pid_list *filtered_pids,
--
2.25.1
^ permalink raw reply related
* [PATCH 2/3] tracing/kprobes: Make setup_boot_kprobe_events() asynchronous
From: Yaxiong Tian @ 2026-01-22 3:24 UTC (permalink / raw)
To: axboe, rostedt, mhiramat, mathieu.desnoyers
Cc: linux-block, linux-kernel, linux-trace-kernel, Yaxiong Tian
In-Reply-To: <20260122032051.386331-1-tianyaxiong@kylinos.cn>
During kernel boot, the setup_boot_kprobe_events() function causes
significant delays, increasing overall startup time.
The root cause is a lock contention chain: its child function
enable_boot_kprobe_events() requires the event_mutex, which is
already held by early_event_add_tracer(). early_event_add_tracer()
itself is blocked waiting for the trace_event_sem read-write lock,
which is held for an extended period by trace_event_update_all().
To resolve this, we have moved the execution of
setup_boot_kprobe_events() to the eval_map_wq workqueue, allowing
it to run asynchronously.
Signed-off-by: Yaxiong Tian <tianyaxiong@kylinos.cn>
---
kernel/trace/trace_kprobe.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 9953506370a5..5e55a8fffd03 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -2031,6 +2031,13 @@ static __init int init_kprobe_trace_early(void)
}
core_initcall(init_kprobe_trace_early);
+static struct work_struct kprobe_trace_work __initdata;
+
+static void __init kprobe_trace_works_func(struct work_struct *work)
+{
+ setup_boot_kprobe_events();
+}
+
/* Make a tracefs interface for controlling probe points */
static __init int init_kprobe_trace(void)
{
@@ -2048,7 +2055,12 @@ static __init int init_kprobe_trace(void)
trace_create_file("kprobe_profile", TRACE_MODE_READ,
NULL, NULL, &kprobe_profile_ops);
- setup_boot_kprobe_events();
+ if (eval_map_wq) {
+ INIT_WORK(&kprobe_trace_work, kprobe_trace_works_func);
+ queue_work(eval_map_wq, &kprobe_trace_work);
+ } else {
+ setup_boot_kprobe_events();
+ }
return 0;
}
--
2.25.1
^ permalink raw reply related
* [PATCH 3/3] blktrace: Make init_blk_tracer() asynchronous
From: Yaxiong Tian @ 2026-01-22 3:24 UTC (permalink / raw)
To: axboe, rostedt, mhiramat, mathieu.desnoyers
Cc: linux-block, linux-kernel, linux-trace-kernel, Yaxiong Tian
In-Reply-To: <20260122032051.386331-1-tianyaxiong@kylinos.cn>
The init_blk_tracer() function causes significant boot delay as it
waits for the trace_event_sem lock held by trace_event_update_all().
Specifically, its child function register_trace_event() requires
this lock, which is occupied for an extended period during boot.
To mitigate this contention, we have moved init_blk_tracer() to the
eval_map_wq workqueue, allowing it to execute asynchronously and
prevent blocking the main boot thread.
Signed-off-by: Yaxiong Tian <tianyaxiong@kylinos.cn>
---
kernel/trace/blktrace.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index d031c8d80be4..dc205873c3b8 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -1832,7 +1832,9 @@ static struct trace_event trace_blk_event = {
.funcs = &trace_blk_event_funcs,
};
-static int __init init_blk_tracer(void)
+static struct work_struct blktrace_works __initdata;
+
+static int __init __init_blk_tracer(void)
{
if (!register_trace_event(&trace_blk_event)) {
pr_warn("Warning: could not register block events\n");
@@ -1852,6 +1854,25 @@ static int __init init_blk_tracer(void)
return 0;
}
+static void __init blktrace_works_func(struct work_struct *work)
+{
+ __init_blk_tracer();
+}
+
+static int __init init_blk_tracer(void)
+{
+ int ret = 0;
+
+ if (eval_map_wq) {
+ INIT_WORK(&blktrace_works, blktrace_works_func);
+ queue_work(eval_map_wq, &blktrace_works);
+ } else {
+ ret = __init_blk_tracer();
+ }
+
+ return ret;
+}
+
device_initcall(init_blk_tracer);
static int blk_trace_remove_queue(struct request_queue *q)
--
2.25.1
^ permalink raw reply related
* Re: [PATCH bpf-next 4/4] selftests/bpf: Allow to benchmark trigger with stacktrace
From: Jiri Olsa @ 2026-01-22 8:35 UTC (permalink / raw)
To: Andrii Nakryiko
Cc: Masami Hiramatsu, Steven Rostedt, Josh Poimboeuf, Peter Zijlstra,
bpf, linux-trace-kernel, x86, Yonghong Song, Song Liu,
Andrii Nakryiko, Mahe Tardy
In-Reply-To: <CAEf4BzaXhGpkycs-TO_1V81-irq3d8Mjfyk=LMc0OC-NW-FnRg@mail.gmail.com>
On Thu, Jan 15, 2026 at 10:48:29AM -0800, Andrii Nakryiko wrote:
> On Mon, Jan 12, 2026 at 1:50 PM Jiri Olsa <jolsa@kernel.org> wrote:
> >
> > Adding support to call bpf_get_stackid helper from trigger programs,
> > so far added for kprobe multi.
> >
> > Adding the --stacktrace/-g option to enable it.
> >
> > Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> > ---
> > tools/testing/selftests/bpf/bench.c | 4 ++++
> > tools/testing/selftests/bpf/bench.h | 1 +
> > .../selftests/bpf/benchs/bench_trigger.c | 1 +
> > .../selftests/bpf/progs/trigger_bench.c | 18 ++++++++++++++++++
> > 4 files changed, 24 insertions(+)
> >
>
> This now actually becomes a stack trace benchmark :) But I don't mind,
> I think it would be good to be able to benchmark this. But I think we
> should then implement it for all different tracing programs (tp,
> raw_tp, fentry/fexit/fmod_ret) for consistency and so we can compare
> and contrast?...
fyi I updated the bench for all program types and got some stats
current fix WITHOUT stacktrace:
usermode-count : 810.652 ± 1.036M/s
kernel-count : 336.645 ± 2.812M/s
syscall-count : 27.798 ± 0.063M/s
fentry : 67.677 ± 0.291M/s
fexit : 49.970 ± 0.214M/s
fmodret : 52.860 ± 0.237M/s
rawtp : 65.196 ± 0.224M/s
tp : 34.120 ± 0.042M/s
kprobe : 25.157 ± 0.019M/s
kprobe-multi : 33.223 ± 0.205M/s
kprobe-multi-all: 4.739 ± 0.003M/s
kretprobe : 10.904 ± 0.020M/s
kretprobe-multi: 15.996 ± 0.023M/s
kretprobe-multi-all: 2.559 ± 0.092M/s
current fix WITH stacktrace:
usermode-count : 782.529 ± 5.866M/s
kernel-count : 341.116 ± 2.247M/s
syscall-count : 27.481 ± 0.267M/s
fentry : 2.397 ± 0.026M/s
fexit : 2.472 ± 0.008M/s
fmodret : 2.475 ± 0.014M/s
rawtp : 2.593 ± 0.031M/s
tp : 2.641 ± 0.020M/s
kprobe : 3.848 ± 0.014M/s
kprobe-multi : 4.188 ± 0.025M/s
kprobe-multi-all: 0.261 ± 0.026M/s
kretprobe : 3.782 ± 0.011M/s
kretprobe-multi: 4.157 ± 0.023M/s
kretprobe-multi-all: 0.177 ± 0.000M/s
with similar fix for fentry/fexit/raw_tp/tp WITH stacktrace:
usermode-count : 792.613 ± 1.322M/s
kernel-count : 337.725 ± 2.422M/s
syscall-count : 27.363 ± 0.030M/s
fentry : 14.911 ± 0.083M/s
fexit : 13.749 ± 0.060M/s
fmodret : 13.987 ± 0.049M/s
rawtp : 13.760 ± 0.042M/s
tp : 7.060 ± 0.026M/s
kprobe : 3.920 ± 0.012M/s
kprobe-multi : 4.186 ± 0.030M/s
kprobe-multi-all: 0.281 ± 0.006M/s
kretprobe : 3.782 ± 0.005M/s
kretprobe-multi: 4.030 ± 0.014M/s
kretprobe-multi-all: 0.178 ± 0.000M/s
so cutting the extra initial unwind gets some speedup ex expected
I'm getting wrong callstack for rawtp programs, so I need to find out why,
but the rest of the tracing programs fentry/fexit.. work ok
jirka
^ permalink raw reply
* Re: [PATCH V5 2/2] mm/khugepaged: retry with sync writeback for MADV_COLLAPSE
From: Dev Jain @ 2026-01-22 11:07 UTC (permalink / raw)
To: Shivank Garg, Andrew Morton, David Hildenbrand, Lorenzo Stoakes
Cc: Zi Yan, Baolin Wang, Liam R . Howlett, Nico Pache, Ryan Roberts,
Barry Song, Lance Yang, Masami Hiramatsu, Steven Rostedt,
linux-trace-kernel, Mathieu Desnoyers, Zach O'Keefe, linux-mm,
linux-kernel, Stephen Rothwell, Branden Moore
In-Reply-To: <20260118190939.8986-7-shivankg@amd.com>
On 19/01/26 12:39 am, Shivank Garg wrote:
> When MADV_COLLAPSE is called on file-backed mappings (e.g., executable
> text sections), the pages may still be dirty from recent writes.
> collapse_file() will trigger async writeback and fail with
> SCAN_PAGE_DIRTY_OR_WRITEBACK (-EAGAIN).
>
> MADV_COLLAPSE is a synchronous operation where userspace expects
> immediate results. If the collapse fails due to dirty pages, perform
> synchronous writeback on the specific range and retry once.
>
> This avoids spurious failures for freshly written executables while
> avoiding unnecessary synchronous I/O for mappings that are already clean.
>
> Reported-by: Branden Moore <Branden.Moore@amd.com>
> Closes: https://lore.kernel.org/all/4e26fe5e-7374-467c-a333-9dd48f85d7cc@amd.com
> Fixes: 34488399fa08 ("mm/madvise: add file and shmem support to MADV_COLLAPSE")
> Suggested-by: David Hildenbrand <david@kernel.org>
> Tested-by: Lance Yang <lance.yang@linux.dev>
> Signed-off-by: Shivank Garg <shivankg@amd.com>
> ---
> mm/khugepaged.c | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
>
> diff --git a/mm/khugepaged.c b/mm/khugepaged.c
> index 219dfa2e523c..16582bdcb6ff 100644
> --- a/mm/khugepaged.c
> +++ b/mm/khugepaged.c
> @@ -22,6 +22,7 @@
> #include <linux/dax.h>
> #include <linux/ksm.h>
> #include <linux/pgalloc.h>
> +#include <linux/backing-dev.h>
>
> #include <asm/tlb.h>
> #include "internal.h"
> @@ -2788,7 +2789,9 @@ int madvise_collapse(struct vm_area_struct *vma, unsigned long start,
>
> for (addr = hstart; addr < hend; addr += HPAGE_PMD_SIZE) {
> int result = SCAN_FAIL;
> + bool triggered_wb = false;
>
> +retry:
> if (!mmap_locked) {
> cond_resched();
> mmap_read_lock(mm);
> @@ -2809,8 +2812,20 @@ int madvise_collapse(struct vm_area_struct *vma, unsigned long start,
>
> mmap_read_unlock(mm);
> mmap_locked = false;
> + *lock_dropped = true;
> result = hpage_collapse_scan_file(mm, addr, file, pgoff,
> cc);
> +
> + if (result == SCAN_PAGE_DIRTY_OR_WRITEBACK && !triggered_wb &&
> + mapping_can_writeback(file->f_mapping)) {
> + loff_t lstart = (loff_t)pgoff << PAGE_SHIFT;
> + loff_t lend = lstart + HPAGE_PMD_SIZE - 1;
> +
> + filemap_write_and_wait_range(file->f_mapping, lstart, lend);
So we don't care about the return value here because this is best-effort.
I really wish we had in our coding-style.rst to typecast such things to (void),
so we know explicitly that we are ignoring the return value, and not that the
function itself returns void.
Nothing jumps out at me,
Reviewed-by: Dev Jain <dev.jain@arm.com>
> + triggered_wb = true;
> + fput(file);
> + goto retry;
> + }
> fput(file);
> } else {
> result = hpage_collapse_scan_pmd(mm, vma, addr,
^ permalink raw reply
* Re: [PATCH 18/26] rv/rvgen: add fill_tracepoint_args_skel stub to ltl2k
From: Wander Lairson Costa @ 2026-01-22 13:10 UTC (permalink / raw)
To: Gabriele Monaco
Cc: Steven Rostedt, Nam Cao, open list,
open list:RUNTIME VERIFICATION (RV)
In-Reply-To: <aXESFlL56FA0PyTZ@fedora>
On Wed, Jan 21, 2026 at 02:53:03PM -0300, Wander Lairson Costa wrote:
> On Wed, Jan 21, 2026 at 02:57:02PM +0100, Gabriele Monaco wrote:
> > On Mon, 2026-01-19 at 17:45 -0300, Wander Lairson Costa wrote:
> > > The ltl2k class inherits from Monitor which requires subclasses to
> > > implement fill_tracepoint_args_skel(). However, the ltl2k template
> > > uses hardcoded tracepoint arguments rather than the placeholders that
> > > this method would fill. The base class fill_trace_h() method calls
> > > fill_tracepoint_args_skel() unconditionally, which was exposed when
> > > the @not_implemented decorator was introduced.
> > >
> > > Add a stub implementation that returns an empty string. Since the
> > > ltl2k trace.h template does not contain the placeholder strings that
> > > would be replaced, the empty return value has no effect on the
> > > generated output while satisfying the base class interface contract.
> > >
> > > Signed-off-by: Wander Lairson Costa <wander@redhat.com>
> >
> > Mmh, this is a bit fishy though.
> > We the patch using the decorator seems fine, but highlights how this method
> > isn't meant to be in Monitor if not all monitors use it..
> > Adding a stub here is just sweeping dust under the carpet.
> >
> > Here should probably keep the common part of fill_trace_h() in Monitor (e.g.
> > replacing MODEL_NAME and other common things) and create specific
> > implementations in dot2k and ltl2k for what is not common while calling the
> > super() counterpart for the rest.
> >
> > Does it make sense to you?
> >
>
> Yes, that is exactly my idea. Since the patch series were getting too
> long and my brain too rot, I thought would be better addressing this in
> a following up patch series. But I can work in the next version if you
> are not ok with that approach.
>
I gave more thought on this matter yesterday before bed. Maybe this
isn't a issue on the design. Some methods on Monitor might just have a
harmless default behavior. I look into it more closely for next the
round.
> > Thanks,
> > Gabriele
> >
> > > ---
> > > tools/verification/rvgen/rvgen/ltl2k.py | 3 +++
> > > 1 file changed, 3 insertions(+)
> > >
> > > diff --git a/tools/verification/rvgen/rvgen/ltl2k.py
> > > b/tools/verification/rvgen/rvgen/ltl2k.py
> > > index 94dc64af1716d..f1eafc16c754b 100644
> > > --- a/tools/verification/rvgen/rvgen/ltl2k.py
> > > +++ b/tools/verification/rvgen/rvgen/ltl2k.py
> > > @@ -257,6 +257,9 @@ class ltl2k(generator.Monitor):
> > >
> > > return '\n'.join(buf)
> > >
> > > + def fill_tracepoint_args_skel(self, tp_type) -> str:
> > > + return ""
> > > +
> > > def fill_monitor_class_type(self):
> > > return "LTL_MON_EVENTS_ID"
> > >
> >
>
^ permalink raw reply
* Re: [PATCH 18/26] rv/rvgen: add fill_tracepoint_args_skel stub to ltl2k
From: Gabriele Monaco @ 2026-01-22 13:49 UTC (permalink / raw)
To: Wander Lairson Costa
Cc: Steven Rostedt, Nam Cao, open list,
open list:RUNTIME VERIFICATION (RV)
In-Reply-To: <aXIhSGAQvflGAEsN@fedora>
On Thu, 2026-01-22 at 10:10 -0300, Wander Lairson Costa wrote:
> On Wed, Jan 21, 2026 at 02:53:03PM -0300, Wander Lairson Costa wrote:
> > On Wed, Jan 21, 2026 at 02:57:02PM +0100, Gabriele Monaco wrote:
> > > Mmh, this is a bit fishy though.
> > > We the patch using the decorator seems fine, but highlights how this
> > > method
> > > isn't meant to be in Monitor if not all monitors use it..
> > > Adding a stub here is just sweeping dust under the carpet.
> > >
> > > Here should probably keep the common part of fill_trace_h() in Monitor
> > > (e.g.
> > > replacing MODEL_NAME and other common things) and create specific
> > > implementations in dot2k and ltl2k for what is not common while calling
> > > the
> > > super() counterpart for the rest.
> > >
> > > Does it make sense to you?
> >
> > Yes, that is exactly my idea. Since the patch series were getting too
> > long and my brain too rot, I thought would be better addressing this in
> > a following up patch series. But I can work in the next version if you
> > are not ok with that approach.
Good point, that can be a separate series so that we don't mix too many things,
but I'd also separate the initial patch introducing the @not_implemented .
> I gave more thought on this matter yesterday before bed. Maybe this
> isn't a issue on the design. Some methods on Monitor might just have a
> harmless default behavior. I look into it more closely for next the
> round.
Well, I believe that if a bunch of methods from the parent class don't need to
be called and we have to create stubs just to avoid errors, those methods
probably shouldn't be there in the first place.
That's particularly valid for the Container class, that won't ever need to fill
tracepoints and other stuff.
Why fill_tracepoint_args_skel() is not required by LTL is an implementation
detail, so that stub could even stay, in case future monitors are going to need
the entire thing.
Though I still find it cleaner to move that away too until there's a need for it
shared in Monitor.
What do you think?
Thanks,
Gabriele
^ permalink raw reply
* Re: [PATCH 01/26] rv/rvgen: introduce AutomataError exception class
From: Nam Cao @ 2026-01-22 14:39 UTC (permalink / raw)
To: Gabriele Monaco, Wander Lairson Costa
Cc: Steven Rostedt, open list, open list:RUNTIME VERIFICATION (RV)
In-Reply-To: <fb6b81910e32dbf7aa16e1961dc1dca0a9bfbf57.camel@redhat.com>
Gabriele Monaco <gmonaco@redhat.com> writes:
> That could be a good tradeoff. Users are developer but (although I'm not sure if
> it really happened yet) are not the rvgen developers, they don't need to know
> where exactly the code complained, unless it really broke.
> All errors that are expected (OSError or wrong format) should have a meaningful
> message for the user, I believe by doing that we'd have a pretty clear idea
> where the error came from in the code too (e.g. event parsing, opening a file,
> etc.).
>
> If the code has a bug, then yes we should throw the exception as is, that's why
> I think it's good not to catch Exception, but to catch only the few exceptions
> we know can happen, all others would be bugs.
I second this. We should only catch expected exceptions (e.g. the .dot
file is malformed) and print meaningful message. Otherwise, just leave
it uncaught.
While working with rvgen, I usually just remove the try-catch, because
it takes away all the useful debug information while not offering
anything else.
Nam
^ permalink raw reply
* Re: [PATCH 02/26] rv/rvgen: remove bare except clauses in generator
From: Nam Cao @ 2026-01-22 14:43 UTC (permalink / raw)
To: Wander Lairson Costa, Steven Rostedt, Gabriele Monaco,
Wander Lairson Costa, open list,
open list:RUNTIME VERIFICATION (RV)
In-Reply-To: <20260119205601.105821-3-wander@redhat.com>
Wander Lairson Costa <wander@redhat.com> writes:
> Remove bare except clauses from the generator module that were
> catching all exceptions including KeyboardInterrupt and SystemExit.
> This follows the same exception handling improvements made in the
> previous AutomataError commit and addresses PEP 8 violations.
>
> The bare except clause in __create_directory was silently catching
> and ignoring all errors after printing a message, which could mask
> serious issues. For __write_file, the bare except created a critical
> bug where the file variable could remain undefined if open() failed,
> causing a NameError when attempting to write to or close the file.
>
> These methods now let OSError propagate naturally, allowing callers
> to handle file system errors appropriately. This provides clearer
> error reporting and allows Python's exception handling to show
> complete stack traces with proper error types and locations.
>
> Signed-off-by: Wander Lairson Costa <wander@redhat.com>
Reviewed-by: Nam Cao <namcao@linutronix.de>
^ permalink raw reply
* Re: [PATCH 03/26] rv/rvgen: replace % string formatting with f-strings
From: Nam Cao @ 2026-01-22 14:46 UTC (permalink / raw)
To: Wander Lairson Costa, Steven Rostedt, Gabriele Monaco,
Wander Lairson Costa, open list,
open list:RUNTIME VERIFICATION (RV)
In-Reply-To: <20260119205601.105821-4-wander@redhat.com>
Wander Lairson Costa <wander@redhat.com> writes:
> Replace all instances of percent-style string formatting with
> f-strings across the rvgen codebase. This modernizes the string
> formatting to use Python 3.6+ features, providing clearer and more
> maintainable code while improving runtime performance.
>
> The conversion handles all formatting cases including simple variable
> substitution, multi-variable formatting, and complex format specifiers.
> Dynamic width formatting is converted from "%*s" to "{var:>{width}}"
> using proper alignment syntax. Template strings for generated C code
> properly escape braces using double-brace syntax to produce literal
> braces in the output.
>
> F-strings provide approximately 2x performance improvement over percent
> formatting and are the recommended approach in modern Python.
>
> Signed-off-by: Wander Lairson Costa <wander@redhat.com>
Reviewed-by: Nam Cao <namcao@linutronix.de>
^ permalink raw reply
* Re: [PATCH 04/26] rv/rvgen: replace __len__() calls with len()
From: Nam Cao @ 2026-01-22 14:46 UTC (permalink / raw)
To: Wander Lairson Costa, Steven Rostedt, Gabriele Monaco,
Wander Lairson Costa, open list,
open list:RUNTIME VERIFICATION (RV)
In-Reply-To: <20260119205601.105821-5-wander@redhat.com>
Wander Lairson Costa <wander@redhat.com> writes:
> Replace all direct calls to the __len__() dunder method with the
> idiomatic len() built-in function across the rvgen codebase. This
> change eliminates a Python anti-pattern where dunder methods are
> called directly instead of using their corresponding built-in
> functions.
>
> The changes affect nine instances across two files. In automata.py,
> the empty string check is further improved by using truthiness
> testing instead of explicit length comparison. In dot2c.py, all
> length checks in the get_minimun_type, __get_max_strlen_of_states,
> and get_aut_init_function methods now use the standard len()
> function. Additionally, spacing around keyword arguments has been
> corrected to follow PEP 8 guidelines.
>
> Direct calls to dunder methods like __len__() are discouraged in
> Python because they bypass the language's abstraction layer and
> reduce code readability. Using len() provides the same functionality
> while adhering to Python community standards and making the code more
> familiar to Python developers.
>
> Signed-off-by: Wander Lairson Costa <wander@redhat.com>
Reviewed-by: Nam Cao <namcao@linutronix.de>
^ permalink raw reply
* Re: [PATCH 05/26] rv/rvgen: remove unnecessary semicolons
From: Nam Cao @ 2026-01-22 14:47 UTC (permalink / raw)
To: Wander Lairson Costa, Steven Rostedt, Gabriele Monaco,
Wander Lairson Costa, open list,
open list:RUNTIME VERIFICATION (RV)
In-Reply-To: <20260119205601.105821-6-wander@redhat.com>
Wander Lairson Costa <wander@redhat.com> writes:
> Remove unnecessary semicolons from Python code in the rvgen tool.
> Python does not require semicolons to terminate statements, and
> their presence goes against PEP 8 style guidelines. These semicolons
> were likely added out of habit from C-style languages.
>
> The changes affect four instances across two files. In dot2c.py, one
> semicolon is removed from a boolean assignment. In dot2k.py, three
> semicolons are removed from string append operations that build
> generated C code. Note that the semicolons inside the string literals
> themselves are correctly preserved as they are part of the C code
> being generated, not Python syntax.
>
> This cleanup improves consistency with Python coding standards and
> aligns with the recent improvements to remove other Python
> anti-patterns from the codebase.
>
> Signed-off-by: Wander Lairson Costa <wander@redhat.com>
Reviewed-by: Nam Cao <namcao@linutronix.de>
^ permalink raw reply
* Re: [PATCH 06/26] rv/rvgen: use context managers for file operations
From: Nam Cao @ 2026-01-22 14:50 UTC (permalink / raw)
To: Wander Lairson Costa, Steven Rostedt, Gabriele Monaco,
Wander Lairson Costa, open list,
open list:RUNTIME VERIFICATION (RV)
In-Reply-To: <20260119205601.105821-7-wander@redhat.com>
Wander Lairson Costa <wander@redhat.com> writes:
> Replace manual file open and close operations with context managers
> throughout the rvgen codebase. The previous implementation used
> explicit open() and close() calls, which could lead to resource leaks
> if exceptions occurred between opening and closing the file handles.
>
> This change affects three file operations: reading DOT specification
> files in the automata parser, reading template files in the generator
> base class, and writing generated monitor files. All now use the with
> statement to ensure proper resource cleanup even in error conditions.
>
> Context managers provide automatic cleanup through the with statement,
> which guarantees that file handles are closed when the with block
> exits regardless of whether an exception occurred. This follows PEP
> 343 recommendations and is the standard Python idiom for resource
> management. The change also reduces code verbosity while improving
> safety and maintainability.
>
> Signed-off-by: Wander Lairson Costa <wander@redhat.com>
Reviewed-by: Nam Cao <namcao@linutronix.de>
^ permalink raw reply
* Re: [PATCH 07/26] rv/rvgen: replace __contains__() with in operator
From: Nam Cao @ 2026-01-22 14:51 UTC (permalink / raw)
To: Wander Lairson Costa, Steven Rostedt, Gabriele Monaco,
Wander Lairson Costa, open list,
open list:RUNTIME VERIFICATION (RV)
In-Reply-To: <20260119205601.105821-8-wander@redhat.com>
Wander Lairson Costa <wander@redhat.com> writes:
> Replace the direct call to the __contains__() dunder method with the
> idiomatic in operator in the dot2c module. The previous implementation
> explicitly called the __contains__() method to check for membership in
> the final_states collection, which is not the recommended Python
> style.
>
> Python provides the in operator as the proper way to test membership,
> which internally calls the __contains__() method. Directly calling
> dunder methods bypasses Python's abstraction layer and reduces code
> readability. Using the in operator makes the code more natural and
> familiar to Python developers while maintaining identical functionality.
>
> Signed-off-by: Wander Lairson Costa <wander@redhat.com>
Reviewed-by: Nam Cao <namcao@linutronix.de>
^ permalink raw reply
* Re: [PATCH 08/26] rv/rvgen: simplify boolean comparison
From: Nam Cao @ 2026-01-22 14:51 UTC (permalink / raw)
To: Wander Lairson Costa, Steven Rostedt, Gabriele Monaco,
Wander Lairson Costa, open list,
open list:RUNTIME VERIFICATION (RV)
In-Reply-To: <20260119205601.105821-9-wander@redhat.com>
Wander Lairson Costa <wander@redhat.com> writes:
> Replace explicit boolean comparison with truthiness test in the dot2c
> module. The previous implementation used the redundant pattern of
> comparing a boolean variable directly to False, which is not idiomatic
> Python and adds unnecessary verbosity to the code.
>
> Python's truthiness allows for more concise and readable boolean
> checks. The expression "if not first" is clearer and more Pythonic
> than "if first == False" while maintaining identical semantics. This
> pattern is preferred in PEP 8 and is the standard approach in the
> Python community.
>
> This change continues the ongoing code quality improvements to align
> the codebase with modern Python best practices.
>
> Signed-off-by: Wander Lairson Costa <wander@redhat.com>
Reviewed-by: Nam Cao <namcao@linutronix.de>
^ permalink raw reply
* Re: [PATCH 09/26] rv/rvgen: replace inline NotImplemented with decorator
From: Nam Cao @ 2026-01-22 14:57 UTC (permalink / raw)
To: Wander Lairson Costa, Steven Rostedt, Gabriele Monaco,
Wander Lairson Costa, open list,
open list:RUNTIME VERIFICATION (RV)
In-Reply-To: <20260119205601.105821-10-wander@redhat.com>
Wander Lairson Costa <wander@redhat.com> writes:
> Replace inline NotImplementedError raises with a dedicated decorator in
> the ltl2ba module. The previous implementation used explicit raise
> statements inside abstract method bodies for BinaryOp and UnaryOp
> classes, which required maintaining identical boilerplate across seven
> different methods that need to be overridden by subclasses.
>
> All stub methods in generator.py have been converted from returning
> strings to using the decorator with ellipsis function bodies, which
> is the recommended Python style for marking incomplete interface
> methods. This ensures that any attempt to use unimplemented
> functionality fails fast with a clear exception rather than silently
> propagating string values through the code.
>
> The new @not_implemented decorator consolidates this pattern into a
> single reusable definition that clearly marks abstract methods while
> reducing code duplication. The decorator creates a wrapper that raises
> NotImplementedError with the function name, providing the same runtime
> behavior with improved maintainability. Method bodies now use the
> ellipsis literal instead of pass statements, which is the preferred
> Python convention for stub methods according to PEP 8.
>
> Signed-off-by: Wander Lairson Costa <wander@redhat.com>
Reviewed-by: Nam Cao <namcao@linutronix.de>
^ permalink raw reply
* Re: [PATCH 10/26] rv/rvgen: fix typos in automata docstring and comments
From: Nam Cao @ 2026-01-22 14:58 UTC (permalink / raw)
To: Wander Lairson Costa, Steven Rostedt, Gabriele Monaco,
Wander Lairson Costa, open list,
open list:RUNTIME VERIFICATION (RV)
In-Reply-To: <20260119205601.105821-11-wander@redhat.com>
Wander Lairson Costa <wander@redhat.com> writes:
> Fix two typos in the Automata class documentation that have been
> present since the initial implementation. The class docstring
> incorrectly stated "part it" instead of "parses it" when
> describing how the class processes DOT files. Additionally, a
> comment describing transition labels contained the misspelling
> "lables" instead of "labels".
>
> Fix a typo in the comment describing the insertion of the initial
> state into the states list: "bein og" should be "beginning of".
>
> Signed-off-by: Wander Lairson Costa <wander@redhat.com>
Reviewed-by: Nam Cao <namcao@linutronix.de>
^ permalink raw reply
* Re: [PATCH 11/26] rv/rvgen: fix typo in generator module docstring
From: Nam Cao @ 2026-01-22 14:59 UTC (permalink / raw)
To: Wander Lairson Costa, Steven Rostedt, Gabriele Monaco,
Wander Lairson Costa, open list,
open list:RUNTIME VERIFICATION (RV)
In-Reply-To: <20260119205601.105821-12-wander@redhat.com>
Wander Lairson Costa <wander@redhat.com> writes:
> Fix typo in the module docstring: "Abtract" should be "Abstract".
>
> Signed-off-by: Wander Lairson Costa <wander@redhat.com>
Reviewed-by: Nam Cao <namcao@linutronix.de>
^ permalink raw reply
* Re: [PATCH 12/26] rv/rvgen: fix PEP 8 whitespace violations
From: Nam Cao @ 2026-01-22 14:59 UTC (permalink / raw)
To: Wander Lairson Costa, Steven Rostedt, Gabriele Monaco,
Wander Lairson Costa, open list,
open list:RUNTIME VERIFICATION (RV)
In-Reply-To: <20260119205601.105821-13-wander@redhat.com>
Wander Lairson Costa <wander@redhat.com> writes:
> Fix whitespace violations throughout the rvgen codebase to comply
> with PEP 8 style guidelines. The changes address missing whitespace
> after commas, around operators, and in collection literals that
> were flagged by pycodestyle.
>
> The fixes include adding whitespace after commas in string replace
> chains and function arguments, adding whitespace around arithmetic
> operators, removing extra whitespace in list comprehensions, and
> fixing dictionary literal spacing. These changes improve code
> readability and consistency with Python coding standards.
>
> Signed-off-by: Wander Lairson Costa <wander@redhat.com>
Reviewed-by: Nam Cao <namcao@linutronix.de>
^ permalink raw reply
* Re: [PATCH 13/26] rv/rvgen: fix DOT file validation logic error
From: Nam Cao @ 2026-01-22 15:01 UTC (permalink / raw)
To: Wander Lairson Costa, Steven Rostedt, Gabriele Monaco,
Wander Lairson Costa, open list,
open list:RUNTIME VERIFICATION (RV)
In-Reply-To: <20260119205601.105821-14-wander@redhat.com>
Wander Lairson Costa <wander@redhat.com> writes:
> Fix incorrect boolean logic in automata DOT file format validation
> that allowed malformed files to pass undetected. The previous
> implementation used a logical AND operator where OR was required,
> causing the validation to only reject files when both the first
> token was not "digraph" AND the second token was not
> "state_automaton". This meant a file starting with "digraph" but
> having an incorrect second token would incorrectly pass validation.
>
> The corrected logic properly rejects DOT files where either the
> first token is not "digraph" or the second token is not
> "state_automaton", ensuring that only properly formatted automaton
> definition files are accepted for processing. Without this fix,
> invalid DOT files could cause downstream parsing failures or
> generate incorrect C code for runtime verification monitors.
>
> Signed-off-by: Wander Lairson Costa <wander@redhat.com>
Reviewed-by: Nam Cao <namcao@linutronix.de>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox