* Re: [PATCH v6 08/12] PCI: liveupdate: Inherit ACS flags in incoming preserved devices
From: Pranjal Shrivastava @ 2026-06-09 15:12 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: David Matlack, kexec, linux-doc, linux-kernel, linux-mm,
linux-pci, Adithya Jayachandran, Alexander Graf, Alex Williamson,
Bjorn Helgaas, Chris Li, David Rientjes, Jacob Pan,
Jonathan Corbet, Josh Hilke, Leon Romanovsky, Lukas Wunner,
Mike Rapoport, Parav Pandit, Pasha Tatashin, Pratyush Yadav,
Saeed Mahameed, Samiullah Khawaja, Shuah Khan, Vipin Sharma,
William Tu, Yi Liu
In-Reply-To: <20260608181640.GO1962447@nvidia.com>
On Mon, Jun 08, 2026 at 03:16:40PM -0300, Jason Gunthorpe wrote:
> On Mon, Jun 08, 2026 at 10:49:29AM +0000, Pranjal Shrivastava wrote:
>
> > My point was that a FW exploit can meddle with the bitfields of the
> > ACS_CTRL to spoof and mis-report the ACS flags.
>
> Devices can also ignore the ACS flags. I don't think this is an area
> where we should be worrying about devices being actively hostile.
I'm wondering what happens if we preserve IOMMU groups across a kexec,
but a switch's ACS capability is dropped or the ACS_RR bit gets cleared?
The incoming kernel assumes that it's the same ACS cap from the old one
Now, the incoming kernel restores the groups assuming they're still
isolated, but the hardware no longer enforces it, silently allowing DMAs
& breaking isolation?
Thanks,
Praan
^ permalink raw reply
* [PATCH v4 1/2] dt-bindings: iio: dac: Add AD5529R
From: Janani Sunil @ 2026-06-09 15:00 UTC (permalink / raw)
To: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron,
David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Philipp Zabel, Jonathan Corbet,
Shuah Khan
Cc: linux-iio, devicetree, linux-kernel, linux-doc, Janani Sunil,
Janani Sunil
In-Reply-To: <20260609-ad5529r-driver-v4-0-2e4c02234a1a@analog.com>
Devicetree bindings for AD5529R 16 channel 12/16 bit high voltage,
buffered voltage output digital-to-analog converter (DAC) with an
integrated precision reference.
Signed-off-by: Janani Sunil <janani.sunil@analog.com>
---
.../devicetree/bindings/iio/dac/adi,ad5529r.yaml | 208 +++++++++++++++++++++
MAINTAINERS | 7 +
2 files changed, 215 insertions(+)
diff --git a/Documentation/devicetree/bindings/iio/dac/adi,ad5529r.yaml b/Documentation/devicetree/bindings/iio/dac/adi,ad5529r.yaml
new file mode 100644
index 000000000000..cc994f439be5
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/dac/adi,ad5529r.yaml
@@ -0,0 +1,208 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/dac/adi,ad5529r.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Analog Devices AD5529R 16-Channel 12/16-bit High Voltage DAC
+
+maintainers:
+ - Janani Sunil <janani.sunil@analog.com>
+
+description: |
+ The AD5529R is a 16-channel, 12-bit or 16-bit, high voltage, buffered voltage
+ output digital-to-analog converter (DAC) with an integrated precision reference.
+ The device operates from unipolar and bipolar supplies. It is guaranteed
+ monotonic and has built-in rail-to-rail output buffers that can source or
+ sink up to 25mA.
+
+ Specifications:
+ * 16 independent 12-bit or 16-bit DAC channels
+ * Independently programmable output ranges: 0V to 5V, 0V to 10V, 0V to 20V,
+ 0V to 40V, ±5V, ±10V, ±15V, and ±20V
+ * The device supports SPI communication with Mode 0 and Mode 3.
+ * 4.096V precision reference, 12ppm/°C maximum
+ * Built-in function generation: Toggle, Sinusoidal Dither, and Ramp waveforms
+ * Multiplexer for output voltage, load current sense and die temperature
+
+ Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ad5529r.pdf
+
+properties:
+ compatible:
+ enum:
+ - adi,ad5529r-16 # 16-bit variant
+ - adi,ad5529r-12 # 12-bit variant
+
+ reg:
+ maxItems: 1
+
+ spi-max-frequency:
+ maximum: 25000000
+ description:
+ Maximum SPI frequency. The device supports SPI Mode 0 and Mode 3.
+ Read operations are limited to 25MHz maximum.
+
+ reset-gpios:
+ maxItems: 1
+ description:
+ GPIO connected to the RESET pin. Active low. When asserted low,
+ performs a power-on reset and initializes the device to its default state.
+
+ clear-gpios:
+ maxItems: 1
+ description:
+ GPIO connected to the CLEAR pin. Active low. When asserted low,
+ clears all DAC data registers without affecting configuration settings.
+
+ interrupts:
+ maxItems: 1
+ description:
+ Interrupt connected to the ALARM pin. Active low interrupt output
+ for overtemperature conditions, SPI CRC errors, and function completion.
+
+ pwms:
+ minItems: 1
+ maxItems: 4
+ description:
+ PWM signals connected to the TG0-TG3 toggle pins. Pulsing these pins
+ based on trigger edge settings allows selected DACs to be updated
+ synchronously for digital function generation.
+
+ pwm-names:
+ minItems: 1
+ maxItems: 4
+ items:
+ enum: [ tg0, tg1, tg2, tg3 ]
+
+ io-channels:
+ maxItems: 1
+ description:
+ ADC channel connected to the MUXOUT pin for monitoring output voltage,
+ load current sense, and die temperature.
+
+ io-channel-names:
+ const: muxout
+
+ vdd-supply:
+ description: Digital power supply (1.08V to 1.98V)
+
+ avdd-supply:
+ description: Analog power supply (4.75V to 5.25V)
+
+ hvdd-supply:
+ description:
+ High voltage positive supply (7V to 45V). Supply voltage should be chosen
+ based on configured output ranges (see datasheet Table 9).
+
+ hvss-supply:
+ description:
+ High voltage negative supply (-22.5V to 0V). Required only when using
+ bipolar output ranges (±5V, ±10V, ±15V, ±20V). Supply voltage should be
+ chosen based on configured output ranges (see datasheet Table 9).
+
+ vref-supply:
+ description:
+ External voltage reference supply (4.056V to 4.136V, typically 4.096V).
+ When specified, the device uses external reference mode and the VREF pin
+ becomes an input. The device uses the internal 4.096V precision reference
+ otherwise.
+
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 0
+
+patternProperties:
+ "^channel@([0-9a-f])$":
+ type: object
+ description: Child nodes for individual channel configuration
+
+ properties:
+ reg:
+ description: Channel number.
+ minimum: 0
+ maximum: 15
+
+ adi,output-range-microvolt:
+ description: |
+ Output voltage range for this channel as [min, max] in microvolts.
+ If not specified, defaults to 0V to 5V range.
+ oneOf:
+ - items:
+ - const: 0
+ - enum: [5000000, 10000000, 20000000, 40000000]
+ - items:
+ - const: -5000000
+ - const: 5000000
+ - items:
+ - const: -10000000
+ - const: 10000000
+ - items:
+ - const: -15000000
+ - const: 15000000
+ - items:
+ - const: -20000000
+ - const: 20000000
+
+ required:
+ - reg
+
+ additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - vdd-supply
+ - avdd-supply
+ - hvdd-supply
+
+dependencies:
+ spi-cpha: [ spi-cpol ]
+ spi-cpol: [ spi-cpha ]
+
+allOf:
+ - $ref: /schemas/spi/spi-peripheral-props.yaml#
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+
+ spi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dac@0 {
+ compatible = "adi,ad5529r-16";
+ reg = <0>;
+ spi-max-frequency = <25000000>;
+
+ vdd-supply = <&vdd_regulator>;
+ avdd-supply = <&avdd_regulator>;
+ hvdd-supply = <&hvdd_regulator>;
+ hvss-supply = <&hvss_regulator>;
+
+ reset-gpios = <&gpio0 87 GPIO_ACTIVE_LOW>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ channel@0 {
+ reg = <0>;
+ adi,output-range-microvolt = <0 5000000>;
+ };
+
+ channel@1 {
+ reg = <1>;
+ adi,output-range-microvolt = <(-10000000) 10000000>;
+ };
+
+ channel@2 {
+ reg = <2>;
+ adi,output-range-microvolt = <0 40000000>;
+ };
+ };
+ };
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index d6c3c7d22403..320e84765ce6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1507,6 +1507,13 @@ W: https://ez.analog.com/linux-software-drivers
F: Documentation/devicetree/bindings/iio/adc/adi,ad4851.yaml
F: drivers/iio/adc/ad4851.c
+ANALOG DEVICES INC AD5529R DRIVER
+M: Janani Sunil <janani.sunil@analog.com>
+L: linux-iio@vger.kernel.org
+S: Supported
+W: https://ez.analog.com/linux-software-drivers
+F: Documentation/devicetree/bindings/iio/dac/adi,ad5529r.yaml
+
ANALOG DEVICES INC AD5706R DRIVER
M: Alexis Czezar Torreno <alexisczezar.torreno@analog.com>
L: linux-iio@vger.kernel.org
--
2.43.0
^ permalink raw reply related
* [PATCH v4 0/2] iio: dac: Add support for AD5529R DAC
From: Janani Sunil @ 2026-06-09 15:00 UTC (permalink / raw)
To: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron,
David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Philipp Zabel, Jonathan Corbet,
Shuah Khan
Cc: linux-iio, devicetree, linux-kernel, linux-doc, Janani Sunil,
Janani Sunil
This patch series adds support for Analog Devices AD5529R, a 16 channel
16 and 12 bit voltage Digital-to-Analog Converter (DAC) with integrated
precision reference. The AD5529R operates from both unipolar and
bipolar supplies. The device communicates via SPI interface.
**Device Overview:**
The AD5529R features 16 independent DAC channels, with 16 or 12 bit
resolution, allowing independently programmable output ranges. The
internal 4.096V precision reference sets the accuracy of the output
voltage.
**Features Implemented:**
- Support for AD5529R 12-bit and 16-bit variants via device match data.
- Reset support via GPIO.
- Dual regmap configuration to handle 8 and 16 bit registers.
- Per-channel output range configuration from devicetree.
- Optional external reference and bipolar supply handling.
**Patch Summary:**
1. **dt-bindings**: Binding documentation with channel configuration.
2. **driver**: Implement IIO DAC Driver with regmap support.
**Testing:**
The driver was compiled and tested on the EVAL-AD5529R-ARDZ using a
coraZ7 with a mainline v7.0 kernel.
**Driver Rationale:**
AD5529R introduces:
1. A unique register layout
2. Mixed 8-bit and 16-bit register accesses
3. Hardware specific features like function generators, multi-die
hotpath registers etc.
The device warrants its own drivers due to these fundamental
architectural differences, that would require substantial changes to
existing drivers without providing reusable benefits. The standalone
driver also allows future extensions for related devices in the same
family.
Signed-off-by: Janani Sunil <janani.sunil@analog.com>
---
Changes in v4:
- Fix DT child-node regex for hexadecimal channel addresses.
- Wrap long DT binding description lines.
- Simplify optional `vref-supply` and `hvss-supply` handling.
- Update REF_SEL programming for optional external reference use.
- Clean up range parsing and error messages.
- Simplify debugfs register access by calling regmap helpers directly.
- Add clarifying comments for reset settling time and RAW reads from `DAC_INPUT_A`.
- Remove an unused vref regulator pointer and an include.
- Rename the REF_SEL bit define and clean up small driver details.
- Toggle pins defined as PWM pins, instead of GPIOs
- Update cover letter to sync up latest changes.
- Link to v3: https://lore.kernel.org/r/20260519-ad5529r-driver-v3-0-267c0731aa68@analog.com
Changes in v3:
- Split into adi,ad5529r-16 and adi,ad5529r-12 device tree compatibles
- Add DT-based output range configuration via adi,output-range-microvolt
- Expand DT binding: vref-supply, clear/tg GPIOs, interrupts, muxout
- Correct power supply voltage specifications as per datasheet
- Reduce SPI frequency limit to 25MHz as per datasheet specs
- Switch to autoincrement addressing mode, remove +1 register offsets
- Use DT match data instead of device ID detection for fallback support
- Implement dynamic scale/offset calculation per configured channel range
- Added explicit val_format_endian and reg_stride for 16-bit regmap bus
- Code cleanup: alphabetical includes, ARRAY_SIZE(), unused defines
- Minor: .sign→.format field, simplify read/write order, optional hvss-supply
- Remove redundant driver documentation ad5529r.rst
- Link to v2: https://lore.kernel.org/r/20260508-ad5529r-driver-v2-0-e315441685d7@analog.com
Changes in v2:
- Fix IIO scale to use millivolts per ABI requirement
- Fix documentation voltage calculations (2.5V not 2.048V)
- Fix bipolar ranges in documentation (±5V, ±10V, ±15V, ±20V)
- Fix alphabetical ordering in documentation index
- Add missing newline to documentation file
- Fix scale units description (millivolts not microvolts)
- Include a section for driver rationale in the cover letter
- Reword contents in cover letter 12/16 bit generic->variant
- Add dependency array for spi-cpha and spi-cpol properties
- Link to v1: https://lore.kernel.org/r/20260507-ad5529r-driver-v1-0-b4460f3cb44f@analog.com
---
Janani Sunil (2):
dt-bindings: iio: dac: Add AD5529R
iio: dac: Add AD5529R DAC driver support
.../devicetree/bindings/iio/dac/adi,ad5529r.yaml | 208 +++++++++
MAINTAINERS | 8 +
drivers/iio/dac/Kconfig | 17 +
drivers/iio/dac/Makefile | 1 +
drivers/iio/dac/ad5529r.c | 517 +++++++++++++++++++++
5 files changed, 751 insertions(+)
---
base-commit: 93df88612859e8e19dec93c69d563b4b73e9bd4b
change-id: 20260507-ad5529r-driver-866bbdd864de
Best regards,
--
Janani Sunil <janani.sunil@analog.com>
^ permalink raw reply
* [PATCH v4 2/2] iio: dac: Add AD5529R DAC driver support
From: Janani Sunil @ 2026-06-09 15:00 UTC (permalink / raw)
To: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron,
David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Philipp Zabel, Jonathan Corbet,
Shuah Khan
Cc: linux-iio, devicetree, linux-kernel, linux-doc, Janani Sunil,
Janani Sunil
In-Reply-To: <20260609-ad5529r-driver-v4-0-2e4c02234a1a@analog.com>
Add support for AD5529R 16-channel, 12/16 bit Digital to Analog Converter
Signed-off-by: Janani Sunil <janani.sunil@analog.com>
---
MAINTAINERS | 1 +
drivers/iio/dac/Kconfig | 17 ++
drivers/iio/dac/Makefile | 1 +
drivers/iio/dac/ad5529r.c | 517 ++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 536 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 320e84765ce6..143714e27d51 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1513,6 +1513,7 @@ L: linux-iio@vger.kernel.org
S: Supported
W: https://ez.analog.com/linux-software-drivers
F: Documentation/devicetree/bindings/iio/dac/adi,ad5529r.yaml
+F: drivers/iio/dac/ad5529r.c
ANALOG DEVICES INC AD5706R DRIVER
M: Alexis Czezar Torreno <alexisczezar.torreno@analog.com>
diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig
index 657c68e75542..bb1d59889a2a 100644
--- a/drivers/iio/dac/Kconfig
+++ b/drivers/iio/dac/Kconfig
@@ -134,6 +134,23 @@ config AD5449
To compile this driver as a module, choose M here: the
module will be called ad5449.
+config AD5529R
+ tristate "Analog Devices AD5529R High Voltage DAC driver"
+ depends on SPI_MASTER
+ select REGMAP_SPI
+ help
+ Say yes here to build support for Analog Devices AD5529R
+ 16-Channel, 12-Bit/16-Bit, 40V High Voltage Precision Digital to Analog
+ Converter.
+
+ The device features multiple output voltage ranges from -20V to +20V,
+ built-in 4.096V voltage reference, and digital functions including
+ toggle, dither, and ramp modes. Supports both 12-bit and 16-bit
+ resolution variants.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ad5529r.
+
config AD5592R_BASE
tristate
diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile
index 003431798498..f35e060b3643 100644
--- a/drivers/iio/dac/Makefile
+++ b/drivers/iio/dac/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_AD5446) += ad5446.o
obj-$(CONFIG_AD5446_SPI) += ad5446-spi.o
obj-$(CONFIG_AD5446_I2C) += ad5446-i2c.o
obj-$(CONFIG_AD5449) += ad5449.o
+obj-$(CONFIG_AD5529R) += ad5529r.o
obj-$(CONFIG_AD5592R_BASE) += ad5592r-base.o
obj-$(CONFIG_AD5592R) += ad5592r.o
obj-$(CONFIG_AD5593R) += ad5593r.o
diff --git a/drivers/iio/dac/ad5529r.c b/drivers/iio/dac/ad5529r.c
new file mode 100644
index 000000000000..d2d0287d0f95
--- /dev/null
+++ b/drivers/iio/dac/ad5529r.c
@@ -0,0 +1,517 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * AD5529R Digital-to-Analog Converter Driver
+ * 16-Channel, 12/16-Bit, 40V High Voltage Precision DAC
+ *
+ * Copyright 2026 Analog Devices Inc.
+ * Author: Janani Sunil <janani.sunil@analog.com>
+ */
+
+#include <linux/array_size.h>
+#include <linux/bits.h>
+#include <linux/delay.h>
+#include <linux/dev_printk.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/iio/iio.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/reset.h>
+#include <linux/spi/spi.h>
+
+#define AD5529R_REG_INTERFACE_CONFIG_A 0x00
+#define AD5529R_REG_DEVICE_CONFIG 0x02
+#define AD5529R_REG_CHIP_GRADE 0x06
+#define AD5529R_REG_SCRATCH_PAD 0x0A
+#define AD5529R_REG_SPI_REVISION 0x0B
+#define AD5529R_REG_VENDOR_H 0x0D
+#define AD5529R_REG_STREAM_MODE 0x0E
+#define AD5529R_REG_INTERFACE_STATUS_A 0x11
+#define AD5529R_REG_MULTI_DAC_CH_SEL 0x14
+#define AD5529R_REG_OUT_RANGE_BASE 0x3C
+#define AD5529R_REG_OUT_RANGE(ch) (AD5529R_REG_OUT_RANGE_BASE + (ch) * 2)
+#define AD5529R_REG_DAC_INPUT_A_BASE 0x148
+#define AD5529R_REG_DAC_INPUT_A(ch) (AD5529R_REG_DAC_INPUT_A_BASE + (ch) * 2)
+#define AD5529R_REG_DAC_DATA_READBACK_BASE 0x16A
+#define AD5529R_REG_TSENS_ALERT_FLAG 0x18C
+#define AD5529R_REG_TSENS_SHTD_FLAG 0x18E
+#define AD5529R_REG_FUNC_BUSY 0x1A0
+#define AD5529R_REG_REF_SEL 0x1A2
+#define AD5529R_REG_INIT_CRC_ERR_STAT 0x1A4
+#define AD5529R_REG_MULTI_DAC_HOTPATH_SW_LDAC 0x1A8
+
+#define AD5529R_INTERFACE_CONFIG_A_SW_RESET (BIT(7) | BIT(0))
+#define AD5529R_INTERFACE_CONFIG_A_ADDR_ASCENSION BIT(5)
+#define AD5529R_INTERFACE_CONFIG_A_SDO_ENABLE BIT(4)
+#define AD5529R_REF_SEL_INTERNAL_REF BIT(0)
+#define AD5529R_MAX_REGISTER 0x232
+#define AD5529R_8BIT_REG_MAX 0x13
+#define AD5529R_SPI_READ_FLAG 0x80
+
+struct ad5529r_model_data {
+ const char *model_name;
+ unsigned int resolution;
+ const struct iio_chan_spec *channels;
+ unsigned int num_channels;
+};
+
+#define AD5529R_DAC_CHANNEL(chan, bits) { \
+ .type = IIO_VOLTAGE, \
+ .indexed = 1, \
+ .output = 1, \
+ .channel = (chan), \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE) | \
+ BIT(IIO_CHAN_INFO_OFFSET), \
+ .scan_type = { \
+ .format = 'u', \
+ .realbits = (bits), \
+ .storagebits = 16, \
+ }, \
+}
+
+static const char * const ad5529r_supply_names[] = {
+ "vdd",
+ "avdd",
+ "hvdd",
+};
+
+static const struct iio_chan_spec ad5529r_channels_16bit[] = {
+ AD5529R_DAC_CHANNEL(0, 16),
+ AD5529R_DAC_CHANNEL(1, 16),
+ AD5529R_DAC_CHANNEL(2, 16),
+ AD5529R_DAC_CHANNEL(3, 16),
+ AD5529R_DAC_CHANNEL(4, 16),
+ AD5529R_DAC_CHANNEL(5, 16),
+ AD5529R_DAC_CHANNEL(6, 16),
+ AD5529R_DAC_CHANNEL(7, 16),
+ AD5529R_DAC_CHANNEL(8, 16),
+ AD5529R_DAC_CHANNEL(9, 16),
+ AD5529R_DAC_CHANNEL(10, 16),
+ AD5529R_DAC_CHANNEL(11, 16),
+ AD5529R_DAC_CHANNEL(12, 16),
+ AD5529R_DAC_CHANNEL(13, 16),
+ AD5529R_DAC_CHANNEL(14, 16),
+ AD5529R_DAC_CHANNEL(15, 16),
+};
+
+static const struct iio_chan_spec ad5529r_channels_12bit[] = {
+ AD5529R_DAC_CHANNEL(0, 12),
+ AD5529R_DAC_CHANNEL(1, 12),
+ AD5529R_DAC_CHANNEL(2, 12),
+ AD5529R_DAC_CHANNEL(3, 12),
+ AD5529R_DAC_CHANNEL(4, 12),
+ AD5529R_DAC_CHANNEL(5, 12),
+ AD5529R_DAC_CHANNEL(6, 12),
+ AD5529R_DAC_CHANNEL(7, 12),
+ AD5529R_DAC_CHANNEL(8, 12),
+ AD5529R_DAC_CHANNEL(9, 12),
+ AD5529R_DAC_CHANNEL(10, 12),
+ AD5529R_DAC_CHANNEL(11, 12),
+ AD5529R_DAC_CHANNEL(12, 12),
+ AD5529R_DAC_CHANNEL(13, 12),
+ AD5529R_DAC_CHANNEL(14, 12),
+ AD5529R_DAC_CHANNEL(15, 12),
+};
+
+static const struct ad5529r_model_data ad5529r_16bit_model_data = {
+ .model_name = "ad5529r-16",
+ .resolution = 16,
+ .channels = ad5529r_channels_16bit,
+ .num_channels = ARRAY_SIZE(ad5529r_channels_16bit),
+};
+
+static const struct ad5529r_model_data ad5529r_12bit_model_data = {
+ .model_name = "ad5529r-12",
+ .resolution = 12,
+ .channels = ad5529r_channels_12bit,
+ .num_channels = ARRAY_SIZE(ad5529r_channels_12bit),
+};
+
+enum ad5529r_output_range {
+ AD5529R_RANGE_0V_5V,
+ AD5529R_RANGE_0V_10V,
+ AD5529R_RANGE_0V_20V,
+ AD5529R_RANGE_0V_40V,
+ AD5529R_RANGE_NEG5V_5V,
+ AD5529R_RANGE_NEG10V_10V,
+ AD5529R_RANGE_NEG15V_15V,
+ AD5529R_RANGE_NEG20V_20V,
+};
+
+static const s32 ad5529r_output_ranges_mv[8][2] = {
+ [AD5529R_RANGE_0V_5V] = { 0, 5000 },
+ [AD5529R_RANGE_0V_10V] = { 0, 10000 },
+ [AD5529R_RANGE_0V_20V] = { 0, 20000 },
+ [AD5529R_RANGE_0V_40V] = { 0, 40000 },
+ [AD5529R_RANGE_NEG5V_5V] = { -5000, 5000 },
+ [AD5529R_RANGE_NEG10V_10V] = { -10000, 10000 },
+ [AD5529R_RANGE_NEG15V_15V] = { -15000, 15000 },
+ [AD5529R_RANGE_NEG20V_20V] = { -20000, 20000 },
+};
+
+struct ad5529r_state {
+ struct spi_device *spi;
+ const struct ad5529r_model_data *model_data;
+ struct regmap *regmap_8bit;
+ struct regmap *regmap_16bit;
+ enum ad5529r_output_range output_range_idx[16];
+};
+
+static const struct regmap_range ad5529r_8bit_readable_ranges[] = {
+ regmap_reg_range(AD5529R_REG_INTERFACE_CONFIG_A, AD5529R_REG_CHIP_GRADE),
+ regmap_reg_range(AD5529R_REG_SCRATCH_PAD, AD5529R_REG_VENDOR_H),
+ regmap_reg_range(AD5529R_REG_STREAM_MODE, AD5529R_REG_INTERFACE_STATUS_A),
+};
+
+static const struct regmap_range ad5529r_16bit_readable_ranges[] = {
+ regmap_reg_range(AD5529R_REG_MULTI_DAC_CH_SEL, AD5529R_REG_INIT_CRC_ERR_STAT),
+ regmap_reg_range(AD5529R_REG_MULTI_DAC_HOTPATH_SW_LDAC, AD5529R_MAX_REGISTER),
+};
+
+static const struct regmap_access_table ad5529r_8bit_readable_table = {
+ .yes_ranges = ad5529r_8bit_readable_ranges,
+ .n_yes_ranges = ARRAY_SIZE(ad5529r_8bit_readable_ranges),
+};
+
+static const struct regmap_access_table ad5529r_16bit_readable_table = {
+ .yes_ranges = ad5529r_16bit_readable_ranges,
+ .n_yes_ranges = ARRAY_SIZE(ad5529r_16bit_readable_ranges),
+};
+
+static const struct regmap_range ad5529r_8bit_read_only_ranges[] = {
+ regmap_reg_range(AD5529R_REG_DEVICE_CONFIG, AD5529R_REG_CHIP_GRADE),
+ regmap_reg_range(AD5529R_REG_SPI_REVISION, AD5529R_REG_VENDOR_H),
+};
+
+static const struct regmap_range ad5529r_16bit_read_only_ranges[] = {
+ regmap_reg_range(AD5529R_REG_DAC_DATA_READBACK_BASE,
+ (AD5529R_REG_DAC_DATA_READBACK_BASE + 15 * 2)),
+ regmap_reg_range(AD5529R_REG_TSENS_ALERT_FLAG, AD5529R_REG_TSENS_SHTD_FLAG),
+ regmap_reg_range(AD5529R_REG_FUNC_BUSY, AD5529R_REG_FUNC_BUSY),
+ regmap_reg_range(AD5529R_REG_INIT_CRC_ERR_STAT, AD5529R_REG_INIT_CRC_ERR_STAT),
+};
+
+static const struct regmap_access_table ad5529r_8bit_writeable_table = {
+ .no_ranges = ad5529r_8bit_read_only_ranges,
+ .n_no_ranges = ARRAY_SIZE(ad5529r_8bit_read_only_ranges),
+};
+
+static const struct regmap_access_table ad5529r_16bit_writeable_table = {
+ .no_ranges = ad5529r_16bit_read_only_ranges,
+ .n_no_ranges = ARRAY_SIZE(ad5529r_16bit_read_only_ranges),
+};
+
+static const struct regmap_config ad5529r_regmap_8bit_config = {
+ .name = "ad5529r-8bit",
+ .reg_bits = 16,
+ .val_bits = 8,
+ .max_register = AD5529R_8BIT_REG_MAX,
+ .read_flag_mask = AD5529R_SPI_READ_FLAG,
+ .rd_table = &ad5529r_8bit_readable_table,
+ .wr_table = &ad5529r_8bit_writeable_table,
+};
+
+static const struct regmap_config ad5529r_regmap_16bit_config = {
+ .name = "ad5529r-16bit",
+ .reg_bits = 16,
+ .val_bits = 16,
+ .max_register = AD5529R_MAX_REGISTER,
+ .read_flag_mask = AD5529R_SPI_READ_FLAG,
+ .val_format_endian = REGMAP_ENDIAN_LITTLE,
+ .rd_table = &ad5529r_16bit_readable_table,
+ .wr_table = &ad5529r_16bit_writeable_table,
+ .reg_stride = 2,
+};
+
+static struct regmap *ad5529r_get_regmap(struct ad5529r_state *st,
+ unsigned int reg)
+{
+ if (reg <= AD5529R_8BIT_REG_MAX)
+ return st->regmap_8bit;
+
+ return st->regmap_16bit;
+}
+
+static int ad5529r_reset(struct ad5529r_state *st)
+{
+ struct reset_control *rst;
+ int ret;
+
+ rst = devm_reset_control_get_optional_exclusive(&st->spi->dev, NULL);
+ if (IS_ERR(rst))
+ return PTR_ERR(rst);
+
+ if (rst) {
+ ret = reset_control_deassert(rst);
+ if (ret)
+ return ret;
+ } else {
+ ret = regmap_write(st->regmap_8bit, AD5529R_REG_INTERFACE_CONFIG_A,
+ AD5529R_INTERFACE_CONFIG_A_SW_RESET);
+ if (ret)
+ return ret;
+ }
+
+ /*
+ * Wait 10 ms for digital initialization to complete.
+ * Per datasheet, Interface Status A register NOT_READY_ERR bit is
+ * set if SPI transactions are attempted before digital initialization
+ * completes.
+ */
+ fsleep(10000);
+
+ return regmap_write(st->regmap_8bit, AD5529R_REG_INTERFACE_CONFIG_A,
+ AD5529R_INTERFACE_CONFIG_A_SDO_ENABLE |
+ AD5529R_INTERFACE_CONFIG_A_ADDR_ASCENSION);
+}
+
+static int ad5529r_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct ad5529r_state *st = iio_priv(indio_dev);
+ unsigned int reg_addr, reg_val_h;
+ int ret, range_idx, span_mv;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ /*
+ * Read from DAC_INPUT_A register rather than DAC_DATA_READBACK.
+ * The DAC operates in transparent mode and directly reflects
+ * whatever value is written to the INPUT_A register.
+ */
+ reg_addr = AD5529R_REG_DAC_INPUT_A(chan->channel);
+ ret = regmap_read(st->regmap_16bit, reg_addr, ®_val_h);
+ if (ret)
+ return ret;
+
+ *val = reg_val_h;
+
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ range_idx = st->output_range_idx[chan->channel];
+
+ span_mv = ad5529r_output_ranges_mv[range_idx][1] -
+ ad5529r_output_ranges_mv[range_idx][0];
+ *val = span_mv;
+ *val2 = st->model_data->resolution;
+
+ return IIO_VAL_FRACTIONAL_LOG2;
+ case IIO_CHAN_INFO_OFFSET:
+ range_idx = st->output_range_idx[chan->channel];
+
+ if (ad5529r_output_ranges_mv[range_idx][0] < 0)
+ *val = -(1 << (st->model_data->resolution - 1));
+ else
+ *val = 0;
+
+ return IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int ad5529r_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val, int val2, long mask)
+{
+ struct ad5529r_state *st = iio_priv(indio_dev);
+ unsigned int reg_addr;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ if (val < 0 || val > GENMASK(st->model_data->resolution - 1, 0))
+ return -EINVAL;
+
+ reg_addr = AD5529R_REG_DAC_INPUT_A(chan->channel);
+
+ return regmap_write(st->regmap_16bit, reg_addr, val);
+ default:
+ return -EINVAL;
+ }
+}
+
+static int ad5529r_find_output_range(const s32 *vals)
+{
+ for (unsigned int i = 0; i < ARRAY_SIZE(ad5529r_output_ranges_mv); i++) {
+ if (vals[0] == ad5529r_output_ranges_mv[i][0] * 1000 &&
+ vals[1] == ad5529r_output_ranges_mv[i][1] * 1000)
+ return i;
+ }
+
+ return -EINVAL;
+}
+
+static int ad5529r_parse_channel_ranges(struct device *dev,
+ struct ad5529r_state *st)
+{
+ int ret, range_idx;
+ u32 ch;
+ s32 vals[2];
+
+ device_for_each_child_node_scoped(dev, child) {
+ range_idx = AD5529R_RANGE_0V_5V;
+
+ ret = fwnode_property_read_u32(child, "reg", &ch);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Missing reg property in channel node\n");
+
+ if (ch >= 16)
+ return dev_err_probe(dev, -EINVAL,
+ "Invalid channel number: %u\n", ch);
+
+ /* Read u32 property into s32 to handle negative voltage ranges */
+ if (!fwnode_property_read_u32_array(child,
+ "adi,output-range-microvolt",
+ (u32 *)vals, ARRAY_SIZE(vals))) {
+ range_idx = ad5529r_find_output_range(vals);
+ if (range_idx < 0)
+ return dev_err_probe(dev, range_idx,
+ "Invalid range [%d %d] for ch %u\n",
+ vals[0], vals[1], ch);
+ }
+
+ st->output_range_idx[ch] = range_idx;
+ ret = regmap_write(st->regmap_16bit,
+ AD5529R_REG_OUT_RANGE(ch), range_idx);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Failed to configure range for ch %u\n",
+ ch);
+ }
+
+ return 0;
+}
+
+static int ad5529r_reg_access(struct iio_dev *indio_dev,
+ unsigned int reg,
+ unsigned int writeval,
+ unsigned int *readval)
+{
+ struct ad5529r_state *st = iio_priv(indio_dev);
+
+ if (readval)
+ return regmap_read(ad5529r_get_regmap(st, reg), reg, readval);
+
+ return regmap_write(ad5529r_get_regmap(st, reg), reg, writeval);
+}
+
+static const struct iio_info ad5529r_info = {
+ .read_raw = ad5529r_read_raw,
+ .write_raw = ad5529r_write_raw,
+ .debugfs_reg_access = ad5529r_reg_access,
+};
+
+static int ad5529r_probe(struct spi_device *spi)
+{
+ struct device *dev = &spi->dev;
+ struct iio_dev *indio_dev;
+ struct ad5529r_state *st;
+ bool external_vref;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ st = iio_priv(indio_dev);
+
+ st->spi = spi;
+
+ st->model_data = spi_get_device_match_data(spi);
+ if (!st->model_data)
+ return dev_err_probe(dev, -EINVAL, "Failed to identify device variant\n");
+
+ ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(ad5529r_supply_names),
+ ad5529r_supply_names);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Failed to get and enable regulators\n");
+
+ ret = devm_regulator_get_enable_optional(dev, "hvss");
+ if (ret && ret != -ENODEV)
+ return dev_err_probe(dev, ret,
+ "Failed to get and enable hvss regulator\n");
+
+ /*
+ * The datasheet mentions a 4.096V external reference for correct
+ * operation.
+ */
+ ret = devm_regulator_get_enable_optional(dev, "vref");
+ if (ret && ret != -ENODEV)
+ return dev_err_probe(dev, ret,
+ "Failed to get and enable vref regulator\n");
+
+ external_vref = ret != -ENODEV;
+
+ st->regmap_8bit = devm_regmap_init_spi(spi, &ad5529r_regmap_8bit_config);
+ if (IS_ERR(st->regmap_8bit))
+ return dev_err_probe(dev, PTR_ERR(st->regmap_8bit),
+ "Failed to initialize 8-bit regmap\n");
+
+ st->regmap_16bit = devm_regmap_init_spi(spi, &ad5529r_regmap_16bit_config);
+ if (IS_ERR(st->regmap_16bit))
+ return dev_err_probe(dev, PTR_ERR(st->regmap_16bit),
+ "Failed to initialize 16-bit regmap\n");
+
+ ret = ad5529r_reset(st);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to reset device\n");
+
+ ret = regmap_assign_bits(st->regmap_16bit, AD5529R_REG_REF_SEL,
+ AD5529R_REF_SEL_INTERNAL_REF,
+ external_vref ? 0 : AD5529R_REF_SEL_INTERNAL_REF);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to configure reference\n");
+
+ ret = ad5529r_parse_channel_ranges(dev, st);
+ if (ret)
+ return ret;
+
+ indio_dev->name = st->model_data->model_name;
+ indio_dev->info = &ad5529r_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = st->model_data->channels;
+ indio_dev->num_channels = st->model_data->num_channels;
+
+ return devm_iio_device_register(dev, indio_dev);
+}
+
+static const struct of_device_id ad5529r_of_match[] = {
+ { .compatible = "adi,ad5529r-16", .data = &ad5529r_16bit_model_data },
+ { .compatible = "adi,ad5529r-12", .data = &ad5529r_12bit_model_data },
+ { }
+};
+MODULE_DEVICE_TABLE(of, ad5529r_of_match);
+
+static const struct spi_device_id ad5529r_id[] = {
+ {
+ .name = "ad5529r-16",
+ .driver_data = (kernel_ulong_t)&ad5529r_16bit_model_data,
+ },
+ {
+ .name = "ad5529r-12",
+ .driver_data = (kernel_ulong_t)&ad5529r_12bit_model_data,
+ },
+ { }
+};
+MODULE_DEVICE_TABLE(spi, ad5529r_id);
+
+static struct spi_driver ad5529r_driver = {
+ .driver = {
+ .name = "ad5529r",
+ .of_match_table = ad5529r_of_match,
+ },
+ .probe = ad5529r_probe,
+ .id_table = ad5529r_id,
+};
+module_spi_driver(ad5529r_driver);
+
+MODULE_AUTHOR("Janani Sunil <janani.sunil@analog.com>");
+MODULE_DESCRIPTION("Analog Devices AD5529R 12/16-bit DAC driver");
+MODULE_LICENSE("GPL");
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v5 07/10] ACPI: APEI: introduce GHES helper
From: Ahmed Tiba @ 2026-06-09 14:58 UTC (permalink / raw)
To: Jonathan Cameron
Cc: will, xueshuai, saket.dumbre, mchehab, dave, djbw, bp, tony.luck,
guohanjun, lenb, skhan, vishal.l.verma, rafael, corbet, ira.weiny,
dave.jiang, krzk+dt, robh, catalin.marinas, alison.schofield,
conor+dt, linux-arm-kernel, Michael.Zhao2, linux-doc,
linux-kernel, linux-cxl, Dmitry.Lamerov, devicetree, linux-acpi,
linux-edac, acpica-devel
In-Reply-To: <20260529172113.74c4ca05@jic23-huawei>
On 29/05/2026 17:21, Jonathan Cameron wrote:
> On Fri, 29 May 2026 10:50:47 +0100
> Ahmed Tiba <ahmed.tiba@arm.com> wrote:
>
>> Add a dedicated GHES_CPER_HELPERS Kconfig entry so the shared helper code
>> can be built even when ACPI_APEI_GHES is disabled. Update the build glue
>> and headers to depend on the new symbol.
>>
>> Signed-off-by: Ahmed Tiba <ahmed.tiba@arm.com>
> I guess it doesn't matter too much as in practice all exiting CXL systems
> are ACPI based, but is this new symbol sufficient for the
> CONFIG_CXL_RAS dependency?
>
> Rest of this looks fine to me.
CONFIG_CXL_RAS still depends on ACPI_APEI_GHES which in turn selects
GHES_CPER_HELPERS so the existing dependency for CXL RAS is unchanged.
The new symbol is intended as internal build glue under ACPI_APEI_GHES,
rather than a change to the CXL RAS dependency model.
Ahmed
^ permalink raw reply
* [PATCH v1] pnp: Documentation improvements
From: Uwe Kleine-König (The Capable Hub) @ 2026-06-09 14:51 UTC (permalink / raw)
To: Rafael J. Wysocki; +Cc: Jonathan Corbet, Shuah Khan, linux-doc, linux-kernel
- Consistently use named initializers and simplify sentinel
- Skip assignment to .driver_data if all are 0
- Use consistent spacing to match Linux coding style
- Fix prototype of probe function
- s/pnp_id/pnp_device_id/
- Drop non-existing .card_id_table
Signed-off-by: Uwe Kleine-König (The Capable Hub) <u.kleine-koenig@baylibre.com>
---
Documentation/admin-guide/pnp.rst | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)
diff --git a/Documentation/admin-guide/pnp.rst b/Documentation/admin-guide/pnp.rst
index 24d80e3eb309..14a0bf400d2d 100644
--- a/Documentation/admin-guide/pnp.rst
+++ b/Documentation/admin-guide/pnp.rst
@@ -203,12 +203,12 @@ The New Way
ex::
- static const struct pnp_id pnp_dev_table[] = {
+ static const struct pnp_device_id pnp_dev_table[] = {
/* Standard LPT Printer Port */
- {.id = "PNP0400", .driver_data = 0},
+ { .id = "PNP0400" },
/* ECP Printer Port */
- {.id = "PNP0401", .driver_data = 0},
- {.id = ""}
+ { .id = "PNP0401" },
+ { }
};
Please note that the character 'X' can be used as a wild card in the function
@@ -217,14 +217,14 @@ The New Way
ex::
/* Unknown PnP modems */
- { "PNPCXXX", UNKNOWN_DEV },
+ { .id = "PNPCXXX", .driver_data = UNKNOWN_DEV },
Supported PnP card IDs can optionally be defined.
ex::
- static const struct pnp_id pnp_card_table[] = {
- { "ANYDEVS", 0 },
- { "", 0 }
+ static const struct pnp_device_id pnp_card_table[] = {
+ { .id = "ANYDEVS" },
+ { }
};
2. Optionally define probe and remove functions. It may make sense not to
@@ -234,14 +234,13 @@ The New Way
ex::
static int
- serial_pnp_probe(struct pnp_dev * dev, const struct pnp_id *card_id, const
- struct pnp_id *dev_id)
+ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
{
. . .
ex::
- static void serial_pnp_remove(struct pnp_dev * dev)
+ static void serial_pnp_remove(struct pnp_dev *dev)
{
. . .
@@ -253,7 +252,6 @@ The New Way
static struct pnp_driver serial_pnp_driver = {
.name = "serial",
- .card_id_table = pnp_card_table,
.id_table = pnp_dev_table,
.probe = serial_pnp_probe,
.remove = serial_pnp_remove,
base-commit: a87737435cfa134f9cdcc696ba3080759d04cf72
--
2.47.3
^ permalink raw reply related
* Re: [PATCH v3 1/2] dt-bindings: iio: dac: Add AD5529R
From: Janani Sunil @ 2026-06-09 14:47 UTC (permalink / raw)
To: Rodrigo Alencar, Janani Sunil, Lars-Peter Clausen,
Michael Hennerich, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Philipp Zabel, Jonathan Corbet, Shuah Khan
Cc: linux-iio, devicetree, linux-kernel, linux-doc
In-Reply-To: <25mh6grzh7zh3b4uytcqnusyv5zjuf6ia4if3ce3oqzqz56ehi@le72iqv7ye3d>
On 5/26/26 15:11, Rodrigo Alencar wrote:
> On 26/05/19 05:42PM, Janani Sunil wrote:
>> Devicetree bindings for AD5529R 16 channel 12/16 bit high voltage,
>> buffered voltage output digital-to-analog converter (DAC) with an
>> integrated precision reference.
> ...
> Probably others may comment on that, but...
>
> This parent node may support device addressing for multi-device support through
> those ID pins. I suppose that each device may have its own power supplies or
> other resources like the toggle pins or reset and enable.
>
> That way I suppose that an example would look like...
>
>> +
>> +patternProperties:
>> + "^channel@([0-9]|1[0-5])$":
>> + type: object
>> + description: Child nodes for individual channel configuration
>> +
>> + properties:
>> + reg:
>> + description: Channel number.
>> + minimum: 0
>> + maximum: 15
>> +
>> + adi,output-range-microvolt:
>> + description: |
>> + Output voltage range for this channel as [min, max] in microvolts.
>> + If not specified, defaults to 0V to 5V range.
>> + oneOf:
>> + - items:
>> + - const: 0
>> + - enum: [5000000, 10000000, 20000000, 40000000]
>> + - items:
>> + - const: -5000000
>> + - const: 5000000
>> + - items:
>> + - const: -10000000
>> + - const: 10000000
>> + - items:
>> + - const: -15000000
>> + - const: 15000000
>> + - items:
>> + - const: -20000000
>> + - const: 20000000
>> +
>> + required:
>> + - reg
>> +
>> + additionalProperties: false
>> +
>> +required:
>> + - compatible
>> + - reg
>> + - vdd-supply
>> + - avdd-supply
>> + - hvdd-supply
>> +
>> +dependencies:
>> + spi-cpha: [ spi-cpol ]
>> + spi-cpol: [ spi-cpha ]
>> +
>> +allOf:
>> + - $ref: /schemas/spi/spi-peripheral-props.yaml#
>> +
>> +unevaluatedProperties: false
>> +
>> +examples:
>> + - |
>> + #include <dt-bindings/gpio/gpio.h>
>> +
>> + spi {
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> +
>> + dac@0 {
>> + compatible = "adi,ad5529r-16";
>> + reg = <0>;
>> + spi-max-frequency = <25000000>;
>> +
>> + vdd-supply = <&vdd_regulator>;
>> + avdd-supply = <&avdd_regulator>;
>> + hvdd-supply = <&hvdd_regulator>;
>> + hvss-supply = <&hvss_regulator>;
>> +
>> + reset-gpios = <&gpio0 87 GPIO_ACTIVE_LOW>;
>> +
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> +
>> + channel@0 {
>> + reg = <0>;
>> + adi,output-range-microvolt = <0 5000000>;
>> + };
>> +
>> + channel@1 {
>> + reg = <1>;
>> + adi,output-range-microvolt = <(-10000000) 10000000>;
>> + };
>> +
>> + channel@2 {
>> + reg = <2>;
>> + adi,output-range-microvolt = <0 40000000>;
>> + };
>> + };
>> + };
> ...
>
> spi {
> #address-cells = <1>;
> #size-cells = <0>;
>
> multi-dac@0 {
> compatible = "adi,ad5529r-16";
> reg = <0>;
> spi-max-frequency = <25000000>;
>
> #address-cells = <1>;
> #size-cells = <0>;
>
> dac@0 {
> reg = <0>;
> vdd-supply = <&vdd_regulator>;
> avdd-supply = <&avdd_regulator>;
> hvdd-supply = <&hvdd_regulator>;
> hvss-supply = <&hvss_regulator>;
>
> reset-gpios = <&gpio0 87 GPIO_ACTIVE_LOW>;
>
> #address-cells = <1>;
> #size-cells = <0>;
>
> channel@0 {
> reg = <0>;
> adi,output-range-microvolt = <0 5000000>;
> };
>
> channel@1 {
> reg = <1>;
> adi,output-range-microvolt = <(-10000000) 10000000>;
> };
>
> channel@2 {
> reg = <2>;
> adi,output-range-microvolt = <0 40000000>;
> };
> }
>
> dac@1 {
> reg = <1>;
> vdd-supply = <&vdd_regulator>;
> avdd-supply = <&avdd_regulator>;
> hvdd-supply = <&hvdd_regulator>;
> hvss-supply = <&hvss_regulator>;
>
> reset-gpios = <&gpio0 88 GPIO_ACTIVE_LOW>;
>
> #address-cells = <1>;
> #size-cells = <0>;
>
> channel@0 {
> reg = <0>;
> adi,output-range-microvolt = <0 5000000>;
> };
>
> channel@1 {
> reg = <1>;
> adi,output-range-microvolt = <(-10000000) 10000000>;
> };
> }
> };
> };
>
> then you might need something like:
>
> patternProperties:
> "^dac@[0-3]$":
>
> and put most of the things under this node pattern.
>
> So the main driver that you're putting together might need to handle up to four instances.
> Even if your current driver cannot handle this, the dt-bindings might need cover that.
>
> Need to double check if each dac node needs a separate compatible, so you would maybe populate
> a platform data to be shared with the child nodes, which would be a separate driver.
> (not sure if it would make sense to mix and match ad5529r-16 and ad5529r-12).
Hi Rodrigo,
Thank you for looking at this.
For now, I would prefer to keep the binding scoped to a single AD5529R device instance. The current
hardware/use case we have only needs one device node and the driver is written around that model as well.
While the device addressing pins could allow multi-device topology, we do not have an actual platform using
that configuration at the moment, so I would prefer not to introduce an extra parent/child binding structure
speculatively without a validating use case.
Best Regards,
Janani Sunil
^ permalink raw reply
* Re: [RFC PATCH v1 00/13] exec: add spawn templates for repeated executable startup
From: Li Chen @ 2026-06-09 14:43 UTC (permalink / raw)
To: Andy Lutomirski
Cc: Christian Brauner, Kees Cook, Alexander Viro, linux-fsdevel,
linux-api, linux-kernel, linux-mm, linux-arch, linux-doc,
linux-kselftest, x86, Arnd Bergmann, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, H. Peter Anvin, Jan Kara,
Jonathan Corbet, Shuah Khan
In-Reply-To: <CALCETrWJQpLR4n1cpichBk8=uExSKLWTMGU3BufGdk_WE_p5UA@mail.gmail.com>
Hi Andy,
---- On Tue, 09 Jun 2026 08:01:57 +0800 Andy Lutomirski <luto@kernel.org> wrote ---
> On Thu, May 28, 2026 at 4:05 AM Christian Brauner <brauner@kernel.org> wrote:
> >
> > On Thu, May 28, 2026 at 05:52:21PM +0800, Li Chen wrote:
> > > Hi,
> > >
> > > This is an early RFC for an idea that is probably still rough in both the
> > > UAPI and implementation details. Sorry for the rough edges; I am sending
> > > it now to check whether this direction is worth pursuing and to get
> > > feedback on the kernel/userspace boundary.
> >
> > The idea of having a builder api for exec isn't all that crazy. But it
> > should simply be built on top of pidfds and thus pidfs itself instead.
> > It has all the basic infrastructure in place already. Any implementation
> > should also allow userspace to implement posix_spawn() on top of it.
> >
> > fd = pidfd_open(0, PIDFD_EMPTY /* or better name */)
> >
> > pidfd_config(fd, ...) // modeled similar to fsconfig()
> >
>
> After contemplating this for a bit... why pidfd? Doesn't a pidfd
> refer to an actual process that is, or at least was, running? This
> new thing is a process that we are contemplating spawning. I can
> imagine that basically all pidfd APIs would be a bit confused by the
> nonexistence of the process in question.
>
Yes, I think that is a real concern.
In my current local WIP I tried to keep that distinction explicit.
pidfd_spawn_open() returns a pidfs-backed builder fd, not a normal pidfd
referring to a process. The builder fd is allocated as an anonymous pidfs
file with builder-specific file operations:
file = pidfs_alloc_anon_file("[pidfd_spawn]",
&pidfd_spawn_builder_fops, builder,
O_RDWR);
and the normal pidfd helpers still reject it because it does not use the
ordinary pidfd file operations:
struct pid *pidfd_pid(const struct file *file)
{
if (file->f_op != &pidfs_file_operations)
return ERR_PTR(-EBADF);
return file_inode(file)->i_private;
}
So the current split is:
builder_fd = pidfd_spawn_open(...); /* builder object */
pidfd_config(builder_fd, ...);
child_pidfd = pidfd_spawn_run(builder_fd, ...); /* real pidfd */
Only the last fd is a normal pidfd for an actual child process. The
builder fd is only accepted by the builder operations.
This avoids having to define what waitid(P_PIDFD), pidfd_send_signal(),
pidfd_getfd(), poll(), etc. mean before the process exists. The downside
is that it adds a separate open-style entry point and is less uniform than
the pidfd_open(0, PIDFD_EMPTY) spelling Christian sketched.
If people think there is a better way to represent the pre-spawn builder
state, or if the preference is to integrate it directly into pidfd_open()
with an explicit empty/future-pidfd state, I would be happy to discuss
that.
Regards,
Li
^ permalink raw reply
* Re: [PATCH v3 4/6] alloc_tag: add accuracy based filtering to ioctl
From: Suren Baghdasaryan @ 2026-06-09 14:41 UTC (permalink / raw)
To: Hao Ge
Cc: Abhishek Bapat, Shuah Khan, Jonathan Corbet, linux-doc,
linux-kernel, linux-mm, Sourav Panda, Andrew Morton,
Kent Overstreet
In-Reply-To: <ebcbe4a8-127b-4d12-83f1-dec93f0a9c61@linux.dev>
On Mon, Jun 8, 2026 at 6:26 PM Hao Ge <hao.ge@linux.dev> wrote:
>
> Hi Suren
>
>
> On 2026/6/9 04:55, Suren Baghdasaryan wrote:
> > On Mon, Jun 8, 2026 at 1:25 AM Hao Ge <hao.ge@linux.dev> wrote:
> >>
> >> On 2026/6/8 14:22, Hao Ge wrote:
> >>> Hi Abhishek
> >>>
> >>>
> >>> On 2026/6/6 07:36, Abhishek Bapat wrote:
> >>>> Extend the allocinfo filtering mechanism to allow users to filter tags
> >>>> based on their accuracy.
> >>>>
> >>>> Signed-off-by: Abhishek Bapat <abhishekbapat@google.com>
> >>>> ---
> >>>> include/uapi/linux/alloc_tag.h | 3 +++
> >>>> lib/alloc_tag.c | 8 ++++++++
> >>>> 2 files changed, 11 insertions(+)
> >>>>
> >>>> diff --git a/include/uapi/linux/alloc_tag.h
> >>>> b/include/uapi/linux/alloc_tag.h
> >>>> index 0e648192df4d..42445bdb11c5 100644
> >>>> --- a/include/uapi/linux/alloc_tag.h
> >>>> +++ b/include/uapi/linux/alloc_tag.h
> >>>> @@ -20,6 +20,7 @@ struct allocinfo_tag {
> >>>> char function[ALLOCINFO_STR_SIZE];
> >>>> char filename[ALLOCINFO_STR_SIZE];
> >>>> __u64 lineno;
> >>>> + __u64 inaccurate;
> >>>
> >>> I was wondering if it would make sense to define inaccurate as a flags
> >>> field
> >>>
> >>> (e.g. __u64 flags with ALLOCINFO_TAG_F_INACCURATE (1 <<0)),
> >>>
> >>> so that only bit 0 is used today and the upper bits are reserved for
> >>> future use,
> >>>
> >>> aligning with current kernel codebase.
> >>>
> >>> This design also allows for better extensibility if we need to
> >>>
> >>> add new flags for any reason in the future.
> >>>
> >>> We also need to add flag validity checks if we go this route.
> >>>
> >> And I've reviewed the issue reported by Sashiko, and I think it's valid.
> >>
> >> When we expand the allocinfo_tag_data structure
> >>
> >> struct allocinfo_tag_data{
> >>
> >> char modname[64];
> >>
> >> char function[64];
> >>
> >> char filename[64];
> >>
> >> __u64 lineno;
> >>
> >> __u64 inaccurate;
> >>
> >> __u64 bytes;
> >>
> >> __u64 calls;
> >>
> >> __u8 accurate;
> >> /* padding */
> >>
> >> }
> >>
> >> I think user space may see two fields related to inaccuracy.
> > Yes but one field (inside allocinfo_tag) is the input parameter which
> > user provides to specify the filtering criteria and the other is the
> > returned tag information. It's similar to any other tag attribute
> > which you can be included in the filters.
> >
> >> How do you like these modifications?
> >>
> >>
> >> diff --git a/include/uapi/linux/alloc_tag.h b/include/uapi/linux/alloc_tag.h
> >> --- a/include/uapi/linux/alloc_tag.h
> >> +++ b/include/uapi/linux/alloc_tag.h
> >> @@ -20,7 +20,6 @@ struct allocinfo_tag {
> >> char function[ALLOCINFO_STR_SIZE];
> >> char filename[ALLOCINFO_STR_SIZE];
> >> __u64 lineno;
> >> - __u64 inaccurate;
> >> };
> >>
> >> /* The alignment ensures 32-bit compatible interfaces are not broken */
> >> @@ -40,7 +39,7 @@ enum {
> >> ALLOCINFO_FILTER_FUNCTION,
> >> ALLOCINFO_FILTER_FILENAME,
> >> ALLOCINFO_FILTER_LINENO,
> >> - ALLOCINFO_FILTER_INACCURATE,
> >> + ALLOCINFO_FILTER_FLAGS,
> >> ALLOCINFO_FILTER_MIN_SIZE,
> >> ALLOCINFO_FILTER_MAX_SIZE,
> >> __ALLOCINFO_FILTER_LAST = ALLOCINFO_FILTER_MAX_SIZE
> >> @@ -50,16 +49,20 @@ enum {
> >> #define ALLOCINFO_FILTER_MASK_FUNCTION (1 <<
> >> ALLOCINFO_FILTER_FUNCTION)
> >> #define ALLOCINFO_FILTER_MASK_FILENAME (1 <<
> >> ALLOCINFO_FILTER_FILENAME)
> >> #define ALLOCINFO_FILTER_MASK_LINENO (1 << ALLOCINFO_FILTER_LINENO)
> >> -#define ALLOCINFO_FILTER_MASK_INACCURATE (1 <<
> >> ALLOCINFO_FILTER_INACCURATE)
> >> +#define ALLOCINFO_FILTER_MASK_FLAGS (1 << ALLOCINFO_FILTER_FLAGS)
> >> #define ALLOCINFO_FILTER_MASK_MIN_SIZE (1 <<
> >> ALLOCINFO_FILTER_MIN_SIZE)
> >> #define ALLOCINFO_FILTER_MASK_MAX_SIZE (1 <<
> >> ALLOCINFO_FILTER_MAX_SIZE)
> >>
> >> #define ALLOCINFO_FILTER_MASKS \
> >> ((1 << (__ALLOCINFO_FILTER_LAST + 1)) - 1)
> >>
> >> +#define ALLOCINFO_FILTER_F_INACCURATE (1ULL << 0)
> >> +#define ALLOCINFO_FILTER_FLAGS_ALL ALLOCINFO_FILTER_F_INACCURATE
> >> +
> >> struct allocinfo_filter {
> >> __u64 mask; /* bitmask of the filter fields used */
> >> struct allocinfo_tag fields;
> >> + __u64 flags; /* bitmask of ALLOCINFO_FILTER_F_* */
> >> __u64 min_size;
> >> __u64 max_size;
> >> };
> >> diff --git a/lib/alloc_tag.c b/lib/alloc_tag.c
> >> --- a/lib/alloc_tag.c
> >> +++ b/lib/alloc_tag.c
> >> @@ -249,8 +249,6 @@ static bool matches_filter(struct codetag *ct,
> >> struct allocinfo_filter *filter,
> >> struct alloc_tag_counters *counters,
> >> bool *fetched_counters)
> >> {
> >> - bool inaccurate;
> >> -
> >> if (!filter || !filter->mask)
> >> return true;
> >>
> >> @@ -277,10 +275,11 @@ static bool matches_filter(struct codetag *ct,
> >> struct allocinfo_filter *filter,
> >> ct->lineno != filter->fields.lineno)
> >> return false;
> >>
> >> - if (filter->mask & ALLOCINFO_FILTER_MASK_INACCURATE) {
> >> - inaccurate = !!(ct->flags & CODETAG_FLAG_INACCURATE);
> >> - if (inaccurate != !!(filter->fields.inaccurate))
> >> - return false;
> >> + if (filter->mask & ALLOCINFO_FILTER_MASK_FLAGS) {
> >> + if (filter->flags & ALLOCINFO_FILTER_F_INACCURATE) {
> >> + if (!(ct->flags & CODETAG_FLAG_INACCURATE))
> > How would you filter records which have only accurate data?
>
>
> Sorry, I overlooked this case.
>
> Since allocinfo_tag_data exposes both inaccurate (from allocinfo_tag) and
>
> accurate (from allocinfo_counter), userspace developers might mistakenly
> read
>
> inaccurate instead of accurate when checking accuracy.
>
> How about we add a comment to clarify?
>
> struct allocinfo_tag {
>
> /* ... */
>
> __u64 lineno;
>
> /* filter criteria only; see allocinfo_counter.accurate for actual
> accuracy */
>
> __u64 inaccurate;
I think we had comments showing which block of parameters are inputs
and which ones are outputs but I'm not opposed to an additional
reminder here.
>
> };
>
>
> LGTM for the rest.
>
>
> Thanks
>
> Best Regards
>
> Hao
>
> > Overall I would prefer ALLOCINFO_FILTER_MASK_INACCURATE rather than
> > ALLOCINFO_FILTER_MASK_FLAGS. The fact that this attribute is a
> > single-bit flag is a technical detail. It's still a tag attribuite
> > like file and module names and IMO deserves its own filter.
> >
> >
> >
> >> + return false;
> >> + }
> >> }
> >>
> >> if (filter->mask & (ALLOCINFO_FILTER_MASK_MIN_SIZE |
> >> ALLOCINFO_FILTER_MASK_MAX_SIZE)) {
> >> @@ -318,6 +317,10 @@ static int allocinfo_ioctl_get_at(struct seq_file
> >> *m, void __user *arg)
> >> if (params.filter.mask & ~ALLOCINFO_FILTER_MASKS)
> >> return -EINVAL;
> >>
> >> + if ((params.filter.mask & ALLOCINFO_FILTER_MASK_FLAGS) &&
> >> + (params.filter.flags & ~ALLOCINFO_FILTER_FLAGS_ALL))
> >> + return -EINVAL;
> >> +
> >> if ((params.filter.mask & ALLOCINFO_FILTER_MASK_MIN_SIZE) &&
> >> (params.filter.mask & ALLOCINFO_FILTER_MASK_MAX_SIZE) &&
> >> params.filter.min_size > params.filter.max_size)
> >>
> >>
> >> Thanks
> >>
> >> Best Regards
> >>
> >> Hao
> >>
> >>
> >>> Thanks
> >>>
> >>> Best Regards
> >>>
> >>> Hao
> >>>
> >>>
> >>>> };
> >>>> /* The alignment ensures 32-bit compatible interfaces are not
> >>>> broken */
> >>>> @@ -39,6 +40,7 @@ enum {
> >>>> ALLOCINFO_FILTER_FUNCTION,
> >>>> ALLOCINFO_FILTER_FILENAME,
> >>>> ALLOCINFO_FILTER_LINENO,
> >>>> + ALLOCINFO_FILTER_INACCURATE,
> >>>> ALLOCINFO_FILTER_MIN_SIZE,
> >>>> ALLOCINFO_FILTER_MAX_SIZE,
> >>>> __ALLOCINFO_FILTER_LAST = ALLOCINFO_FILTER_MAX_SIZE
> >>>> @@ -48,6 +50,7 @@ enum {
> >>>> #define ALLOCINFO_FILTER_MASK_FUNCTION (1 <<
> >>>> ALLOCINFO_FILTER_FUNCTION)
> >>>> #define ALLOCINFO_FILTER_MASK_FILENAME (1 <<
> >>>> ALLOCINFO_FILTER_FILENAME)
> >>>> #define ALLOCINFO_FILTER_MASK_LINENO (1 <<
> >>>> ALLOCINFO_FILTER_LINENO)
> >>>> +#define ALLOCINFO_FILTER_MASK_INACCURATE (1 <<
> >>>> ALLOCINFO_FILTER_INACCURATE)
> >>>> #define ALLOCINFO_FILTER_MASK_MIN_SIZE (1 <<
> >>>> ALLOCINFO_FILTER_MIN_SIZE)
> >>>> #define ALLOCINFO_FILTER_MASK_MAX_SIZE (1 <<
> >>>> ALLOCINFO_FILTER_MAX_SIZE)
> >>>> diff --git a/lib/alloc_tag.c b/lib/alloc_tag.c
> >>>> index ddc6946f56ab..cbcd12c4ef9c 100644
> >>>> --- a/lib/alloc_tag.c
> >>>> +++ b/lib/alloc_tag.c
> >>>> @@ -249,6 +249,8 @@ static bool matches_filter(struct codetag *ct,
> >>>> struct allocinfo_filter *filter,
> >>>> struct alloc_tag_counters *counters,
> >>>> bool *fetched_counters)
> >>>> {
> >>>> + bool inaccurate;
> >>>> +
> >>>> if (!filter || !filter->mask)
> >>>> return true;
> >>>> @@ -275,6 +277,12 @@ static bool matches_filter(struct codetag *ct,
> >>>> struct allocinfo_filter *filter,
> >>>> ct->lineno != filter->fields.lineno)
> >>>> return false;
> >>>> + if (filter->mask & ALLOCINFO_FILTER_MASK_INACCURATE) {
> >>>> + inaccurate = !!(ct->flags & CODETAG_FLAG_INACCURATE);
> >>>> + if (inaccurate != !!(filter->fields.inaccurate))
> >>>> + return false;
> >>>> + }
> >>>> +
> >>>> if (filter->mask & (ALLOCINFO_FILTER_MASK_MIN_SIZE |
> >>>> ALLOCINFO_FILTER_MASK_MAX_SIZE)) {
> >>>> if (!*fetched_counters) {
> >>>> *counters = allocinfo_prefetch_counters(ct);
^ permalink raw reply
* Re: [PATCH v9 2/6] mm/memory-failure: surface unhandlable kernel pages as -ENOTRECOVERABLE
From: David Hildenbrand (Arm) @ 2026-06-09 14:41 UTC (permalink / raw)
To: Breno Leitao, Miaohe Lin, Andrew Morton, Lorenzo Stoakes,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
Shuah Khan, Naoya Horiguchi, Jonathan Corbet, Shuah Khan,
Liam R. Howlett, lance.yang, Steven Rostedt, Masami Hiramatsu,
Mathieu Desnoyers
Cc: linux-mm, linux-kernel, linux-doc, linux-kselftest,
linux-trace-kernel, kernel-team
In-Reply-To: <20260609-ecc_panic-v9-2-432a74002e74@debian.org>
On 6/9/26 12:56, Breno Leitao wrote:
> get_any_page() collapses every HWPoisonHandlable() rejection into a
> single -EIO via the __get_hwpoison_page() -> -EBUSY -> shake_page()
> -> retry path. That is correct for the transient case (a userspace
> folio briefly off LRU during migration or compaction, which a later
> shake can drag back), but wrong for stable kernel-owned pages: slab,
> page-table, large-kmalloc and PG_reserved pages will never become
> HWPoisonHandlable(), so the retry loop is wasted work and the final
> -EIO loses the "this is structurally unrecoverable" information.
> memory_failure() then maps -EIO into MF_MSG_GET_HWPOISON, which the
> panic-on-unrecoverable sysctl deliberately does not act on.
>
> Introduce HWPoisonKernelOwned(), a small predicate that positively
> identifies pages the hwpoison handler cannot recover from:
>
> HWPoisonKernelOwned(p, flags) :=
> !(MF_SOFT_OFFLINE && page_has_movable_ops(p)) &&
> (PageReserved(p) ||
> PageSlab(head) || PageTable(head) || PageLargeKmalloc(head))
>
> where head = compound_head(p).
>
> PG_reserved is a per-page flag (PF_NO_COMPOUND) and is tested on the
> page directly. The slab, page-table and large-kmalloc page-type bits
> are only stored on the head page, so those tests resolve the compound
> head first, then re-read compound_head(page) afterwards: a concurrent
> split or compound free that moves head invalidates the just-read flags
> and the loop retries. The lookup still takes no refcount, mirroring
> the rest of get_any_page(); the recheck closes the common split race,
> and a residual free->alloc->free in the same window can only mis-tag
> a genuinely poisoned page, never reclassify a handlable one.
>
> The MF_SOFT_OFFLINE / page_has_movable_ops() opt-out mirrors the
> same exception in HWPoisonHandlable(): soft-offline is allowed to
> migrate movable_ops pages even though they are not on the LRU, and
> we must not pre-empt that with an unrecoverable verdict.
>
> The list is intentionally not exhaustive. vmalloc and kernel-stack
> pages, for example, do not carry a page_type bit and would need a
> different oracle; they keep going through the existing retry path
> unchanged. This is the smallest set we can identify with certainty
> by page type.
>
> Wire the helper into the top of get_any_page() to short-circuit
> those pages before the retry loop runs. On a hit, drop the caller's
> MF_COUNT_INCREASED reference (if any) and return -ENOTRECOVERABLE
> straight away. Pages outside the helper's positive list still take
> the existing retry path and return -EIO, leaving operator-visible
> behaviour for those cases unchanged.
>
> Extend the unhandlable-page pr_err() to fire for either errno and
> update the get_hwpoison_page() kerneldoc to document the new return.
>
> memory_failure() still folds every negative return into
> MF_MSG_GET_HWPOISON via its existing "else if (res < 0)" branch, so
> this patch on its own only changes the errno that soft_offline_page()
> can propagate to its callers. A follow-up wires -ENOTRECOVERABLE
> through memory_failure() and reports MF_MSG_KERNEL for the
> unrecoverable cases, which is what the
> panic_on_unrecoverable_memory_failure sysctl observes.
>
> Suggested-by: David Hildenbrand <david@kernel.org>
> Suggested-by: Lance Yang <lance.yang@linux.dev>
> Signed-off-by: Breno Leitao <leitao@debian.org>
> ---
> mm/memory-failure.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 58 insertions(+), 2 deletions(-)
>
> diff --git a/mm/memory-failure.c b/mm/memory-failure.c
> index f4d3e6e20e13..eed9de387694 100644
> --- a/mm/memory-failure.c
> +++ b/mm/memory-failure.c
> @@ -1325,6 +1325,46 @@ static inline bool HWPoisonHandlable(struct page *page, unsigned long flags)
> return PageLRU(page) || is_free_buddy_page(page);
> }
>
> +/*
> + * Positive identification of pages the hwpoison handler cannot recover.
> + * These page types are owned by kernel internals (no userspace mapping
> + * to unmap, no file mapping to invalidate, no migration target), so the
> + * shake_page() / retry loop in get_any_page() can never turn them into
> + * something HWPoisonHandlable() will accept. Short-circuit them to
> + * -ENOTRECOVERABLE so callers can panic on operator request instead of
> + * spinning through retries that exit as a transient-looking -EIO.
> + *
> + * The MF_SOFT_OFFLINE / page_has_movable_ops() opt-out mirrors
> + * HWPoisonHandlable(): soft-offline is allowed to migrate movable_ops
> + * pages even though they are not on the LRU.
> + */
> +static inline bool HWPoisonKernelOwned(struct page *page, unsigned long flags)
> +{
> + struct page *head;
> +
> + if ((flags & MF_SOFT_OFFLINE) && page_has_movable_ops(page))
> + return false;
> +
On a second look: Do we really need that? The page types below never support
migration. So I guess that check is not required?
Apart from that, looks good with two comments:
a) HWPoisonKernelOwned: this is not the common style for us to name functions.
is_kernel_owned_page() or sth like that would do.
b) The function doc can likely be simplified a bit. No need to mention the
short-circuit stuff, for example, IMHO.
--
Cheers,
David
^ permalink raw reply
* [PATCH v5 19/19] perf test cs-etm: Move existing tests to coresight folder
From: James Clark @ 2026-06-09 14:40 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, Leo Yan, Arnaldo Carvalho de Melo,
Namhyung Kim, Jiri Olsa, Ian Rogers, Amir Ayupov, Jonathan Corbet,
Shuah Khan, Paschalis Mpeis
Cc: coresight, linux-perf-users, linux-kernel,
Arnaldo Carvalho de Melo, linux-doc, James Clark
In-Reply-To: <20260609-james-cs-context-tracking-fix-v5-0-d53a7d096a19@linaro.org>
There is a subfolder for Coresight tests so might as well keep them all
in here.
Reviewed-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: James Clark <james.clark@linaro.org>
---
MAINTAINERS | 1 -
tools/perf/tests/shell/{ => coresight}/test_arm_coresight.sh | 0
tools/perf/tests/shell/{ => coresight}/test_arm_coresight_disasm.sh | 2 +-
3 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index 7efb893edcbb..ff8935b459ea 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2749,7 +2749,6 @@ F: tools/perf/arch/arm/util/auxtrace.c
F: tools/perf/arch/arm/util/cs-etm.c
F: tools/perf/arch/arm/util/cs-etm.h
F: tools/perf/arch/arm/util/pmu.c
-F: tools/perf/tests/shell/*coresight*
F: tools/perf/tests/shell/coresight/*
F: tools/perf/util/cs-etm-decoder/*
F: tools/perf/util/cs-etm.*
diff --git a/tools/perf/tests/shell/test_arm_coresight.sh b/tools/perf/tests/shell/coresight/test_arm_coresight.sh
similarity index 100%
rename from tools/perf/tests/shell/test_arm_coresight.sh
rename to tools/perf/tests/shell/coresight/test_arm_coresight.sh
diff --git a/tools/perf/tests/shell/test_arm_coresight_disasm.sh b/tools/perf/tests/shell/coresight/test_arm_coresight_disasm.sh
similarity index 96%
rename from tools/perf/tests/shell/test_arm_coresight_disasm.sh
rename to tools/perf/tests/shell/coresight/test_arm_coresight_disasm.sh
index f2fb1aa92252..ccb90dda2475 100755
--- a/tools/perf/tests/shell/test_arm_coresight_disasm.sh
+++ b/tools/perf/tests/shell/coresight/test_arm_coresight_disasm.sh
@@ -24,7 +24,7 @@ perfdata_dir=$(mktemp -d /tmp/__perf_test.perf.data.XXXXX)
perfdata=${perfdata_dir}/perf.data
file=$(mktemp /tmp/temporary_file.XXXXX)
# Relative path works whether it's installed or running from repo
-script_path=$(dirname "$0")/../../scripts/python/arm-cs-trace-disasm.py
+script_path=$(dirname "$0")/../../../scripts/python/arm-cs-trace-disasm.py
cleanup_files()
{
--
2.34.1
^ permalink raw reply related
* [PATCH v5 18/19] perf test cs-etm: Speed up disassembly test
From: James Clark @ 2026-06-09 14:40 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, Leo Yan, Arnaldo Carvalho de Melo,
Namhyung Kim, Jiri Olsa, Ian Rogers, Amir Ayupov, Jonathan Corbet,
Shuah Khan, Paschalis Mpeis
Cc: coresight, linux-perf-users, linux-kernel,
Arnaldo Carvalho de Melo, linux-doc, James Clark
In-Reply-To: <20260609-james-cs-context-tracking-fix-v5-0-d53a7d096a19@linaro.org>
We can use exit snapshot to limit the amount of trace to decode here
too. Also each call to objdump is quite expensive on kcore so limit it
to 2 samples instead of 30. We only want to see if there is no data at
all.
Reviewed-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: James Clark <james.clark@linaro.org>
---
tools/perf/tests/shell/test_arm_coresight_disasm.sh | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tools/perf/tests/shell/test_arm_coresight_disasm.sh b/tools/perf/tests/shell/test_arm_coresight_disasm.sh
index f78dfb6bf73e..f2fb1aa92252 100755
--- a/tools/perf/tests/shell/test_arm_coresight_disasm.sh
+++ b/tools/perf/tests/shell/test_arm_coresight_disasm.sh
@@ -43,9 +43,9 @@ branch_search='[[:space:]](bl|b(\.(eq|ne|cs|cc|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al)
## Test kernel ##
if [ "$(id -u)" == 0 ] && [ -e /proc/kcore ]; then
echo "Testing kernel disassembly"
- perf record -o ${perfdata} -e cs_etm//k --kcore -- touch $file > /dev/null 2>&1
+ perf record -o ${perfdata} -e cs_etm//k --kcore -Se -m,64K -- touch $file > /dev/null 2>&1
perf script -i ${perfdata} -s python:${script_path} -- \
- -d --stop-sample=30 -k ${perfdata}/kcore_dir/kcore 2> /dev/null > ${file}
+ -d --stop-sample=2 -k ${perfdata}/kcore_dir/kcore 2> /dev/null > ${file}
grep -q -E ${branch_search} ${file}
echo "Found kernel branches"
else
@@ -55,9 +55,9 @@ fi
## Test user ##
echo "Testing userspace disassembly"
-perf record -o ${perfdata} -e cs_etm//u -- touch $file > /dev/null 2>&1
+perf record -o ${perfdata} -e cs_etm//u -Se -m,64K -- touch $file > /dev/null 2>&1
perf script -i ${perfdata} -s python:${script_path} -- \
- -d --stop-sample=30 2> /dev/null > ${file}
+ -d --stop-sample=2 2> /dev/null > ${file}
grep -q -E ${branch_search} ${file}
echo "Found userspace branches"
--
2.34.1
^ permalink raw reply related
* [PATCH v5 17/19] perf test cs-etm: Add all branch instructions to test
From: James Clark @ 2026-06-09 14:40 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, Leo Yan, Arnaldo Carvalho de Melo,
Namhyung Kim, Jiri Olsa, Ian Rogers, Amir Ayupov, Jonathan Corbet,
Shuah Khan, Paschalis Mpeis
Cc: coresight, linux-perf-users, linux-kernel,
Arnaldo Carvalho de Melo, linux-doc, James Clark
In-Reply-To: <20260609-james-cs-context-tracking-fix-v5-0-d53a7d096a19@linaro.org>
If we reduce the number of samples searched to speed up the test, then
there will be less chance of hitting one of these branches. Extend the
regex to cover all branches so the test will always pass.
Reviewed-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: James Clark <james.clark@linaro.org>
---
tools/perf/tests/shell/test_arm_coresight_disasm.sh | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/tools/perf/tests/shell/test_arm_coresight_disasm.sh b/tools/perf/tests/shell/test_arm_coresight_disasm.sh
index 87797d239f76..f78dfb6bf73e 100755
--- a/tools/perf/tests/shell/test_arm_coresight_disasm.sh
+++ b/tools/perf/tests/shell/test_arm_coresight_disasm.sh
@@ -38,8 +38,7 @@ cleanup_files()
trap cleanup_files EXIT TERM INT
# Ranges start and end on branches, so check for some likely branch instructions
-sep="\s\|\s"
-branch_search="\sbl${sep}b${sep}b.ne${sep}b.eq${sep}cbz\s"
+branch_search='[[:space:]](bl|b(\.(eq|ne|cs|cc|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al))?|br|blr|ret|cbz|cbnz|tbz|tbnz|svc|eret)([[:space:]]|$)'
## Test kernel ##
if [ "$(id -u)" == 0 ] && [ -e /proc/kcore ]; then
@@ -47,7 +46,7 @@ if [ "$(id -u)" == 0 ] && [ -e /proc/kcore ]; then
perf record -o ${perfdata} -e cs_etm//k --kcore -- touch $file > /dev/null 2>&1
perf script -i ${perfdata} -s python:${script_path} -- \
-d --stop-sample=30 -k ${perfdata}/kcore_dir/kcore 2> /dev/null > ${file}
- grep -q -e ${branch_search} ${file}
+ grep -q -E ${branch_search} ${file}
echo "Found kernel branches"
else
# Root and kcore are required for correct kernel decode due to runtime code patching
@@ -59,7 +58,7 @@ echo "Testing userspace disassembly"
perf record -o ${perfdata} -e cs_etm//u -- touch $file > /dev/null 2>&1
perf script -i ${perfdata} -s python:${script_path} -- \
-d --stop-sample=30 2> /dev/null > ${file}
-grep -q -e ${branch_search} ${file}
+grep -q -E ${branch_search} ${file}
echo "Found userspace branches"
glb_err=0
--
2.34.1
^ permalink raw reply related
* [PATCH v5 16/19] perf test cs-etm: Make disassembly test use kcore
From: James Clark @ 2026-06-09 14:40 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, Leo Yan, Arnaldo Carvalho de Melo,
Namhyung Kim, Jiri Olsa, Ian Rogers, Amir Ayupov, Jonathan Corbet,
Shuah Khan, Paschalis Mpeis
Cc: coresight, linux-perf-users, linux-kernel,
Arnaldo Carvalho de Melo, linux-doc, James Clark
In-Reply-To: <20260609-james-cs-context-tracking-fix-v5-0-d53a7d096a19@linaro.org>
Hits in modules return empty disassembly with vmlinux as an input to
objdump. Make the disassembly test more reliable by always using kcore.
And update the comments to say that this is supported by the script.
Signed-off-by: James Clark <james.clark@linaro.org>
---
tools/perf/scripts/python/arm-cs-trace-disasm.py | 20 ++++++++++----------
tools/perf/tests/shell/test_arm_coresight_disasm.sh | 2 +-
2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/tools/perf/scripts/python/arm-cs-trace-disasm.py b/tools/perf/scripts/python/arm-cs-trace-disasm.py
index ba208c90d631..8f6fa4a007b4 100755
--- a/tools/perf/scripts/python/arm-cs-trace-disasm.py
+++ b/tools/perf/scripts/python/arm-cs-trace-disasm.py
@@ -18,29 +18,29 @@ from perf_trace_context import perf_sample_srccode, perf_config_get
# Below are some example commands for using this script.
# Note a --kcore recording is required for accurate decode
-# due to the alternatives patching mechanism. However this
-# script only supports reading vmlinux for disassembly dump,
-# meaning that any patched instructions will appear
-# as unpatched, but the instruction ranges themselves will
-# be correct. In addition to this, source line info comes
-# from Perf, and when using kcore there is no debug info. The
-# following lists the supported features in each mode:
+# due to the alternatives patching mechanism. In addition to this,
+# source line info comes from Perf, and when using kcore there is
+# no debug info. The following lists the supported features in each mode:
#
# +-----------+-----------------+------------------+------------------+
# | Recording | Accurate decode | Source line dump | Disassembly dump |
# +-----------+-----------------+------------------+------------------+
# | --kcore | yes | no | yes |
-# | normal | no | yes | yes |
+# | normal | no | yes (inaccurate) | yes (inaccurate) |
# +-----------+-----------------+------------------+------------------+
#
# Output disassembly with objdump and auto detect vmlinux
-# (when running on same machine.)
+# (when running on same machine.):
# perf script -s scripts/python/arm-cs-trace-disasm.py -d
#
# Output disassembly with llvm-objdump:
# perf script -s scripts/python/arm-cs-trace-disasm.py \
# -- -d llvm-objdump-11 -k path/to/vmlinux
#
+# Output accurate disassembly by passing kcore to script:
+# perf script -s scripts/python/arm-cs-trace-disasm.py \
+# -- -d -k perf.data/kcore_dir/kcore
+#
# Output only source line and symbols:
# perf script -s scripts/python/arm-cs-trace-disasm.py
@@ -57,7 +57,7 @@ def int_arg(v):
args = argparse.ArgumentParser()
args.add_argument("-k", "--vmlinux",
- help="Set path to vmlinux file. Omit to autodetect if running on same machine")
+ help="Set path to vmlinux or kcore file. Omit to autodetect if running on same machine")
args.add_argument("-d", "--objdump", nargs="?", const=default_objdump(),
help="Show disassembly. Can also be used to change the objdump path"),
args.add_argument("-v", "--verbose", action="store_true", help="Enable debugging log")
diff --git a/tools/perf/tests/shell/test_arm_coresight_disasm.sh b/tools/perf/tests/shell/test_arm_coresight_disasm.sh
index 339ae4831868..87797d239f76 100755
--- a/tools/perf/tests/shell/test_arm_coresight_disasm.sh
+++ b/tools/perf/tests/shell/test_arm_coresight_disasm.sh
@@ -46,7 +46,7 @@ if [ "$(id -u)" == 0 ] && [ -e /proc/kcore ]; then
echo "Testing kernel disassembly"
perf record -o ${perfdata} -e cs_etm//k --kcore -- touch $file > /dev/null 2>&1
perf script -i ${perfdata} -s python:${script_path} -- \
- -d --stop-sample=30 2> /dev/null > ${file}
+ -d --stop-sample=30 -k ${perfdata}/kcore_dir/kcore 2> /dev/null > ${file}
grep -q -e ${branch_search} ${file}
echo "Found kernel branches"
else
--
2.34.1
^ permalink raw reply related
* [PATCH v5 15/19] perf test cs-etm: Remove unused Coresight workloads
From: James Clark @ 2026-06-09 14:40 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, Leo Yan, Arnaldo Carvalho de Melo,
Namhyung Kim, Jiri Olsa, Ian Rogers, Amir Ayupov, Jonathan Corbet,
Shuah Khan, Paschalis Mpeis
Cc: coresight, linux-perf-users, linux-kernel,
Arnaldo Carvalho de Melo, linux-doc, James Clark
In-Reply-To: <20260609-james-cs-context-tracking-fix-v5-0-d53a7d096a19@linaro.org>
These are now unused and had various issues like not working with out of
source builds and being slow to compile. Delete them.
Signed-off-by: James Clark <james.clark@linaro.org>
---
Documentation/trace/coresight/coresight-perf.rst | 78 +-----------
MAINTAINERS | 1 -
tools/perf/Makefile.perf | 14 +--
tools/perf/tests/shell/coresight/Makefile | 29 -----
.../perf/tests/shell/coresight/Makefile.miniconfig | 14 ---
.../tests/shell/coresight/asm_pure_loop/.gitignore | 1 -
.../tests/shell/coresight/asm_pure_loop/Makefile | 34 ------
.../shell/coresight/asm_pure_loop/asm_pure_loop.S | 30 -----
.../tests/shell/coresight/memcpy_thread/.gitignore | 1 -
.../tests/shell/coresight/memcpy_thread/Makefile | 33 -----
.../shell/coresight/memcpy_thread/memcpy_thread.c | 80 ------------
.../tests/shell/coresight/thread_loop/.gitignore | 1 -
.../tests/shell/coresight/thread_loop/Makefile | 33 -----
.../shell/coresight/thread_loop/thread_loop.c | 85 -------------
.../shell/coresight/unroll_loop_thread/.gitignore | 1 -
.../shell/coresight/unroll_loop_thread/Makefile | 33 -----
.../unroll_loop_thread/unroll_loop_thread.c | 75 ------------
tools/perf/tests/shell/lib/coresight.sh | 134 ---------------------
18 files changed, 5 insertions(+), 672 deletions(-)
diff --git a/Documentation/trace/coresight/coresight-perf.rst b/Documentation/trace/coresight/coresight-perf.rst
index 30be89320621..0a77741a431e 100644
--- a/Documentation/trace/coresight/coresight-perf.rst
+++ b/Documentation/trace/coresight/coresight-perf.rst
@@ -112,78 +112,6 @@ Example for triggering AUX pause and resume with PMU event::
Perf test - Verify kernel and userspace perf CoreSight work
-----------------------------------------------------------
-When you run perf test, it will do a lot of self tests. Some of those
-tests will cover CoreSight (only if enabled and on ARM64). You
-generally would run perf test from the tools/perf directory in the
-kernel tree. Some tests will check some internal perf support like:
-
- Check Arm CoreSight trace data recording and synthesized samples
- Check Arm SPE trace data recording and synthesized samples
-
-Some others will actually use perf record and some test binaries that
-are in tests/shell/coresight and will collect traces to ensure a
-minimum level of functionality is met. The scripts that launch these
-tests are in the same directory. These will all look like:
-
- CoreSight / ASM Pure Loop
- CoreSight / Memcpy 16k 10 Threads
- CoreSight / Thread Loop 10 Threads - Check TID
- etc.
-
-These perf record tests will not run if the tool binaries do not exist
-in tests/shell/coresight/\*/ and will be skipped. If you do not have
-CoreSight support in hardware then either do not build perf with
-CoreSight support or remove these binaries in order to not have these
-tests fail and have them skip instead.
-
-These tests will log historical results in the current working
-directory (e.g. tools/perf) and will be named stats-\*.csv like:
-
- stats-asm_pure_loop-out.csv
- stats-memcpy_thread-16k_10.csv
- ...
-
-These statistic files log some aspects of the AUX data sections in
-the perf data output counting some numbers of certain encodings (a
-good way to know that it's working in a very simple way). One problem
-with CoreSight is that given a large enough amount of data needing to
-be logged, some of it can be lost due to the processor not waking up
-in time to read out all the data from buffers etc.. You will notice
-that the amount of data collected can vary a lot per run of perf test.
-If you wish to see how this changes over time, simply run perf test
-multiple times and all these csv files will have more and more data
-appended to it that you can later examine, graph and otherwise use to
-figure out if things have become worse or better.
-
-This means sometimes these tests fail as they don't capture all the
-data needed. This is about tracking quality and amount of data
-produced over time and to see when changes to the Linux kernel improve
-quality of traces.
-
-Be aware that some of these tests take quite a while to run, specifically
-in processing the perf data file and dumping contents to then examine what
-is inside.
-
-You can change where these csv logs are stored by setting the
-PERF_TEST_CORESIGHT_STATDIR environment variable before running perf
-test like::
-
- export PERF_TEST_CORESIGHT_STATDIR=/var/tmp
- perf test
-
-They will also store resulting perf output data in the current
-directory for later inspection like::
-
- perf-asm_pure_loop-out.data
- perf-memcpy_thread-16k_10.data
- ...
-
-You can alter where the perf data files are stored by setting the
-PERF_TEST_CORESIGHT_DATADIR environment variable such as::
-
- PERF_TEST_CORESIGHT_DATADIR=/var/tmp
- perf test
-
-You may wish to set these above environment variables if you wish to
-keep the output of tests outside of the current working directory for
-longer term storage and examination.
+There are a set of Perf tests for CoreSight which can be run with::
+
+ sudo perf test coresight
diff --git a/MAINTAINERS b/MAINTAINERS
index b539be153f6a..7efb893edcbb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2751,7 +2751,6 @@ F: tools/perf/arch/arm/util/cs-etm.h
F: tools/perf/arch/arm/util/pmu.c
F: tools/perf/tests/shell/*coresight*
F: tools/perf/tests/shell/coresight/*
-F: tools/perf/tests/shell/lib/*coresight*
F: tools/perf/util/cs-etm-decoder/*
F: tools/perf/util/cs-etm.*
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index ab661a1d271c..f29c267bf842 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -508,16 +508,7 @@ arm64-sysreg-defs-clean:
$(Q)$(MAKE) -C $(arm64_gen_sysreg_dir) O=$(arm64_gen_sysreg_outdir) \
prefix= subdir= clean > /dev/null
-TESTS_CORESIGHT_DIR := $(srctree)/tools/perf/tests/shell/coresight
-
-tests-coresight-targets: FORCE
- $(Q)$(MAKE) -C $(TESTS_CORESIGHT_DIR)
-
-tests-coresight-targets-clean:
- $(call QUIET_CLEAN, coresight)
- $(Q)$(MAKE) -C $(TESTS_CORESIGHT_DIR) O=$(OUTPUT) clean >/dev/null
-
-all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS) tests-coresight-targets
+all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS)
# Create python binding output directory if not already present
$(shell [ -d '$(OUTPUT)python' ] || mkdir -p '$(OUTPUT)python')
@@ -896,7 +887,6 @@ install-tests: all install-gtk
$(INSTALL) tests/shell/base_report/*.txt '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/base_report'; \
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/coresight' ; \
$(INSTALL) tests/shell/coresight/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/coresight'
- $(Q)$(MAKE) -C tests/shell/coresight install-tests
install-bin: install-tools install-tests
@@ -939,7 +929,7 @@ endif
clean:: $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBSYMBOL)-clean $(LIBPERF)-clean \
arm64-sysreg-defs-clean fixdep-clean python-clean bpf-skel-clean \
- tests-coresight-targets-clean pmu-events-clean
+ pmu-events-clean
$(call QUIET_CLEAN, core-objs) $(RM) $(LIBPERF_A) $(OUTPUT)perf-archive \
$(OUTPUT)perf-iostat $(LANG_BINDINGS)
$(Q)find $(or $(OUTPUT),.) -name '*.o' -delete -o -name '*.a' -delete -o \
diff --git a/tools/perf/tests/shell/coresight/Makefile b/tools/perf/tests/shell/coresight/Makefile
deleted file mode 100644
index fa08fd9a5991..000000000000
--- a/tools/perf/tests/shell/coresight/Makefile
+++ /dev/null
@@ -1,29 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-# Carsten Haitzler <carsten.haitzler@arm.com>, 2021
-include ../../../../../tools/scripts/Makefile.include
-include ../../../../../tools/scripts/Makefile.arch
-include ../../../../../tools/scripts/utilities.mak
-
-SUBDIRS = \
- asm_pure_loop \
- memcpy_thread \
- thread_loop \
- unroll_loop_thread
-
-all: $(SUBDIRS)
-$(SUBDIRS):
- @$(MAKE) -C $@ >/dev/null
-
-INSTALLDIRS = $(SUBDIRS:%=install-%)
-
-install-tests: $(INSTALLDIRS)
-$(INSTALLDIRS):
- @$(MAKE) -C $(@:install-%=%) install-tests >/dev/null
-
-CLEANDIRS = $(SUBDIRS:%=clean-%)
-
-clean: $(CLEANDIRS)
-$(CLEANDIRS):
- $(call QUIET_CLEAN, test-$(@:clean-%=%)) $(MAKE) -C $(@:clean-%=%) clean >/dev/null
-
-.PHONY: all clean $(SUBDIRS) $(CLEANDIRS) $(INSTALLDIRS)
diff --git a/tools/perf/tests/shell/coresight/Makefile.miniconfig b/tools/perf/tests/shell/coresight/Makefile.miniconfig
deleted file mode 100644
index 5f72a9cb43f3..000000000000
--- a/tools/perf/tests/shell/coresight/Makefile.miniconfig
+++ /dev/null
@@ -1,14 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-# Carsten Haitzler <carsten.haitzler@arm.com>, 2021
-
-ifndef DESTDIR
-prefix ?= $(HOME)
-endif
-
-DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
-INSTALL = install
-INSTDIR_SUB = tests/shell/coresight
-
-include ../../../../../scripts/Makefile.include
-include ../../../../../scripts/Makefile.arch
-include ../../../../../scripts/utilities.mak
diff --git a/tools/perf/tests/shell/coresight/asm_pure_loop/.gitignore b/tools/perf/tests/shell/coresight/asm_pure_loop/.gitignore
deleted file mode 100644
index 468673ac32e8..000000000000
--- a/tools/perf/tests/shell/coresight/asm_pure_loop/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-asm_pure_loop
diff --git a/tools/perf/tests/shell/coresight/asm_pure_loop/Makefile b/tools/perf/tests/shell/coresight/asm_pure_loop/Makefile
deleted file mode 100644
index 206849e92bc9..000000000000
--- a/tools/perf/tests/shell/coresight/asm_pure_loop/Makefile
+++ /dev/null
@@ -1,34 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-# Carsten Haitzler <carsten.haitzler@arm.com>, 2021
-
-include ../Makefile.miniconfig
-
-# Binary to produce
-BIN=asm_pure_loop
-# Any linking/libraries needed for the binary - empty if none needed
-LIB=
-
-all: $(BIN)
-
-$(BIN): $(BIN).S
-ifdef CORESIGHT
-ifeq ($(ARCH),arm64)
-# Build line - this is raw asm with no libc to have an always exact binary
- $(Q)$(CC) $(BIN).S -nostdlib -static -o $(BIN) $(LIB)
-endif
-endif
-
-install-tests: all
-ifdef CORESIGHT
-ifeq ($(ARCH),arm64)
-# Install the test tool in the right place
- $(call QUIET_INSTALL, tests) \
- $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/$(INSTDIR_SUB)/$(BIN)'; \
- $(INSTALL) $(BIN) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/$(INSTDIR_SUB)/$(BIN)/$(BIN)'
-endif
-endif
-
-clean:
- $(Q)$(RM) -f $(BIN)
-
-.PHONY: all clean install-tests
diff --git a/tools/perf/tests/shell/coresight/asm_pure_loop/asm_pure_loop.S b/tools/perf/tests/shell/coresight/asm_pure_loop/asm_pure_loop.S
deleted file mode 100644
index 577760046772..000000000000
--- a/tools/perf/tests/shell/coresight/asm_pure_loop/asm_pure_loop.S
+++ /dev/null
@@ -1,30 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Tamas Zsoldos <tamas.zsoldos@arm.com>, 2021 */
-
-.globl _start
-_start:
- mov x0, 0x0000ffff
- mov x1, xzr
-loop:
- nop
- nop
- cbnz x1, noskip
- nop
- nop
- adrp x2, skip
- add x2, x2, :lo12:skip
- br x2
- nop
- nop
-noskip:
- nop
- nop
-skip:
- sub x0, x0, 1
- cbnz x0, loop
-
- mov x0, #0
- mov x8, #93 // __NR_exit syscall
- svc #0
-
-.section .note.GNU-stack, "", @progbits
diff --git a/tools/perf/tests/shell/coresight/memcpy_thread/.gitignore b/tools/perf/tests/shell/coresight/memcpy_thread/.gitignore
deleted file mode 100644
index f8217e56091e..000000000000
--- a/tools/perf/tests/shell/coresight/memcpy_thread/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-memcpy_thread
diff --git a/tools/perf/tests/shell/coresight/memcpy_thread/Makefile b/tools/perf/tests/shell/coresight/memcpy_thread/Makefile
deleted file mode 100644
index 2db637eb2c26..000000000000
--- a/tools/perf/tests/shell/coresight/memcpy_thread/Makefile
+++ /dev/null
@@ -1,33 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-# Carsten Haitzler <carsten.haitzler@arm.com>, 2021
-include ../Makefile.miniconfig
-
-# Binary to produce
-BIN=memcpy_thread
-# Any linking/libraries needed for the binary - empty if none needed
-LIB=-pthread
-
-all: $(BIN)
-
-$(BIN): $(BIN).c
-ifdef CORESIGHT
-ifeq ($(ARCH),arm64)
-# Build line
- $(Q)$(CC) $(BIN).c -o $(BIN) $(LIB)
-endif
-endif
-
-install-tests: all
-ifdef CORESIGHT
-ifeq ($(ARCH),arm64)
-# Install the test tool in the right place
- $(call QUIET_INSTALL, tests) \
- $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/$(INSTDIR_SUB)/$(BIN)'; \
- $(INSTALL) $(BIN) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/$(INSTDIR_SUB)/$(BIN)/$(BIN)'
-endif
-endif
-
-clean:
- $(Q)$(RM) -f $(BIN)
-
-.PHONY: all clean install-tests
diff --git a/tools/perf/tests/shell/coresight/memcpy_thread/memcpy_thread.c b/tools/perf/tests/shell/coresight/memcpy_thread/memcpy_thread.c
deleted file mode 100644
index 7e879217be30..000000000000
--- a/tools/perf/tests/shell/coresight/memcpy_thread/memcpy_thread.c
+++ /dev/null
@@ -1,80 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Carsten Haitzler <carsten.haitzler@arm.com>, 2021
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <pthread.h>
-
-struct args {
- unsigned long loops;
- unsigned long size;
- pthread_t th;
- void *ret;
-};
-
-static void *thrfn(void *arg)
-{
- struct args *a = arg;
- unsigned long i, len = a->loops;
- unsigned char *src, *dst;
-
- src = malloc(a->size * 1024);
- dst = malloc(a->size * 1024);
- if ((!src) || (!dst)) {
- printf("ERR: Can't allocate memory\n");
- exit(1);
- }
- for (i = 0; i < len; i++)
- memcpy(dst, src, a->size * 1024);
-
- return NULL;
-}
-
-static pthread_t new_thr(void *(*fn) (void *arg), void *arg)
-{
- pthread_t t;
- pthread_attr_t attr;
-
- pthread_attr_init(&attr);
- pthread_create(&t, &attr, fn, arg);
- return t;
-}
-
-int main(int argc, char **argv)
-{
- unsigned long i, len, size, thr;
- struct args args[256];
- long long v;
-
- if (argc < 4) {
- printf("ERR: %s [copysize Kb] [numthreads] [numloops (hundreds)]\n", argv[0]);
- exit(1);
- }
-
- v = atoll(argv[1]);
- if ((v < 1) || (v > (1024 * 1024))) {
- printf("ERR: max memory 1GB (1048576 KB)\n");
- exit(1);
- }
- size = v;
- thr = atol(argv[2]);
- if ((thr < 1) || (thr > 256)) {
- printf("ERR: threads 1-256\n");
- exit(1);
- }
- v = atoll(argv[3]);
- if ((v < 1) || (v > 40000000000ll)) {
- printf("ERR: loops 1-40000000000 (hundreds)\n");
- exit(1);
- }
- len = v * 100;
- for (i = 0; i < thr; i++) {
- args[i].loops = len;
- args[i].size = size;
- args[i].th = new_thr(thrfn, &(args[i]));
- }
- for (i = 0; i < thr; i++)
- pthread_join(args[i].th, &(args[i].ret));
- return 0;
-}
diff --git a/tools/perf/tests/shell/coresight/thread_loop/.gitignore b/tools/perf/tests/shell/coresight/thread_loop/.gitignore
deleted file mode 100644
index 6d4c33eaa9e8..000000000000
--- a/tools/perf/tests/shell/coresight/thread_loop/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-thread_loop
diff --git a/tools/perf/tests/shell/coresight/thread_loop/Makefile b/tools/perf/tests/shell/coresight/thread_loop/Makefile
deleted file mode 100644
index ea846c038e7a..000000000000
--- a/tools/perf/tests/shell/coresight/thread_loop/Makefile
+++ /dev/null
@@ -1,33 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-# Carsten Haitzler <carsten.haitzler@arm.com>, 2021
-include ../Makefile.miniconfig
-
-# Binary to produce
-BIN=thread_loop
-# Any linking/libraries needed for the binary - empty if none needed
-LIB=-pthread
-
-all: $(BIN)
-
-$(BIN): $(BIN).c
-ifdef CORESIGHT
-ifeq ($(ARCH),arm64)
-# Build line
- $(Q)$(CC) $(BIN).c -o $(BIN) $(LIB)
-endif
-endif
-
-install-tests: all
-ifdef CORESIGHT
-ifeq ($(ARCH),arm64)
-# Install the test tool in the right place
- $(call QUIET_INSTALL, tests) \
- $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/$(INSTDIR_SUB)/$(BIN)'; \
- $(INSTALL) $(BIN) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/$(INSTDIR_SUB)/$(BIN)/$(BIN)'
-endif
-endif
-
-clean:
- $(Q)$(RM) -f $(BIN)
-
-.PHONY: all clean install-tests
diff --git a/tools/perf/tests/shell/coresight/thread_loop/thread_loop.c b/tools/perf/tests/shell/coresight/thread_loop/thread_loop.c
deleted file mode 100644
index 86f3f548b006..000000000000
--- a/tools/perf/tests/shell/coresight/thread_loop/thread_loop.c
+++ /dev/null
@@ -1,85 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Carsten Haitzler <carsten.haitzler@arm.com>, 2021
-
-// define this for gettid()
-#define _GNU_SOURCE
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <pthread.h>
-#include <sys/syscall.h>
-#ifndef SYS_gettid
-// gettid is 178 on arm64
-# define SYS_gettid 178
-#endif
-#define gettid() syscall(SYS_gettid)
-
-struct args {
- unsigned int loops;
- pthread_t th;
- void *ret;
-};
-
-static void *thrfn(void *arg)
-{
- struct args *a = arg;
- int i = 0, len = a->loops;
-
- if (getenv("SHOW_TID")) {
- unsigned long long tid = gettid();
-
- printf("%llu\n", tid);
- }
- asm volatile(
- "loop:\n"
- "add %w[i], %w[i], #1\n"
- "cmp %w[i], %w[len]\n"
- "blt loop\n"
- : /* out */
- : /* in */ [i] "r" (i), [len] "r" (len)
- : /* clobber */
- );
- return (void *)(long)i;
-}
-
-static pthread_t new_thr(void *(*fn) (void *arg), void *arg)
-{
- pthread_t t;
- pthread_attr_t attr;
-
- pthread_attr_init(&attr);
- pthread_create(&t, &attr, fn, arg);
- return t;
-}
-
-int main(int argc, char **argv)
-{
- unsigned int i, len, thr;
- struct args args[256];
-
- if (argc < 3) {
- printf("ERR: %s [numthreads] [numloops (millions)]\n", argv[0]);
- exit(1);
- }
-
- thr = atoi(argv[1]);
- if ((thr < 1) || (thr > 256)) {
- printf("ERR: threads 1-256\n");
- exit(1);
- }
- len = atoi(argv[2]);
- if ((len < 1) || (len > 4000)) {
- printf("ERR: max loops 4000 (millions)\n");
- exit(1);
- }
- len *= 1000000;
- for (i = 0; i < thr; i++) {
- args[i].loops = len;
- args[i].th = new_thr(thrfn, &(args[i]));
- }
- for (i = 0; i < thr; i++)
- pthread_join(args[i].th, &(args[i].ret));
- return 0;
-}
diff --git a/tools/perf/tests/shell/coresight/unroll_loop_thread/.gitignore b/tools/perf/tests/shell/coresight/unroll_loop_thread/.gitignore
deleted file mode 100644
index 2cb4e996dbf3..000000000000
--- a/tools/perf/tests/shell/coresight/unroll_loop_thread/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-unroll_loop_thread
diff --git a/tools/perf/tests/shell/coresight/unroll_loop_thread/Makefile b/tools/perf/tests/shell/coresight/unroll_loop_thread/Makefile
deleted file mode 100644
index 6264c4e3abd1..000000000000
--- a/tools/perf/tests/shell/coresight/unroll_loop_thread/Makefile
+++ /dev/null
@@ -1,33 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-# Carsten Haitzler <carsten.haitzler@arm.com>, 2021
-include ../Makefile.miniconfig
-
-# Binary to produce
-BIN=unroll_loop_thread
-# Any linking/libraries needed for the binary - empty if none needed
-LIB=-pthread
-
-all: $(BIN)
-
-$(BIN): $(BIN).c
-ifdef CORESIGHT
-ifeq ($(ARCH),arm64)
-# Build line
- $(Q)$(CC) $(BIN).c -o $(BIN) $(LIB)
-endif
-endif
-
-install-tests: all
-ifdef CORESIGHT
-ifeq ($(ARCH),arm64)
-# Install the test tool in the right place
- $(call QUIET_INSTALL, tests) \
- $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/$(INSTDIR_SUB)/$(BIN)'; \
- $(INSTALL) $(BIN) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/$(INSTDIR_SUB)/$(BIN)/$(BIN)'
-endif
-endif
-
-clean:
- $(Q)$(RM) -f $(BIN)
-
-.PHONY: all clean install-tests
diff --git a/tools/perf/tests/shell/coresight/unroll_loop_thread/unroll_loop_thread.c b/tools/perf/tests/shell/coresight/unroll_loop_thread/unroll_loop_thread.c
deleted file mode 100644
index 8f4e1c985ca3..000000000000
--- a/tools/perf/tests/shell/coresight/unroll_loop_thread/unroll_loop_thread.c
+++ /dev/null
@@ -1,75 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Carsten Haitzler <carsten.haitzler@arm.com>, 2021
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <pthread.h>
-
-struct args {
- pthread_t th;
- unsigned int in;
- void *ret;
-};
-
-static void *thrfn(void *arg)
-{
- struct args *a = arg;
- unsigned int i, in = a->in;
-
- for (i = 0; i < 10000; i++) {
- asm volatile (
-// force an unroll of thia add instruction so we can test long runs of code
-#define SNIP1 "add %w[in], %w[in], #1\n"
-// 10
-#define SNIP2 SNIP1 SNIP1 SNIP1 SNIP1 SNIP1 SNIP1 SNIP1 SNIP1 SNIP1 SNIP1
-// 100
-#define SNIP3 SNIP2 SNIP2 SNIP2 SNIP2 SNIP2 SNIP2 SNIP2 SNIP2 SNIP2 SNIP2
-// 1000
-#define SNIP4 SNIP3 SNIP3 SNIP3 SNIP3 SNIP3 SNIP3 SNIP3 SNIP3 SNIP3 SNIP3
-// 10000
-#define SNIP5 SNIP4 SNIP4 SNIP4 SNIP4 SNIP4 SNIP4 SNIP4 SNIP4 SNIP4 SNIP4
-// 100000
- SNIP5 SNIP5 SNIP5 SNIP5 SNIP5 SNIP5 SNIP5 SNIP5 SNIP5 SNIP5
- : /* out */
- : /* in */ [in] "r" (in)
- : /* clobber */
- );
- }
-
- return NULL;
-}
-
-static pthread_t new_thr(void *(*fn) (void *arg), void *arg)
-{
- pthread_t t;
- pthread_attr_t attr;
-
- pthread_attr_init(&attr);
- pthread_create(&t, &attr, fn, arg);
- return t;
-}
-
-int main(int argc, char **argv)
-{
- unsigned int i, thr;
- struct args args[256];
-
- if (argc < 2) {
- printf("ERR: %s [numthreads]\n", argv[0]);
- exit(1);
- }
-
- thr = atoi(argv[1]);
- if ((thr > 256) || (thr < 1)) {
- printf("ERR: threads 1-256\n");
- exit(1);
- }
- for (i = 0; i < thr; i++) {
- args[i].in = rand();
- args[i].th = new_thr(thrfn, &(args[i]));
- }
- for (i = 0; i < thr; i++)
- pthread_join(args[i].th, &(args[i].ret));
- return 0;
-}
diff --git a/tools/perf/tests/shell/lib/coresight.sh b/tools/perf/tests/shell/lib/coresight.sh
deleted file mode 100644
index 184d62e7e5bd..000000000000
--- a/tools/perf/tests/shell/lib/coresight.sh
+++ /dev/null
@@ -1,134 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-# Carsten Haitzler <carsten.haitzler@arm.com>, 2021
-
-# This is sourced from a driver script so no need for #!/bin... etc. at the
-# top - the assumption below is that it runs as part of sourcing after the
-# test sets up some basic env vars to say what it is.
-
-# This currently works with ETMv4 / ETF not any other packet types at thi
-# point. This will need changes if that changes.
-
-# perf record options for the perf tests to use
-PERFRECMEM="-m ,16M"
-PERFRECOPT="$PERFRECMEM -e cs_etm//u"
-
-TOOLS=$(dirname $0)
-DIR="$TOOLS/$TEST"
-BIN="$DIR/$TEST"
-# If the test tool/binary does not exist and is executable then skip the test
-if ! test -x "$BIN"; then exit 2; fi
-# If CoreSight is not available, skip the test
-perf list pmu | grep -q cs_etm || exit 2
-DATD="."
-# If the data dir env is set then make the data dir use that instead of ./
-if test -n "$PERF_TEST_CORESIGHT_DATADIR"; then
- DATD="$PERF_TEST_CORESIGHT_DATADIR";
-fi
-# If the stat dir env is set then make the data dir use that instead of ./
-STATD="."
-if test -n "$PERF_TEST_CORESIGHT_STATDIR"; then
- STATD="$PERF_TEST_CORESIGHT_STATDIR";
-fi
-
-# Called if the test fails - error code 1
-err() {
- echo "$1"
- exit 1
-}
-
-# Check that some statistics from our perf
-check_val_min() {
- STATF="$4"
- if test "$2" -lt "$3"; then
- echo ", FAILED" >> "$STATF"
- err "Sanity check number of $1 is too low ($2 < $3)"
- fi
-}
-
-perf_dump_aux_verify() {
- # Some basic checking that the AUX chunk contains some sensible data
- # to see that we are recording something and at least a minimum
- # amount of it. We should almost always see Fn packets in just about
- # anything but certainly we will see some trace info and async
- # packets
- DUMP="$DATD/perf-tmp-aux-dump.txt"
- perf report --stdio --dump -i "$1" | \
- grep -o -e I_ATOM_F -e I_ASYNC -e I_TRACE_INFO > "$DUMP"
- # Simply count how many of these packets we find to see that we are
- # producing a reasonable amount of data - exact checks are not sane
- # as this is a lossy process where we may lose some blocks and the
- # compiler may produce different code depending on the compiler and
- # optimization options, so this is rough just to see if we're
- # either missing almost all the data or all of it
- ATOM_FX_NUM=$(grep -c I_ATOM_F "$DUMP")
- ASYNC_NUM=$(grep -c I_ASYNC "$DUMP")
- TRACE_INFO_NUM=$(grep -c I_TRACE_INFO "$DUMP")
- rm -f "$DUMP"
-
- # Arguments provide minimums for a pass
- CHECK_FX_MIN="$2"
- CHECK_ASYNC_MIN="$3"
- CHECK_TRACE_INFO_MIN="$4"
-
- # Write out statistics, so over time you can track results to see if
- # there is a pattern - for example we have less "noisy" results that
- # produce more consistent amounts of data each run, to see if over
- # time any techinques to minimize data loss are having an effect or
- # not
- STATF="$STATD/stats-$TEST-$DATV.csv"
- if ! test -f "$STATF"; then
- echo "ATOM Fx Count, Minimum, ASYNC Count, Minimum, TRACE INFO Count, Minimum" > "$STATF"
- fi
- echo -n "$ATOM_FX_NUM, $CHECK_FX_MIN, $ASYNC_NUM, $CHECK_ASYNC_MIN, $TRACE_INFO_NUM, $CHECK_TRACE_INFO_MIN" >> "$STATF"
-
- # Actually check to see if we passed or failed.
- check_val_min "ATOM_FX" "$ATOM_FX_NUM" "$CHECK_FX_MIN" "$STATF"
- check_val_min "ASYNC" "$ASYNC_NUM" "$CHECK_ASYNC_MIN" "$STATF"
- check_val_min "TRACE_INFO" "$TRACE_INFO_NUM" "$CHECK_TRACE_INFO_MIN" "$STATF"
- echo ", Ok" >> "$STATF"
-}
-
-perf_dump_aux_tid_verify() {
- # Specifically crafted test will produce a list of Tread ID's to
- # stdout that need to be checked to see that they have had trace
- # info collected in AUX blocks in the perf data. This will go
- # through all the TID's that are listed as CID=0xabcdef and see
- # that all the Thread IDs the test tool reports are in the perf
- # data AUX chunks
-
- # The TID test tools will print a TID per stdout line that are being
- # tested
- TIDS=$(cat "$2")
- # Scan the perf report to find the TIDs that are actually CID in hex
- # and build a list of the ones found
- FOUND_TIDS=$(perf report --stdio --dump -i "$1" | \
- grep -o "CID=0x[0-9a-z]\+" | sed 's/CID=//g' | \
- uniq | sort | uniq)
- # No CID=xxx found - maybe your kernel is reporting these as
- # VMID=xxx so look there
- if test -z "$FOUND_TIDS"; then
- FOUND_TIDS=$(perf report --stdio --dump -i "$1" | \
- grep -o "VMID=0x[0-9a-z]\+" | sed 's/VMID=//g' | \
- uniq | sort | uniq)
- fi
-
- # Iterate over the list of TIDs that the test says it has and find
- # them in the TIDs found in the perf report
- MISSING=""
- for TID2 in $TIDS; do
- FOUND=""
- for TIDHEX in $FOUND_TIDS; do
- TID=$(printf "%i" $TIDHEX)
- if test "$TID" -eq "$TID2"; then
- FOUND="y"
- break
- fi
- done
- if test -z "$FOUND"; then
- MISSING="$MISSING $TID"
- fi
- done
- if test -n "$MISSING"; then
- err "Thread IDs $MISSING not found in perf AUX data"
- fi
-}
--
2.34.1
^ permalink raw reply related
* [PATCH v5 14/19] perf test cs-etm: Speed up basic test
From: James Clark @ 2026-06-09 14:40 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, Leo Yan, Arnaldo Carvalho de Melo,
Namhyung Kim, Jiri Olsa, Ian Rogers, Amir Ayupov, Jonathan Corbet,
Shuah Khan, Paschalis Mpeis
Cc: coresight, linux-perf-users, linux-kernel,
Arnaldo Carvalho de Melo, linux-doc, James Clark
In-Reply-To: <20260609-james-cs-context-tracking-fix-v5-0-d53a7d096a19@linaro.org>
Like the name says, this should be the most basic test possible. Kernel
recording is slow and already has coverage on the systemwide test. Perf
report output also has coverage elsewhere. 'ls' also produces more trace
than 'true'.
We only want to test if the combination of recording options works at
all, so fix all of these things to make it as fast as possible.
Reviewed-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: James Clark <james.clark@linaro.org>
---
tools/perf/tests/shell/test_arm_coresight.sh | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/tools/perf/tests/shell/test_arm_coresight.sh b/tools/perf/tests/shell/test_arm_coresight.sh
index da2f599393e2..83295a8fe179 100755
--- a/tools/perf/tests/shell/test_arm_coresight.sh
+++ b/tools/perf/tests/shell/test_arm_coresight.sh
@@ -179,10 +179,9 @@ arm_cs_etm_snapshot_test() {
arm_cs_etm_basic_test() {
echo "Recording trace with '$*'"
- perf record -o ${perfdata} "$@" -m,8M -- ls > /dev/null 2>&1
+ perf record -o ${perfdata} "$@" -- true > /dev/null 2>&1
- perf_script_branch_samples ls &&
- perf_report_instruction_samples ls
+ perf_script_branch_samples true
err=$?
arm_cs_report "CoreSight basic testing with '$*'" $err
@@ -246,12 +245,12 @@ arm_cs_etm_snapshot_test
# Test all combinations of per-thread, system-wide and normal mode with
# and without timestamps
-arm_cs_etm_basic_test -e cs_etm/timestamp=0/ --per-thread
-arm_cs_etm_basic_test -e cs_etm/timestamp=1/ --per-thread
-arm_cs_etm_basic_test -e cs_etm/timestamp=0/ -a
-arm_cs_etm_basic_test -e cs_etm/timestamp=1/ -a
-arm_cs_etm_basic_test -e cs_etm/timestamp=0/
-arm_cs_etm_basic_test -e cs_etm/timestamp=1/
+arm_cs_etm_basic_test -e cs_etm/timestamp=0/u --per-thread
+arm_cs_etm_basic_test -e cs_etm/timestamp=1/u --per-thread
+arm_cs_etm_basic_test -e cs_etm/timestamp=0/u -a
+arm_cs_etm_basic_test -e cs_etm/timestamp=1/u -a
+arm_cs_etm_basic_test -e cs_etm/timestamp=0/u
+arm_cs_etm_basic_test -e cs_etm/timestamp=1/u
arm_cs_etm_sparse_cpus_test
--
2.34.1
^ permalink raw reply related
* [PATCH v5 13/19] perf test cs-etm: Reduce snapshot size
From: James Clark @ 2026-06-09 14:40 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, Leo Yan, Arnaldo Carvalho de Melo,
Namhyung Kim, Jiri Olsa, Ian Rogers, Amir Ayupov, Jonathan Corbet,
Shuah Khan, Paschalis Mpeis
Cc: coresight, linux-perf-users, linux-kernel,
Arnaldo Carvalho de Melo, linux-doc, James Clark
In-Reply-To: <20260609-james-cs-context-tracking-fix-v5-0-d53a7d096a19@linaro.org>
The default buffer size for root is 4MB which is very slow to decode. We
only need a few KB to verify that the dd process is hit so reduce the
size to 128KB.
Reviewed-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: James Clark <james.clark@linaro.org>
---
tools/perf/tests/shell/test_arm_coresight.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/perf/tests/shell/test_arm_coresight.sh b/tools/perf/tests/shell/test_arm_coresight.sh
index 8ed2c934c87d..da2f599393e2 100755
--- a/tools/perf/tests/shell/test_arm_coresight.sh
+++ b/tools/perf/tests/shell/test_arm_coresight.sh
@@ -156,7 +156,7 @@ arm_cs_etm_system_wide_test() {
arm_cs_etm_snapshot_test() {
echo "Recording trace with snapshot mode"
- perf record -o ${perfdata} -e cs_etm// -S \
+ perf record -o ${perfdata} -e cs_etm// -S -m,128K \
-- dd if=/dev/zero of=/dev/null > /dev/null 2>&1 &
PERFPID=$!
--
2.34.1
^ permalink raw reply related
* [PATCH v5 12/19] perf test cs-etm: Skip if not root
From: James Clark @ 2026-06-09 14:40 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, Leo Yan, Arnaldo Carvalho de Melo,
Namhyung Kim, Jiri Olsa, Ian Rogers, Amir Ayupov, Jonathan Corbet,
Shuah Khan, Paschalis Mpeis
Cc: coresight, linux-perf-users, linux-kernel,
Arnaldo Carvalho de Melo, linux-doc, James Clark
In-Reply-To: <20260609-james-cs-context-tracking-fix-v5-0-d53a7d096a19@linaro.org>
Use the common idiom for skipping tests if not running as root, which is
required for these tests.
Signed-off-by: James Clark <james.clark@linaro.org>
---
tools/perf/tests/shell/test_arm_coresight.sh | 6 ++++++
tools/perf/tests/shell/test_arm_coresight_disasm.sh | 6 +++---
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/tools/perf/tests/shell/test_arm_coresight.sh b/tools/perf/tests/shell/test_arm_coresight.sh
index 39553702c1f3..8ed2c934c87d 100755
--- a/tools/perf/tests/shell/test_arm_coresight.sh
+++ b/tools/perf/tests/shell/test_arm_coresight.sh
@@ -20,6 +20,12 @@ skip_if_no_cs_etm_event() {
skip_if_no_cs_etm_event || exit 2
+if [ "$(id -u)" != 0 ]; then
+ # Requires root for -C and system wide tests
+ echo "[Skip] No root permission"
+ exit 2
+fi
+
perfdata=$(mktemp /tmp/__perf_test.perf.data.XXXXX)
file=$(mktemp /tmp/temporary_file.XXXXX)
diff --git a/tools/perf/tests/shell/test_arm_coresight_disasm.sh b/tools/perf/tests/shell/test_arm_coresight_disasm.sh
index 0dfb4fadf531..339ae4831868 100755
--- a/tools/perf/tests/shell/test_arm_coresight_disasm.sh
+++ b/tools/perf/tests/shell/test_arm_coresight_disasm.sh
@@ -42,7 +42,7 @@ sep="\s\|\s"
branch_search="\sbl${sep}b${sep}b.ne${sep}b.eq${sep}cbz\s"
## Test kernel ##
-if [ -e /proc/kcore ]; then
+if [ "$(id -u)" == 0 ] && [ -e /proc/kcore ]; then
echo "Testing kernel disassembly"
perf record -o ${perfdata} -e cs_etm//k --kcore -- touch $file > /dev/null 2>&1
perf script -i ${perfdata} -s python:${script_path} -- \
@@ -50,8 +50,8 @@ if [ -e /proc/kcore ]; then
grep -q -e ${branch_search} ${file}
echo "Found kernel branches"
else
- # kcore is required for correct kernel decode due to runtime code patching
- echo "No kcore, skipping kernel test"
+ # Root and kcore are required for correct kernel decode due to runtime code patching
+ echo "No root or kcore, skipping kernel test"
fi
## Test user ##
--
2.34.1
^ permalink raw reply related
* [PATCH v5 11/19] perf test cs-etm: Remove duplicate branch tests
From: James Clark @ 2026-06-09 14:40 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, Leo Yan, Arnaldo Carvalho de Melo,
Namhyung Kim, Jiri Olsa, Ian Rogers, Amir Ayupov, Jonathan Corbet,
Shuah Khan, Paschalis Mpeis
Cc: coresight, linux-perf-users, linux-kernel,
Arnaldo Carvalho de Melo, linux-doc, James Clark
In-Reply-To: <20260609-james-cs-context-tracking-fix-v5-0-d53a7d096a19@linaro.org>
We already test branch output in perf script mode, but then retest it in
Perf report mode. This is more of a test of Perf itself than Coresight
because Perf uses the same samples to generate both outputs. Also we're
already testing instruction output in Perf report mode.
Remove this test for a speedup. On the systemwide test also remove the
Perf report test because systemwide mode records a lot more data so
running multiple tests on it has a big runtime impact.
Reviewed-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: James Clark <james.clark@linaro.org>
---
tools/perf/tests/shell/test_arm_coresight.sh | 18 +-----------------
1 file changed, 1 insertion(+), 17 deletions(-)
diff --git a/tools/perf/tests/shell/test_arm_coresight.sh b/tools/perf/tests/shell/test_arm_coresight.sh
index bbf89e944e7b..39553702c1f3 100755
--- a/tools/perf/tests/shell/test_arm_coresight.sh
+++ b/tools/perf/tests/shell/test_arm_coresight.sh
@@ -52,17 +52,6 @@ perf_script_branch_samples() {
grep -E " +$1 +[0-9]+ .* +branches:(.*:)? +" > /dev/null 2>&1
}
-perf_report_branch_samples() {
- echo "Looking at perf.data file for reporting branch samples:"
-
- # Below is an example of the branch samples reporting:
- # 73.04% 73.04% touch libc-2.27.so [.] _dl_addr
- # 7.71% 7.71% touch libc-2.27.so [.] getenv
- # 2.59% 2.59% touch ld-2.27.so [.] strcmp
- perf report --stdio -i ${perfdata} 2>&1 | \
- grep -E " +[0-9]+\.[0-9]+% +[0-9]+\.[0-9]+% +$1 " > /dev/null 2>&1
-}
-
perf_report_instruction_samples() {
echo "Looking at perf.data file for instruction samples:"
@@ -123,7 +112,6 @@ arm_cs_iterate_devices() {
record_touch_file $device_name $2 &&
perf_script_branch_samples touch &&
- perf_report_branch_samples touch &&
perf_report_instruction_samples touch
err=$?
@@ -154,9 +142,7 @@ arm_cs_etm_system_wide_test() {
# System-wide mode should include perf samples so test for that
# instead of ls
- perf_script_branch_samples perf &&
- perf_report_branch_samples perf &&
- perf_report_instruction_samples perf
+ perf_script_branch_samples perf
err=$?
arm_cs_report "CoreSight system wide testing" $err
@@ -179,7 +165,6 @@ arm_cs_etm_snapshot_test() {
wait $PERFPID
perf_script_branch_samples dd &&
- perf_report_branch_samples dd &&
perf_report_instruction_samples dd
err=$?
@@ -191,7 +176,6 @@ arm_cs_etm_basic_test() {
perf record -o ${perfdata} "$@" -m,8M -- ls > /dev/null 2>&1
perf_script_branch_samples ls &&
- perf_report_branch_samples ls &&
perf_report_instruction_samples ls
err=$?
--
2.34.1
^ permalink raw reply related
* [PATCH v5 10/19] perf test cs-etm: Test decoding for concurrent threads test
From: James Clark @ 2026-06-09 14:40 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, Leo Yan, Arnaldo Carvalho de Melo,
Namhyung Kim, Jiri Olsa, Ian Rogers, Amir Ayupov, Jonathan Corbet,
Shuah Khan, Paschalis Mpeis
Cc: coresight, linux-perf-users, linux-kernel,
Arnaldo Carvalho de Melo, linux-doc, James Clark
In-Reply-To: <20260609-james-cs-context-tracking-fix-v5-0-d53a7d096a19@linaro.org>
The thread_loop test only looks for context IDs in the raw trace.
There's a lot more that can go wrong when decoding these, so replace it
with a test that looks at the final output for matching thread names and
symbols.
In the future we might use timestamps and context switch events to track
threads, so looking at context IDs in the raw trace wouldn't always
work.
Reviewed-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: James Clark <james.clark@linaro.org>
---
.../tests/shell/coresight/concurrent_threads.sh | 45 ++++++++++++++++++++++
.../shell/coresight/thread_loop_check_tid_10.sh | 23 -----------
.../shell/coresight/thread_loop_check_tid_2.sh | 23 -----------
3 files changed, 45 insertions(+), 46 deletions(-)
diff --git a/tools/perf/tests/shell/coresight/concurrent_threads.sh b/tools/perf/tests/shell/coresight/concurrent_threads.sh
new file mode 100755
index 000000000000..3349fff8c767
--- /dev/null
+++ b/tools/perf/tests/shell/coresight/concurrent_threads.sh
@@ -0,0 +1,45 @@
+#!/bin/bash -e
+# CoreSight concurrent threads (exclusive)
+
+# SPDX-License-Identifier: GPL-2.0
+
+# If CoreSight is not available, skip the test
+perf list pmu | grep -q cs_etm || exit 2
+
+tmpdir=$(mktemp -d /tmp/__perf_test.coresight_concurrent_threads.XXXXX)
+
+cleanup() {
+ rm -rf "${tmpdir}"
+ trap - EXIT TERM INT
+}
+
+trap_cleanup() {
+ cleanup
+ exit 1
+}
+trap trap_cleanup EXIT TERM INT
+
+cf="$tmpdir/ctl"
+af="$tmpdir/ack"
+mkfifo "$cf" "$af"
+
+nthreads=10
+
+# Timestamps off to reduce trace size, start disabled and use the control FIFO
+# to only record the workload and not startup.
+perf record -o "$tmpdir/data" -e cs_etm/timestamp=0/u -D -1 --control fifo:"$cf","$af" \
+ -- perf test --record-ctl fifo:"$cf","$af" -w named_threads $nthreads 1 > /dev/null 2>&1
+
+perf script -i "$tmpdir/data" > "$tmpdir/script" 2>/dev/null
+
+# Check all threads were traced and they have the correct thread name and symbol
+for i in $(seq 1 $nthreads); do
+ if ! grep -q "thread${i} .* named_threads_thread${i}" "$tmpdir/script"; then
+ echo "Error: thread${i} missing" >&2
+ cleanup
+ exit 1
+ fi
+done
+
+cleanup
+exit 0
diff --git a/tools/perf/tests/shell/coresight/thread_loop_check_tid_10.sh b/tools/perf/tests/shell/coresight/thread_loop_check_tid_10.sh
deleted file mode 100755
index 7f43a93a2ac2..000000000000
--- a/tools/perf/tests/shell/coresight/thread_loop_check_tid_10.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/bash -e
-# CoreSight / Thread Loop 10 Threads - Check TID (exclusive)
-
-# SPDX-License-Identifier: GPL-2.0
-# Carsten Haitzler <carsten.haitzler@arm.com>, 2021
-
-TEST="thread_loop"
-
-# shellcheck source=../lib/coresight.sh
-. "$(dirname $0)"/../lib/coresight.sh
-
-ARGS="10 1"
-DATV="check-tid-10th"
-# shellcheck disable=SC2153
-DATA="$DATD/perf-$TEST-$DATV.data"
-STDO="$DATD/perf-$TEST-$DATV.stdout"
-
-SHOW_TID=1 perf record -s $PERFRECOPT -o "$DATA" "$BIN" $ARGS > $STDO
-
-perf_dump_aux_tid_verify "$DATA" "$STDO"
-
-err=$?
-exit $err
diff --git a/tools/perf/tests/shell/coresight/thread_loop_check_tid_2.sh b/tools/perf/tests/shell/coresight/thread_loop_check_tid_2.sh
deleted file mode 100755
index a94d2079ed06..000000000000
--- a/tools/perf/tests/shell/coresight/thread_loop_check_tid_2.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/bash -e
-# CoreSight / Thread Loop 2 Threads - Check TID (exclusive)
-
-# SPDX-License-Identifier: GPL-2.0
-# Carsten Haitzler <carsten.haitzler@arm.com>, 2021
-
-TEST="thread_loop"
-
-# shellcheck source=../lib/coresight.sh
-. "$(dirname $0)"/../lib/coresight.sh
-
-ARGS="2 20"
-DATV="check-tid-2th"
-# shellcheck disable=SC2153
-DATA="$DATD/perf-$TEST-$DATV.data"
-STDO="$DATD/perf-$TEST-$DATV.stdout"
-
-SHOW_TID=1 perf record -s $PERFRECOPT -o "$DATA" "$BIN" $ARGS > $STDO
-
-perf_dump_aux_tid_verify "$DATA" "$STDO"
-
-err=$?
-exit $err
--
2.34.1
^ permalink raw reply related
* [PATCH v5 09/19] perf test: Add named_threads workload
From: James Clark @ 2026-06-09 14:40 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, Leo Yan, Arnaldo Carvalho de Melo,
Namhyung Kim, Jiri Olsa, Ian Rogers, Amir Ayupov, Jonathan Corbet,
Shuah Khan, Paschalis Mpeis
Cc: coresight, linux-perf-users, linux-kernel,
Arnaldo Carvalho de Melo, linux-doc, James Clark
In-Reply-To: <20260609-james-cs-context-tracking-fix-v5-0-d53a7d096a19@linaro.org>
Add a workload that runs X threads that run a unique function named
"named_threads_thread[x]" which performs a multiplication in a loop for
Y loops. Each thread sets its name to "thread[x]".
This can be used to test that processor trace decoding handles
concurrent threads correctly and the correct symbols and thread names
are assigned to samples.
Signed-off-by: James Clark <james.clark@linaro.org>
---
tools/perf/Documentation/perf-test.txt | 5 +-
tools/perf/tests/builtin-test.c | 1 +
tools/perf/tests/tests.h | 1 +
tools/perf/tests/workloads/Build | 1 +
tools/perf/tests/workloads/named_threads.c | 109 +++++++++++++++++++++++++++++
5 files changed, 116 insertions(+), 1 deletion(-)
diff --git a/tools/perf/Documentation/perf-test.txt b/tools/perf/Documentation/perf-test.txt
index c50a4b2d2d29..81c8525f5946 100644
--- a/tools/perf/Documentation/perf-test.txt
+++ b/tools/perf/Documentation/perf-test.txt
@@ -57,7 +57,7 @@ OPTIONS
--workload=::
Run a built-in workload, to list them use '--list-workloads', current
ones include: noploop, thloop, leafloop, sqrtloop, brstack, datasym,
- context_switch_loop, deterministic and landlock.
+ context_switch_loop, deterministic, named_threads and landlock.
Used with the shell script regression tests.
@@ -66,6 +66,9 @@ OPTIONS
seconds: leafloop, noploop, sqrtloop, thloop
nrloops: brstack, context_switch_loop
+ 'named_threads' accepts the number of threads and the number of loops to
+ do in each thread.
+
The datasym, landlock and deterministic workloads don't accept any.
--list-workloads::
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index ef7e3f52a383..afc06cec4954 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -155,6 +155,7 @@ static struct test_suite *generic_tests[] = {
static struct test_workload *workloads[] = {
&workload__noploop,
&workload__thloop,
+ &workload__named_threads,
&workload__leafloop,
&workload__sqrtloop,
&workload__brstack,
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index bcfe9c33fc66..7cedf05be544 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -237,6 +237,7 @@ struct test_workload workload__##work = { \
/* The list of test workloads */
DECLARE_WORKLOAD(noploop);
DECLARE_WORKLOAD(thloop);
+DECLARE_WORKLOAD(named_threads);
DECLARE_WORKLOAD(leafloop);
DECLARE_WORKLOAD(sqrtloop);
DECLARE_WORKLOAD(brstack);
diff --git a/tools/perf/tests/workloads/Build b/tools/perf/tests/workloads/Build
index 90f2d8aa4941..75b377934a0e 100644
--- a/tools/perf/tests/workloads/Build
+++ b/tools/perf/tests/workloads/Build
@@ -2,6 +2,7 @@
perf-test-y += noploop.o
perf-test-y += thloop.o
+perf-test-y += named_threads.o
perf-test-y += leafloop.o
perf-test-y += sqrtloop.o
perf-test-y += brstack.o
diff --git a/tools/perf/tests/workloads/named_threads.c b/tools/perf/tests/workloads/named_threads.c
new file mode 100644
index 000000000000..d051d41a3cfe
--- /dev/null
+++ b/tools/perf/tests/workloads/named_threads.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <errno.h>
+#include <limits.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <linux/compiler.h>
+#include "../tests.h"
+
+#define MAX_THREADS 25
+
+static int iterations = 500;
+int named_threads_work = 1234;
+
+typedef void *(*thread_fn_t)(void *);
+
+#define DEFINE_THREAD(n) \
+noinline void *named_threads_thread##n(void *arg __maybe_unused) \
+{ \
+ pthread_setname_np(pthread_self(), "thread" #n); \
+ for (int i = 0; i < iterations; i++) \
+ named_threads_work += 3; \
+ \
+ return NULL; \
+}
+
+#define THREAD_LIST(macro) \
+ macro(1) \
+ macro(2) \
+ macro(3) \
+ macro(4) \
+ macro(5) \
+ macro(6) \
+ macro(7) \
+ macro(8) \
+ macro(9) \
+ macro(10) \
+ macro(11) \
+ macro(12) \
+ macro(13) \
+ macro(14) \
+ macro(15) \
+ macro(16) \
+ macro(17) \
+ macro(18) \
+ macro(19) \
+ macro(20) \
+ macro(21) \
+ macro(22) \
+ macro(23) \
+ macro(24) \
+ macro(25)
+
+#define DECLARE_THREAD(n) void *named_threads_thread##n(void *arg);
+
+THREAD_LIST(DECLARE_THREAD)
+THREAD_LIST(DEFINE_THREAD)
+
+#define THREAD_ENTRY(n) named_threads_thread##n,
+
+static thread_fn_t thread_fns[MAX_THREADS] = {
+ THREAD_LIST(THREAD_ENTRY)
+};
+
+/*
+ * Creates argv[0] threads that run a unique function named "thread[x]" which performs
+ * a multiplication in a loop for argv[1] loops.
+ */
+static int named_threads(int argc, const char **argv)
+{
+ pthread_t threads[MAX_THREADS];
+ int nr_threads = 1;
+ int err = 0;
+
+ if (argc > 0)
+ nr_threads = atoi(argv[0]);
+
+ if (nr_threads <= 0 || nr_threads > MAX_THREADS) {
+ fprintf(stderr, "Error: num threads must be 1 - %d\n", MAX_THREADS);
+ return 1;
+ }
+
+ if (argc > 1)
+ iterations = atoi(argv[1]);
+
+ if (iterations < 0) {
+ fprintf(stderr, "Error: iterations must be non-negative\n");
+ return 1;
+ }
+
+ for (int i = 0; i < nr_threads; i++) {
+ int ret;
+
+ ret = pthread_create(&threads[i], NULL, thread_fns[i], NULL);
+ if (ret) {
+ fprintf(stderr, "Error: failed to create thread%d: %s\n",
+ i + 1, strerror(ret));
+ return 1;
+ }
+ }
+
+ for (int i = 0; i < nr_threads; i++)
+ pthread_join(threads[i], NULL);
+
+ return err;
+}
+
+DEFINE_WORKLOAD(named_threads);
--
2.34.1
^ permalink raw reply related
* [PATCH v5 08/19] perf test cs-etm: Replace memcpy test with raw dump stress test
From: James Clark @ 2026-06-09 14:40 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, Leo Yan, Arnaldo Carvalho de Melo,
Namhyung Kim, Jiri Olsa, Ian Rogers, Amir Ayupov, Jonathan Corbet,
Shuah Khan, Paschalis Mpeis
Cc: coresight, linux-perf-users, linux-kernel,
Arnaldo Carvalho de Melo, linux-doc, James Clark
In-Reply-To: <20260609-james-cs-context-tracking-fix-v5-0-d53a7d096a19@linaro.org>
Like asm_pure_loop, this memcpy test only checks that 10 of each of a
few trace packet types occur after recording a lot of trace, which isn't
more specific than other existing Coresight tests.
Assume it was supposed to be a stress test for dumping and replace it
with one that doesn't require a custom binary and checks for a specific
amount of raw output. Don't bother checking for packets because the
other tests that test decoding will catch issues with malformed data.
This also adds coverage for exit snapshot mode which was missing.
Signed-off-by: James Clark <james.clark@linaro.org>
---
.../tests/shell/coresight/memcpy_thread_16k_10.sh | 22 --------
.../perf/tests/shell/coresight/raw_dump_stress.sh | 65 ++++++++++++++++++++++
2 files changed, 65 insertions(+), 22 deletions(-)
diff --git a/tools/perf/tests/shell/coresight/memcpy_thread_16k_10.sh b/tools/perf/tests/shell/coresight/memcpy_thread_16k_10.sh
deleted file mode 100755
index 1f765d69acc3..000000000000
--- a/tools/perf/tests/shell/coresight/memcpy_thread_16k_10.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/bash -e
-# CoreSight / Memcpy 16k 10 Threads (exclusive)
-
-# SPDX-License-Identifier: GPL-2.0
-# Carsten Haitzler <carsten.haitzler@arm.com>, 2021
-
-TEST="memcpy_thread"
-
-# shellcheck source=../lib/coresight.sh
-. "$(dirname $0)"/../lib/coresight.sh
-
-ARGS="16 10 1"
-DATV="16k_10"
-# shellcheck disable=SC2153
-DATA="$DATD/perf-$TEST-$DATV.data"
-
-perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
-
-perf_dump_aux_verify "$DATA" 10 10 10
-
-err=$?
-exit $err
diff --git a/tools/perf/tests/shell/coresight/raw_dump_stress.sh b/tools/perf/tests/shell/coresight/raw_dump_stress.sh
new file mode 100755
index 000000000000..bea70d825596
--- /dev/null
+++ b/tools/perf/tests/shell/coresight/raw_dump_stress.sh
@@ -0,0 +1,65 @@
+#!/bin/bash -e
+# CoreSight raw dump stress (exclusive)
+
+# SPDX-License-Identifier: GPL-2.0
+
+if [ "$(id -u)" != 0 ]; then
+ # Requires root for larger buffer size
+ echo "[Skip] No root permission"
+ exit 2
+fi
+
+# If CoreSight is not available, skip the test
+perf list pmu | grep -q cs_etm || exit 2
+
+tmpdir=$(mktemp -d /tmp/__perf_test.coresight_raw_dump_stress.XXXXX)
+
+cleanup() {
+ rm -r "${tmpdir}"
+ trap - EXIT TERM INT
+}
+
+trap_cleanup() {
+ cleanup
+ exit 1
+}
+trap trap_cleanup EXIT TERM INT
+
+# Use exit snapshot to record 2M of trace to make about 80MB of raw dump data.
+echo "Recording..."
+perf record -e cs_etm/timestamp=0/u -m,2M -Se -o "$tmpdir/data" -- \
+ perf test -w brstack 20000 > /dev/null 2>&1
+
+# Test raw dump runs to completion but don't decode because that's too slow for
+# a test
+echo "Dumping raw trace..."
+perf report --dump-raw-trace -i "$tmpdir/data" 2>/dev/null > "$tmpdir/rawdump"
+
+# Get the size and offset of the first AUXTRACE buffer and the index of the last
+# packet in the raw dump.
+read -r size offset last_idx <<< "$(awk '
+ found && /PERF_RECORD_/ { exit }
+ /PERF_RECORD_AUXTRACE / { found = 1; size = $7; offset = $9; next }
+ found && /Idx:/ { last_idx = $1; gsub(/Idx:|;/, "", last_idx) }
+ END { if (last_idx) print size, offset, last_idx }
+' "$tmpdir/rawdump")"
+
+# The last Idx minus start offset should equal the size of the buffer if
+# everything was dumped. Allow 48 bytes difference to cover 3 frames: current
+# frame length, a partial frame and a final empty one, all of which aren't
+# dumped.
+#
+# TODO: for a single snapshot, offset should always be zero. However, we
+# currently output AUX records in snapshot mode when we shouldn't, which
+# increments the offset. Allow for that until it's fixed so we can test raw
+# dumping.
+decode_size=$((1 + last_idx - offset))
+if [ "$decode_size" -gt "$((size - 48))" ] && [ "$decode_size" -le "$((size))" ]; then
+ echo "PASS: AUXTRACE buffer length matches dumped packet index"
+ cleanup
+ exit 0
+fi
+
+echo "FAIL: AUXTRACE buffer length mismatch: size=$size offset=$offset last_idx=$last_idx decode_size=$decode_size"
+cleanup
+exit 1
--
2.34.1
^ permalink raw reply related
* [PATCH v5 07/19] perf test cs-etm: Remove asm_pure_loop test
From: James Clark @ 2026-06-09 14:40 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, Leo Yan, Arnaldo Carvalho de Melo,
Namhyung Kim, Jiri Olsa, Ian Rogers, Amir Ayupov, Jonathan Corbet,
Shuah Khan, Paschalis Mpeis
Cc: coresight, linux-perf-users, linux-kernel,
Arnaldo Carvalho de Melo, linux-doc, James Clark
In-Reply-To: <20260609-james-cs-context-tracking-fix-v5-0-d53a7d096a19@linaro.org>
It's not obvious what this test is for so remove it. It's not a stress
test because it doesn't output lots of data and it's not a functional
test because it only looks for raw trace output. It seems to imply that
a program written in assembly influences whether trace would be
generated by the CPU or not, but the CPU doesn't know what language the
program is written in.
We already have lots of Coresight tests that test the full pipeline
including decoding, and in many more modes of operation than this one,
so if no trace was collected they will already fail leaving this one
redundant.
Reviewed-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: James Clark <james.clark@linaro.org>
---
tools/perf/tests/shell/coresight/asm_pure_loop.sh | 22 ----------------------
1 file changed, 22 deletions(-)
diff --git a/tools/perf/tests/shell/coresight/asm_pure_loop.sh b/tools/perf/tests/shell/coresight/asm_pure_loop.sh
deleted file mode 100755
index 0301904b9637..000000000000
--- a/tools/perf/tests/shell/coresight/asm_pure_loop.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/bash -e
-# CoreSight / ASM Pure Loop (exclusive)
-
-# SPDX-License-Identifier: GPL-2.0
-# Carsten Haitzler <carsten.haitzler@arm.com>, 2021
-
-TEST="asm_pure_loop"
-
-# shellcheck source=../lib/coresight.sh
-. "$(dirname $0)"/../lib/coresight.sh
-
-ARGS=""
-DATV="out"
-# shellcheck disable=SC2153
-DATA="$DATD/perf-$TEST-$DATV.data"
-
-perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
-
-perf_dump_aux_verify "$DATA" 10 10 10
-
-err=$?
-exit $err
--
2.34.1
^ permalink raw reply related
* [PATCH v5 06/19] perf test cs-etm: Replace unroll loop thread with deterministic decode test
From: James Clark @ 2026-06-09 14:40 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, Leo Yan, Arnaldo Carvalho de Melo,
Namhyung Kim, Jiri Olsa, Ian Rogers, Amir Ayupov, Jonathan Corbet,
Shuah Khan, Paschalis Mpeis
Cc: coresight, linux-perf-users, linux-kernel,
Arnaldo Carvalho de Melo, linux-doc, James Clark
In-Reply-To: <20260609-james-cs-context-tracking-fix-v5-0-d53a7d096a19@linaro.org>
Testing a long sequence without branches seems like it would be better
as a decoder unit test, and this test doesn't test decoding either, so
it's not clear what bugs this is trying to catch.
The new deterministic workload has somewhat long sequences when built
unoptimized, and we can always increase them later if we want to. But
now we test that decoding always gives the same result for the same
sequence of code which we've never had before.
Signed-off-by: James Clark <james.clark@linaro.org>
---
tools/perf/tests/shell/coresight/deterministic.sh | 72 ++++++++++++++++++++++
.../tests/shell/coresight/unroll_loop_thread_10.sh | 22 -------
2 files changed, 72 insertions(+), 22 deletions(-)
diff --git a/tools/perf/tests/shell/coresight/deterministic.sh b/tools/perf/tests/shell/coresight/deterministic.sh
new file mode 100755
index 000000000000..75d4973056f0
--- /dev/null
+++ b/tools/perf/tests/shell/coresight/deterministic.sh
@@ -0,0 +1,72 @@
+#!/bin/bash -e
+# CoreSight deterministic workload decode (exclusive)
+
+# SPDX-License-Identifier: GPL-2.0
+
+# If CoreSight is not available, skip the test
+perf list pmu | grep -q cs_etm || exit 2
+
+tmpdir=$(mktemp -d /tmp/__perf_test.coresight_deterministic.XXXXX)
+
+cleanup() {
+ rm -rf "${tmpdir}"
+ trap - EXIT TERM INT
+}
+
+trap_cleanup() {
+ cleanup
+ exit 1
+}
+trap trap_cleanup EXIT TERM INT
+
+cf="$tmpdir/ctl"
+af="$tmpdir/ack"
+mkfifo "$cf" "$af"
+
+# Start disabled and use the control FIFO to only record the workload and not
+# startup.
+perf record -o "$tmpdir/data" -e cs_etm//u -D -1 --control fifo:"$cf","$af" -- \
+ perf test --record-ctl fifo:"$cf","$af" -w deterministic > /dev/null 2>&1
+
+perf script -i "$tmpdir/data" --itrace=i1i -F ip,srcline | \
+ grep "deterministic.c" | uniq > "$tmpdir/script" 2>/dev/null
+
+
+# Remove brace lines and call sites as they may not be hit or may have
+# extra hits after returning, depending on the compiler.
+sed -i \
+ -e '/deterministic.c:8$/d' \
+ -e '/deterministic.c:12$/d' \
+ -e '/deterministic.c:15$/d' \
+ -e '/deterministic.c:19$/d' \
+ -e '/deterministic.c:23$/d' \
+ -e '/deterministic.c:28$/d' \
+ -e '/deterministic.c:34$/d' \
+ -e '/deterministic.c:36$/d' \
+ -e '/deterministic.c:37$/d' \
+ "$tmpdir/script"
+
+cat > "$tmpdir/expected" << EOF
+ deterministic.c:24
+ deterministic.c:25
+ deterministic.c:26
+ deterministic.c:9
+ deterministic.c:10
+ deterministic.c:11
+ deterministic.c:30
+ deterministic.c:31
+ deterministic.c:32
+ deterministic.c:16
+ deterministic.c:17
+ deterministic.c:18
+EOF
+
+if ! diff -q "$tmpdir/script" "$tmpdir/expected"; then
+ echo "FAIL: line numbers don't match expected: "
+ head -n 100 "$tmpdir/script"
+ cleanup
+ exit 1
+fi
+
+cleanup
+exit 0
diff --git a/tools/perf/tests/shell/coresight/unroll_loop_thread_10.sh b/tools/perf/tests/shell/coresight/unroll_loop_thread_10.sh
deleted file mode 100755
index cb3e97a0a89f..000000000000
--- a/tools/perf/tests/shell/coresight/unroll_loop_thread_10.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/bash -e
-# CoreSight / Unroll Loop Thread 10 (exclusive)
-
-# SPDX-License-Identifier: GPL-2.0
-# Carsten Haitzler <carsten.haitzler@arm.com>, 2021
-
-TEST="unroll_loop_thread"
-
-# shellcheck source=../lib/coresight.sh
-. "$(dirname $0)"/../lib/coresight.sh
-
-ARGS="10"
-DATV="10"
-# shellcheck disable=SC2153
-DATA="$DATD/perf-$TEST-$DATV.data"
-
-perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
-
-perf_dump_aux_verify "$DATA" 10 10 10
-
-err=$?
-exit $err
--
2.34.1
^ permalink raw reply related
* [PATCH v5 05/19] perf test: Add deterministic workload
From: James Clark @ 2026-06-09 14:40 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, Leo Yan, Arnaldo Carvalho de Melo,
Namhyung Kim, Jiri Olsa, Ian Rogers, Amir Ayupov, Jonathan Corbet,
Shuah Khan, Paschalis Mpeis
Cc: coresight, linux-perf-users, linux-kernel,
Arnaldo Carvalho de Melo, linux-doc, James Clark
In-Reply-To: <20260609-james-cs-context-tracking-fix-v5-0-d53a7d096a19@linaro.org>
Add a workload that does the same thing every time for testing CPU trace
decoding.
Reviewed-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: James Clark <james.clark@linaro.org>
---
tools/perf/Documentation/perf-test.txt | 4 +--
tools/perf/tests/builtin-test.c | 1 +
tools/perf/tests/tests.h | 1 +
tools/perf/tests/workloads/Build | 2 ++
tools/perf/tests/workloads/deterministic.c | 39 ++++++++++++++++++++++++++++++
5 files changed, 45 insertions(+), 2 deletions(-)
diff --git a/tools/perf/Documentation/perf-test.txt b/tools/perf/Documentation/perf-test.txt
index 213eb62603eb..c50a4b2d2d29 100644
--- a/tools/perf/Documentation/perf-test.txt
+++ b/tools/perf/Documentation/perf-test.txt
@@ -57,7 +57,7 @@ OPTIONS
--workload=::
Run a built-in workload, to list them use '--list-workloads', current
ones include: noploop, thloop, leafloop, sqrtloop, brstack, datasym,
- context_switch_loop and landlock.
+ context_switch_loop, deterministic and landlock.
Used with the shell script regression tests.
@@ -66,7 +66,7 @@ OPTIONS
seconds: leafloop, noploop, sqrtloop, thloop
nrloops: brstack, context_switch_loop
- The datasym and landlock workloads don't accept any.
+ The datasym, landlock and deterministic workloads don't accept any.
--list-workloads::
List the available workloads to use with -w/--workload.
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 9284f897de3c..ef7e3f52a383 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -164,6 +164,7 @@ static struct test_workload *workloads[] = {
&workload__inlineloop,
&workload__jitdump,
&workload__context_switch_loop,
+ &workload__deterministic,
#ifdef HAVE_RUST_SUPPORT
&workload__code_with_type,
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index 7cd4da4e96d3..bcfe9c33fc66 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -246,6 +246,7 @@ DECLARE_WORKLOAD(traploop);
DECLARE_WORKLOAD(inlineloop);
DECLARE_WORKLOAD(jitdump);
DECLARE_WORKLOAD(context_switch_loop);
+DECLARE_WORKLOAD(deterministic);
#ifdef HAVE_RUST_SUPPORT
DECLARE_WORKLOAD(code_with_type);
diff --git a/tools/perf/tests/workloads/Build b/tools/perf/tests/workloads/Build
index 7134a031cb7c..90f2d8aa4941 100644
--- a/tools/perf/tests/workloads/Build
+++ b/tools/perf/tests/workloads/Build
@@ -11,6 +11,7 @@ perf-test-y += traploop.o
perf-test-y += inlineloop.o
perf-test-y += jitdump.o
perf-test-y += context_switch_loop.o
+perf-test-y += deterministic.o
ifeq ($(CONFIG_RUST_SUPPORT),y)
perf-test-y += code_with_type.o
@@ -23,3 +24,4 @@ CFLAGS_brstack.o = -g -O0 -fno-inline -U_FORTIFY_SOURCE
CFLAGS_datasym.o = -g -O0 -fno-inline -U_FORTIFY_SOURCE
CFLAGS_traploop.o = -g -O0 -fno-inline -U_FORTIFY_SOURCE
CFLAGS_inlineloop.o = -g -O2
+CFLAGS_deterministic.o = -g -O0 -fno-inline -U_FORTIFY_SOURCE
diff --git a/tools/perf/tests/workloads/deterministic.c b/tools/perf/tests/workloads/deterministic.c
new file mode 100644
index 000000000000..8a78519fd075
--- /dev/null
+++ b/tools/perf/tests/workloads/deterministic.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/compiler.h>
+#include "../tests.h"
+
+int dt_work = 1234;
+
+static void function1(void)
+{
+ dt_work += 7;
+ dt_work += 7;
+ dt_work += 7;
+}
+
+static void function2(void)
+{
+ dt_work += 7;
+ dt_work += 7;
+ dt_work += 7;
+}
+
+static int deterministic(int argc __maybe_unused,
+ const char **argv __maybe_unused)
+{
+ dt_work += 7;
+ dt_work += 7;
+ dt_work += 7;
+
+ function1();
+
+ dt_work += 7;
+ dt_work += 7;
+ dt_work += 7;
+
+ function2();
+
+ return 0;
+}
+
+DEFINE_WORKLOAD(deterministic);
--
2.34.1
^ permalink raw reply related
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