* Re: [PATCH v3 0/3] crypto: atmel-sha204a - multiple RNG fixes
From: Lothar Rubusch @ 2026-04-25 13:34 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: Herbert Xu, Thorsten Blum, davem, nicolas.ferre,
alexandre.belloni, claudiu.beznea, Linus Walleij, linux-crypto,
linux-arm-kernel, linux-kernel
In-Reply-To: <a82278e5-9b5e-4fb9-9e7a-800ef2898ec5@app.fastmail.com>
Hi Ard and ML!
On Thu, Apr 23, 2026 at 11:25 AM Ard Biesheuvel <ardb@kernel.org> wrote:
>
> Hi Lothar,
>
> On Wed, 22 Apr 2026, at 23:09, Lothar Rubusch wrote:
> > When testing the RNG functionality on the Atmel SHA204a hardware, I
> > found the following issues: rngtest reported failures and hexdump
> > reveiled only the first 8 bytes out of 32 provided actually entropy.
> >
> > Having a closer look into it, I found a (small) memory leak, missing
> > to free work_data, miss-reading of the count field into the entropy
> > fields and parts of the 32 random bytes staying 0 due to reading the
> > slow i2c device.
> >
> > The series proposes fixes and how fixed functionality can be/was
> > verified. Executing rngtest afterward showed a decent result, due
> > to the i2c bus a bit slow.
> >
> > All setups require selecting the Atmel-sha204a as active RNG.
> > $ cat /sys/class/misc/hw_random/rng_available
> > 3f104000.rng 1-0064 none
> >
> > $ echo 1-0064 > /sys/class/misc/hw_random/rng_current
> >
> > $ cat /sys/class/misc/hw_random/rng_current
> > 1-0064
> >
> > Testing RNG properties currently shows problematic results:
> > $ rngtest < /dev/hwrng
> > rngtest 2.6
> > Copyright (c) 2004 by Henrique de Moraes Holschuh
> > This is free software; see the source for copying conditions. There is NO
> > warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
> >
> > rngtest: starting FIPS tests...
> > rngtest: bits received from input: 1040032
> > rngtest: FIPS 140-2 successes: 0
> > rngtest: FIPS 140-2 failures: 52
> > rngtest: FIPS 140-2(2001-10-10) Monobit: 52
> > rngtest: FIPS 140-2(2001-10-10) Poker: 52
> > rngtest: FIPS 140-2(2001-10-10) Runs: 52
> > rngtest: FIPS 140-2(2001-10-10) Long run: 52
> > rngtest: FIPS 140-2(2001-10-10) Continuous run: 52
> > rngtest: input channel speed: (min=7.631; avg=7.804; max=7.827)Kibits/s
> > rngtest: FIPS tests speed: (min=32.273; avg=32.701; max=33.056)Mibits/s
> > rngtest: Program run time: 130177956 microseconds
> >
> > Signed-off-by: Lothar Rubusch <l.rubusch@gmail.com>
> > ---
> > v2 -> v3: Removal blank line, rebased
> > v1 -> v2: Removal of C++ style comment (I saw it too late, sry for that)
> > ---
> > Lothar Rubusch (3):
> > crypto: atmel-sha204a - fix memory leak at non-blocking RNG work_data
> > crypto: atmel-sha204a - fix truncated 32-byte blocking read
> > crypto: atmel-sha204a - fix non-blocking read logic
> >
> > drivers/crypto/atmel-sha204a.c | 60 ++++++++++++++++++++++------------
> > 1 file changed, 39 insertions(+), 21 deletions(-)
> >
>
> Thanks for the report and the fixes. However, I'm not sure you are entirely
> on the right track here. I managed to fix the rngtest issues that you report by
> making the changes below. As I already replied, I think it would be better to
> propose this as a standalone patch, and backport it to stable.
>
Thank you so much for taking the time and answering, I really appreciate!
Like two months ago I started playing a bit more with these Atmel i2c
devices. Actually I wanted to prepare something
different (and still pretend doing so). Figuring out things here, I
noticed this RNG feature did not work as I expected.
Around that time I prepared this patch set.
Probably, I was a bit too euphoric - I mean, it's a bit unlikely the
driver was upstreamed and never really worked.
I have to admit, I did not go thoroughly through the git history
first, since the driver does not do significantly more than
RNG, there must have happened a degradation. I'll keep this in mind:
first to build up better understanding of the driver
history. than to start digging into the code. Anyway, I wanted to get
some feedback.
> The remaining changes are somewhat debatable IMO: the leak is not really a leak,
> so I'd like to understand better what you are fixing here. The command field
> changes seems completely misguided (unless I am missing something)
>
So, firstly in the current RNG implementation I definitely see an
issue. If that's ok, I'll to prepare a patch to re-init probably
rather
to what you proposed, since it makes more sense to me now. Thank you
for pointing this out.
Secondly, I noticed the device is picky about its i2c communication
timings. Yes, definitely. Nowadays, after having worked with
it a bit more, I'd rather say generally reducing response time is
probably not the solution. I still think I see some timing issue,
which
I wanted to better address in an upcoming patch set (but probably not
related to this RNG thing). Currently the AtSHA204a and
the AtECC508a (and related families) are sharing the same Atmel i2c
driver. This core driver uses hardcoded max timings for
its i2c command operations. Going over the datasheets of both chips,
both have totally different max timings.
Currently just having RNG for AtSHA204a and ECDH and related for AtECC
- it probably doesn't matter too much. Anyway, also
read and write command timings differ and mix up then in the Atmel i2c
core driver. I guess, this was kind of a starting point for
me to dig deeper. So, I probably will drop that i2c timing change from
this RNG fix set.
Thirdly, the "leak" I think is probably rather a theoretic issue. I'll
sepearate it out, think over it, and in case prepare something,
let me then know what you think.
>
>
> --- a/drivers/crypto/atmel-sha204a.c
> +++ b/drivers/crypto/atmel-sha204a.c
> @@ -47,8 +47,8 @@
>
> if (rng->priv) {
> work_data = (struct atmel_i2c_work_data *)rng->priv;
> - max = min(sizeof(work_data->cmd.data), max);
> - memcpy(data, &work_data->cmd.data, max);
> + max = min(RANDOM_RSP_SIZE - CMD_OVERHEAD_SIZE, max);
> + memcpy(data, &work_data->cmd.data[1], max);
> rng->priv = 0;
> } else {
> work_data = kmalloc_obj(*work_data, GFP_ATOMIC);
> @@ -86,8 +86,8 @@
> if (ret)
> return ret;
>
> - max = min(sizeof(cmd.data), max);
> - memcpy(data, cmd.data, max);
> + max = min(RANDOM_RSP_SIZE - CMD_OVERHEAD_SIZE, max);
> + memcpy(data, &cmd.data[1], max);
>
> return max;
> }
^ permalink raw reply
* Re: [PATCH v3 2/3] crypto: atmel-sha204a - fix truncated 32-byte blocking read
From: Thorsten Blum @ 2026-04-25 13:46 UTC (permalink / raw)
To: Lothar Rubusch
Cc: herbert, davem, nicolas.ferre, alexandre.belloni, claudiu.beznea,
ardb, linusw, linux-crypto, linux-arm-kernel, linux-kernel
In-Reply-To: <20260422210936.20095-3-l.rubusch@gmail.com>
Hi Lothar,
On Wed, Apr 22, 2026 at 09:09:35PM +0000, Lothar Rubusch wrote:
> The ATSHA204A returns a 35-byte packet consisting of a 1-byte count,
> 32 bytes of entropy, and a 2-byte CRC. The current blocking read
> implementation was incorrectly copying data starting from the
> count byte, leading to offset data and truncated entropy.
>
> Additionally, the chip requires significant execution time to
> generate random numbers, going by the datasheet. Reading the I2C bus
> too early results in the chip NACK-ing or returning a partial buffer
> followed by zeros.
>
> Verification:
> Tests before showed repeadetly reading only 8 bytes of entropy:
> $ head -c 32 /dev/hwrng | hexdump -C
> 00000000 02 28 85 b3 47 40 f2 ee 00 00 00 00 00 00 00 00 |.(..G@..........|
> 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
> 00000020
>
> After this patch applied, the result will be as follows:
> $ head -c 32 /dev/hwrng | hexdump -C
> 00000000 5a fc 3f 13 14 68 fe 06 68 0a bd 04 83 6e 09 69 |Z.?..h..h....n.i|
> 00000010 75 ff cf 87 10 84 3b c9 c1 df ae eb 45 53 4c c3 |u.....;.....ESL.|
> 00000020
>
> Fix these issues by:
> Increase cmd.msecs to 30ms to provide sufficient execution time. Then
> set cmd.rxsize to RANDOM_RSP_SIZE (35 bytes) to capture the entire
> hardware response. Eventually, correct the memcpy() offset to index 1 of
> the data buffer to skip the count byte and retrieve exactly 32 bytes of
> entropy.
>
> Fixes: da001fb651b0 ("crypto: atmel-i2c - add support for SHA204A random number generator")
> Signed-off-by: Lothar Rubusch <l.rubusch@gmail.com>
Thank you for your patches. I tested patch 2/3 on real hardware and it
fixes rngtest for me. However, I have a few comments below.
> ---
> drivers/crypto/atmel-sha204a.c | 9 +++++++--
> 1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/crypto/atmel-sha204a.c b/drivers/crypto/atmel-sha204a.c
> index 19720bdd446d..f7dc00d0f4cd 100644
> --- a/drivers/crypto/atmel-sha204a.c
> +++ b/drivers/crypto/atmel-sha204a.c
> @@ -19,6 +19,9 @@
> #include <linux/workqueue.h>
> #include "atmel-i2c.h"
>
> +#define ATMEL_RNG_BLOCK_SIZE 32
> +#define ATMEL_RNG_EXEC_TIME 30
> +
> static void atmel_sha204a_rng_done(struct atmel_i2c_work_data *work_data,
> void *areq, int status)
> {
> @@ -91,13 +94,15 @@ static int atmel_sha204a_rng_read(struct hwrng *rng, void *data, size_t max,
> i2c_priv = container_of(rng, struct atmel_i2c_client_priv, hwrng);
>
> atmel_i2c_init_random_cmd(&cmd);
> + cmd.msecs = ATMEL_RNG_EXEC_TIME;
> + cmd.rxsize = RANDOM_RSP_SIZE;
atmel_i2c_init_random_cmd() already sets cmd.rxsize to RANDOM_RSP_SIZE.
Changing cmd.msecs does not appear to be strictly necessary for the fix.
The only difference I observe is that rngtest runs faster with the new
value.
Here are my test results without changing cmd.msecs:
$ sudo head -c 300000 /dev/hwrng | rngtest -c 100
[...]
rngtest: starting FIPS tests...
rngtest: bits received from input: 2000032
rngtest: FIPS 140-2 successes: 100
rngtest: FIPS 140-2 failures: 0
[...]
rngtest: input channel speed: (min=1.118; avg=3.746; max=6510416.667)Kibits/s
rngtest: FIPS tests speed: (min=26.272; avg=27.471; max=32.829)Mibits/s
rngtest: Program run time: 538942640 microseconds
and with 'cmd.msecs = ATMEL_RNG_EXEC_TIME':
$ sudo head -c 300000 /dev/hwrng | rngtest -c 100
[...]
rngtest: starting FIPS tests...
rngtest: bits received from input: 2000032
rngtest: FIPS 140-2 successes: 100
rngtest: FIPS 140-2 failures: 0
[...]
rngtest: input channel speed: (min=1.584; avg=5.295; max=6510416.667)Kibits/s
rngtest: FIPS tests speed: (min=26.602; avg=27.321; max=28.257)Mibits/s
rngtest: Program run time: 381309284 microseconds
> ret = atmel_i2c_send_receive(i2c_priv->client, &cmd);
> if (ret)
> return ret;
>
> - max = min(sizeof(cmd.data), max);
> - memcpy(data, cmd.data, max);
> + max = min_t(size_t, ATMEL_RNG_BLOCK_SIZE, max);
> + memcpy(data, &cmd.data[1], max);
This works and fixes rngtest for me on real hardware.
min_t() is not strictly necessary here, since the types are compatible
and min() is sufficient.
I agree with Ard that patch 2/3 should be a separate patch for easier
stable backporting.
Thanks,
Thorsten
^ permalink raw reply
* Re: [PATCH v3 2/3] crypto: atmel-sha204a - fix truncated 32-byte blocking read
From: Thorsten Blum @ 2026-04-25 14:08 UTC (permalink / raw)
To: Lothar Rubusch
Cc: herbert, davem, nicolas.ferre, alexandre.belloni, claudiu.beznea,
ardb, linusw, linux-crypto, linux-arm-kernel, linux-kernel
In-Reply-To: <aezFsF8gLkABZZ1O@linux.dev>
On Sat, Apr 25, 2026 at 03:46:30PM +0200, Thorsten Blum wrote:
> Hi Lothar,
>
> On Wed, Apr 22, 2026 at 09:09:35PM +0000, Lothar Rubusch wrote:
> > The ATSHA204A returns a 35-byte packet consisting of a 1-byte count,
> > 32 bytes of entropy, and a 2-byte CRC. The current blocking read
> > implementation was incorrectly copying data starting from the
> > count byte, leading to offset data and truncated entropy.
> >
> > Additionally, the chip requires significant execution time to
> > generate random numbers, going by the datasheet. Reading the I2C bus
> > too early results in the chip NACK-ing or returning a partial buffer
> > followed by zeros.
> >
> > Verification:
> > Tests before showed repeadetly reading only 8 bytes of entropy:
> > $ head -c 32 /dev/hwrng | hexdump -C
> > 00000000 02 28 85 b3 47 40 f2 ee 00 00 00 00 00 00 00 00 |.(..G@..........|
> > 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
> > 00000020
> >
> > After this patch applied, the result will be as follows:
> > $ head -c 32 /dev/hwrng | hexdump -C
> > 00000000 5a fc 3f 13 14 68 fe 06 68 0a bd 04 83 6e 09 69 |Z.?..h..h....n.i|
> > 00000010 75 ff cf 87 10 84 3b c9 c1 df ae eb 45 53 4c c3 |u.....;.....ESL.|
> > 00000020
> >
> > Fix these issues by:
> > Increase cmd.msecs to 30ms to provide sufficient execution time. Then
> > set cmd.rxsize to RANDOM_RSP_SIZE (35 bytes) to capture the entire
> > hardware response. Eventually, correct the memcpy() offset to index 1 of
> > the data buffer to skip the count byte and retrieve exactly 32 bytes of
> > entropy.
> >
> > Fixes: da001fb651b0 ("crypto: atmel-i2c - add support for SHA204A random number generator")
> > Signed-off-by: Lothar Rubusch <l.rubusch@gmail.com>
[...]
> > - max = min(sizeof(cmd.data), max);
> > - memcpy(data, cmd.data, max);
> > + max = min_t(size_t, ATMEL_RNG_BLOCK_SIZE, max);
> > + memcpy(data, &cmd.data[1], max);
I just noticed that index 1 is already defined as RSP_DATA_IDX in
drivers/crypto/atmel-i2c.h.
> This works and fixes rngtest for me on real hardware.
>
> min_t() is not strictly necessary here, since the types are compatible
> and min() is sufficient.
>
> I agree with Ard that patch 2/3 should be a separate patch for easier
> stable backporting.
Thanks,
Thorsten
^ permalink raw reply
* Re: [PATCH net] net: airoha: Do not read uninitialized fragment address in airoha_dev_xmit()
From: Lorenzo Bianconi @ 2026-04-25 14:10 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Simon Horman, linux-arm-kernel, linux-mediatek, netdev
In-Reply-To: <20260424-airoha-xmit-fix-read-frag-v1-1-fdc0a83c79e8@kernel.org>
[-- Attachment #1: Type: text/plain, Size: 3356 bytes --]
> The transmit loop in airoha_dev_xmit() reads fragment address and length
> during its final iteration, when the loop index equals
> skb_shinfo(skb)->nr_frags, at which point the fragment data is
> uninitialized. While these values are never consumed, the read itself is
> unsafe and may trigger a page fault. Fix this by avoiding the fragment
> read on the last iteration.
> Additionally, move the skb pointer from the first to the last used packet
> descriptor, so that airoha_qdma_tx_napi_poll() defers freeing the skb
> until the final descriptor is processed.
>
> Fixes: 23020f0493270 ("net: airoha: Introduce ethernet support for EN7581 SoC")
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> ---
> drivers/net/ethernet/airoha/airoha_eth.c | 9 ++++++---
> 1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
> index 2bb0a3ff9810..d3a841908c82 100644
> --- a/drivers/net/ethernet/airoha/airoha_eth.c
> +++ b/drivers/net/ethernet/airoha/airoha_eth.c
> @@ -1997,8 +1997,8 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
> struct netdev_queue *txq;
> struct airoha_queue *q;
> LIST_HEAD(tx_list);
> + int i = 0, qid;
> void *data;
> - int i, qid;
> u16 index;
> u8 fport;
>
> @@ -2057,7 +2057,7 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
> list);
> index = e - q->entry;
>
> - for (i = 0; i < nr_frags; i++) {
> + while (true) {
> struct airoha_qdma_desc *desc = &q->desc[index];
> skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
> dma_addr_t addr;
> @@ -2069,7 +2069,7 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
> goto error_unmap;
>
> list_move_tail(&e->list, &tx_list);
> - e->skb = i ? NULL : skb;
> + e->skb = i == nr_frags - 1 ? skb : NULL;
> e->dma_addr = addr;
> e->dma_len = len;
>
> @@ -2088,6 +2088,9 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
> WRITE_ONCE(desc->msg1, cpu_to_le32(msg1));
> WRITE_ONCE(desc->msg2, cpu_to_le32(0xffff));
>
> + if (++i == nr_frags)
> + break;
> +
> data = skb_frag_address(frag);
> len = skb_frag_size(frag);
> }
>
> ---
> base-commit: e728258debd553c95d2e70f9cd97c9fde27c7130
> change-id: 20260423-airoha-xmit-fix-read-frag-dc6aa001ca4b
>
> Best regards,
> --
> Lorenzo Bianconi <lorenzo@kernel.org>
>
Commenting on Sashiko reported issues:
https://sashiko.dev/#/patchset/20260424-airoha-xmit-fix-read-frag-v1-1-fdc0a83c79e8%40kernel.org
- Does the TSO checksum calculation earlier in this function ensure the
TCP header is in the linear portion of the SKB?
This issue is not related to the current patch. Moreover, can we have a TSO
packet where the tcp header is not in the linear area of the skb?
- If dma_map_single() fails partway through a multi-fragment packet and
triggers this goto error_unmap, will it break the Tx ring contiguity?
This issue is not related to the current patch. Moreover, I guess the hw is
capable of managing out-of-order descriptors.
- Is it safe to map fragment data using dma_map_single() instead of
skb_frag_dma_map()?
This issue is not related to the current patch. I will post a dedicated patch
for it.
Regards,
Lorenzo
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH v3 2/3] crypto: atmel-sha204a - fix truncated 32-byte blocking read
From: Lothar Rubusch @ 2026-04-25 14:11 UTC (permalink / raw)
To: Thorsten Blum
Cc: herbert, davem, nicolas.ferre, alexandre.belloni, claudiu.beznea,
ardb, linusw, linux-crypto, linux-arm-kernel, linux-kernel
In-Reply-To: <aezFsF8gLkABZZ1O@linux.dev>
Hi Thorsten!
On Sat, Apr 25, 2026 at 3:46 PM Thorsten Blum <thorsten.blum@linux.dev> wrote:
>
> Hi Lothar,
>
> On Wed, Apr 22, 2026 at 09:09:35PM +0000, Lothar Rubusch wrote:
> > The ATSHA204A returns a 35-byte packet consisting of a 1-byte count,
> > 32 bytes of entropy, and a 2-byte CRC. The current blocking read
> > implementation was incorrectly copying data starting from the
> > count byte, leading to offset data and truncated entropy.
> >
> > Additionally, the chip requires significant execution time to
> > generate random numbers, going by the datasheet. Reading the I2C bus
> > too early results in the chip NACK-ing or returning a partial buffer
> > followed by zeros.
> >
> > Verification:
> > Tests before showed repeadetly reading only 8 bytes of entropy:
> > $ head -c 32 /dev/hwrng | hexdump -C
> > 00000000 02 28 85 b3 47 40 f2 ee 00 00 00 00 00 00 00 00 |.(..G@..........|
> > 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
> > 00000020
> >
> > After this patch applied, the result will be as follows:
> > $ head -c 32 /dev/hwrng | hexdump -C
> > 00000000 5a fc 3f 13 14 68 fe 06 68 0a bd 04 83 6e 09 69 |Z.?..h..h....n.i|
> > 00000010 75 ff cf 87 10 84 3b c9 c1 df ae eb 45 53 4c c3 |u.....;.....ESL.|
> > 00000020
> >
> > Fix these issues by:
> > Increase cmd.msecs to 30ms to provide sufficient execution time. Then
> > set cmd.rxsize to RANDOM_RSP_SIZE (35 bytes) to capture the entire
> > hardware response. Eventually, correct the memcpy() offset to index 1 of
> > the data buffer to skip the count byte and retrieve exactly 32 bytes of
> > entropy.
> >
> > Fixes: da001fb651b0 ("crypto: atmel-i2c - add support for SHA204A random number generator")
> > Signed-off-by: Lothar Rubusch <l.rubusch@gmail.com>
>
> Thank you for your patches. I tested patch 2/3 on real hardware and it
> fixes rngtest for me. However, I have a few comments below.
>
> > ---
> > drivers/crypto/atmel-sha204a.c | 9 +++++++--
> > 1 file changed, 7 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/crypto/atmel-sha204a.c b/drivers/crypto/atmel-sha204a.c
> > index 19720bdd446d..f7dc00d0f4cd 100644
> > --- a/drivers/crypto/atmel-sha204a.c
> > +++ b/drivers/crypto/atmel-sha204a.c
> > @@ -19,6 +19,9 @@
> > #include <linux/workqueue.h>
> > #include "atmel-i2c.h"
> >
> > +#define ATMEL_RNG_BLOCK_SIZE 32
> > +#define ATMEL_RNG_EXEC_TIME 30
> > +
> > static void atmel_sha204a_rng_done(struct atmel_i2c_work_data *work_data,
> > void *areq, int status)
> > {
> > @@ -91,13 +94,15 @@ static int atmel_sha204a_rng_read(struct hwrng *rng, void *data, size_t max,
> > i2c_priv = container_of(rng, struct atmel_i2c_client_priv, hwrng);
> >
> > atmel_i2c_init_random_cmd(&cmd);
> > + cmd.msecs = ATMEL_RNG_EXEC_TIME;
> > + cmd.rxsize = RANDOM_RSP_SIZE;
>
> atmel_i2c_init_random_cmd() already sets cmd.rxsize to RANDOM_RSP_SIZE.
>
> Changing cmd.msecs does not appear to be strictly necessary for the fix.
> The only difference I observe is that rngtest runs faster with the new
> value.
>
> Here are my test results without changing cmd.msecs:
>
> $ sudo head -c 300000 /dev/hwrng | rngtest -c 100
> [...]
> rngtest: starting FIPS tests...
> rngtest: bits received from input: 2000032
> rngtest: FIPS 140-2 successes: 100
> rngtest: FIPS 140-2 failures: 0
> [...]
> rngtest: input channel speed: (min=1.118; avg=3.746; max=6510416.667)Kibits/s
> rngtest: FIPS tests speed: (min=26.272; avg=27.471; max=32.829)Mibits/s
> rngtest: Program run time: 538942640 microseconds
>
> and with 'cmd.msecs = ATMEL_RNG_EXEC_TIME':
>
> $ sudo head -c 300000 /dev/hwrng | rngtest -c 100
> [...]
> rngtest: starting FIPS tests...
> rngtest: bits received from input: 2000032
> rngtest: FIPS 140-2 successes: 100
> rngtest: FIPS 140-2 failures: 0
> [...]
> rngtest: input channel speed: (min=1.584; avg=5.295; max=6510416.667)Kibits/s
> rngtest: FIPS tests speed: (min=26.602; avg=27.321; max=28.257)Mibits/s
> rngtest: Program run time: 381309284 microseconds
>
> > ret = atmel_i2c_send_receive(i2c_priv->client, &cmd);
> > if (ret)
> > return ret;
> >
> > - max = min(sizeof(cmd.data), max);
> > - memcpy(data, cmd.data, max);
> > + max = min_t(size_t, ATMEL_RNG_BLOCK_SIZE, max);
> > + memcpy(data, &cmd.data[1], max);
>
> This works and fixes rngtest for me on real hardware.
>
> min_t() is not strictly necessary here, since the types are compatible
> and min() is sufficient.
>
> I agree with Ard that patch 2/3 should be a separate patch for easier
> stable backporting.
>
I appreciate your answers and will take the review into account. Looks
like we had similar plans for
this weekend. So, since I answered to Ard quite in parallel to your
review, I'll restructure as I said in my
last mail on this list. I'll go through your comments and think about it.
Best,
L
> Thanks,
> Thorsten
^ permalink raw reply
* Re: [RFC PATCH v3 4/4] Revert "firmware: arm_ffa: Change initcall level of ffa_init() to rootfs_initcall"
From: Jarkko Sakkinen @ 2026-04-25 14:19 UTC (permalink / raw)
To: Jonathan McDowell
Cc: linux-security-module, linux-kernel, linux-integrity,
linux-arm-kernel, kvmarm, paul, jmorris, serge, zohar,
roberto.sassu, dmitry.kasatkin, eric.snowberg, jgg, sudeep.holla,
maz, oupton, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, will, noodles, sebastianene, Yeoreum Yun
In-Reply-To: <2e7b4dc552b45ddf14cc43bc449cbebb4ade0027.1777036497.git.noodles@meta.com>
On Fri, Apr 24, 2026 at 02:24:42PM +0100, Jonathan McDowell wrote:
> From: Yeoreum Yun <yeoreum.yun@arm.com>
>
> This reverts commit 0e0546eabcd6c19765a8dbf5b5db3723e7b0ea75, which was
> added to address ordering issues with the IMA LSM initialisation where
> the TPM would not be fully ready by the time IMA wanted it. This has
> been resolved within IMA by retrying setup during late_initcall_sync if
> the TPM is not available at first.
>
> Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
> Signed-off-by: Jonathan McDowell <noodles@meta.com>
> ---
> drivers/firmware/arm_ffa/driver.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
> index f2f94d4d533e..01547c5c0e38 100644
> --- a/drivers/firmware/arm_ffa/driver.c
> +++ b/drivers/firmware/arm_ffa/driver.c
> @@ -2106,7 +2106,7 @@ static int __init ffa_init(void)
> kfree(drv_info);
> return ret;
> }
> -rootfs_initcall(ffa_init);
> +module_init(ffa_init);
>
> static void __exit ffa_exit(void)
> {
> --
> 2.53.0
>
LGTM (for both tpm patches).
However, I'll hold on any further comments/tags up until I've sorted 7.1 PRs
(just so that I have full focus).
BR, Jarkko
^ permalink raw reply
* Re: [PATCH v8 3/6] drm/bridge: simple: Add the Lontium LT8711UXD DP-to-HDMI bridge
From: Dmitry Baryshkov @ 2026-04-25 14:24 UTC (permalink / raw)
To: Laurent Pinchart
Cc: Dennis Gilmore, Heiko Stuebner, Andrzej Hajda, Neil Armstrong,
Robert Foss, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Jonas Karlman, Jernej Skrabec, Maxime Ripard, Alexey Charkov,
devicetree, linux-rockchip, linux-arm-kernel, dri-devel,
linux-kernel
In-Reply-To: <20260425112844.GB2964234@killaraus.ideasonboard.com>
On Sat, Apr 25, 2026 at 02:28:44PM +0300, Laurent Pinchart wrote:
> Hi Dennis,
>
> Thank you for the patch.
>
> On Fri, Apr 24, 2026 at 10:10:08PM -0500, Dennis Gilmore wrote:
> > The Lontium LT8711UXD is a high performance two lane Type-C/DP1.4
> > to HDMI2.0 converter, designed to connect a USB Type-C source or
> > a DP1.4 source to an HDMI2.0 sink.
>
> As far as I can tell, the LT8711UXD has an I2C control interface.
> Shouldn't it be an I2C device ?
From the datasheet:
The device is capable of automatic operation which is
enabled by an integrated microprocessor that uses an
embedded SPI flash for firmware storage. System control
is also available through the use of a dedicated
configuration I2C slave interface.
My guess was that it can either be an I2C device or it can function as a
simple platdev with no I2C controls. Please correct me if my
understanding was wrong.
But now looking at the schematics, it seems to be connected to I2C6.
Which means that it should be desribed (and bound) as such.
>
> > Signed-off-by: Dennis Gilmore <dennis@ausil.us>
> > Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> > ---
> > drivers/gpu/drm/bridge/simple-bridge.c | 5 +++++
> > 1 file changed, 5 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/bridge/simple-bridge.c b/drivers/gpu/drm/bridge/simple-bridge.c
> > index 8aa31ca3c72d..42c1f3d5ba0c 100644
> > --- a/drivers/gpu/drm/bridge/simple-bridge.c
> > +++ b/drivers/gpu/drm/bridge/simple-bridge.c
> > @@ -270,6 +270,11 @@ static const struct of_device_id simple_bridge_match[] = {
> > .data = &(const struct simple_bridge_info) {
> > .connector_type = DRM_MODE_CONNECTOR_HDMIA,
> > },
> > + }, {
> > + .compatible = "lontium,lt8711uxd",
> > + .data = &(const struct simple_bridge_info) {
> > + .connector_type = DRM_MODE_CONNECTOR_HDMIA,
> > + },
> > }, {
> > .compatible = "parade,ps185hdm",
> > .data = &(const struct simple_bridge_info) {
>
> --
> Regards,
>
> Laurent Pinchart
--
With best wishes
Dmitry
^ permalink raw reply
* Re: [PATCH v3 0/3] iio: adc: xilinx-ams: refactor alarm handling to table-driven design
From: Jonathan Cameron @ 2026-04-25 15:34 UTC (permalink / raw)
To: Guilherme Ivo Bozi
Cc: Salih Erim, Conall O'Griofa, Michal Simek, David Lechner,
Nuno Sá, Andy Shevchenko, linux-iio, linux-arm-kernel,
linux-kernel
In-Reply-To: <20260414224245.8493-1-guilherme.bozi@usp.br>
On Tue, 14 Apr 2026 19:40:32 -0300
Guilherme Ivo Bozi <guilherme.bozi@usp.br> wrote:
> This series addresses significant code duplication in alarm handling
> logic across the Xilinx AMS IIO driver.
>
> To address this, the series introduces a centralized table-driven
> mapping (alarm_map) that replaces multiple switch statements spread
> across the driver.
>
> This improves:
> - maintainability (single source of truth for mappings)
> - readability (removes repeated switch logic)
> - extensibility (new alarms require only table updates)
>
> No functional changes are intended.
This series looks fine to me.
Given the AMD Xilinx folk are fairly active reviewers I'm just
waiting on them taking a look.
>
> Series overview:
> - Patch 1: fix out-of-bounds channel lookup
> - Patch 2: convert mutex handling to guard(mutex)
> - Patch 3: introduce table-driven alarm mapping
>
> v1 -> v2:
> - Fixed Fixes tag format
> - Replaced AMS_ALARM_INVALID with AMS_ALARM_NONE
> - Changed alarm_map base_offset type
>
> v2 -> v3:
> - Replace 'i >= num_channels' with 'i == num_channels'
> - Add missing trailing comma in alarm_map array initializer
>
> Guilherme Ivo Bozi (3):
> iio: adc: xilinx-ams: fix out-of-bounds channel lookup in event
> handling
> iio: adc: xilinx-ams: use guard(mutex) for automatic locking
> iio: adc: xilinx-ams: refactor alarm mapping to table-driven approach
>
> drivers/iio/adc/xilinx-ams.c | 190 +++++++++++++----------------------
> 1 file changed, 71 insertions(+), 119 deletions(-)
>
^ permalink raw reply
* [PATCH] pinctrl: qcom: Make important drivers default
From: Krzysztof Kozlowski @ 2026-04-25 15:55 UTC (permalink / raw)
To: Russell King, Bjorn Andersson, Konrad Dybcio, Linus Walleij,
linux-arm-kernel, linux-kernel, linux-arm-msm, linux-gpio
Cc: Krzysztof Kozlowski
The main SoC TLMM (Top-Level Multiplexer) pin controller drivers are
essential for booting up SoCs and are not really optional for a given
platform. Kernel should not ask users choice of drivers when that
choice is obvious and known to the developers that answer should be
'yes' or 'module'.
Switch all Qualcomm TLMM pin controller drivers to a default 'yes' for
ARCH_QCOM. This has impact:
1. arm64 defconfig: enable PINCTRL_SM7150 and PINCTRL_HAWI, which were
not selected before but should be, because these platforms need them
for proper boot.
2. arm qcom_defconfig: no changes.
3. arm multi_v7 defconfig: enable drivers necessary to boot ARM 32-bit
platforms, which are already enabled on qcom_defconfig.
4. COMPILE_TEST builds: enable by default all drivers for arm or arm64
builds, whenever ARCH_QCOM is selected. This has impact on build
time and feels logical, because if one selects ARCH_QCOM then
probably by default wants to build test it entirely. Kernels with
COMPILE_TEST are not supposed to be used for booting.
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
---
I did similar change for clocks and I will be continuing with
interconnect and other missing pieces.
---
arch/arm/configs/multi_v7_defconfig | 8 ----
arch/arm/configs/qcom_defconfig | 15 --------
arch/arm64/configs/defconfig | 46 ----------------------
drivers/pinctrl/qcom/Kconfig | 1 +
drivers/pinctrl/qcom/Kconfig.msm | 60 +++++++++++++++++++++++++++++
5 files changed, 61 insertions(+), 69 deletions(-)
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index bcc9aabc1202..3847a6c17193 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -483,14 +483,6 @@ CONFIG_PINCTRL_PALMAS=y
CONFIG_PINCTRL_STMFX=y
CONFIG_PINCTRL_OWL=y
CONFIG_PINCTRL_S500=y
-CONFIG_PINCTRL_MSM=y
-CONFIG_PINCTRL_APQ8064=y
-CONFIG_PINCTRL_APQ8084=y
-CONFIG_PINCTRL_IPQ8064=y
-CONFIG_PINCTRL_MSM8660=y
-CONFIG_PINCTRL_MSM8960=y
-CONFIG_PINCTRL_MSM8X74=y
-CONFIG_PINCTRL_MSM8916=y
CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
CONFIG_PINCTRL_QCOM_SSBI_PMIC=y
CONFIG_PINCTRL_RZA2=y
diff --git a/arch/arm/configs/qcom_defconfig b/arch/arm/configs/qcom_defconfig
index 29a1dea500f0..03309b89ea4c 100644
--- a/arch/arm/configs/qcom_defconfig
+++ b/arch/arm/configs/qcom_defconfig
@@ -123,22 +123,7 @@ CONFIG_I2C_QUP=y
CONFIG_SPI=y
CONFIG_SPI_QUP=y
CONFIG_SPMI=y
-CONFIG_PINCTRL_MSM=y
-CONFIG_PINCTRL_APQ8064=y
-CONFIG_PINCTRL_APQ8084=y
-CONFIG_PINCTRL_IPQ4019=y
-CONFIG_PINCTRL_IPQ8064=y
-CONFIG_PINCTRL_MSM8226=y
-CONFIG_PINCTRL_MSM8660=y
-CONFIG_PINCTRL_MSM8960=y
-CONFIG_PINCTRL_MDM9607=y
-CONFIG_PINCTRL_MDM9615=y
-CONFIG_PINCTRL_MSM8X74=y
-CONFIG_PINCTRL_MSM8909=y
-CONFIG_PINCTRL_MSM8916=y
CONFIG_GPIOLIB=y
-CONFIG_PINCTRL_SDX55=y
-CONFIG_PINCTRL_SDX65=y
CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
CONFIG_PINCTRL_QCOM_SSBI_PMIC=y
CONFIG_GPIO_SYSFS=y
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index dd1ac01ee29b..f4dfd0cc853c 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -652,54 +652,8 @@ CONFIG_PINCTRL_IMX8ULP=y
CONFIG_PINCTRL_IMX91=y
CONFIG_PINCTRL_IMX93=y
CONFIG_PINCTRL_IMX_SCMI=y
-CONFIG_PINCTRL_MSM=y
-CONFIG_PINCTRL_ELIZA=y
-CONFIG_PINCTRL_GLYMUR=y
-CONFIG_PINCTRL_IPQ5018=y
-CONFIG_PINCTRL_IPQ5210=y
-CONFIG_PINCTRL_IPQ5332=y
-CONFIG_PINCTRL_IPQ5424=y
-CONFIG_PINCTRL_IPQ8074=y
-CONFIG_PINCTRL_IPQ6018=y
-CONFIG_PINCTRL_IPQ9574=y
-CONFIG_PINCTRL_KAANAPALI=y
-CONFIG_PINCTRL_MSM8916=y
-CONFIG_PINCTRL_MSM8953=y
-CONFIG_PINCTRL_MSM8976=y
-CONFIG_PINCTRL_MSM8994=y
-CONFIG_PINCTRL_MSM8996=y
-CONFIG_PINCTRL_MSM8998=y
-CONFIG_PINCTRL_QCM2290=y
-CONFIG_PINCTRL_QCS404=y
-CONFIG_PINCTRL_QCS615=y
-CONFIG_PINCTRL_QCS8300=y
-CONFIG_PINCTRL_QDF2XXX=y
-CONFIG_PINCTRL_QDU1000=y
CONFIG_PINCTRL_RP1=m
-CONFIG_PINCTRL_SA8775P=y
-CONFIG_PINCTRL_SC7180=y
-CONFIG_PINCTRL_SC7280=y
-CONFIG_PINCTRL_SC8180X=y
-CONFIG_PINCTRL_SC8280XP=y
-CONFIG_PINCTRL_SDM660=y
-CONFIG_PINCTRL_SDM670=y
-CONFIG_PINCTRL_SDM845=y
-CONFIG_PINCTRL_SDX75=y
CONFIG_PINCTRL_SKY1=y
-CONFIG_PINCTRL_SM4450=y
-CONFIG_PINCTRL_SM6115=y
-CONFIG_PINCTRL_SM6125=y
-CONFIG_PINCTRL_SM6350=y
-CONFIG_PINCTRL_SM6375=y
-CONFIG_PINCTRL_MILOS=y
-CONFIG_PINCTRL_SM8150=y
-CONFIG_PINCTRL_SM8250=y
-CONFIG_PINCTRL_SM8350=y
-CONFIG_PINCTRL_SM8450=y
-CONFIG_PINCTRL_SM8550=y
-CONFIG_PINCTRL_SM8650=y
-CONFIG_PINCTRL_SM8750=y
-CONFIG_PINCTRL_X1E80100=y
CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
CONFIG_PINCTRL_LPASS_LPI=m
CONFIG_PINCTRL_MILOS_LPASS_LPI=m
diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig
index 80af372a1147..ed5347cebb4c 100644
--- a/drivers/pinctrl/qcom/Kconfig
+++ b/drivers/pinctrl/qcom/Kconfig
@@ -6,6 +6,7 @@ config PINCTRL_MSM
depends on GPIOLIB
# OF for pinconf_generic_dt_node_to_map_group() from GENERIC_PINCONF
depends on OF
+ default ARCH_QCOM
select QCOM_SCM
select PINMUX
select GENERIC_PINMUX_FUNCTIONS
diff --git a/drivers/pinctrl/qcom/Kconfig.msm b/drivers/pinctrl/qcom/Kconfig.msm
index 836cdeca1006..1f77ccb2dcaf 100644
--- a/drivers/pinctrl/qcom/Kconfig.msm
+++ b/drivers/pinctrl/qcom/Kconfig.msm
@@ -4,6 +4,7 @@ if PINCTRL_MSM
config PINCTRL_APQ8064
tristate "Qualcomm APQ8064 pin controller driver"
depends on ARM || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm TLMM block found in the Qualcomm APQ8064 platform.
@@ -11,6 +12,7 @@ config PINCTRL_APQ8064
config PINCTRL_APQ8084
tristate "Qualcomm APQ8084 pin controller driver"
depends on ARM || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm TLMM block found in the Qualcomm APQ8084 platform.
@@ -18,6 +20,7 @@ config PINCTRL_APQ8084
config PINCTRL_ELIZA
tristate "Qualcomm Technologies Inc Eliza pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc Top Level Mode Multiplexer block (TLMM)
@@ -28,6 +31,7 @@ config PINCTRL_ELIZA
config PINCTRL_GLYMUR
tristate "Qualcomm Technologies Inc Glymur pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc Top Level Mode Multiplexer block (TLMM)
@@ -38,6 +42,7 @@ config PINCTRL_GLYMUR
config PINCTRL_HAWI
tristate "Qualcomm Technologies Inc Hawi pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc Top Level Mode Multiplexer block (TLMM)
@@ -48,6 +53,7 @@ config PINCTRL_HAWI
config PINCTRL_IPQ4019
tristate "Qualcomm IPQ4019 pin controller driver"
depends on ARM || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm TLMM block found in the Qualcomm IPQ4019 platform.
@@ -55,6 +61,7 @@ config PINCTRL_IPQ4019
config PINCTRL_IPQ5018
tristate "Qualcomm Technologies, Inc. IPQ5018 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for
the Qualcomm Technologies Inc. TLMM block found on the
@@ -64,6 +71,7 @@ config PINCTRL_IPQ5018
config PINCTRL_IPQ8064
tristate "Qualcomm IPQ8064 pin controller driver"
depends on ARM || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm TLMM block found in the Qualcomm IPQ8064 platform.
@@ -71,6 +79,7 @@ config PINCTRL_IPQ8064
config PINCTRL_IPQ5210
tristate "Qualcomm Technologies Inc IPQ5210 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -79,6 +88,7 @@ config PINCTRL_IPQ5210
config PINCTRL_IPQ5332
tristate "Qualcomm Technologies Inc IPQ5332 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -87,6 +97,7 @@ config PINCTRL_IPQ5332
config PINCTRL_IPQ5424
tristate "Qualcomm Technologies, Inc. IPQ5424 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for
the Qualcomm Technologies Inc. TLMM block found on the
@@ -96,6 +107,7 @@ config PINCTRL_IPQ5424
config PINCTRL_IPQ8074
tristate "Qualcomm Technologies, Inc. IPQ8074 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for
the Qualcomm Technologies Inc. TLMM block found on the
@@ -105,6 +117,7 @@ config PINCTRL_IPQ8074
config PINCTRL_IPQ6018
tristate "Qualcomm Technologies, Inc. IPQ6018 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for
the Qualcomm Technologies Inc. TLMM block found on the
@@ -114,6 +127,7 @@ config PINCTRL_IPQ6018
config PINCTRL_IPQ9574
tristate "Qualcomm Technologies, Inc. IPQ9574 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for
the Qualcomm Technologies Inc. TLMM block found on the
@@ -123,6 +137,7 @@ config PINCTRL_IPQ9574
config PINCTRL_KAANAPALI
tristate "Qualcomm Technologies Inc Kaanapali pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -131,6 +146,7 @@ config PINCTRL_KAANAPALI
config PINCTRL_MSM8226
tristate "Qualcomm 8226 pin controller driver"
depends on ARM || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -139,6 +155,7 @@ config PINCTRL_MSM8226
config PINCTRL_MSM8660
tristate "Qualcomm 8660 pin controller driver"
depends on ARM || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm TLMM block found in the Qualcomm 8660 platform.
@@ -146,12 +163,14 @@ config PINCTRL_MSM8660
config PINCTRL_MSM8960
tristate "Qualcomm 8960 pin controller driver"
depends on ARM || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm TLMM block found in the Qualcomm 8960 platform.
config PINCTRL_MDM9607
tristate "Qualcomm 9607 pin controller driver"
+ default ARCH_QCOM if ARM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm TLMM block found in the Qualcomm 9607 platform.
@@ -159,6 +178,7 @@ config PINCTRL_MDM9607
config PINCTRL_MDM9615
tristate "Qualcomm 9615 pin controller driver"
depends on ARM || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm TLMM block found in the Qualcomm 9615 platform.
@@ -166,6 +186,7 @@ config PINCTRL_MDM9615
config PINCTRL_MSM8X74
tristate "Qualcomm 8x74 pin controller driver"
depends on ARM || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm TLMM block found in the Qualcomm 8974 platform.
@@ -173,12 +194,14 @@ config PINCTRL_MSM8X74
config PINCTRL_MSM8909
tristate "Qualcomm 8909 pin controller driver"
depends on ARM || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm TLMM block found on the Qualcomm MSM8909 platform.
config PINCTRL_MSM8916
tristate "Qualcomm 8916 pin controller driver"
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm TLMM block found on the Qualcomm 8916 platform.
@@ -192,6 +215,7 @@ config PINCTRL_MSM8917
config PINCTRL_MSM8953
tristate "Qualcomm 8953 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm TLMM block found on the Qualcomm MSM8953 platform.
@@ -201,6 +225,7 @@ config PINCTRL_MSM8953
config PINCTRL_MSM8976
tristate "Qualcomm 8976 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm TLMM block found on the Qualcomm MSM8976 platform.
@@ -210,6 +235,7 @@ config PINCTRL_MSM8976
config PINCTRL_MSM8994
tristate "Qualcomm 8994 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm TLMM block found in the Qualcomm 8994 platform. The
@@ -218,6 +244,7 @@ config PINCTRL_MSM8994
config PINCTRL_MSM8996
tristate "Qualcomm MSM8996 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm TLMM block found in the Qualcomm MSM8996 platform.
@@ -225,6 +252,7 @@ config PINCTRL_MSM8996
config PINCTRL_MSM8998
tristate "Qualcomm MSM8998 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm TLMM block found in the Qualcomm MSM8998 platform.
@@ -232,6 +260,7 @@ config PINCTRL_MSM8998
config PINCTRL_QCM2290
tristate "Qualcomm QCM2290 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
TLMM block found in the Qualcomm QCM2290 platform.
@@ -239,6 +268,7 @@ config PINCTRL_QCM2290
config PINCTRL_QCS404
tristate "Qualcomm QCS404 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
TLMM block found in the Qualcomm QCS404 platform.
@@ -246,6 +276,7 @@ config PINCTRL_QCS404
config PINCTRL_QCS615
tristate "Qualcomm Technologies QCS615 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
TLMM block found on the Qualcomm QCS615 platform.
@@ -253,6 +284,7 @@ config PINCTRL_QCS615
config PINCTRL_QCS8300
tristate "Qualcomm Technologies QCS8300 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux and pinconf driver for the Qualcomm
TLMM block found on the Qualcomm QCS8300 platform.
@@ -260,6 +292,7 @@ config PINCTRL_QCS8300
config PINCTRL_QDF2XXX
tristate "Qualcomm Technologies QDF2xxx pin controller driver"
depends on ACPI
+ default ARCH_QCOM if ARM64
help
This is the GPIO driver for the TLMM block found on the
Qualcomm Technologies QDF2xxx SOCs.
@@ -267,6 +300,7 @@ config PINCTRL_QDF2XXX
config PINCTRL_QDU1000
tristate "Qualcomm Technologies Inc QDU1000/QRU1000 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf, and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -275,6 +309,7 @@ config PINCTRL_QDU1000
config PINCTRL_SA8775P
tristate "Qualcomm Technologies Inc SA8775P pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux and pinconf driver for the Qualcomm
TLMM block found on the Qualcomm SA8775P platforms.
@@ -290,6 +325,7 @@ config PINCTRL_SAR2130P
config PINCTRL_SC7180
tristate "Qualcomm Technologies Inc SC7180 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -298,6 +334,7 @@ config PINCTRL_SC7180
config PINCTRL_SC7280
tristate "Qualcomm Technologies Inc SC7280 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -307,6 +344,7 @@ config PINCTRL_SC8180X
tristate "Qualcomm Technologies Inc SC8180x pin controller driver"
depends on (OF || ACPI)
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -315,6 +353,7 @@ config PINCTRL_SC8180X
config PINCTRL_SC8280XP
tristate "Qualcomm Technologies Inc SC8280xp pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -323,6 +362,7 @@ config PINCTRL_SC8280XP
config PINCTRL_SDM660
tristate "Qualcomm Technologies Inc SDM660 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -331,6 +371,7 @@ config PINCTRL_SDM660
config PINCTRL_SDM670
tristate "Qualcomm Technologies Inc SDM670 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -340,6 +381,7 @@ config PINCTRL_SDM845
tristate "Qualcomm Technologies Inc SDM845 pin controller driver"
depends on (OF || ACPI)
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -348,6 +390,7 @@ config PINCTRL_SDM845
config PINCTRL_SDX55
tristate "Qualcomm Technologies Inc SDX55 pin controller driver"
depends on ARM || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -356,6 +399,7 @@ config PINCTRL_SDX55
config PINCTRL_SDX65
tristate "Qualcomm Technologies Inc SDX65 pin controller driver"
depends on ARM || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -364,6 +408,7 @@ config PINCTRL_SDX65
config PINCTRL_SDX75
tristate "Qualcomm Technologies Inc SDX75 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -372,6 +417,7 @@ config PINCTRL_SDX75
config PINCTRL_SM4450
tristate "Qualcomm Technologies Inc SM4450 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -380,6 +426,7 @@ config PINCTRL_SM4450
config PINCTRL_SM6115
tristate "Qualcomm Technologies Inc SM6115,SM4250 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -388,6 +435,7 @@ config PINCTRL_SM6115
config PINCTRL_SM6125
tristate "Qualcomm Technologies Inc SM6125 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -396,6 +444,7 @@ config PINCTRL_SM6125
config PINCTRL_SM6350
tristate "Qualcomm Technologies Inc SM6350 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -404,6 +453,7 @@ config PINCTRL_SM6350
config PINCTRL_SM6375
tristate "Qualcomm Technologies Inc SM6375 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -412,6 +462,7 @@ config PINCTRL_SM6375
config PINCTRL_SM7150
tristate "Qualcomm Technologies Inc SM7150 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -420,6 +471,7 @@ config PINCTRL_SM7150
config PINCTRL_MILOS
tristate "Qualcomm Technologies Inc Milos pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -428,6 +480,7 @@ config PINCTRL_MILOS
config PINCTRL_SM8150
tristate "Qualcomm Technologies Inc SM8150 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -436,6 +489,7 @@ config PINCTRL_SM8150
config PINCTRL_SM8250
tristate "Qualcomm Technologies Inc SM8250 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -444,6 +498,7 @@ config PINCTRL_SM8250
config PINCTRL_SM8350
tristate "Qualcomm Technologies Inc SM8350 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -452,6 +507,7 @@ config PINCTRL_SM8350
config PINCTRL_SM8450
tristate "Qualcomm Technologies Inc SM8450 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -460,6 +516,7 @@ config PINCTRL_SM8450
config PINCTRL_SM8550
tristate "Qualcomm Technologies Inc SM8550 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -468,6 +525,7 @@ config PINCTRL_SM8550
config PINCTRL_SM8650
tristate "Qualcomm Technologies Inc SM8650 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -476,6 +534,7 @@ config PINCTRL_SM8650
config PINCTRL_SM8750
tristate "Qualcomm Technologies Inc SM8750 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -484,6 +543,7 @@ config PINCTRL_SM8750
config PINCTRL_X1E80100
tristate "Qualcomm Technologies Inc X1E80100 pin controller driver"
depends on ARM64 || COMPILE_TEST
+ default ARCH_QCOM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc Top Level Mode Multiplexer block (TLMM)
--
2.51.0
^ permalink raw reply related
* [PATCH] iio: adc: meson-saradc: fix calibration buffer leak on error
From: Felix Gu @ 2026-04-25 16:07 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Rosen Penev
Cc: linux-iio, linux-arm-kernel, linux-amlogic, linux-kernel,
Jonathan Cameron, Felix Gu
meson_sar_adc_temp_sensor_init() allocates a buffer with
nvmem_cell_read(), but the old code leaked it if
syscon_regmap_lookup_by_phandle() failed.
Switch buf to __free(kfree) so all return paths release it.
Fixes: d6f2eac64403 ("iio: adc: meson: no devm for nvmem_cell_get")
Signed-off-by: Felix Gu <ustc.gu@gmail.com>
---
drivers/iio/adc/meson_saradc.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/drivers/iio/adc/meson_saradc.c b/drivers/iio/adc/meson_saradc.c
index 23991a3612bd..9708ddcc4919 100644
--- a/drivers/iio/adc/meson_saradc.c
+++ b/drivers/iio/adc/meson_saradc.c
@@ -786,7 +786,7 @@ static int meson_sar_adc_clk_init(struct iio_dev *indio_dev,
static int meson_sar_adc_temp_sensor_init(struct iio_dev *indio_dev)
{
struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
- u8 *buf, trimming_bits, trimming_mask, upper_adc_val;
+ u8 trimming_bits, trimming_mask, upper_adc_val;
struct device *dev = indio_dev->dev.parent;
struct nvmem_cell *temperature_calib;
size_t read_len;
@@ -807,14 +807,12 @@ static int meson_sar_adc_temp_sensor_init(struct iio_dev *indio_dev)
}
read_len = MESON_SAR_ADC_EFUSE_BYTES;
- buf = nvmem_cell_read(temperature_calib, &read_len);
+ u8 *buf __free(kfree) = nvmem_cell_read(temperature_calib, &read_len);
nvmem_cell_put(temperature_calib);
if (IS_ERR(buf))
return dev_err_probe(dev, PTR_ERR(buf), "failed to read temperature_calib cell\n");
- if (read_len != MESON_SAR_ADC_EFUSE_BYTES) {
- kfree(buf);
+ if (read_len != MESON_SAR_ADC_EFUSE_BYTES)
return dev_err_probe(dev, -EINVAL, "invalid read size of temperature_calib cell\n");
- }
priv->tsc_regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "amlogic,hhi-sysctrl");
if (IS_ERR(priv->tsc_regmap))
@@ -835,8 +833,6 @@ static int meson_sar_adc_temp_sensor_init(struct iio_dev *indio_dev)
priv->temperature_sensor_adc_val |= upper_adc_val << BITS_PER_BYTE;
priv->temperature_sensor_adc_val >>= trimming_bits;
- kfree(buf);
-
return 0;
}
---
base-commit: 7080e32d3f09d8688c4a87d81bdcc71f7f606b16
change-id: 20260425-meson_saradc-54abc52d9b31
Best regards,
--
Felix Gu <ustc.gu@gmail.com>
^ permalink raw reply related
* Re: [PATCH] iio: adc: meson-saradc: fix calibration buffer leak on error
From: David Lechner @ 2026-04-25 16:17 UTC (permalink / raw)
To: Felix Gu, Jonathan Cameron, Nuno Sá, Andy Shevchenko,
Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Rosen Penev
Cc: linux-iio, linux-arm-kernel, linux-amlogic, linux-kernel
In-Reply-To: <20260426-meson_saradc-v1-1-6e96b2982c43@gmail.com>
On 4/25/26 11:07 AM, Felix Gu wrote:
> meson_sar_adc_temp_sensor_init() allocates a buffer with
> nvmem_cell_read(), but the old code leaked it if
> syscon_regmap_lookup_by_phandle() failed.
>
> Switch buf to __free(kfree) so all return paths release it.
>
> Fixes: d6f2eac64403 ("iio: adc: meson: no devm for nvmem_cell_get")
> Signed-off-by: Felix Gu <ustc.gu@gmail.com>
> ---
> drivers/iio/adc/meson_saradc.c | 10 +++-------
> 1 file changed, 3 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/iio/adc/meson_saradc.c b/drivers/iio/adc/meson_saradc.c
> index 23991a3612bd..9708ddcc4919 100644
> --- a/drivers/iio/adc/meson_saradc.c
> +++ b/drivers/iio/adc/meson_saradc.c
> @@ -786,7 +786,7 @@ static int meson_sar_adc_clk_init(struct iio_dev *indio_dev,
> static int meson_sar_adc_temp_sensor_init(struct iio_dev *indio_dev)
> {
Nice to see one of these cleanup.h patches that is actually fixing a bug.
Should `#include <linux/cleanup.h>` though rather that relying on it being
included through another header.
With that fixed...
Reviewed-by: David Lechner <dlechner@baylibre.com>
^ permalink raw reply
* [PATCH v6 01/59] perf inject: Fix itrace branch stack synthesis
From: Ian Rogers @ 2026-04-25 17:47 UTC (permalink / raw)
To: acme, adrian.hunter, james.clark, leo.yan, namhyung, tmricht
Cc: alice.mei.rogers, dapeng1.mi, linux-arm-kernel, linux-kernel,
linux-perf-users, mingo, peterz, Ian Rogers
In-Reply-To: <20260425174858.3922152-1-irogers@google.com>
When using "perf inject --itrace=L" to synthesize branch stacks from
AUX data, several issues caused failures:
1. The synthesized samples were delivered without the
PERF_SAMPLE_BRANCH_STACK flag if it was not in the original event's
sample_type. Fixed by using sample_type | evsel->synth_sample_type
in intel_pt_deliver_synth_event.
2. The record layout was misaligned because of inconsistent handling
of PERF_SAMPLE_BRANCH_HW_INDEX. Fixed by explicitly writing nr and
hw_idx in perf_event__synthesize_sample.
3. Modifying evsel->core.attr.sample_type early in __cmd_inject caused
parse failures for subsequent records in the input file. Fixed by
moving this modification to just before writing the header.
4. perf_event__repipe_sample was narrowed to only synthesize samples
when branch stack injection was requested, and restored the use of
perf_inject__cut_auxtrace_sample as a fallback to preserve
functionality.
Assisted-by: Gemini:gemini-3.1-pro-preview
Signed-off-by: Ian Rogers <irogers@google.com>
---
Issues fixed in v2:
1. Potential Heap Overflow in perf_event__repipe_sample : Addressed by
adding a check that prints an error and returns -EFAULT if the
calculated event size exceeds PERF_SAMPLE_MAX_SIZE , as you
requested.
2. Header vs Payload Mismatch in __cmd_inject : Addressed by narrowing
the condition so that HEADER_BRANCH_STACK is only set in the file
header if add_last_branch was true.
3. NULL Pointer Dereference in intel-pt.c : Addressed by updating the
condition in intel_pt_do_synth_pebs_sample to fill sample.
branch_stack if it was synthesized, even if not in the original
sample_type .
4. Unsafe Reads for events lacking HW_INDEX in synthetic-events.c :
Addressed by using the perf_sample__branch_entries() macro and
checking sample->no_hw_idx .
5. Size mismatch in perf_event__sample_event_size : Addressed by
passing branch_sample_type to it and conditioning the hw_idx size on
PERF_SAMPLE_BRANCH_HW_INDEX .
---
tools/perf/bench/inject-buildid.c | 9 ++--
tools/perf/builtin-inject.c | 77 ++++++++++++++++++++++++++++--
tools/perf/tests/dlfilter-test.c | 8 +++-
tools/perf/tests/sample-parsing.c | 5 +-
tools/perf/util/arm-spe.c | 7 ++-
tools/perf/util/cs-etm.c | 6 ++-
tools/perf/util/intel-bts.c | 3 +-
tools/perf/util/intel-pt.c | 13 +++--
tools/perf/util/synthetic-events.c | 25 +++++++---
tools/perf/util/synthetic-events.h | 6 ++-
10 files changed, 129 insertions(+), 30 deletions(-)
diff --git a/tools/perf/bench/inject-buildid.c b/tools/perf/bench/inject-buildid.c
index aad572a78d7f..bfd2c5ec9488 100644
--- a/tools/perf/bench/inject-buildid.c
+++ b/tools/perf/bench/inject-buildid.c
@@ -228,9 +228,12 @@ static ssize_t synthesize_sample(struct bench_data *data, struct bench_dso *dso,
event.header.type = PERF_RECORD_SAMPLE;
event.header.misc = PERF_RECORD_MISC_USER;
- event.header.size = perf_event__sample_event_size(&sample, bench_sample_type, 0);
-
- perf_event__synthesize_sample(&event, bench_sample_type, 0, &sample);
+ event.header.size = perf_event__sample_event_size(&sample, bench_sample_type,
+ /*read_format=*/0,
+ /*branch_sample_type=*/0);
+ perf_event__synthesize_sample(&event, bench_sample_type,
+ /*read_format=*/0,
+ /*branch_sample_type=*/0, &sample);
return writen(data->input_pipe[1], &event, event.header.size);
}
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index f174bc69cec4..88c0ef4f5ff1 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -375,7 +375,59 @@ static int perf_event__repipe_sample(const struct perf_tool *tool,
build_id__mark_dso_hit(tool, event, sample, evsel, machine);
- if (inject->itrace_synth_opts.set && sample->aux_sample.size) {
+ if (inject->itrace_synth_opts.set &&
+ (inject->itrace_synth_opts.last_branch ||
+ inject->itrace_synth_opts.add_last_branch)) {
+ union perf_event *event_copy = (void *)inject->event_copy;
+ struct branch_stack dummy_bs = { .nr = 0 };
+ int err;
+ size_t sz;
+ u64 orig_type = evsel->core.attr.sample_type;
+ u64 orig_branch_type = evsel->core.attr.branch_sample_type;
+
+ if (event_copy == NULL) {
+ inject->event_copy = malloc(PERF_SAMPLE_MAX_SIZE);
+ if (!inject->event_copy)
+ return -ENOMEM;
+
+ event_copy = (void *)inject->event_copy;
+ }
+
+ if (!sample->branch_stack)
+ sample->branch_stack = &dummy_bs;
+
+ if (inject->itrace_synth_opts.add_last_branch) {
+ /* Temporarily add in type bits for synthesis. */
+ evsel->core.attr.sample_type |= PERF_SAMPLE_BRANCH_STACK;
+ evsel->core.attr.branch_sample_type |= PERF_SAMPLE_BRANCH_HW_INDEX;
+ evsel->core.attr.sample_type &= ~PERF_SAMPLE_AUX;
+ }
+
+ sz = perf_event__sample_event_size(sample, evsel->core.attr.sample_type,
+ evsel->core.attr.read_format,
+ evsel->core.attr.branch_sample_type);
+
+ if (sz > PERF_SAMPLE_MAX_SIZE) {
+ pr_err("Sample size %zu exceeds max size %d\n", sz, PERF_SAMPLE_MAX_SIZE);
+ return -EFAULT;
+ }
+
+ event_copy->header.type = PERF_RECORD_SAMPLE;
+ event_copy->header.size = sz;
+
+ err = perf_event__synthesize_sample(event_copy, evsel->core.attr.sample_type,
+ evsel->core.attr.read_format,
+ evsel->core.attr.branch_sample_type, sample);
+
+ evsel->core.attr.sample_type = orig_type;
+ evsel->core.attr.branch_sample_type = orig_branch_type;
+
+ if (err) {
+ pr_err("Failed to synthesize sample\n");
+ return err;
+ }
+ event = event_copy;
+ } else if (inject->itrace_synth_opts.set && sample->aux_sample.size) {
event = perf_inject__cut_auxtrace_sample(inject, event, sample);
if (IS_ERR(event))
return PTR_ERR(event);
@@ -464,7 +516,8 @@ static int perf_event__convert_sample_callchain(const struct perf_tool *tool,
sample_type &= ~(PERF_SAMPLE_STACK_USER | PERF_SAMPLE_REGS_USER);
perf_event__synthesize_sample(event_copy, sample_type,
- evsel->core.attr.read_format, sample);
+ evsel->core.attr.read_format,
+ evsel->core.attr.branch_sample_type, sample);
return perf_event__repipe_synth(tool, event_copy);
}
@@ -1100,7 +1153,8 @@ static int perf_inject__sched_stat(const struct perf_tool *tool,
sample_sw.period = sample->period;
sample_sw.time = sample->time;
perf_event__synthesize_sample(event_sw, evsel->core.attr.sample_type,
- evsel->core.attr.read_format, &sample_sw);
+ evsel->core.attr.read_format,
+ evsel->core.attr.branch_sample_type, &sample_sw);
build_id__mark_dso_hit(tool, event_sw, &sample_sw, evsel, machine);
ret = perf_event__repipe(tool, event_sw, &sample_sw, machine);
perf_sample__exit(&sample_sw);
@@ -2434,12 +2488,25 @@ static int __cmd_inject(struct perf_inject *inject)
* synthesized hardware events, so clear the feature flag.
*/
if (inject->itrace_synth_opts.set) {
+ struct evsel *evsel;
+
perf_header__clear_feat(&session->header,
HEADER_AUXTRACE);
- if (inject->itrace_synth_opts.last_branch ||
- inject->itrace_synth_opts.add_last_branch)
+
+ evlist__for_each_entry(session->evlist, evsel) {
+ evsel->core.attr.sample_type &= ~PERF_SAMPLE_AUX;
+ }
+
+ if (inject->itrace_synth_opts.add_last_branch) {
perf_header__set_feat(&session->header,
HEADER_BRANCH_STACK);
+
+ evlist__for_each_entry(session->evlist, evsel) {
+ evsel->core.attr.sample_type |= PERF_SAMPLE_BRANCH_STACK;
+ evsel->core.attr.branch_sample_type |=
+ PERF_SAMPLE_BRANCH_HW_INDEX;
+ }
+ }
}
/*
diff --git a/tools/perf/tests/dlfilter-test.c b/tools/perf/tests/dlfilter-test.c
index e63790c61d53..204663571943 100644
--- a/tools/perf/tests/dlfilter-test.c
+++ b/tools/perf/tests/dlfilter-test.c
@@ -188,8 +188,12 @@ static int write_sample(struct test_data *td, u64 sample_type, u64 id, pid_t pid
event->header.type = PERF_RECORD_SAMPLE;
event->header.misc = PERF_RECORD_MISC_USER;
- event->header.size = perf_event__sample_event_size(&sample, sample_type, 0);
- err = perf_event__synthesize_sample(event, sample_type, 0, &sample);
+ event->header.size = perf_event__sample_event_size(&sample, sample_type,
+ /*read_format=*/0,
+ /*branch_sample_type=*/0);
+ err = perf_event__synthesize_sample(event, sample_type,
+ /*read_format=*/0,
+ /*branch_sample_type=*/0, &sample);
if (err)
return test_result("perf_event__synthesize_sample() failed", TEST_FAIL);
diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-parsing.c
index a7327c942ca2..55f0b73ca20e 100644
--- a/tools/perf/tests/sample-parsing.c
+++ b/tools/perf/tests/sample-parsing.c
@@ -310,7 +310,8 @@ static int do_test(u64 sample_type, u64 sample_regs, u64 read_format)
sample.read.one.lost = 1;
}
- sz = perf_event__sample_event_size(&sample, sample_type, read_format);
+ sz = perf_event__sample_event_size(&sample, sample_type, read_format,
+ evsel.core.attr.branch_sample_type);
bufsz = sz + 4096; /* Add a bit for overrun checking */
event = malloc(bufsz);
if (!event) {
@@ -324,7 +325,7 @@ static int do_test(u64 sample_type, u64 sample_regs, u64 read_format)
event->header.size = sz;
err = perf_event__synthesize_sample(event, sample_type, read_format,
- &sample);
+ evsel.core.attr.branch_sample_type, &sample);
if (err) {
pr_debug("%s failed for sample_type %#"PRIx64", error %d\n",
"perf_event__synthesize_sample", sample_type, err);
diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c
index e5835042acdf..c4ed9f10e731 100644
--- a/tools/perf/util/arm-spe.c
+++ b/tools/perf/util/arm-spe.c
@@ -484,8 +484,11 @@ static void arm_spe__prep_branch_stack(struct arm_spe_queue *speq)
static int arm_spe__inject_event(union perf_event *event, struct perf_sample *sample, u64 type)
{
- event->header.size = perf_event__sample_event_size(sample, type, 0);
- return perf_event__synthesize_sample(event, type, 0, sample);
+ event->header.type = PERF_RECORD_SAMPLE;
+ event->header.size = perf_event__sample_event_size(sample, type, /*read_format=*/0,
+ /*branch_sample_type=*/0);
+ return perf_event__synthesize_sample(event, type, /*read_format=*/0,
+ /*branch_sample_type=*/0, sample);
}
static inline int
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index 8a639d2e51a4..1ebc1a6a5e75 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -1425,8 +1425,10 @@ static void cs_etm__update_last_branch_rb(struct cs_etm_queue *etmq,
static int cs_etm__inject_event(union perf_event *event,
struct perf_sample *sample, u64 type)
{
- event->header.size = perf_event__sample_event_size(sample, type, 0);
- return perf_event__synthesize_sample(event, type, 0, sample);
+ event->header.size = perf_event__sample_event_size(sample, type, /*read_format=*/0,
+ /*branch_sample_type=*/0);
+ return perf_event__synthesize_sample(event, type, /*read_format=*/0,
+ /*branch_sample_type=*/0, sample);
}
diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c
index 382255393fb3..0b18ebd13f7c 100644
--- a/tools/perf/util/intel-bts.c
+++ b/tools/perf/util/intel-bts.c
@@ -303,7 +303,8 @@ static int intel_bts_synth_branch_sample(struct intel_bts_queue *btsq,
event.sample.header.size = bts->branches_event_size;
ret = perf_event__synthesize_sample(&event,
bts->branches_sample_type,
- 0, &sample);
+ /*read_format=*/0, /*branch_sample_type=*/0,
+ &sample);
if (ret)
return ret;
}
diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c
index fc9eec8b54b8..2dce6106c038 100644
--- a/tools/perf/util/intel-pt.c
+++ b/tools/perf/util/intel-pt.c
@@ -1731,8 +1731,12 @@ static void intel_pt_prep_b_sample(struct intel_pt *pt,
static int intel_pt_inject_event(union perf_event *event,
struct perf_sample *sample, u64 type)
{
- event->header.size = perf_event__sample_event_size(sample, type, 0);
- return perf_event__synthesize_sample(event, type, 0, sample);
+ event->header.type = PERF_RECORD_SAMPLE;
+ event->header.size = perf_event__sample_event_size(sample, type, /*read_format=*/0,
+ /*branch_sample_type=*/0);
+
+ return perf_event__synthesize_sample(event, type, /*read_format=*/0,
+ /*branch_sample_type=*/0, sample);
}
static inline int intel_pt_opt_inject(struct intel_pt *pt,
@@ -2486,7 +2490,7 @@ static int intel_pt_do_synth_pebs_sample(struct intel_pt_queue *ptq, struct evse
intel_pt_add_xmm(intr_regs, pos, items, regs_mask);
}
- if (sample_type & PERF_SAMPLE_BRANCH_STACK) {
+ if ((sample_type | evsel->synth_sample_type) & PERF_SAMPLE_BRANCH_STACK) {
if (items->mask[INTEL_PT_LBR_0_POS] ||
items->mask[INTEL_PT_LBR_1_POS] ||
items->mask[INTEL_PT_LBR_2_POS]) {
@@ -2557,7 +2561,8 @@ static int intel_pt_do_synth_pebs_sample(struct intel_pt_queue *ptq, struct evse
sample.transaction = txn;
}
- ret = intel_pt_deliver_synth_event(pt, event, &sample, sample_type);
+ ret = intel_pt_deliver_synth_event(pt, event, &sample,
+ sample_type | evsel->synth_sample_type);
perf_sample__exit(&sample);
return ret;
}
diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c
index 85bee747f4cd..2461f25a4d7d 100644
--- a/tools/perf/util/synthetic-events.c
+++ b/tools/perf/util/synthetic-events.c
@@ -1455,7 +1455,8 @@ int perf_event__synthesize_stat_round(const struct perf_tool *tool,
return process(tool, (union perf_event *) &event, NULL, machine);
}
-size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, u64 read_format)
+size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, u64 read_format,
+ u64 branch_sample_type)
{
size_t sz, result = sizeof(struct perf_record_sample);
@@ -1515,8 +1516,10 @@ size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type,
if (type & PERF_SAMPLE_BRANCH_STACK) {
sz = sample->branch_stack->nr * sizeof(struct branch_entry);
- /* nr, hw_idx */
- sz += 2 * sizeof(u64);
+ /* nr */
+ sz += sizeof(u64);
+ if (branch_sample_type & PERF_SAMPLE_BRANCH_HW_INDEX)
+ sz += sizeof(u64);
result += sz;
}
@@ -1605,7 +1608,7 @@ static __u64 *copy_read_group_values(__u64 *array, __u64 read_format,
}
int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_format,
- const struct perf_sample *sample)
+ u64 branch_sample_type, const struct perf_sample *sample)
{
__u64 *array;
size_t sz;
@@ -1719,9 +1722,17 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_fo
if (type & PERF_SAMPLE_BRANCH_STACK) {
sz = sample->branch_stack->nr * sizeof(struct branch_entry);
- /* nr, hw_idx */
- sz += 2 * sizeof(u64);
- memcpy(array, sample->branch_stack, sz);
+
+ *array++ = sample->branch_stack->nr;
+
+ if (branch_sample_type & PERF_SAMPLE_BRANCH_HW_INDEX) {
+ if (sample->no_hw_idx)
+ *array++ = 0;
+ else
+ *array++ = sample->branch_stack->hw_idx;
+ }
+
+ memcpy(array, perf_sample__branch_entries((struct perf_sample *)sample), sz);
array = (void *)array + sz;
}
diff --git a/tools/perf/util/synthetic-events.h b/tools/perf/util/synthetic-events.h
index b0edad0c3100..8c7f49f9ccf5 100644
--- a/tools/perf/util/synthetic-events.h
+++ b/tools/perf/util/synthetic-events.h
@@ -81,7 +81,8 @@ int perf_event__synthesize_mmap_events(const struct perf_tool *tool, union perf_
int perf_event__synthesize_modules(const struct perf_tool *tool, perf_event__handler_t process, struct machine *machine);
int perf_event__synthesize_namespaces(const struct perf_tool *tool, union perf_event *event, pid_t pid, pid_t tgid, perf_event__handler_t process, struct machine *machine);
int perf_event__synthesize_cgroups(const struct perf_tool *tool, perf_event__handler_t process, struct machine *machine);
-int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_format, const struct perf_sample *sample);
+int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_format,
+ u64 branch_sample_type, const struct perf_sample *sample);
int perf_event__synthesize_stat_config(const struct perf_tool *tool, struct perf_stat_config *config, perf_event__handler_t process, struct machine *machine);
int perf_event__synthesize_stat_events(struct perf_stat_config *config, const struct perf_tool *tool, struct evlist *evlist, perf_event__handler_t process, bool attrs);
int perf_event__synthesize_stat_round(const struct perf_tool *tool, u64 time, u64 type, perf_event__handler_t process, struct machine *machine);
@@ -97,7 +98,8 @@ void perf_event__synthesize_final_bpf_metadata(struct perf_session *session,
int perf_tool__process_synth_event(const struct perf_tool *tool, union perf_event *event, struct machine *machine, perf_event__handler_t process);
-size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, u64 read_format);
+size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type,
+ u64 read_format, u64 branch_sample_type);
int __machine__synthesize_threads(struct machine *machine, const struct perf_tool *tool,
struct target *target, struct perf_thread_map *threads,
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [PATCH v6 00/59] perf: Reorganize scripting support
From: Ian Rogers @ 2026-04-25 17:47 UTC (permalink / raw)
To: acme, adrian.hunter, james.clark, leo.yan, namhyung, tmricht
Cc: alice.mei.rogers, dapeng1.mi, linux-arm-kernel, linux-kernel,
linux-perf-users, mingo, peterz, Ian Rogers
In-Reply-To: <20260424164721.2229025-1-irogers@google.com>
The perf script command has long supported running Python and Perl scripts by
embedding libpython and libperl. This approach has several drawbacks:
- overhead by creating Python dictionaries for every event (whether used or
not),
- complex build dependencies on specific Python/Perl versions,
- complications with threading due to perf being the interpreter,
- no clear way to run standalone scripts like ilist.py.
This series takes a different approach with some initial implementation posted
as an RFC last October:
https://lore.kernel.org/linux-perf-users/20251029053413.355154-1-irogers@google.com/
with the motivation coming up on the mailing list earlier:
https://lore.kernel.org/lkml/CAP-5=fWDqE8SYfOLZkg_0=4Ayx6E7O+h7uUp4NDeCFkiN4b7-w@mail.gmail.com/
The changes remove the embedded libpython and libperl support from perf
entirely. Instead, they expand the existing perf Python module to provide full
access to perf data files and events, allowing scripts to be run as standalone
Python applications.
To demonstrate the benefits, we ported all existing Python and Perl scripts to
use the new Python session API. The performance improvement is dramatic. For
example, porting mem-phys-addr.py:
Before (using embedded libpython in perf script):
```
$ perf mem record a sleep 1
$ time perf script tools/perf/scripts/python/mem-phys-addr.py
Event: cpu_core/mem-loads-aux/
Memory type count percentage
--------------------------------------- ---------- ----------
0-fff : Reserved 3217 100.0
real 0m3.754s
user 0m0.023s
sys 0m0.018s
```
After (using standalone Python script with perf module):
```
$ PYTHONPATH=/tmp/perf/python time python3 tools/perf/python/mem-phys-addr.py
Event: evsel(cpu_core/mem-loads-aux/)
Memory type count percentage
--------------------------------------- ---------- ----------
0-fff : Reserved 3217 100.0
real 0m0.106s
user 0m0.021s
sys 0m0.020s
```
This is a roughly 35x speedup!
The change is large (11423 insertions, 16029 deletions, net 4606
deletions) due to porting all existing perl and python code to the new
API. Gemini was used to achieve this and to improve the code
quality. Removing support may be controversial, however, the first 52
patches are additive and merging those would allow us to focus on the
remaining 7 patches that finalize the new perf script behavior.
---
v6 Changes
----------
- Refactored `pyrf_event__new` to take `evsel` and `session` arguments,
and use dynamic allocation based on the actual event size to improve
memory safety and efficiency.
- Moved callchain and branch stack resolution logic from
`pyrf_session_tool__sample` into `pyrf_event__new`, centralizing
initialization.
- Added an optional keyword-only `elf_machine` argument to `syscall_name`
and `syscall_id` functions to allow specifying non-host architectures,
defaulting to `EM_HOST`.
- Renamed `process` method to `find_thread` in the Python API and C
implementation for better intention-revealing naming.
- Fixed a terminal injection vulnerability in `flamegraph.py` by not
printing unverified downloaded content in the prompt.
- Fixed CWD exposure and symlink attack risks in `gecko.py` by using a
secure temporary directory for the HTTP server.
- Fixed a severe performance issue in `event_analyzing_sample.py` by
removing SQLite autocommit mode and batching commits.
- Fixed `AttributeError` crashes in `rw-by-file.py` and `rw-by-pid.py` by
correctly extracting event names.
- Fixed man page formatting issues in `perf-script-python.txt` by using
indented code blocks.
- Updated `perf.pyi` stubs file to reflect all API changes.
- Verified all commit messages with `checkpatch.pl` and ensured lines are
wrapped appropriately.
- Fixed segmentation faults in `perf sched stats` in diff mode.
v5 Changes
----------
Resending due to partial send of v4 due to a quota limit.
v4 Changes
----------
1. Git Fixup Cleanups
- Squashed the lingering `fixup!` commit remaining from the previous session back
into `perf check-perf-trace: Port check-perf-trace to use python module`.
v3 Changes
----------
1. Memory Safety & Reference Counting Fixes
- Stored transient mmap event data inside the Python object's permanent
`pevent->event` and invoked `evsel__parse_sample()` to safely point
attributes into it, resolving Use-After-Free vulnerabilities.
- Nullified `sample->evsel` after calling `evsel__put()` in
`perf_sample__exit()` to protect against potential refcount double-put
crashes in error paths.
- Reordered operations inside `evlist__remove()` to invoke
`perf_evlist__remove()` before reference release.
- Patched an `evsel` reference leak inside `evlist__deliver_deferred_callchain()`.
2. Sashiko AI Review Cleanups
- Corrected the broken event name equality check in `gecko.py` to search
for a substring match within the parsed event string.
- Fixed a latent `AttributeError` crash in `task-analyzer.py` by properly
assigning the session instance.
- Safeguarded thread reporting in `check-perf-trace.py` by utilizing
`sample_tid` instead of `sample_pid`, and wrapping the session thread
resolution in a try-except block.
3. Omitted Minor Issues
- The minor review comments (such as permanent iterator exhaustion on
`brstack`, or dead-code in `failed-syscalls-by-pid.py`) have been omitted
because they do not affect correctness, lead to crashes, or require
significant architectural rework.
v2 Changes
----------
1. String Match and Event Name Accuracy
- Replaced loose substring event matching across the script suite with exact
matches or specific prefix constraints (syscalls:sys_exit_,
evsel(skb:kfree_skb), etc.).
- Added getattr() safety checks to prevent script failures caused by
unresolved attributes from older kernel traces.
2. OOM and Memory Protections
- Refactored netdev-times.py to compute and process network statistics
chronologically on-the-fly, eliminating an unbounded in-memory list
that caused Out-Of-Memory crashes on large files.
- Implemented threshold limits on intel-pt-events.py to cap memory allocation
during event interleaving.
- Optimized export-to-sqlite.py to periodically commit database transactions
(every 10,000 samples) to reduce temporary SQLite journal sizes.
3. Portability & Environment Independence
- Re-keyed internal tracking dictionaries in scripts like powerpc-hcalls.py to
use thread PIDs instead of CPUs, ensuring correctness when threads migrate.
- Switched net_dropmonitor.py from host-specific /proc/kallsyms parsing to
perf's built-in symbol resolution API.
- Added the --iomem parameter to mem-phys-addr.py to support offline analysis
of data collected on different architectures.
4. Standalone Scripting Improvements
- Patched builtin-script.c to ensure --input parameters are successfully passed
down to standalone execution pipelines via execvp().
- Guarded against string buffer overflows during .py extension path resolving.
5. Code Cleanups
- Removed stale perl subdirectories from being detected by the TUI script
browser.
- Ran the entire script suite through mypy and pylint to achieve strict static
type checking and resolve unreferenced variables.
Ian Rogers (59):
perf inject: Fix itrace branch stack synthesis
perf arch arm: Sort includes and add missed explicit dependencies
perf arch x86: Sort includes and add missed explicit dependencies
perf tests: Sort includes and add missed explicit dependencies
perf script: Sort includes and add missed explicit dependencies
perf util: Sort includes and add missed explicit dependencies
perf python: Add missed explicit dependencies
perf evsel/evlist: Avoid unnecessary #includes
perf data: Add open flag
perf evlist: Add reference count
perf evsel: Add reference count
perf evlist: Add reference count checking
perf python: Use evsel in sample in pyrf_event
perf python: Add wrapper for perf_data file abstraction
perf python: Add python session abstraction wrapping perf's session
perf python: Add syscall name/id to convert syscall number and name
perf python: Refactor and add accessors to sample event
perf python: Add callchain support
perf python: Add config file access
perf python: Extend API for stat events in python.c
perf python: Expose brstack in sample event
perf python: Add perf.pyi stubs file
perf python: Add LiveSession helper
perf python: Move exported-sql-viewer.py and parallel-perf.py to
tools/perf/python/
perf stat-cpi: Port stat-cpi to use python module
perf mem-phys-addr: Port mem-phys-addr to use python module
perf syscall-counts: Port syscall-counts to use python module
perf syscall-counts-by-pid: Port syscall-counts-by-pid to use python
module
perf futex-contention: Port futex-contention to use python module
perf flamegraph: Port flamegraph to use python module
perf gecko: Port gecko to use python module
perf arm-cs-trace-disasm: Port arm-cs-trace-disasm to use python
module
perf check-perf-trace: Port check-perf-trace to use python module
perf compaction-times: Port compaction-times to use python module
perf event_analyzing_sample: Port event_analyzing_sample to use python
module
perf export-to-sqlite: Port export-to-sqlite to use python module
perf export-to-postgresql: Port export-to-postgresql to use python
module
perf failed-syscalls-by-pid: Port failed-syscalls-by-pid to use python
module
perf intel-pt-events: Port intel-pt-events/libxed to use python module
perf net_dropmonitor: Port net_dropmonitor to use python module
perf netdev-times: Port netdev-times to use python module
perf powerpc-hcalls: Port powerpc-hcalls to use python module
perf sched-migration: Port sched-migration/SchedGui to use python
module
perf sctop: Port sctop to use python module
perf stackcollapse: Port stackcollapse to use python module
perf task-analyzer: Port task-analyzer to use python module
perf failed-syscalls: Port failed-syscalls to use python module
perf rw-by-file: Port rw-by-file to use python module
perf rw-by-pid: Port rw-by-pid to use python module
perf rwtop: Port rwtop to use python module
perf wakeup-latency: Port wakeup-latency to use python module
perf test: Migrate Intel PT virtual LBR test to use Python API
perf: Remove libperl support, legacy Perl scripts and tests
perf: Remove libpython support and legacy Python scripts
perf Makefile: Update Python script installation path
perf script: Refactor to support standalone scripts and remove legacy
features
perf Documentation: Update for standalone Python scripts and remove
obsolete data
perf python: Improve perf script -l descriptions
perf sched stats: Fix segmentation faults in diff mode
tools/build/Makefile.feature | 5 +-
tools/build/feature/Makefile | 23 +-
tools/build/feature/test-all.c | 6 +-
tools/build/feature/test-libperl.c | 10 -
tools/build/feature/test-libpython.c | 10 -
tools/build/feature/test-python-module.c | 12 +
tools/perf/Documentation/perf-check.txt | 2 -
tools/perf/Documentation/perf-script-perl.txt | 216 --
.../perf/Documentation/perf-script-python.txt | 713 +-----
tools/perf/Documentation/perf-script.txt | 70 +-
tools/perf/Makefile.config | 37 +-
tools/perf/Makefile.perf | 22 +-
tools/perf/arch/arm/util/cs-etm.c | 36 +-
tools/perf/arch/arm64/util/arm-spe.c | 8 +-
tools/perf/arch/arm64/util/hisi-ptt.c | 2 +-
tools/perf/arch/x86/tests/hybrid.c | 22 +-
tools/perf/arch/x86/tests/topdown.c | 2 +-
tools/perf/arch/x86/util/auxtrace.c | 2 +-
tools/perf/arch/x86/util/intel-bts.c | 26 +-
tools/perf/arch/x86/util/intel-pt.c | 38 +-
tools/perf/arch/x86/util/iostat.c | 8 +-
tools/perf/bench/evlist-open-close.c | 29 +-
tools/perf/bench/inject-buildid.c | 9 +-
tools/perf/builtin-annotate.c | 2 +-
tools/perf/builtin-check.c | 3 +-
tools/perf/builtin-ftrace.c | 14 +-
tools/perf/builtin-inject.c | 81 +-
tools/perf/builtin-kvm.c | 14 +-
tools/perf/builtin-kwork.c | 8 +-
tools/perf/builtin-lock.c | 2 +-
tools/perf/builtin-record.c | 95 +-
tools/perf/builtin-report.c | 6 +-
tools/perf/builtin-sched.c | 111 +-
tools/perf/builtin-script.c | 895 +++----
tools/perf/builtin-stat.c | 81 +-
tools/perf/builtin-top.c | 104 +-
tools/perf/builtin-trace.c | 60 +-
tools/perf/python/SchedGui.py | 219 ++
tools/perf/python/arm-cs-trace-disasm.py | 338 +++
tools/perf/python/check-perf-trace.py | 113 +
tools/perf/python/compaction-times.py | 326 +++
tools/perf/python/counting.py | 1 +
tools/perf/python/event_analyzing_sample.py | 297 +++
tools/perf/python/export-to-postgresql.py | 701 ++++++
tools/perf/python/export-to-sqlite.py | 372 +++
.../python/exported-sql-viewer.py | 6 +-
tools/perf/python/failed-syscalls-by-pid.py | 119 +
tools/perf/python/failed-syscalls.py | 78 +
tools/perf/python/flamegraph.py | 250 ++
tools/perf/python/futex-contention.py | 87 +
tools/perf/python/gecko.py | 385 +++
tools/perf/python/intel-pt-events.py | 435 ++++
tools/perf/python/libxed.py | 122 +
.../{scripts => }/python/mem-phys-addr.py | 66 +-
tools/perf/python/net_dropmonitor.py | 58 +
tools/perf/python/netdev-times.py | 472 ++++
.../{scripts => }/python/parallel-perf.py | 0
tools/perf/python/perf.pyi | 581 +++++
tools/perf/python/perf_live.py | 48 +
tools/perf/python/powerpc-hcalls.py | 211 ++
tools/perf/python/rw-by-file.py | 103 +
tools/perf/python/rw-by-pid.py | 158 ++
tools/perf/python/rwtop.py | 219 ++
tools/perf/python/sched-migration.py | 469 ++++
tools/perf/python/sctop.py | 186 ++
tools/perf/python/stackcollapse.py | 126 +
tools/perf/python/stat-cpi.py | 151 ++
tools/perf/python/syscall-counts-by-pid.py | 88 +
tools/perf/python/syscall-counts.py | 72 +
tools/perf/python/task-analyzer.py | 547 ++++
tools/perf/python/tracepoint.py | 1 +
tools/perf/python/twatch.py | 1 +
tools/perf/python/wakeup-latency.py | 88 +
tools/perf/scripts/Build | 4 -
tools/perf/scripts/perl/Perf-Trace-Util/Build | 9 -
.../scripts/perl/Perf-Trace-Util/Context.c | 122 -
.../scripts/perl/Perf-Trace-Util/Context.xs | 42 -
.../scripts/perl/Perf-Trace-Util/Makefile.PL | 18 -
.../perf/scripts/perl/Perf-Trace-Util/README | 59 -
.../Perf-Trace-Util/lib/Perf/Trace/Context.pm | 55 -
.../Perf-Trace-Util/lib/Perf/Trace/Core.pm | 192 --
.../Perf-Trace-Util/lib/Perf/Trace/Util.pm | 94 -
.../perf/scripts/perl/Perf-Trace-Util/typemap | 1 -
.../scripts/perl/bin/check-perf-trace-record | 2 -
.../scripts/perl/bin/failed-syscalls-record | 3 -
.../scripts/perl/bin/failed-syscalls-report | 10 -
tools/perf/scripts/perl/bin/rw-by-file-record | 3 -
tools/perf/scripts/perl/bin/rw-by-file-report | 10 -
tools/perf/scripts/perl/bin/rw-by-pid-record | 2 -
tools/perf/scripts/perl/bin/rw-by-pid-report | 3 -
tools/perf/scripts/perl/bin/rwtop-record | 2 -
tools/perf/scripts/perl/bin/rwtop-report | 20 -
.../scripts/perl/bin/wakeup-latency-record | 6 -
.../scripts/perl/bin/wakeup-latency-report | 3 -
tools/perf/scripts/perl/check-perf-trace.pl | 106 -
tools/perf/scripts/perl/failed-syscalls.pl | 47 -
tools/perf/scripts/perl/rw-by-file.pl | 106 -
tools/perf/scripts/perl/rw-by-pid.pl | 184 --
tools/perf/scripts/perl/rwtop.pl | 203 --
tools/perf/scripts/perl/wakeup-latency.pl | 107 -
.../perf/scripts/python/Perf-Trace-Util/Build | 4 -
.../scripts/python/Perf-Trace-Util/Context.c | 225 --
.../Perf-Trace-Util/lib/Perf/Trace/Core.py | 116 -
.../lib/Perf/Trace/EventClass.py | 97 -
.../lib/Perf/Trace/SchedGui.py | 184 --
.../Perf-Trace-Util/lib/Perf/Trace/Util.py | 92 -
.../scripts/python/arm-cs-trace-disasm.py | 355 ---
.../python/bin/compaction-times-record | 2 -
.../python/bin/compaction-times-report | 4 -
.../python/bin/event_analyzing_sample-record | 8 -
.../python/bin/event_analyzing_sample-report | 3 -
.../python/bin/export-to-postgresql-record | 8 -
.../python/bin/export-to-postgresql-report | 29 -
.../python/bin/export-to-sqlite-record | 8 -
.../python/bin/export-to-sqlite-report | 29 -
.../python/bin/failed-syscalls-by-pid-record | 3 -
.../python/bin/failed-syscalls-by-pid-report | 10 -
.../perf/scripts/python/bin/flamegraph-record | 2 -
.../perf/scripts/python/bin/flamegraph-report | 3 -
.../python/bin/futex-contention-record | 2 -
.../python/bin/futex-contention-report | 4 -
tools/perf/scripts/python/bin/gecko-record | 2 -
tools/perf/scripts/python/bin/gecko-report | 7 -
.../scripts/python/bin/intel-pt-events-record | 13 -
.../scripts/python/bin/intel-pt-events-report | 3 -
.../scripts/python/bin/mem-phys-addr-record | 19 -
.../scripts/python/bin/mem-phys-addr-report | 3 -
.../scripts/python/bin/net_dropmonitor-record | 2 -
.../scripts/python/bin/net_dropmonitor-report | 4 -
.../scripts/python/bin/netdev-times-record | 8 -
.../scripts/python/bin/netdev-times-report | 5 -
.../scripts/python/bin/powerpc-hcalls-record | 2 -
.../scripts/python/bin/powerpc-hcalls-report | 2 -
.../scripts/python/bin/sched-migration-record | 2 -
.../scripts/python/bin/sched-migration-report | 3 -
tools/perf/scripts/python/bin/sctop-record | 3 -
tools/perf/scripts/python/bin/sctop-report | 24 -
.../scripts/python/bin/stackcollapse-record | 8 -
.../scripts/python/bin/stackcollapse-report | 3 -
.../python/bin/syscall-counts-by-pid-record | 3 -
.../python/bin/syscall-counts-by-pid-report | 10 -
.../scripts/python/bin/syscall-counts-record | 3 -
.../scripts/python/bin/syscall-counts-report | 10 -
.../scripts/python/bin/task-analyzer-record | 2 -
.../scripts/python/bin/task-analyzer-report | 3 -
tools/perf/scripts/python/check-perf-trace.py | 84 -
tools/perf/scripts/python/compaction-times.py | 311 ---
.../scripts/python/event_analyzing_sample.py | 192 --
.../scripts/python/export-to-postgresql.py | 1114 ---------
tools/perf/scripts/python/export-to-sqlite.py | 799 ------
.../scripts/python/failed-syscalls-by-pid.py | 79 -
tools/perf/scripts/python/flamegraph.py | 267 --
tools/perf/scripts/python/futex-contention.py | 57 -
tools/perf/scripts/python/gecko.py | 395 ---
tools/perf/scripts/python/intel-pt-events.py | 494 ----
tools/perf/scripts/python/libxed.py | 107 -
tools/perf/scripts/python/net_dropmonitor.py | 78 -
tools/perf/scripts/python/netdev-times.py | 473 ----
tools/perf/scripts/python/powerpc-hcalls.py | 202 --
tools/perf/scripts/python/sched-migration.py | 462 ----
tools/perf/scripts/python/sctop.py | 89 -
tools/perf/scripts/python/stackcollapse.py | 127 -
tools/perf/scripts/python/stat-cpi.py | 79 -
.../scripts/python/syscall-counts-by-pid.py | 75 -
tools/perf/scripts/python/syscall-counts.py | 65 -
tools/perf/scripts/python/task-analyzer.py | 934 -------
tools/perf/tests/backward-ring-buffer.c | 26 +-
tools/perf/tests/code-reading.c | 14 +-
tools/perf/tests/dlfilter-test.c | 8 +-
tools/perf/tests/event-times.c | 6 +-
tools/perf/tests/event_update.c | 4 +-
tools/perf/tests/evsel-roundtrip-name.c | 8 +-
tools/perf/tests/evsel-tp-sched.c | 4 +-
tools/perf/tests/expand-cgroup.c | 12 +-
tools/perf/tests/hists_cumulate.c | 2 +-
tools/perf/tests/hists_filter.c | 2 +-
tools/perf/tests/hists_link.c | 2 +-
tools/perf/tests/hists_output.c | 2 +-
tools/perf/tests/hwmon_pmu.c | 21 +-
tools/perf/tests/keep-tracking.c | 10 +-
tools/perf/tests/make | 9 +-
tools/perf/tests/mmap-basic.c | 42 +-
tools/perf/tests/openat-syscall-all-cpus.c | 6 +-
tools/perf/tests/openat-syscall-tp-fields.c | 26 +-
tools/perf/tests/openat-syscall.c | 6 +-
tools/perf/tests/parse-events.c | 139 +-
tools/perf/tests/parse-metric.c | 8 +-
tools/perf/tests/parse-no-sample-id-all.c | 2 +-
tools/perf/tests/perf-record.c | 38 +-
tools/perf/tests/perf-time-to-tsc.c | 12 +-
tools/perf/tests/pfm.c | 12 +-
tools/perf/tests/pmu-events.c | 11 +-
tools/perf/tests/pmu.c | 4 +-
tools/perf/tests/sample-parsing.c | 39 +-
.../perf/tests/shell/lib/perf_brstack_max.py | 43 +
tools/perf/tests/shell/script.sh | 4 +-
tools/perf/tests/shell/script_perl.sh | 102 -
tools/perf/tests/shell/script_python.sh | 113 -
.../tests/shell/test_arm_coresight_disasm.sh | 12 +-
tools/perf/tests/shell/test_intel_pt.sh | 35 +-
tools/perf/tests/shell/test_task_analyzer.sh | 79 +-
tools/perf/tests/sw-clock.c | 20 +-
tools/perf/tests/switch-tracking.c | 10 +-
tools/perf/tests/task-exit.c | 20 +-
tools/perf/tests/time-utils-test.c | 14 +-
tools/perf/tests/tool_pmu.c | 7 +-
tools/perf/tests/topology.c | 4 +-
tools/perf/ui/browsers/annotate.c | 2 +-
tools/perf/ui/browsers/hists.c | 22 +-
tools/perf/ui/browsers/scripts.c | 21 +-
tools/perf/util/Build | 1 -
tools/perf/util/amd-sample-raw.c | 2 +-
tools/perf/util/annotate-data.c | 2 +-
tools/perf/util/annotate.c | 10 +-
tools/perf/util/arm-spe.c | 7 +-
tools/perf/util/auxtrace.c | 14 +-
tools/perf/util/block-info.c | 4 +-
tools/perf/util/bpf_counter.c | 2 +-
tools/perf/util/bpf_counter_cgroup.c | 10 +-
tools/perf/util/bpf_ftrace.c | 9 +-
tools/perf/util/bpf_lock_contention.c | 12 +-
tools/perf/util/bpf_off_cpu.c | 44 +-
tools/perf/util/bpf_trace_augment.c | 8 +-
tools/perf/util/cgroup.c | 26 +-
tools/perf/util/cs-etm.c | 6 +-
tools/perf/util/data-convert-bt.c | 2 +-
tools/perf/util/data.c | 26 +-
tools/perf/util/data.h | 4 +-
tools/perf/util/evlist.c | 487 ++--
tools/perf/util/evlist.h | 273 +-
tools/perf/util/evsel.c | 109 +-
tools/perf/util/evsel.h | 35 +-
tools/perf/util/expr.c | 2 +-
tools/perf/util/header.c | 51 +-
tools/perf/util/header.h | 2 +-
tools/perf/util/intel-bts.c | 3 +-
tools/perf/util/intel-pt.c | 13 +-
tools/perf/util/intel-tpebs.c | 7 +-
tools/perf/util/map.h | 9 +-
tools/perf/util/metricgroup.c | 12 +-
tools/perf/util/parse-events.c | 10 +-
tools/perf/util/parse-events.y | 2 +-
tools/perf/util/perf_api_probe.c | 20 +-
tools/perf/util/pfm.c | 4 +-
tools/perf/util/print-events.c | 2 +-
tools/perf/util/print_insn.h | 5 +-
tools/perf/util/python.c | 1923 ++++++++++++--
tools/perf/util/record.c | 11 +-
tools/perf/util/s390-sample-raw.c | 19 +-
tools/perf/util/sample-raw.c | 4 +-
tools/perf/util/sample.c | 17 +-
tools/perf/util/scripting-engines/Build | 9 -
.../util/scripting-engines/trace-event-perl.c | 773 ------
.../scripting-engines/trace-event-python.c | 2209 -----------------
tools/perf/util/session.c | 59 +-
tools/perf/util/sideband_evlist.c | 40 +-
tools/perf/util/sort.c | 2 +-
tools/perf/util/stat-display.c | 6 +-
tools/perf/util/stat-shadow.c | 24 +-
tools/perf/util/stat.c | 20 +-
tools/perf/util/stream.c | 4 +-
tools/perf/util/synthetic-events.c | 36 +-
tools/perf/util/synthetic-events.h | 6 +-
tools/perf/util/time-utils.c | 12 +-
tools/perf/util/top.c | 4 +-
tools/perf/util/trace-event-parse.c | 65 -
tools/perf/util/trace-event-scripting.c | 410 ---
tools/perf/util/trace-event.h | 75 +-
268 files changed, 11423 insertions(+), 16029 deletions(-)
delete mode 100644 tools/build/feature/test-libperl.c
delete mode 100644 tools/build/feature/test-libpython.c
create mode 100644 tools/build/feature/test-python-module.c
delete mode 100644 tools/perf/Documentation/perf-script-perl.txt
create mode 100755 tools/perf/python/SchedGui.py
create mode 100755 tools/perf/python/arm-cs-trace-disasm.py
create mode 100755 tools/perf/python/check-perf-trace.py
create mode 100755 tools/perf/python/compaction-times.py
create mode 100755 tools/perf/python/event_analyzing_sample.py
create mode 100755 tools/perf/python/export-to-postgresql.py
create mode 100755 tools/perf/python/export-to-sqlite.py
rename tools/perf/{scripts => }/python/exported-sql-viewer.py (99%)
create mode 100755 tools/perf/python/failed-syscalls-by-pid.py
create mode 100755 tools/perf/python/failed-syscalls.py
create mode 100755 tools/perf/python/flamegraph.py
create mode 100755 tools/perf/python/futex-contention.py
create mode 100755 tools/perf/python/gecko.py
create mode 100755 tools/perf/python/intel-pt-events.py
create mode 100755 tools/perf/python/libxed.py
rename tools/perf/{scripts => }/python/mem-phys-addr.py (73%)
mode change 100644 => 100755
create mode 100755 tools/perf/python/net_dropmonitor.py
create mode 100755 tools/perf/python/netdev-times.py
rename tools/perf/{scripts => }/python/parallel-perf.py (100%)
create mode 100644 tools/perf/python/perf.pyi
create mode 100755 tools/perf/python/perf_live.py
create mode 100755 tools/perf/python/powerpc-hcalls.py
create mode 100755 tools/perf/python/rw-by-file.py
create mode 100755 tools/perf/python/rw-by-pid.py
create mode 100755 tools/perf/python/rwtop.py
create mode 100755 tools/perf/python/sched-migration.py
create mode 100755 tools/perf/python/sctop.py
create mode 100755 tools/perf/python/stackcollapse.py
create mode 100755 tools/perf/python/stat-cpi.py
create mode 100755 tools/perf/python/syscall-counts-by-pid.py
create mode 100755 tools/perf/python/syscall-counts.py
create mode 100755 tools/perf/python/task-analyzer.py
create mode 100755 tools/perf/python/wakeup-latency.py
delete mode 100644 tools/perf/scripts/perl/Perf-Trace-Util/Build
delete mode 100644 tools/perf/scripts/perl/Perf-Trace-Util/Context.c
delete mode 100644 tools/perf/scripts/perl/Perf-Trace-Util/Context.xs
delete mode 100644 tools/perf/scripts/perl/Perf-Trace-Util/Makefile.PL
delete mode 100644 tools/perf/scripts/perl/Perf-Trace-Util/README
delete mode 100644 tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Context.pm
delete mode 100644 tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Core.pm
delete mode 100644 tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Util.pm
delete mode 100644 tools/perf/scripts/perl/Perf-Trace-Util/typemap
delete mode 100644 tools/perf/scripts/perl/bin/check-perf-trace-record
delete mode 100644 tools/perf/scripts/perl/bin/failed-syscalls-record
delete mode 100644 tools/perf/scripts/perl/bin/failed-syscalls-report
delete mode 100644 tools/perf/scripts/perl/bin/rw-by-file-record
delete mode 100644 tools/perf/scripts/perl/bin/rw-by-file-report
delete mode 100644 tools/perf/scripts/perl/bin/rw-by-pid-record
delete mode 100644 tools/perf/scripts/perl/bin/rw-by-pid-report
delete mode 100644 tools/perf/scripts/perl/bin/rwtop-record
delete mode 100644 tools/perf/scripts/perl/bin/rwtop-report
delete mode 100644 tools/perf/scripts/perl/bin/wakeup-latency-record
delete mode 100644 tools/perf/scripts/perl/bin/wakeup-latency-report
delete mode 100644 tools/perf/scripts/perl/check-perf-trace.pl
delete mode 100644 tools/perf/scripts/perl/failed-syscalls.pl
delete mode 100644 tools/perf/scripts/perl/rw-by-file.pl
delete mode 100644 tools/perf/scripts/perl/rw-by-pid.pl
delete mode 100644 tools/perf/scripts/perl/rwtop.pl
delete mode 100644 tools/perf/scripts/perl/wakeup-latency.pl
delete mode 100644 tools/perf/scripts/python/Perf-Trace-Util/Build
delete mode 100644 tools/perf/scripts/python/Perf-Trace-Util/Context.c
delete mode 100644 tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Core.py
delete mode 100755 tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/EventClass.py
delete mode 100644 tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/SchedGui.py
delete mode 100644 tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py
delete mode 100755 tools/perf/scripts/python/arm-cs-trace-disasm.py
delete mode 100644 tools/perf/scripts/python/bin/compaction-times-record
delete mode 100644 tools/perf/scripts/python/bin/compaction-times-report
delete mode 100644 tools/perf/scripts/python/bin/event_analyzing_sample-record
delete mode 100644 tools/perf/scripts/python/bin/event_analyzing_sample-report
delete mode 100644 tools/perf/scripts/python/bin/export-to-postgresql-record
delete mode 100644 tools/perf/scripts/python/bin/export-to-postgresql-report
delete mode 100644 tools/perf/scripts/python/bin/export-to-sqlite-record
delete mode 100644 tools/perf/scripts/python/bin/export-to-sqlite-report
delete mode 100644 tools/perf/scripts/python/bin/failed-syscalls-by-pid-record
delete mode 100644 tools/perf/scripts/python/bin/failed-syscalls-by-pid-report
delete mode 100755 tools/perf/scripts/python/bin/flamegraph-record
delete mode 100755 tools/perf/scripts/python/bin/flamegraph-report
delete mode 100644 tools/perf/scripts/python/bin/futex-contention-record
delete mode 100644 tools/perf/scripts/python/bin/futex-contention-report
delete mode 100644 tools/perf/scripts/python/bin/gecko-record
delete mode 100755 tools/perf/scripts/python/bin/gecko-report
delete mode 100644 tools/perf/scripts/python/bin/intel-pt-events-record
delete mode 100644 tools/perf/scripts/python/bin/intel-pt-events-report
delete mode 100644 tools/perf/scripts/python/bin/mem-phys-addr-record
delete mode 100644 tools/perf/scripts/python/bin/mem-phys-addr-report
delete mode 100755 tools/perf/scripts/python/bin/net_dropmonitor-record
delete mode 100755 tools/perf/scripts/python/bin/net_dropmonitor-report
delete mode 100644 tools/perf/scripts/python/bin/netdev-times-record
delete mode 100644 tools/perf/scripts/python/bin/netdev-times-report
delete mode 100644 tools/perf/scripts/python/bin/powerpc-hcalls-record
delete mode 100644 tools/perf/scripts/python/bin/powerpc-hcalls-report
delete mode 100644 tools/perf/scripts/python/bin/sched-migration-record
delete mode 100644 tools/perf/scripts/python/bin/sched-migration-report
delete mode 100644 tools/perf/scripts/python/bin/sctop-record
delete mode 100644 tools/perf/scripts/python/bin/sctop-report
delete mode 100755 tools/perf/scripts/python/bin/stackcollapse-record
delete mode 100755 tools/perf/scripts/python/bin/stackcollapse-report
delete mode 100644 tools/perf/scripts/python/bin/syscall-counts-by-pid-record
delete mode 100644 tools/perf/scripts/python/bin/syscall-counts-by-pid-report
delete mode 100644 tools/perf/scripts/python/bin/syscall-counts-record
delete mode 100644 tools/perf/scripts/python/bin/syscall-counts-report
delete mode 100755 tools/perf/scripts/python/bin/task-analyzer-record
delete mode 100755 tools/perf/scripts/python/bin/task-analyzer-report
delete mode 100644 tools/perf/scripts/python/check-perf-trace.py
delete mode 100644 tools/perf/scripts/python/compaction-times.py
delete mode 100644 tools/perf/scripts/python/event_analyzing_sample.py
delete mode 100644 tools/perf/scripts/python/export-to-postgresql.py
delete mode 100644 tools/perf/scripts/python/export-to-sqlite.py
delete mode 100644 tools/perf/scripts/python/failed-syscalls-by-pid.py
delete mode 100755 tools/perf/scripts/python/flamegraph.py
delete mode 100644 tools/perf/scripts/python/futex-contention.py
delete mode 100644 tools/perf/scripts/python/gecko.py
delete mode 100644 tools/perf/scripts/python/intel-pt-events.py
delete mode 100644 tools/perf/scripts/python/libxed.py
delete mode 100755 tools/perf/scripts/python/net_dropmonitor.py
delete mode 100644 tools/perf/scripts/python/netdev-times.py
delete mode 100644 tools/perf/scripts/python/powerpc-hcalls.py
delete mode 100644 tools/perf/scripts/python/sched-migration.py
delete mode 100644 tools/perf/scripts/python/sctop.py
delete mode 100755 tools/perf/scripts/python/stackcollapse.py
delete mode 100644 tools/perf/scripts/python/stat-cpi.py
delete mode 100644 tools/perf/scripts/python/syscall-counts-by-pid.py
delete mode 100644 tools/perf/scripts/python/syscall-counts.py
delete mode 100755 tools/perf/scripts/python/task-analyzer.py
create mode 100644 tools/perf/tests/shell/lib/perf_brstack_max.py
delete mode 100755 tools/perf/tests/shell/script_perl.sh
delete mode 100755 tools/perf/tests/shell/script_python.sh
delete mode 100644 tools/perf/util/scripting-engines/Build
delete mode 100644 tools/perf/util/scripting-engines/trace-event-perl.c
delete mode 100644 tools/perf/util/scripting-engines/trace-event-python.c
delete mode 100644 tools/perf/util/trace-event-scripting.c
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply
* [PATCH v6 04/59] perf tests: Sort includes and add missed explicit dependencies
From: Ian Rogers @ 2026-04-25 17:48 UTC (permalink / raw)
To: acme, adrian.hunter, james.clark, leo.yan, namhyung, tmricht
Cc: alice.mei.rogers, dapeng1.mi, linux-arm-kernel, linux-kernel,
linux-perf-users, mingo, peterz, Ian Rogers
In-Reply-To: <20260425174858.3922152-1-irogers@google.com>
Fix missing #includes found while cleaning the evsel/evlist header
files. Sort the remaining header files for consistency with the rest
of the code.
Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/perf/tests/hwmon_pmu.c | 14 +++++++++-----
tools/perf/tests/mmap-basic.c | 18 +++++++++++-------
2 files changed, 20 insertions(+), 12 deletions(-)
diff --git a/tools/perf/tests/hwmon_pmu.c b/tools/perf/tests/hwmon_pmu.c
index 4aa4aac94f09..ada6e445c4c4 100644
--- a/tools/perf/tests/hwmon_pmu.c
+++ b/tools/perf/tests/hwmon_pmu.c
@@ -1,15 +1,19 @@
// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
-#include "debug.h"
-#include "evlist.h"
#include "hwmon_pmu.h"
-#include "parse-events.h"
-#include "tests.h"
+
#include <errno.h>
+
#include <fcntl.h>
-#include <sys/stat.h>
#include <linux/compiler.h>
#include <linux/kernel.h>
#include <linux/string.h>
+#include <sys/stat.h>
+
+#include "debug.h"
+#include "evlist.h"
+#include "parse-events.h"
+#include "pmus.h"
+#include "tests.h"
static const struct test_event {
const char *name;
diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c
index 3313c236104e..8d04f6edb004 100644
--- a/tools/perf/tests/mmap-basic.c
+++ b/tools/perf/tests/mmap-basic.c
@@ -1,25 +1,29 @@
// SPDX-License-Identifier: GPL-2.0
#include <errno.h>
-#include <fcntl.h>
#include <inttypes.h>
#include <stdlib.h>
+
+#include <fcntl.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+
#include <perf/cpumap.h>
+#include <perf/evlist.h>
+#include <perf/mmap.h>
#include "cpumap.h"
#include "debug.h"
#include "event.h"
#include "evlist.h"
#include "evsel.h"
-#include "thread_map.h"
+#include "pmu.h"
+#include "pmus.h"
#include "tests.h"
+#include "thread_map.h"
#include "util/affinity.h"
#include "util/mmap.h"
#include "util/sample.h"
-#include <linux/err.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <perf/evlist.h>
-#include <perf/mmap.h>
/*
* This test will generate random numbers of calls to some getpid syscalls,
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [PATCH v6 02/59] perf arch arm: Sort includes and add missed explicit dependencies
From: Ian Rogers @ 2026-04-25 17:48 UTC (permalink / raw)
To: acme, adrian.hunter, james.clark, leo.yan, namhyung, tmricht
Cc: alice.mei.rogers, dapeng1.mi, linux-arm-kernel, linux-kernel,
linux-perf-users, mingo, peterz, Ian Rogers
In-Reply-To: <20260425174858.3922152-1-irogers@google.com>
Fix missing #includes found while cleaning the evsel/evlist header
files. Sort the remaining header files for consistency with the rest
of the code.
Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/perf/arch/arm/util/cs-etm.c | 26 ++++++++++++++------------
1 file changed, 14 insertions(+), 12 deletions(-)
diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
index b7a839de8707..cdf8e3e60606 100644
--- a/tools/perf/arch/arm/util/cs-etm.c
+++ b/tools/perf/arch/arm/util/cs-etm.c
@@ -3,10 +3,13 @@
* Copyright(C) 2015 Linaro Limited. All rights reserved.
* Author: Mathieu Poirier <mathieu.poirier@linaro.org>
*/
+#include "../../../util/cs-etm.h"
+
+#include <errno.h>
+#include <stdlib.h>
-#include <api/fs/fs.h>
-#include <linux/bits.h>
#include <linux/bitops.h>
+#include <linux/bits.h>
#include <linux/compiler.h>
#include <linux/coresight-pmu.h>
#include <linux/kernel.h>
@@ -14,25 +17,24 @@
#include <linux/string.h>
#include <linux/types.h>
#include <linux/zalloc.h>
+#include <sys/stat.h>
+
+#include <api/fs/fs.h>
+#include <internal/lib.h> // page_size
-#include "cs-etm.h"
-#include "../../../util/debug.h"
-#include "../../../util/record.h"
#include "../../../util/auxtrace.h"
#include "../../../util/cpumap.h"
+#include "../../../util/debug.h"
#include "../../../util/event.h"
#include "../../../util/evlist.h"
#include "../../../util/evsel.h"
-#include "../../../util/perf_api_probe.h"
#include "../../../util/evsel_config.h"
+#include "../../../util/perf_api_probe.h"
+#include "../../../util/pmu.h"
#include "../../../util/pmus.h"
-#include "../../../util/cs-etm.h"
-#include <internal/lib.h> // page_size
+#include "../../../util/record.h"
#include "../../../util/session.h"
-
-#include <errno.h>
-#include <stdlib.h>
-#include <sys/stat.h>
+#include "cs-etm.h"
struct cs_etm_recording {
struct auxtrace_record itr;
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [PATCH v6 03/59] perf arch x86: Sort includes and add missed explicit dependencies
From: Ian Rogers @ 2026-04-25 17:48 UTC (permalink / raw)
To: acme, adrian.hunter, james.clark, leo.yan, namhyung, tmricht
Cc: alice.mei.rogers, dapeng1.mi, linux-arm-kernel, linux-kernel,
linux-perf-users, mingo, peterz, Ian Rogers
In-Reply-To: <20260425174858.3922152-1-irogers@google.com>
Fix missing #includes found while cleaning the evsel/evlist header
files. Sort the remaining header files for consistency with the rest
of the code.
Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/perf/arch/x86/util/intel-bts.c | 20 +++++++++++--------
tools/perf/arch/x86/util/intel-pt.c | 29 +++++++++++++++-------------
2 files changed, 28 insertions(+), 21 deletions(-)
diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c
index 85c8186300c8..100a23d27998 100644
--- a/tools/perf/arch/x86/util/intel-bts.c
+++ b/tools/perf/arch/x86/util/intel-bts.c
@@ -4,26 +4,30 @@
* Copyright (c) 2013-2015, Intel Corporation.
*/
+#include "../../../util/intel-bts.h"
+
#include <errno.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
+
#include <linux/bitops.h>
+#include <linux/kernel.h>
#include <linux/log2.h>
+#include <linux/types.h>
#include <linux/zalloc.h>
+#include <internal/lib.h> // page_size
+
+#include "../../../util/auxtrace.h"
#include "../../../util/cpumap.h"
+#include "../../../util/debug.h"
#include "../../../util/event.h"
-#include "../../../util/evsel.h"
#include "../../../util/evlist.h"
+#include "../../../util/evsel.h"
#include "../../../util/mmap.h"
-#include "../../../util/session.h"
+#include "../../../util/pmu.h"
#include "../../../util/pmus.h"
-#include "../../../util/debug.h"
#include "../../../util/record.h"
+#include "../../../util/session.h"
#include "../../../util/tsc.h"
-#include "../../../util/auxtrace.h"
-#include "../../../util/intel-bts.h"
-#include <internal/lib.h> // page_size
#define KiB(x) ((x) * 1024)
#define MiB(x) ((x) * 1024 * 1024)
diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c
index c131a727774f..0307ff15d9fc 100644
--- a/tools/perf/arch/x86/util/intel-pt.c
+++ b/tools/perf/arch/x86/util/intel-pt.c
@@ -3,36 +3,39 @@
* intel_pt.c: Intel Processor Trace support
* Copyright (c) 2013-2015, Intel Corporation.
*/
+#include "../../../util/intel-pt.h"
#include <errno.h>
#include <stdbool.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
+
#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
#include <linux/log2.h>
+#include <linux/types.h>
#include <linux/zalloc.h>
-#include <linux/err.h>
-#include "../../../util/session.h"
+#include <api/fs/fs.h>
+#include <internal/lib.h> // page_size
+#include <subcmd/parse-options.h>
+
+#include "../../../util/auxtrace.h"
+#include "../../../util/config.h"
+#include "../../../util/cpumap.h"
+#include "../../../util/debug.h"
#include "../../../util/event.h"
#include "../../../util/evlist.h"
#include "../../../util/evsel.h"
#include "../../../util/evsel_config.h"
-#include "../../../util/config.h"
-#include "../../../util/cpumap.h"
#include "../../../util/mmap.h"
-#include <subcmd/parse-options.h>
#include "../../../util/parse-events.h"
-#include "../../../util/pmus.h"
-#include "../../../util/debug.h"
-#include "../../../util/auxtrace.h"
#include "../../../util/perf_api_probe.h"
+#include "../../../util/pmu.h"
+#include "../../../util/pmus.h"
#include "../../../util/record.h"
+#include "../../../util/session.h"
#include "../../../util/target.h"
#include "../../../util/tsc.h"
-#include <internal/lib.h> // page_size
-#include "../../../util/intel-pt.h"
-#include <api/fs/fs.h>
#include "cpuid.h"
#define KiB(x) ((x) * 1024)
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [PATCH v6 05/59] perf script: Sort includes and add missed explicit dependencies
From: Ian Rogers @ 2026-04-25 17:48 UTC (permalink / raw)
To: acme, adrian.hunter, james.clark, leo.yan, namhyung, tmricht
Cc: alice.mei.rogers, dapeng1.mi, linux-arm-kernel, linux-kernel,
linux-perf-users, mingo, peterz, Ian Rogers
In-Reply-To: <20260425174858.3922152-1-irogers@google.com>
Fix missing #include of pmu.h found while cleaning the evsel/evlist
header files. Sort the remaining header files for consistency with the
rest of the code. Doing this exposed a missing forward declaration of
addr_location in print_insn.h, add this and sort the forward
declarations.
Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/perf/builtin-script.c | 111 ++++++++++++++++++-----------------
tools/perf/util/print_insn.h | 5 +-
2 files changed, 60 insertions(+), 56 deletions(-)
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index c8ac9f01a36b..853b141a0d50 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -1,74 +1,77 @@
// SPDX-License-Identifier: GPL-2.0
-#include "builtin.h"
+#include <errno.h>
+#include <inttypes.h>
+#include <signal.h>
+#include <stdio.h>
+
+#include <dirent.h>
+#include <fcntl.h>
+#include <linux/bitmap.h>
+#include <linux/compiler.h>
+#include <linux/ctype.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/stringify.h>
+#include <linux/time64.h>
+#include <linux/unaligned.h>
+#include <linux/zalloc.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
+#include <unistd.h>
+#include <perf/evlist.h>
+#include <subcmd/exec-cmd.h>
+#include <subcmd/pager.h>
+#include <subcmd/parse-options.h>
+
+#include "asm/bug.h"
+#include "builtin.h"
+#include "perf.h"
+#include "print_binary.h"
+#include "print_insn.h"
+#include "ui/ui.h"
+#include "util/annotate.h"
+#include "util/auxtrace.h"
+#include "util/cgroup.h"
+#include "util/color.h"
#include "util/counts.h"
+#include "util/cpumap.h"
+#include "util/data.h"
#include "util/debug.h"
+#include "util/dlfilter.h"
#include "util/dso.h"
-#include <subcmd/exec-cmd.h>
-#include "util/header.h"
-#include <subcmd/parse-options.h>
-#include "util/perf_regs.h"
-#include "util/session.h"
-#include "util/tool.h"
-#include "util/map.h"
-#include "util/srcline.h"
-#include "util/symbol.h"
-#include "util/thread.h"
-#include "util/trace-event.h"
+#include "util/dump-insn.h"
#include "util/env.h"
+#include "util/event.h"
#include "util/evlist.h"
#include "util/evsel.h"
#include "util/evsel_fprintf.h"
#include "util/evswitch.h"
+#include "util/header.h"
+#include "util/map.h"
+#include "util/mem-events.h"
+#include "util/mem-info.h"
+#include "util/metricgroup.h"
+#include "util/path.h"
+#include "util/perf_regs.h"
+#include "util/pmu.h"
+#include "util/record.h"
+#include "util/session.h"
#include "util/sort.h"
-#include "util/data.h"
-#include "util/auxtrace.h"
-#include "util/cpumap.h"
-#include "util/thread_map.h"
+#include "util/srcline.h"
#include "util/stat.h"
-#include "util/color.h"
#include "util/string2.h"
+#include "util/symbol.h"
#include "util/thread-stack.h"
+#include "util/thread.h"
+#include "util/thread_map.h"
#include "util/time-utils.h"
-#include "util/path.h"
-#include "util/event.h"
-#include "util/mem-info.h"
-#include "util/metricgroup.h"
-#include "ui/ui.h"
-#include "print_binary.h"
-#include "print_insn.h"
-#include <linux/bitmap.h>
-#include <linux/compiler.h>
-#include <linux/kernel.h>
-#include <linux/stringify.h>
-#include <linux/time64.h>
-#include <linux/zalloc.h>
-#include <linux/unaligned.h>
-#include <sys/utsname.h>
-#include "asm/bug.h"
-#include "util/mem-events.h"
-#include "util/dump-insn.h"
-#include <dirent.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <signal.h>
-#include <stdio.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <subcmd/pager.h>
-#include <perf/evlist.h>
-#include <linux/err.h>
-#include "util/dlfilter.h"
-#include "util/record.h"
+#include "util/tool.h"
+#include "util/trace-event.h"
#include "util/util.h"
-#include "util/cgroup.h"
-#include "util/annotate.h"
-#include "perf.h"
-#include <linux/ctype.h>
#ifdef HAVE_LIBTRACEEVENT
#include <event-parse.h>
#endif
diff --git a/tools/perf/util/print_insn.h b/tools/perf/util/print_insn.h
index 07d11af3fc1c..a54f7e858e49 100644
--- a/tools/perf/util/print_insn.h
+++ b/tools/perf/util/print_insn.h
@@ -5,10 +5,11 @@
#include <stddef.h>
#include <stdio.h>
-struct perf_sample;
-struct thread;
+struct addr_location;
struct machine;
struct perf_insn;
+struct perf_sample;
+struct thread;
#define PRINT_INSN_IMM_HEX (1<<0)
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [PATCH v6 07/59] perf python: Add missed explicit dependencies
From: Ian Rogers @ 2026-04-25 17:48 UTC (permalink / raw)
To: acme, adrian.hunter, james.clark, leo.yan, namhyung, tmricht
Cc: alice.mei.rogers, dapeng1.mi, linux-arm-kernel, linux-kernel,
linux-perf-users, mingo, peterz, Ian Rogers
In-Reply-To: <20260425174858.3922152-1-irogers@google.com>
Fix missing #include of pmus.h found while cleaning the evsel/evlist
header files.
Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/perf/util/python.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index cc1019d29a5d..1e6c99efff90 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -5,26 +5,29 @@
#include <poll.h>
#include <linux/err.h>
#include <perf/cpumap.h>
-#ifdef HAVE_LIBTRACEEVENT
-#include <event-parse.h>
-#endif
+#include <internal/lib.h>
#include <perf/mmap.h>
+
#include "callchain.h"
#include "counts.h"
+#include "event.h"
#include "evlist.h"
#include "evsel.h"
-#include "event.h"
#include "expr.h"
+#include "metricgroup.h"
+#include "mmap.h"
+#include "pmus.h"
#include "print_binary.h"
#include "record.h"
#include "strbuf.h"
#include "thread_map.h"
#include "tp_pmu.h"
#include "trace-event.h"
-#include "metricgroup.h"
-#include "mmap.h"
#include "util/sample.h"
-#include <internal/lib.h>
+
+#ifdef HAVE_LIBTRACEEVENT
+#include <event-parse.h>
+#endif
PyMODINIT_FUNC PyInit_perf(void);
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [PATCH v6 08/59] perf evsel/evlist: Avoid unnecessary #includes
From: Ian Rogers @ 2026-04-25 17:48 UTC (permalink / raw)
To: acme, adrian.hunter, james.clark, leo.yan, namhyung, tmricht
Cc: alice.mei.rogers, dapeng1.mi, linux-arm-kernel, linux-kernel,
linux-perf-users, mingo, peterz, Ian Rogers
In-Reply-To: <20260425174858.3922152-1-irogers@google.com>
Use forward declarations and remove unnecessary #includes in
evsel.h. Sort the forward declarations in evsel.h and evlist.h.
Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/perf/util/evlist.h | 15 +++++++++------
tools/perf/util/evsel.h | 20 +++++++++++---------
2 files changed, 20 insertions(+), 15 deletions(-)
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index e507f5f20ef6..e54761c670b6 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -2,29 +2,32 @@
#ifndef __PERF_EVLIST_H
#define __PERF_EVLIST_H 1
+#include <signal.h>
+
#include <linux/compiler.h>
#include <linux/kernel.h>
-#include <linux/refcount.h>
#include <linux/list.h>
+#include <linux/refcount.h>
+#include <pthread.h>
+#include <unistd.h>
+
#include <api/fd/array.h>
#include <internal/evlist.h>
#include <internal/evsel.h>
#include <perf/evlist.h>
+
#include "affinity.h"
#include "events_stats.h"
#include "evsel.h"
#include "rblist.h"
-#include <pthread.h>
-#include <signal.h>
-#include <unistd.h>
-struct pollfd;
-struct thread_map;
struct perf_cpu_map;
struct perf_stat_config;
+struct pollfd;
struct record_opts;
struct strbuf;
struct target;
+struct thread_map;
/*
* State machine of bkw_mmap_state:
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 339b5c08a33d..b099c8e5dd86 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -2,28 +2,30 @@
#ifndef __PERF_EVSEL_H
#define __PERF_EVSEL_H 1
-#include <linux/list.h>
#include <stdbool.h>
-#include <sys/types.h>
+
+#include <linux/list.h>
#include <linux/perf_event.h>
#include <linux/types.h>
+#include <sys/types.h>
+
#include <internal/evsel.h>
#include <perf/evsel.h>
+
#include "symbol_conf.h"
-#include "pmus.h"
-#include "pmu.h"
+struct bperf_follower_bpf;
+struct bperf_leader_bpf;
+struct bpf_counter_ops;
struct bpf_object;
struct cgroup;
+struct hashmap;
struct perf_counts;
+struct perf_pmu;
struct perf_stat_config;
struct perf_stat_evsel;
-union perf_event;
-struct bpf_counter_ops;
struct target;
-struct hashmap;
-struct bperf_leader_bpf;
-struct bperf_follower_bpf;
+union perf_event;
typedef int (evsel__sb_cb_t)(union perf_event *event, void *data);
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [PATCH v6 06/59] perf util: Sort includes and add missed explicit dependencies
From: Ian Rogers @ 2026-04-25 17:48 UTC (permalink / raw)
To: acme, adrian.hunter, james.clark, leo.yan, namhyung, tmricht
Cc: alice.mei.rogers, dapeng1.mi, linux-arm-kernel, linux-kernel,
linux-perf-users, mingo, peterz, Ian Rogers
In-Reply-To: <20260425174858.3922152-1-irogers@google.com>
Fix missing includes found while cleaning the evsel/evlist header
files. Sort the remaining header files for consistency with the rest
of the code.
Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/perf/util/bpf_off_cpu.c | 30 +++++-----
tools/perf/util/bpf_trace_augment.c | 8 +--
tools/perf/util/evlist.c | 91 +++++++++++++++--------------
tools/perf/util/evsel.c | 75 ++++++++++++------------
tools/perf/util/map.h | 9 ++-
tools/perf/util/perf_api_probe.c | 18 +++---
tools/perf/util/s390-sample-raw.c | 19 +++---
tools/perf/util/stat-shadow.c | 20 ++++---
tools/perf/util/stat.c | 16 +++--
9 files changed, 152 insertions(+), 134 deletions(-)
diff --git a/tools/perf/util/bpf_off_cpu.c b/tools/perf/util/bpf_off_cpu.c
index a3b699a5322f..48cb930cdd2e 100644
--- a/tools/perf/util/bpf_off_cpu.c
+++ b/tools/perf/util/bpf_off_cpu.c
@@ -1,23 +1,25 @@
// SPDX-License-Identifier: GPL-2.0
-#include "util/bpf_counter.h"
-#include "util/debug.h"
-#include "util/evsel.h"
-#include "util/evlist.h"
-#include "util/off_cpu.h"
-#include "util/perf-hooks.h"
-#include "util/record.h"
-#include "util/session.h"
-#include "util/target.h"
-#include "util/cpumap.h"
-#include "util/thread_map.h"
-#include "util/cgroup.h"
-#include "util/strlist.h"
+#include <linux/time64.h>
+
#include <bpf/bpf.h>
#include <bpf/btf.h>
#include <internal/xyarray.h>
-#include <linux/time64.h>
+#include "bpf_counter.h"
#include "bpf_skel/off_cpu.skel.h"
+#include "cgroup.h"
+#include "cpumap.h"
+#include "debug.h"
+#include "evlist.h"
+#include "evsel.h"
+#include "off_cpu.h"
+#include "parse-events.h"
+#include "perf-hooks.h"
+#include "record.h"
+#include "session.h"
+#include "strlist.h"
+#include "target.h"
+#include "thread_map.h"
#define MAX_STACKS 32
#define MAX_PROC 4096
diff --git a/tools/perf/util/bpf_trace_augment.c b/tools/perf/util/bpf_trace_augment.c
index 9e706f0fa53d..a9cf2a77ded1 100644
--- a/tools/perf/util/bpf_trace_augment.c
+++ b/tools/perf/util/bpf_trace_augment.c
@@ -1,11 +1,11 @@
#include <bpf/libbpf.h>
#include <internal/xyarray.h>
-#include "util/debug.h"
-#include "util/evlist.h"
-#include "util/trace_augment.h"
-
#include "bpf_skel/augmented_raw_syscalls.skel.h"
+#include "debug.h"
+#include "evlist.h"
+#include "parse-events.h"
+#include "trace_augment.h"
static struct augmented_raw_syscalls_bpf *skel;
static struct evsel *bpf_output;
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index ee971d15b3c6..35d65fe50e06 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -5,67 +5,68 @@
* Parts came from builtin-{top,stat,record}.c, see those files for further
* copyright notes.
*/
-#include <api/fs/fs.h>
+#include "evlist.h"
+
#include <errno.h>
#include <inttypes.h>
-#include <poll.h>
-#include "cpumap.h"
-#include "util/mmap.h"
-#include "thread_map.h"
-#include "target.h"
-#include "dwarf-regs.h"
-#include "evlist.h"
-#include "evsel.h"
-#include "record.h"
-#include "debug.h"
-#include "units.h"
-#include "bpf_counter.h"
-#include <internal/lib.h> // page_size
-#include "affinity.h"
-#include "../perf.h"
-#include "asm/bug.h"
-#include "bpf-event.h"
-#include "util/event.h"
-#include "util/string2.h"
-#include "util/perf_api_probe.h"
-#include "util/evsel_fprintf.h"
-#include "util/pmu.h"
-#include "util/sample.h"
-#include "util/bpf-filter.h"
-#include "util/stat.h"
-#include "util/util.h"
-#include "util/env.h"
-#include "util/intel-tpebs.h"
-#include "util/metricgroup.h"
-#include "util/strbuf.h"
#include <signal.h>
-#include <unistd.h>
-#include <sched.h>
#include <stdlib.h>
-#include "parse-events.h"
-#include <subcmd/parse-options.h>
-
#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <sys/prctl.h>
-#include <sys/timerfd.h>
-#include <sys/wait.h>
-
#include <linux/bitops.h>
+#include <linux/err.h>
#include <linux/hash.h>
#include <linux/log2.h>
-#include <linux/err.h>
#include <linux/string.h>
#include <linux/time64.h>
#include <linux/zalloc.h>
+#include <poll.h>
+#include <sched.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/prctl.h>
+#include <sys/timerfd.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <api/fs/fs.h>
+#include <internal/lib.h> // page_size
+#include <internal/xyarray.h>
+#include <perf/cpumap.h>
#include <perf/evlist.h>
#include <perf/evsel.h>
-#include <perf/cpumap.h>
#include <perf/mmap.h>
+#include <subcmd/parse-options.h>
-#include <internal/xyarray.h>
+#include "../perf.h"
+#include "affinity.h"
+#include "asm/bug.h"
+#include "bpf-event.h"
+#include "bpf-filter.h"
+#include "bpf_counter.h"
+#include "cpumap.h"
+#include "debug.h"
+#include "dwarf-regs.h"
+#include "env.h"
+#include "event.h"
+#include "evsel.h"
+#include "evsel_fprintf.h"
+#include "intel-tpebs.h"
+#include "metricgroup.h"
+#include "mmap.h"
+#include "parse-events.h"
+#include "perf_api_probe.h"
+#include "pmu.h"
+#include "pmus.h"
+#include "record.h"
+#include "sample.h"
+#include "stat.h"
+#include "strbuf.h"
+#include "string2.h"
+#include "target.h"
+#include "thread_map.h"
+#include "units.h"
+#include "util.h"
#ifdef LACKS_SIGQUEUE_PROTOTYPE
int sigqueue(pid_t pid, int sig, const union sigval value);
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 2ee87fd84d3e..e03727d395e9 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -11,68 +11,71 @@
*/
#define __SANE_USERSPACE_TYPES__
-#include <byteswap.h>
+#include "evsel.h"
+
#include <errno.h>
#include <inttypes.h>
+#include <stdlib.h>
+
+#include <dirent.h>
#include <linux/bitops.h>
-#include <api/fs/fs.h>
-#include <api/fs/tracing_path.h>
-#include <linux/hw_breakpoint.h>
-#include <linux/perf_event.h>
#include <linux/compiler.h>
+#include <linux/ctype.h>
#include <linux/err.h>
+#include <linux/hw_breakpoint.h>
+#include <linux/perf_event.h>
#include <linux/zalloc.h>
#include <sys/ioctl.h>
#include <sys/resource.h>
#include <sys/syscall.h>
#include <sys/types.h>
-#include <dirent.h>
-#include <stdlib.h>
+
+#include <api/fs/fs.h>
+#include <api/fs/tracing_path.h>
+#include <byteswap.h>
+#include <internal/lib.h>
+#include <internal/threadmap.h>
+#include <internal/xyarray.h>
+#include <perf/cpumap.h>
#include <perf/evsel.h>
+
+#include "../perf-sys.h"
#include "asm/bug.h"
+#include "bpf-filter.h"
#include "bpf_counter.h"
#include "callchain.h"
#include "cgroup.h"
#include "counts.h"
+#include "debug.h"
+#include "drm_pmu.h"
#include "dwarf-regs.h"
+#include "env.h"
#include "event.h"
-#include "evsel.h"
-#include "time-utils.h"
-#include "util/env.h"
-#include "util/evsel_config.h"
-#include "util/evsel_fprintf.h"
#include "evlist.h"
-#include <perf/cpumap.h>
-#include "thread_map.h"
-#include "target.h"
+#include "evsel_config.h"
+#include "evsel_fprintf.h"
+#include "hashmap.h"
+#include "hist.h"
+#include "hwmon_pmu.h"
+#include "intel-tpebs.h"
+#include "memswap.h"
+#include "off_cpu.h"
+#include "parse-branch-options.h"
#include "perf_regs.h"
+#include "pmu.h"
+#include "pmus.h"
#include "record.h"
-#include "debug.h"
-#include "trace-event.h"
+#include "rlimit.h"
#include "session.h"
#include "stat.h"
#include "string2.h"
-#include "memswap.h"
-#include "util.h"
-#include "util/hashmap.h"
-#include "off_cpu.h"
-#include "pmu.h"
-#include "pmus.h"
-#include "drm_pmu.h"
-#include "hwmon_pmu.h"
+#include "target.h"
+#include "thread_map.h"
+#include "time-utils.h"
#include "tool_pmu.h"
#include "tp_pmu.h"
-#include "rlimit.h"
-#include "../perf-sys.h"
-#include "util/parse-branch-options.h"
-#include "util/bpf-filter.h"
-#include "util/hist.h"
-#include <internal/xyarray.h>
-#include <internal/lib.h>
-#include <internal/threadmap.h>
-#include "util/intel-tpebs.h"
-
-#include <linux/ctype.h>
+#include "trace-event.h"
+#include "util.h"
#ifdef HAVE_LIBTRACEEVENT
#include <event-parse.h>
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index 979b3e11b9bc..fb0279810ae9 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -2,14 +2,13 @@
#ifndef __PERF_MAP_H
#define __PERF_MAP_H
-#include <linux/refcount.h>
-#include <linux/compiler.h>
-#include <linux/list.h>
-#include <linux/rbtree.h>
+#include <stdbool.h>
#include <stdio.h>
#include <string.h>
-#include <stdbool.h>
+
+#include <linux/refcount.h>
#include <linux/types.h>
+
#include <internal/rc_check.h>
struct dso;
diff --git a/tools/perf/util/perf_api_probe.c b/tools/perf/util/perf_api_probe.c
index 6ecf38314f01..e1904a330b28 100644
--- a/tools/perf/util/perf_api_probe.c
+++ b/tools/perf/util/perf_api_probe.c
@@ -1,14 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0 */
+#include "perf_api_probe.h"
-#include "perf-sys.h"
-#include "util/cloexec.h"
-#include "util/evlist.h"
-#include "util/evsel.h"
-#include "util/parse-events.h"
-#include "util/perf_api_probe.h"
-#include <perf/cpumap.h>
#include <errno.h>
+#include <perf/cpumap.h>
+
+#include "cloexec.h"
+#include "evlist.h"
+#include "evsel.h"
+#include "parse-events.h"
+#include "perf-sys.h"
+#include "pmu.h"
+#include "pmus.h"
+
typedef void (*setup_probe_fn_t)(struct evsel *evsel);
static int perf_do_probe_api(setup_probe_fn_t fn, struct perf_cpu cpu, const char *str)
diff --git a/tools/perf/util/s390-sample-raw.c b/tools/perf/util/s390-sample-raw.c
index c6ae0ae8d86a..6bf0edf80d4e 100644
--- a/tools/perf/util/s390-sample-raw.c
+++ b/tools/perf/util/s390-sample-raw.c
@@ -12,25 +12,26 @@
* sample was taken from.
*/
-#include <unistd.h>
+#include <inttypes.h>
#include <stdio.h>
#include <string.h>
-#include <inttypes.h>
-#include <sys/stat.h>
+#include <asm/byteorder.h>
#include <linux/compiler.h>
#include <linux/err.h>
-#include <asm/byteorder.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include "color.h"
#include "debug.h"
-#include "session.h"
#include "evlist.h"
-#include "color.h"
#include "hashmap.h"
-#include "sample-raw.h"
+#include "pmu.h"
+#include "pmus.h"
#include "s390-cpumcf-kernel.h"
-#include "util/pmu.h"
-#include "util/sample.h"
+#include "sample-raw.h"
+#include "sample.h"
+#include "session.h"
static size_t ctrset_size(struct cf_ctrset_entry *set)
{
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
index bc2d44df7baf..48524450326d 100644
--- a/tools/perf/util/stat-shadow.c
+++ b/tools/perf/util/stat-shadow.c
@@ -2,20 +2,24 @@
#include <errno.h>
#include <math.h>
#include <stdio.h>
-#include "evsel.h"
-#include "stat.h"
+
+#include <linux/zalloc.h>
+
+#include "cgroup.h"
#include "color.h"
#include "debug.h"
-#include "pmu.h"
-#include "rblist.h"
#include "evlist.h"
+#include "evsel.h"
#include "expr.h"
-#include "metricgroup.h"
-#include "cgroup.h"
-#include "units.h"
+#include "hashmap.h"
#include "iostat.h"
-#include "util/hashmap.h"
+#include "metricgroup.h"
+#include "pmu.h"
+#include "pmus.h"
+#include "rblist.h"
+#include "stat.h"
#include "tool_pmu.h"
+#include "units.h"
static bool tool_pmu__is_time_event(const struct perf_stat_config *config,
const struct evsel *evsel, int *tool_aggr_idx)
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index 14d169e22e8f..66eb9a66a4f7 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -1,21 +1,25 @@
// SPDX-License-Identifier: GPL-2.0
+#include "stat.h"
+
#include <errno.h>
-#include <linux/err.h>
#include <inttypes.h>
#include <math.h>
#include <string.h>
+
+#include <linux/err.h>
+#include <linux/zalloc.h>
+
#include "counts.h"
#include "cpumap.h"
#include "debug.h"
+#include "evlist.h"
+#include "evsel.h"
+#include "hashmap.h"
#include "header.h"
-#include "stat.h"
+#include "pmu.h"
#include "session.h"
#include "target.h"
-#include "evlist.h"
-#include "evsel.h"
#include "thread_map.h"
-#include "util/hashmap.h"
-#include <linux/zalloc.h>
void update_stats(struct stats *stats, u64 val)
{
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [PATCH v6 09/59] perf data: Add open flag
From: Ian Rogers @ 2026-04-25 17:48 UTC (permalink / raw)
To: acme, adrian.hunter, james.clark, leo.yan, namhyung, tmricht
Cc: alice.mei.rogers, dapeng1.mi, linux-arm-kernel, linux-kernel,
linux-perf-users, mingo, peterz, Ian Rogers
In-Reply-To: <20260425174858.3922152-1-irogers@google.com>
Avoid double opens and ensure only open files are closed. This
addresses some issues with python integration where the data file
wants to be opened before being given to a session.
Assisted-by: Gemini:gemini-3.1-pro-preview
Signed-off-by: Ian Rogers <irogers@google.com>
---
Changes in v2:
1. Fixed File Rotation: In perf_data__switch() , I added data->open =
false; after the file is closed. This ensures that the subsequent
perf_data__open() call will not exit early and will successfully
open the new file.
2. Fixed Memory Leak: In open_dir() , I added a call to
zfree(&data->file.path) if mkdir() fails, preventing the leak of
the path string.
---
tools/perf/util/data.c | 26 ++++++++++++++++++++++----
tools/perf/util/data.h | 4 +++-
2 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c
index 94dc534a7386..17baf71897d1 100644
--- a/tools/perf/util/data.c
+++ b/tools/perf/util/data.c
@@ -346,8 +346,10 @@ static int open_dir(struct perf_data *data)
return -1;
if (perf_data__is_write(data) &&
- mkdir(data->path, S_IRWXU) < 0)
+ mkdir(data->path, S_IRWXU) < 0) {
+ zfree(&data->file.path);
return -1;
+ }
ret = open_file(data);
@@ -360,9 +362,16 @@ static int open_dir(struct perf_data *data)
int perf_data__open(struct perf_data *data)
{
- if (check_pipe(data))
+ int ret;
+
+ if (data->open)
return 0;
+ if (check_pipe(data)) {
+ data->open = true;
+ return 0;
+ }
+
/* currently it allows stdio for pipe only */
data->file.use_stdio = false;
@@ -375,16 +384,24 @@ int perf_data__open(struct perf_data *data)
if (perf_data__is_read(data))
data->is_dir = is_dir(data);
- return perf_data__is_dir(data) ?
- open_dir(data) : open_file_dup(data);
+ ret = perf_data__is_dir(data) ? open_dir(data) : open_file_dup(data);
+
+ if (!ret)
+ data->open = true;
+
+ return ret;
}
void perf_data__close(struct perf_data *data)
{
+ if (!data->open)
+ return;
+
if (perf_data__is_dir(data))
perf_data__close_dir(data);
perf_data_file__close(&data->file);
+ data->open = false;
}
static ssize_t perf_data_file__read(struct perf_data_file *file, void *buf, size_t size)
@@ -457,6 +474,7 @@ int perf_data__switch(struct perf_data *data,
if (!at_exit) {
perf_data_file__close(&data->file);
+ data->open = false;
ret = perf_data__open(data);
if (ret < 0)
goto out;
diff --git a/tools/perf/util/data.h b/tools/perf/util/data.h
index 8299fb5fa7da..76f57f60361f 100644
--- a/tools/perf/util/data.h
+++ b/tools/perf/util/data.h
@@ -50,6 +50,8 @@ struct perf_data {
const char *path;
/** @file: Underlying file to be used. */
struct perf_data_file file;
+ /** @open: Has the file or directory been opened. */
+ bool open;
/** @is_pipe: Underlying file is a pipe. */
bool is_pipe;
/** @is_dir: Underlying file is a directory. */
@@ -59,7 +61,7 @@ struct perf_data {
/** @in_place_update: A file opened for reading but will be written to. */
bool in_place_update;
/** @mode: Read or write mode. */
- enum perf_data_mode mode;
+ enum perf_data_mode mode:8;
struct {
/** @version: perf_dir_version. */
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [PATCH v6 10/59] perf evlist: Add reference count
From: Ian Rogers @ 2026-04-25 17:48 UTC (permalink / raw)
To: acme, adrian.hunter, james.clark, leo.yan, namhyung, tmricht
Cc: alice.mei.rogers, dapeng1.mi, linux-arm-kernel, linux-kernel,
linux-perf-users, mingo, peterz, Ian Rogers
In-Reply-To: <20260425174858.3922152-1-irogers@google.com>
This a no-op for most of the perf tool. The reference count is set to
1 at allocation, the put will see the 1, decrement it and perform the
delete. The purpose for adding the reference count is for the python
code. Prior to this change the python code would clone evlists, but
this has issues if events are opened, etc. This change adds a
reference count for the evlists and a later change will add it to
evsels. The combination is needed for the python code to operate
correctly (not hit asserts in the evsel clone), but the changes are
broken apart for the sake of smaller patches.
Assisted-by: Gemini:gemini-3.1-pro-preview
Signed-off-by: Ian Rogers <irogers@google.com>
---
v2: Added evlist__put to pyrf_evlist__init in case init is called more
than once.
I double-checked trace__replay() and confirmed that trace->evlist
is not assigned to session->evlist in that function.
trace__replay creates a new session and uses its own evlist for
processing file events, leaving trace->evlist pointing to the
empty list created at startup. Therefore, the
evlist__put(trace->evlist) call in trace__exit() is safe and
correct to avoid leaking that empty list.
---
tools/perf/arch/x86/tests/hybrid.c | 2 +-
tools/perf/arch/x86/tests/topdown.c | 2 +-
tools/perf/arch/x86/util/iostat.c | 2 +-
tools/perf/bench/evlist-open-close.c | 18 +-
tools/perf/builtin-ftrace.c | 8 +-
tools/perf/builtin-kvm.c | 4 +-
tools/perf/builtin-lock.c | 2 +-
tools/perf/builtin-record.c | 4 +-
tools/perf/builtin-sched.c | 6 +-
tools/perf/builtin-script.c | 2 +-
tools/perf/builtin-stat.c | 10 +-
tools/perf/builtin-top.c | 52 ++---
tools/perf/builtin-trace.c | 26 +--
tools/perf/tests/backward-ring-buffer.c | 18 +-
tools/perf/tests/code-reading.c | 4 +-
tools/perf/tests/event-times.c | 4 +-
tools/perf/tests/event_update.c | 2 +-
tools/perf/tests/evsel-roundtrip-name.c | 8 +-
tools/perf/tests/expand-cgroup.c | 8 +-
tools/perf/tests/hists_cumulate.c | 2 +-
tools/perf/tests/hists_filter.c | 2 +-
tools/perf/tests/hists_link.c | 2 +-
tools/perf/tests/hists_output.c | 2 +-
tools/perf/tests/hwmon_pmu.c | 2 +-
tools/perf/tests/keep-tracking.c | 2 +-
tools/perf/tests/mmap-basic.c | 18 +-
tools/perf/tests/openat-syscall-tp-fields.c | 18 +-
tools/perf/tests/parse-events.c | 4 +-
tools/perf/tests/parse-metric.c | 4 +-
tools/perf/tests/parse-no-sample-id-all.c | 2 +-
tools/perf/tests/perf-record.c | 18 +-
tools/perf/tests/perf-time-to-tsc.c | 2 +-
tools/perf/tests/pfm.c | 4 +-
tools/perf/tests/pmu-events.c | 6 +-
tools/perf/tests/pmu.c | 4 +-
tools/perf/tests/sw-clock.c | 14 +-
tools/perf/tests/switch-tracking.c | 2 +-
tools/perf/tests/task-exit.c | 14 +-
tools/perf/tests/tool_pmu.c | 2 +-
tools/perf/tests/topology.c | 2 +-
tools/perf/util/cgroup.c | 4 +-
tools/perf/util/data-convert-bt.c | 2 +-
tools/perf/util/evlist.c | 20 +-
tools/perf/util/evlist.h | 7 +-
tools/perf/util/expr.c | 2 +-
| 12 +-
tools/perf/util/metricgroup.c | 6 +-
tools/perf/util/parse-events.c | 4 +-
tools/perf/util/perf_api_probe.c | 2 +-
tools/perf/util/python.c | 200 +++++++-------------
tools/perf/util/record.c | 2 +-
tools/perf/util/session.c | 2 +-
tools/perf/util/sideband_evlist.c | 16 +-
53 files changed, 268 insertions(+), 319 deletions(-)
diff --git a/tools/perf/arch/x86/tests/hybrid.c b/tools/perf/arch/x86/tests/hybrid.c
index e221ea104174..dfb0ffc0d030 100644
--- a/tools/perf/arch/x86/tests/hybrid.c
+++ b/tools/perf/arch/x86/tests/hybrid.c
@@ -268,7 +268,7 @@ static int test_event(const struct evlist_test *e)
ret = e->check(evlist);
}
parse_events_error__exit(&err);
- evlist__delete(evlist);
+ evlist__put(evlist);
return ret;
}
diff --git a/tools/perf/arch/x86/tests/topdown.c b/tools/perf/arch/x86/tests/topdown.c
index 3ee4e5e71be3..2d0ae5b0d76c 100644
--- a/tools/perf/arch/x86/tests/topdown.c
+++ b/tools/perf/arch/x86/tests/topdown.c
@@ -56,7 +56,7 @@ static int event_cb(void *state, struct pmu_event_info *info)
*ret = TEST_FAIL;
}
}
- evlist__delete(evlist);
+ evlist__put(evlist);
return 0;
}
diff --git a/tools/perf/arch/x86/util/iostat.c b/tools/perf/arch/x86/util/iostat.c
index 7442a2cd87ed..e0417552b0cb 100644
--- a/tools/perf/arch/x86/util/iostat.c
+++ b/tools/perf/arch/x86/util/iostat.c
@@ -337,7 +337,7 @@ int iostat_prepare(struct evlist *evlist, struct perf_stat_config *config)
if (evlist->core.nr_entries > 0) {
pr_warning("The -e and -M options are not supported."
"All chosen events/metrics will be dropped\n");
- evlist__delete(evlist);
+ evlist__put(evlist);
evlist = evlist__new();
if (!evlist)
return -ENOMEM;
diff --git a/tools/perf/bench/evlist-open-close.c b/tools/perf/bench/evlist-open-close.c
index faf9c34b4a5d..304929d1f67f 100644
--- a/tools/perf/bench/evlist-open-close.c
+++ b/tools/perf/bench/evlist-open-close.c
@@ -76,7 +76,7 @@ static struct evlist *bench__create_evlist(char *evstr, const char *uid_str)
parse_events_error__exit(&err);
pr_err("Run 'perf list' for a list of valid events\n");
ret = 1;
- goto out_delete_evlist;
+ goto out_put_evlist;
}
parse_events_error__exit(&err);
if (uid_str) {
@@ -85,24 +85,24 @@ static struct evlist *bench__create_evlist(char *evstr, const char *uid_str)
if (uid == UINT_MAX) {
pr_err("Invalid User: %s", uid_str);
ret = -EINVAL;
- goto out_delete_evlist;
+ goto out_put_evlist;
}
ret = parse_uid_filter(evlist, uid);
if (ret)
- goto out_delete_evlist;
+ goto out_put_evlist;
}
ret = evlist__create_maps(evlist, &opts.target);
if (ret < 0) {
pr_err("Not enough memory to create thread/cpu maps\n");
- goto out_delete_evlist;
+ goto out_put_evlist;
}
evlist__config(evlist, &opts, NULL);
return evlist;
-out_delete_evlist:
- evlist__delete(evlist);
+out_put_evlist:
+ evlist__put(evlist);
return NULL;
}
@@ -151,7 +151,7 @@ static int bench_evlist_open_close__run(char *evstr, const char *uid_str)
evlist->core.nr_entries, evlist__count_evsel_fds(evlist));
printf(" Number of iterations:\t%d\n", iterations);
- evlist__delete(evlist);
+ evlist__put(evlist);
for (i = 0; i < iterations; i++) {
pr_debug("Started iteration %d\n", i);
@@ -162,7 +162,7 @@ static int bench_evlist_open_close__run(char *evstr, const char *uid_str)
gettimeofday(&start, NULL);
err = bench__do_evlist_open_close(evlist);
if (err) {
- evlist__delete(evlist);
+ evlist__put(evlist);
return err;
}
@@ -171,7 +171,7 @@ static int bench_evlist_open_close__run(char *evstr, const char *uid_str)
runtime_us = timeval2usec(&diff);
update_stats(&time_stats, runtime_us);
- evlist__delete(evlist);
+ evlist__put(evlist);
pr_debug("Iteration %d took:\t%" PRIu64 "us\n", i, runtime_us);
}
diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c
index 8a7dbfb14535..676239148b87 100644
--- a/tools/perf/builtin-ftrace.c
+++ b/tools/perf/builtin-ftrace.c
@@ -1999,20 +1999,20 @@ int cmd_ftrace(int argc, const char **argv)
ret = evlist__create_maps(ftrace.evlist, &ftrace.target);
if (ret < 0)
- goto out_delete_evlist;
+ goto out_put_evlist;
if (argc) {
ret = evlist__prepare_workload(ftrace.evlist, &ftrace.target,
argv, false,
ftrace__workload_exec_failed_signal);
if (ret < 0)
- goto out_delete_evlist;
+ goto out_put_evlist;
}
ret = cmd_func(&ftrace);
-out_delete_evlist:
- evlist__delete(ftrace.evlist);
+out_put_evlist:
+ evlist__put(ftrace.evlist);
out_delete_filters:
delete_filter_func(&ftrace.filters);
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 0c5e6b3aac74..d88855e3c7b4 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -1811,7 +1811,7 @@ static struct evlist *kvm_live_event_list(void)
out:
if (err) {
- evlist__delete(evlist);
+ evlist__put(evlist);
evlist = NULL;
}
@@ -1942,7 +1942,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
out:
perf_session__delete(kvm->session);
kvm->session = NULL;
- evlist__delete(kvm->evlist);
+ evlist__put(kvm->evlist);
return err;
}
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
index 5585aeb97684..c40d070f6c36 100644
--- a/tools/perf/builtin-lock.c
+++ b/tools/perf/builtin-lock.c
@@ -2145,7 +2145,7 @@ static int __cmd_contention(int argc, const char **argv)
out_delete:
lock_filter_finish();
- evlist__delete(con.evlist);
+ evlist__put(con.evlist);
lock_contention_finish(&con);
perf_session__delete(session);
perf_env__exit(&host_env);
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 4a5eba498c02..b4fffa936e01 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -4289,7 +4289,7 @@ int cmd_record(int argc, const char **argv)
goto out;
evlist__splice_list_tail(rec->evlist, &def_evlist->core.entries);
- evlist__delete(def_evlist);
+ evlist__put(def_evlist);
}
if (rec->opts.target.tid && !rec->opts.no_inherit_set)
@@ -4397,7 +4397,7 @@ int cmd_record(int argc, const char **argv)
auxtrace_record__free(rec->itr);
out_opts:
evlist__close_control(rec->opts.ctl_fd, rec->opts.ctl_fd_ack, &rec->opts.ctl_fd_close);
- evlist__delete(rec->evlist);
+ evlist__put(rec->evlist);
return err;
}
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 555247568e7a..d683642ab4e0 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -3829,7 +3829,7 @@ static int perf_sched__schedstat_record(struct perf_sched *sched,
session = perf_session__new(&data, &sched->tool);
if (IS_ERR(session)) {
pr_err("Perf session creation failed.\n");
- evlist__delete(evlist);
+ evlist__put(evlist);
return PTR_ERR(session);
}
@@ -3925,7 +3925,7 @@ static int perf_sched__schedstat_record(struct perf_sched *sched,
else
fprintf(stderr, "[ perf sched stats: Failed !! ]\n");
- evlist__delete(evlist);
+ evlist__put(evlist);
close(fd);
return err;
}
@@ -4724,7 +4724,7 @@ static int perf_sched__schedstat_live(struct perf_sched *sched,
free_cpu_domain_info(cd_map, sv, nr);
out:
free_schedstat(&cpu_head);
- evlist__delete(evlist);
+ evlist__put(evlist);
return err;
}
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 853b141a0d50..0ead134940d5 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -2269,7 +2269,7 @@ static int script_find_metrics(const struct pmu_metric *pm,
}
pr_debug("Found metric '%s' whose evsels match those of in the perf data\n",
pm->metric_name);
- evlist__delete(metric_evlist);
+ evlist__put(metric_evlist);
out:
return 0;
}
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 99d7db372b48..bfa3512e1686 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -2113,7 +2113,7 @@ static int add_default_events(void)
stat_config.user_requested_cpu_list,
stat_config.system_wide,
stat_config.hardware_aware_grouping) < 0) {
- evlist__delete(metric_evlist);
+ evlist__put(metric_evlist);
ret = -1;
break;
}
@@ -2125,7 +2125,7 @@ static int add_default_events(void)
metricgroup__copy_metric_events(evlist, /*cgrp=*/NULL,
&evlist->metric_events,
&metric_evlist->metric_events);
- evlist__delete(metric_evlist);
+ evlist__put(metric_evlist);
}
list_sort(/*priv=*/NULL, &evlist->core.entries, default_evlist_evsel_cmp);
@@ -2146,7 +2146,7 @@ static int add_default_events(void)
metricgroup__copy_metric_events(evsel_list, /*cgrp=*/NULL,
&evsel_list->metric_events,
&evlist->metric_events);
- evlist__delete(evlist);
+ evlist__put(evlist);
return ret;
}
@@ -2381,7 +2381,7 @@ static int __cmd_report(int argc, const char **argv)
perf_stat.session = session;
stat_config.output = stderr;
- evlist__delete(evsel_list);
+ evlist__put(evsel_list);
evsel_list = session->evlist;
ret = perf_session__process_events(session);
@@ -3060,7 +3060,7 @@ int cmd_stat(int argc, const char **argv)
if (smi_cost && smi_reset)
sysfs__write_int(FREEZE_ON_SMI_PATH, 0);
- evlist__delete(evsel_list);
+ evlist__put(evsel_list);
evlist__close_control(stat_config.ctl_fd, stat_config.ctl_fd_ack, &stat_config.ctl_fd_close);
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index f6eb543de537..c509cfef8285 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -1652,14 +1652,14 @@ int cmd_top(int argc, const char **argv)
perf_env__init(&host_env);
status = perf_config(perf_top_config, &top);
if (status)
- goto out_delete_evlist;
+ goto out_put_evlist;
/*
* Since the per arch annotation init routine may need the cpuid, read
* it here, since we are not getting this from the perf.data header.
*/
status = perf_env__set_cmdline(&host_env, argc, argv);
if (status)
- goto out_delete_evlist;
+ goto out_put_evlist;
status = perf_env__read_cpuid(&host_env);
if (status) {
@@ -1680,30 +1680,30 @@ int cmd_top(int argc, const char **argv)
annotate_opts.disassembler_style = strdup(disassembler_style);
if (!annotate_opts.disassembler_style) {
status = -ENOMEM;
- goto out_delete_evlist;
+ goto out_put_evlist;
}
}
if (objdump_path) {
annotate_opts.objdump_path = strdup(objdump_path);
if (!annotate_opts.objdump_path) {
status = -ENOMEM;
- goto out_delete_evlist;
+ goto out_put_evlist;
}
}
if (addr2line_path) {
symbol_conf.addr2line_path = strdup(addr2line_path);
if (!symbol_conf.addr2line_path) {
status = -ENOMEM;
- goto out_delete_evlist;
+ goto out_put_evlist;
}
}
status = symbol__validate_sym_arguments();
if (status)
- goto out_delete_evlist;
+ goto out_put_evlist;
if (annotate_check_args() < 0)
- goto out_delete_evlist;
+ goto out_put_evlist;
status = target__validate(target);
if (status) {
@@ -1718,15 +1718,15 @@ int cmd_top(int argc, const char **argv)
struct evlist *def_evlist = evlist__new_default(target, callchain_param.enabled);
if (!def_evlist)
- goto out_delete_evlist;
+ goto out_put_evlist;
evlist__splice_list_tail(top.evlist, &def_evlist->core.entries);
- evlist__delete(def_evlist);
+ evlist__put(def_evlist);
}
status = evswitch__init(&top.evswitch, top.evlist, stderr);
if (status)
- goto out_delete_evlist;
+ goto out_put_evlist;
if (symbol_conf.report_hierarchy) {
/* disable incompatible options */
@@ -1737,18 +1737,18 @@ int cmd_top(int argc, const char **argv)
pr_err("Error: --hierarchy and --fields options cannot be used together\n");
parse_options_usage(top_usage, options, "fields", 0);
parse_options_usage(NULL, options, "hierarchy", 0);
- goto out_delete_evlist;
+ goto out_put_evlist;
}
}
if (top.stitch_lbr && !(callchain_param.record_mode == CALLCHAIN_LBR)) {
pr_err("Error: --stitch-lbr must be used with --call-graph lbr\n");
- goto out_delete_evlist;
+ goto out_put_evlist;
}
if (nr_cgroups > 0 && opts->record_cgroup) {
pr_err("--cgroup and --all-cgroups cannot be used together\n");
- goto out_delete_evlist;
+ goto out_put_evlist;
}
if (branch_call_mode) {
@@ -1772,7 +1772,7 @@ int cmd_top(int argc, const char **argv)
status = perf_env__read_core_pmu_caps(&host_env);
if (status) {
pr_err("PMU capability data is not available\n");
- goto out_delete_evlist;
+ goto out_put_evlist;
}
}
@@ -1795,7 +1795,7 @@ int cmd_top(int argc, const char **argv)
if (IS_ERR(top.session)) {
status = PTR_ERR(top.session);
top.session = NULL;
- goto out_delete_evlist;
+ goto out_put_evlist;
}
top.evlist->session = top.session;
@@ -1805,7 +1805,7 @@ int cmd_top(int argc, const char **argv)
if (field_order)
parse_options_usage(sort_order ? NULL : top_usage,
options, "fields", 0);
- goto out_delete_evlist;
+ goto out_put_evlist;
}
if (top.uid_str) {
@@ -1814,18 +1814,18 @@ int cmd_top(int argc, const char **argv)
if (uid == UINT_MAX) {
ui__error("Invalid User: %s", top.uid_str);
status = -EINVAL;
- goto out_delete_evlist;
+ goto out_put_evlist;
}
status = parse_uid_filter(top.evlist, uid);
if (status)
- goto out_delete_evlist;
+ goto out_put_evlist;
}
if (evlist__create_maps(top.evlist, target) < 0) {
ui__error("Couldn't create thread/CPU maps: %s\n",
errno == ENOENT ? "No such process" : str_error_r(errno, errbuf, sizeof(errbuf)));
status = -errno;
- goto out_delete_evlist;
+ goto out_put_evlist;
}
if (top.delay_secs < 1)
@@ -1833,7 +1833,7 @@ int cmd_top(int argc, const char **argv)
if (record_opts__config(opts)) {
status = -EINVAL;
- goto out_delete_evlist;
+ goto out_put_evlist;
}
top.sym_evsel = evlist__first(top.evlist);
@@ -1848,14 +1848,14 @@ int cmd_top(int argc, const char **argv)
status = symbol__annotation_init();
if (status < 0)
- goto out_delete_evlist;
+ goto out_put_evlist;
annotation_config__init();
symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL);
status = symbol__init(NULL);
if (status < 0)
- goto out_delete_evlist;
+ goto out_put_evlist;
sort__setup_elide(stdout);
@@ -1875,13 +1875,13 @@ int cmd_top(int argc, const char **argv)
if (top.sb_evlist == NULL) {
pr_err("Couldn't create side band evlist.\n.");
status = -EINVAL;
- goto out_delete_evlist;
+ goto out_put_evlist;
}
if (evlist__add_bpf_sb_event(top.sb_evlist, &host_env)) {
pr_err("Couldn't ask for PERF_RECORD_BPF_EVENT side band events.\n.");
status = -EINVAL;
- goto out_delete_evlist;
+ goto out_put_evlist;
}
}
#endif
@@ -1896,8 +1896,8 @@ int cmd_top(int argc, const char **argv)
if (!opts->no_bpf_event)
evlist__stop_sb_thread(top.sb_evlist);
-out_delete_evlist:
- evlist__delete(top.evlist);
+out_put_evlist:
+ evlist__put(top.evlist);
perf_session__delete(top.session);
annotation_options__exit();
perf_env__exit(&host_env);
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index e58c49d047a2..da703d762433 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -4388,7 +4388,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
if (trace->summary_bpf) {
if (trace_prepare_bpf_summary(trace->summary_mode) < 0)
- goto out_delete_evlist;
+ goto out_put_evlist;
if (trace->summary_only)
goto create_maps;
@@ -4456,19 +4456,19 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
err = evlist__create_maps(evlist, &trace->opts.target);
if (err < 0) {
fprintf(trace->output, "Problems parsing the target to trace, check your options!\n");
- goto out_delete_evlist;
+ goto out_put_evlist;
}
err = trace__symbols_init(trace, argc, argv, evlist);
if (err < 0) {
fprintf(trace->output, "Problems initializing symbol libraries!\n");
- goto out_delete_evlist;
+ goto out_put_evlist;
}
if (trace->summary_mode == SUMMARY__BY_TOTAL && !trace->summary_bpf) {
trace->syscall_stats = alloc_syscall_stats();
if (!trace->syscall_stats)
- goto out_delete_evlist;
+ goto out_put_evlist;
}
evlist__config(evlist, &trace->opts, &callchain_param);
@@ -4477,7 +4477,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
err = evlist__prepare_workload(evlist, &trace->opts.target, argv, false, NULL);
if (err < 0) {
fprintf(trace->output, "Couldn't run the workload!\n");
- goto out_delete_evlist;
+ goto out_put_evlist;
}
workload_pid = evlist->workload.pid;
}
@@ -4525,7 +4525,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
err = trace__expand_filters(trace, &evsel);
if (err)
- goto out_delete_evlist;
+ goto out_put_evlist;
err = evlist__apply_filters(evlist, &evsel, &trace->opts.target);
if (err < 0)
goto out_error_apply_filters;
@@ -4642,12 +4642,12 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
}
}
-out_delete_evlist:
+out_put_evlist:
trace_cleanup_bpf_summary();
delete_syscall_stats(trace->syscall_stats);
trace__symbols__exit(trace);
evlist__free_syscall_tp_fields(evlist);
- evlist__delete(evlist);
+ evlist__put(evlist);
cgroup__put(trace->cgroup);
trace->evlist = NULL;
trace->live = false;
@@ -4672,21 +4672,21 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
out_error:
fprintf(trace->output, "%s\n", errbuf);
- goto out_delete_evlist;
+ goto out_put_evlist;
out_error_apply_filters:
fprintf(trace->output,
"Failed to set filter \"%s\" on event %s: %m\n",
evsel->filter, evsel__name(evsel));
- goto out_delete_evlist;
+ goto out_put_evlist;
}
out_error_mem:
fprintf(trace->output, "Not enough memory to run!\n");
- goto out_delete_evlist;
+ goto out_put_evlist;
out_errno:
fprintf(trace->output, "%m\n");
- goto out_delete_evlist;
+ goto out_put_evlist;
}
static int trace__replay(struct trace *trace)
@@ -5364,7 +5364,7 @@ static void trace__exit(struct trace *trace)
zfree(&trace->syscalls.table);
}
zfree(&trace->perfconfig_events);
- evlist__delete(trace->evlist);
+ evlist__put(trace->evlist);
trace->evlist = NULL;
ordered_events__free(&trace->oe.data);
#ifdef HAVE_LIBBPF_SUPPORT
diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c
index c5e7999f2817..2b49b002d749 100644
--- a/tools/perf/tests/backward-ring-buffer.c
+++ b/tools/perf/tests/backward-ring-buffer.c
@@ -111,7 +111,7 @@ static int test__backward_ring_buffer(struct test_suite *test __maybe_unused, in
err = evlist__create_maps(evlist, &opts.target);
if (err < 0) {
pr_debug("Not enough memory to create thread/cpu maps\n");
- goto out_delete_evlist;
+ goto out_put_evlist;
}
parse_events_error__init(&parse_error);
@@ -124,7 +124,7 @@ static int test__backward_ring_buffer(struct test_suite *test __maybe_unused, in
if (err) {
pr_debug("Failed to parse tracepoint event, try use root\n");
ret = TEST_SKIP;
- goto out_delete_evlist;
+ goto out_put_evlist;
}
evlist__config(evlist, &opts, NULL);
@@ -133,19 +133,19 @@ static int test__backward_ring_buffer(struct test_suite *test __maybe_unused, in
if (err < 0) {
pr_debug("perf_evlist__open: %s\n",
str_error_r(errno, sbuf, sizeof(sbuf)));
- goto out_delete_evlist;
+ goto out_put_evlist;
}
ret = TEST_FAIL;
err = do_test(evlist, opts.mmap_pages, &sample_count,
&comm_count);
if (err != TEST_OK)
- goto out_delete_evlist;
+ goto out_put_evlist;
if ((sample_count != NR_ITERS) || (comm_count != NR_ITERS)) {
pr_err("Unexpected counter: sample_count=%d, comm_count=%d\n",
sample_count, comm_count);
- goto out_delete_evlist;
+ goto out_put_evlist;
}
evlist__close(evlist);
@@ -154,16 +154,16 @@ static int test__backward_ring_buffer(struct test_suite *test __maybe_unused, in
if (err < 0) {
pr_debug("perf_evlist__open: %s\n",
str_error_r(errno, sbuf, sizeof(sbuf)));
- goto out_delete_evlist;
+ goto out_put_evlist;
}
err = do_test(evlist, 1, &sample_count, &comm_count);
if (err != TEST_OK)
- goto out_delete_evlist;
+ goto out_put_evlist;
ret = TEST_OK;
-out_delete_evlist:
- evlist__delete(evlist);
+out_put_evlist:
+ evlist__put(evlist);
return ret;
}
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index 47043a3a2fb4..fc65a17f67f7 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -807,7 +807,7 @@ static int do_test_code_reading(bool try_kcore)
}
perf_evlist__set_maps(&evlist->core, NULL, NULL);
- evlist__delete(evlist);
+ evlist__put(evlist);
evlist = NULL;
continue;
}
@@ -844,7 +844,7 @@ static int do_test_code_reading(bool try_kcore)
out_put:
thread__put(thread);
out_err:
- evlist__delete(evlist);
+ evlist__put(evlist);
perf_cpu_map__put(cpus);
perf_thread_map__put(threads);
machine__delete(machine);
diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c
index ae3b98bb42cf..94ab54ecd3f9 100644
--- a/tools/perf/tests/event-times.c
+++ b/tools/perf/tests/event-times.c
@@ -186,7 +186,7 @@ static int test_times(int (attach)(struct evlist *),
err = attach(evlist);
if (err == TEST_SKIP) {
pr_debug(" SKIP : not enough rights\n");
- evlist__delete(evlist);
+ evlist__put(evlist);
return err;
}
@@ -205,7 +205,7 @@ static int test_times(int (attach)(struct evlist *),
count.ena, count.run);
out_err:
- evlist__delete(evlist);
+ evlist__put(evlist);
return !err ? TEST_OK : TEST_FAIL;
}
diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_update.c
index facc65e29f20..73141b122d2f 100644
--- a/tools/perf/tests/event_update.c
+++ b/tools/perf/tests/event_update.c
@@ -117,7 +117,7 @@ static int test__event_update(struct test_suite *test __maybe_unused, int subtes
TEST_ASSERT_VAL("failed to synthesize attr update cpus",
!perf_event__synthesize_event_update_cpus(&tmp.tool, evsel, process_event_cpus));
- evlist__delete(evlist);
+ evlist__put(evlist);
return 0;
}
diff --git a/tools/perf/tests/evsel-roundtrip-name.c b/tools/perf/tests/evsel-roundtrip-name.c
index 1922cac13a24..6a220634c52f 100644
--- a/tools/perf/tests/evsel-roundtrip-name.c
+++ b/tools/perf/tests/evsel-roundtrip-name.c
@@ -33,7 +33,7 @@ static int perf_evsel__roundtrip_cache_name_test(void)
if (err) {
pr_debug("Failure to parse cache event '%s' possibly as PMUs don't support it",
name);
- evlist__delete(evlist);
+ evlist__put(evlist);
continue;
}
evlist__for_each_entry(evlist, evsel) {
@@ -42,7 +42,7 @@ static int perf_evsel__roundtrip_cache_name_test(void)
ret = TEST_FAIL;
}
}
- evlist__delete(evlist);
+ evlist__put(evlist);
}
}
}
@@ -66,7 +66,7 @@ static int perf_evsel__name_array_test(const char *const names[], int nr_names)
if (err) {
pr_debug("failed to parse event '%s', err %d\n",
names[i], err);
- evlist__delete(evlist);
+ evlist__put(evlist);
ret = TEST_FAIL;
continue;
}
@@ -76,7 +76,7 @@ static int perf_evsel__name_array_test(const char *const names[], int nr_names)
ret = TEST_FAIL;
}
}
- evlist__delete(evlist);
+ evlist__put(evlist);
}
return ret;
}
diff --git a/tools/perf/tests/expand-cgroup.c b/tools/perf/tests/expand-cgroup.c
index dd547f2f77cc..a7a445f12693 100644
--- a/tools/perf/tests/expand-cgroup.c
+++ b/tools/perf/tests/expand-cgroup.c
@@ -106,7 +106,7 @@ static int expand_default_events(void)
TEST_ASSERT_VAL("failed to get evlist", evlist);
ret = test_expand_events(evlist);
- evlist__delete(evlist);
+ evlist__put(evlist);
return ret;
}
@@ -133,7 +133,7 @@ static int expand_group_events(void)
ret = test_expand_events(evlist);
out:
parse_events_error__exit(&err);
- evlist__delete(evlist);
+ evlist__put(evlist);
return ret;
}
@@ -164,7 +164,7 @@ static int expand_libpfm_events(void)
ret = test_expand_events(evlist);
out:
- evlist__delete(evlist);
+ evlist__put(evlist);
return ret;
}
@@ -188,7 +188,7 @@ static int expand_metric_events(void)
ret = test_expand_events(evlist);
out:
- evlist__delete(evlist);
+ evlist__put(evlist);
return ret;
}
diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.c
index 606aa926a8fc..eca4ecb63ca8 100644
--- a/tools/perf/tests/hists_cumulate.c
+++ b/tools/perf/tests/hists_cumulate.c
@@ -744,7 +744,7 @@ static int test__hists_cumulate(struct test_suite *test __maybe_unused, int subt
out:
/* tear down everything */
- evlist__delete(evlist);
+ evlist__put(evlist);
machines__exit(&machines);
put_fake_samples();
diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filter.c
index cc6b26e373d1..0d09dc306019 100644
--- a/tools/perf/tests/hists_filter.c
+++ b/tools/perf/tests/hists_filter.c
@@ -332,7 +332,7 @@ static int test__hists_filter(struct test_suite *test __maybe_unused, int subtes
out:
/* tear down everything */
- evlist__delete(evlist);
+ evlist__put(evlist);
reset_output_field();
machines__exit(&machines);
put_fake_samples();
diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c
index 996f5f0b3bd1..9646c3b7b4de 100644
--- a/tools/perf/tests/hists_link.c
+++ b/tools/perf/tests/hists_link.c
@@ -352,7 +352,7 @@ static int test__hists_link(struct test_suite *test __maybe_unused, int subtest
out:
/* tear down everything */
- evlist__delete(evlist);
+ evlist__put(evlist);
reset_output_field();
machines__exit(&machines);
put_fake_samples();
diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_output.c
index 7818950d786e..3f3bc978553e 100644
--- a/tools/perf/tests/hists_output.c
+++ b/tools/perf/tests/hists_output.c
@@ -631,7 +631,7 @@ static int test__hists_output(struct test_suite *test __maybe_unused, int subtes
out:
/* tear down everything */
- evlist__delete(evlist);
+ evlist__put(evlist);
machines__exit(&machines);
put_fake_samples();
diff --git a/tools/perf/tests/hwmon_pmu.c b/tools/perf/tests/hwmon_pmu.c
index ada6e445c4c4..1b60c3a900f1 100644
--- a/tools/perf/tests/hwmon_pmu.c
+++ b/tools/perf/tests/hwmon_pmu.c
@@ -214,7 +214,7 @@ static int do_test(size_t i, bool with_pmu, bool with_alias)
out:
parse_events_error__exit(&err);
- evlist__delete(evlist);
+ evlist__put(evlist);
return ret;
}
diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c
index 729cc9cc1cb7..51cfd6522867 100644
--- a/tools/perf/tests/keep-tracking.c
+++ b/tools/perf/tests/keep-tracking.c
@@ -153,7 +153,7 @@ static int test__keep_tracking(struct test_suite *test __maybe_unused, int subte
out_err:
if (evlist) {
evlist__disable(evlist);
- evlist__delete(evlist);
+ evlist__put(evlist);
}
perf_cpu_map__put(cpus);
perf_thread_map__put(threads);
diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c
index 8d04f6edb004..e6501791c505 100644
--- a/tools/perf/tests/mmap-basic.c
+++ b/tools/perf/tests/mmap-basic.c
@@ -94,7 +94,7 @@ static int test__basic_mmap(struct test_suite *test __maybe_unused, int subtest
/* Permissions failure, flag the failure as a skip. */
err = TEST_SKIP;
}
- goto out_delete_evlist;
+ goto out_put_evlist;
}
evsels[i]->core.attr.wakeup_events = 1;
@@ -106,7 +106,7 @@ static int test__basic_mmap(struct test_suite *test __maybe_unused, int subtest
pr_debug("failed to open counter: %s, "
"tweak /proc/sys/kernel/perf_event_paranoid?\n",
str_error_r(errno, sbuf, sizeof(sbuf)));
- goto out_delete_evlist;
+ goto out_put_evlist;
}
nr_events[i] = 0;
@@ -116,7 +116,7 @@ static int test__basic_mmap(struct test_suite *test __maybe_unused, int subtest
if (evlist__mmap(evlist, 128) < 0) {
pr_debug("failed to mmap events: %d (%s)\n", errno,
str_error_r(errno, sbuf, sizeof(sbuf)));
- goto out_delete_evlist;
+ goto out_put_evlist;
}
for (i = 0; i < nsyscalls; ++i)
@@ -134,7 +134,7 @@ static int test__basic_mmap(struct test_suite *test __maybe_unused, int subtest
if (event->header.type != PERF_RECORD_SAMPLE) {
pr_debug("unexpected %s event\n",
perf_event__name(event->header.type));
- goto out_delete_evlist;
+ goto out_put_evlist;
}
perf_sample__init(&sample, /*all=*/false);
@@ -142,7 +142,7 @@ static int test__basic_mmap(struct test_suite *test __maybe_unused, int subtest
if (err) {
pr_err("Can't parse sample, err = %d\n", err);
perf_sample__exit(&sample);
- goto out_delete_evlist;
+ goto out_put_evlist;
}
err = -1;
@@ -151,7 +151,7 @@ static int test__basic_mmap(struct test_suite *test __maybe_unused, int subtest
if (evsel == NULL) {
pr_debug("event with id %" PRIu64
" doesn't map to an evsel\n", sample.id);
- goto out_delete_evlist;
+ goto out_put_evlist;
}
nr_events[evsel->core.idx]++;
perf_mmap__consume(&md->core);
@@ -166,12 +166,12 @@ static int test__basic_mmap(struct test_suite *test __maybe_unused, int subtest
expected_nr_events[evsel->core.idx],
evsel__name(evsel), nr_events[evsel->core.idx]);
err = -1;
- goto out_delete_evlist;
+ goto out_put_evlist;
}
}
-out_delete_evlist:
- evlist__delete(evlist);
+out_put_evlist:
+ evlist__put(evlist);
out_free_cpus:
perf_cpu_map__put(cpus);
out_free_threads:
diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c
index 2a139d2781a8..3ff595c7a86a 100644
--- a/tools/perf/tests/openat-syscall-tp-fields.c
+++ b/tools/perf/tests/openat-syscall-tp-fields.c
@@ -51,7 +51,7 @@ static int test__syscall_openat_tp_fields(struct test_suite *test __maybe_unused
if (IS_ERR(evsel)) {
pr_debug("%s: evsel__newtp\n", __func__);
ret = PTR_ERR(evsel) == -EACCES ? TEST_SKIP : TEST_FAIL;
- goto out_delete_evlist;
+ goto out_put_evlist;
}
evlist__add(evlist, evsel);
@@ -59,7 +59,7 @@ static int test__syscall_openat_tp_fields(struct test_suite *test __maybe_unused
err = evlist__create_maps(evlist, &opts.target);
if (err < 0) {
pr_debug("%s: evlist__create_maps\n", __func__);
- goto out_delete_evlist;
+ goto out_put_evlist;
}
evsel__config(evsel, &opts, NULL);
@@ -70,14 +70,14 @@ static int test__syscall_openat_tp_fields(struct test_suite *test __maybe_unused
if (err < 0) {
pr_debug("perf_evlist__open: %s\n",
str_error_r(errno, sbuf, sizeof(sbuf)));
- goto out_delete_evlist;
+ goto out_put_evlist;
}
err = evlist__mmap(evlist, UINT_MAX);
if (err < 0) {
pr_debug("evlist__mmap: %s\n",
str_error_r(errno, sbuf, sizeof(sbuf)));
- goto out_delete_evlist;
+ goto out_put_evlist;
}
evlist__enable(evlist);
@@ -115,7 +115,7 @@ static int test__syscall_openat_tp_fields(struct test_suite *test __maybe_unused
if (err) {
pr_debug("Can't parse sample, err = %d\n", err);
perf_sample__exit(&sample);
- goto out_delete_evlist;
+ goto out_put_evlist;
}
tp_flags = evsel__intval(evsel, &sample, "flags");
@@ -123,7 +123,7 @@ static int test__syscall_openat_tp_fields(struct test_suite *test __maybe_unused
if (flags != tp_flags) {
pr_debug("%s: Expected flags=%#x, got %#x\n",
__func__, flags, tp_flags);
- goto out_delete_evlist;
+ goto out_put_evlist;
}
goto out_ok;
@@ -136,13 +136,13 @@ static int test__syscall_openat_tp_fields(struct test_suite *test __maybe_unused
if (++nr_polls > 5) {
pr_debug("%s: no events!\n", __func__);
- goto out_delete_evlist;
+ goto out_put_evlist;
}
}
out_ok:
ret = TEST_OK;
-out_delete_evlist:
- evlist__delete(evlist);
+out_put_evlist:
+ evlist__put(evlist);
out:
return ret;
}
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
index 05c3e899b425..19dc7b7475d2 100644
--- a/tools/perf/tests/parse-events.c
+++ b/tools/perf/tests/parse-events.c
@@ -2568,7 +2568,7 @@ static int test_event(const struct evlist_test *e)
ret = e->check(evlist);
}
parse_events_error__exit(&err);
- evlist__delete(evlist);
+ evlist__put(evlist);
return ret;
}
@@ -2594,7 +2594,7 @@ static int test_event_fake_pmu(const char *str)
}
parse_events_error__exit(&err);
- evlist__delete(evlist);
+ evlist__put(evlist);
return ret;
}
diff --git a/tools/perf/tests/parse-metric.c b/tools/perf/tests/parse-metric.c
index 7c7f489a5eb0..3f0ec839c056 100644
--- a/tools/perf/tests/parse-metric.c
+++ b/tools/perf/tests/parse-metric.c
@@ -84,7 +84,7 @@ static int __compute_metric(const char *name, struct value *vals,
cpus = perf_cpu_map__new("0");
if (!cpus) {
- evlist__delete(evlist);
+ evlist__put(evlist);
return -ENOMEM;
}
@@ -113,7 +113,7 @@ static int __compute_metric(const char *name, struct value *vals,
/* ... cleanup. */
evlist__free_stats(evlist);
perf_cpu_map__put(cpus);
- evlist__delete(evlist);
+ evlist__put(evlist);
return err;
}
diff --git a/tools/perf/tests/parse-no-sample-id-all.c b/tools/perf/tests/parse-no-sample-id-all.c
index 50e68b7d43aa..d5a8d065809e 100644
--- a/tools/perf/tests/parse-no-sample-id-all.c
+++ b/tools/perf/tests/parse-no-sample-id-all.c
@@ -49,7 +49,7 @@ static int process_events(union perf_event **events, size_t count)
for (i = 0; i < count && !err; i++)
err = process_event(&evlist, events[i]);
- evlist__delete(evlist);
+ evlist__put(evlist);
return err;
}
diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c
index ad44cc68820b..f95752b2ed1c 100644
--- a/tools/perf/tests/perf-record.c
+++ b/tools/perf/tests/perf-record.c
@@ -105,7 +105,7 @@ static int test__PERF_RECORD(struct test_suite *test __maybe_unused, int subtest
err = evlist__create_maps(evlist, &opts.target);
if (err < 0) {
pr_debug("Not enough memory to create thread/cpu maps\n");
- goto out_delete_evlist;
+ goto out_put_evlist;
}
/*
@@ -117,7 +117,7 @@ static int test__PERF_RECORD(struct test_suite *test __maybe_unused, int subtest
err = evlist__prepare_workload(evlist, &opts.target, argv, false, NULL);
if (err < 0) {
pr_debug("Couldn't run the workload!\n");
- goto out_delete_evlist;
+ goto out_put_evlist;
}
/*
@@ -134,7 +134,7 @@ static int test__PERF_RECORD(struct test_suite *test __maybe_unused, int subtest
pr_debug("sched__get_first_possible_cpu: %s\n",
str_error_r(errno, sbuf, sizeof(sbuf)));
evlist__cancel_workload(evlist);
- goto out_delete_evlist;
+ goto out_put_evlist;
}
cpu = err;
@@ -146,7 +146,7 @@ static int test__PERF_RECORD(struct test_suite *test __maybe_unused, int subtest
pr_debug("sched_setaffinity: %s\n",
str_error_r(errno, sbuf, sizeof(sbuf)));
evlist__cancel_workload(evlist);
- goto out_delete_evlist;
+ goto out_put_evlist;
}
/*
@@ -158,7 +158,7 @@ static int test__PERF_RECORD(struct test_suite *test __maybe_unused, int subtest
pr_debug("perf_evlist__open: %s\n",
str_error_r(errno, sbuf, sizeof(sbuf)));
evlist__cancel_workload(evlist);
- goto out_delete_evlist;
+ goto out_put_evlist;
}
/*
@@ -171,7 +171,7 @@ static int test__PERF_RECORD(struct test_suite *test __maybe_unused, int subtest
pr_debug("evlist__mmap: %s\n",
str_error_r(errno, sbuf, sizeof(sbuf)));
evlist__cancel_workload(evlist);
- goto out_delete_evlist;
+ goto out_put_evlist;
}
/*
@@ -209,7 +209,7 @@ static int test__PERF_RECORD(struct test_suite *test __maybe_unused, int subtest
if (verbose > 0)
perf_event__fprintf(event, NULL, stderr);
pr_debug("Couldn't parse sample\n");
- goto out_delete_evlist;
+ goto out_put_evlist;
}
if (verbose > 0) {
@@ -350,9 +350,9 @@ static int test__PERF_RECORD(struct test_suite *test __maybe_unused, int subtest
pr_debug("PERF_RECORD_MMAP for %s missing!\n", "[vdso]");
++errs;
}
-out_delete_evlist:
+out_put_evlist:
CPU_FREE(cpu_mask);
- evlist__delete(evlist);
+ evlist__put(evlist);
out:
perf_sample__exit(&sample);
if (err == -EACCES)
diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c
index cca41bd37ae3..d3538fa20af3 100644
--- a/tools/perf/tests/perf-time-to-tsc.c
+++ b/tools/perf/tests/perf-time-to-tsc.c
@@ -201,7 +201,7 @@ static int test__perf_time_to_tsc(struct test_suite *test __maybe_unused, int su
err = TEST_OK;
out_err:
- evlist__delete(evlist);
+ evlist__put(evlist);
perf_cpu_map__put(cpus);
perf_thread_map__put(threads);
return err;
diff --git a/tools/perf/tests/pfm.c b/tools/perf/tests/pfm.c
index fca4a86452df..8d19b1bfecbc 100644
--- a/tools/perf/tests/pfm.c
+++ b/tools/perf/tests/pfm.c
@@ -80,7 +80,7 @@ static int test__pfm_events(struct test_suite *test __maybe_unused,
evlist__nr_groups(evlist),
0);
- evlist__delete(evlist);
+ evlist__put(evlist);
}
return 0;
}
@@ -165,7 +165,7 @@ static int test__pfm_group(struct test_suite *test __maybe_unused,
evlist__nr_groups(evlist),
table[i].nr_groups);
- evlist__delete(evlist);
+ evlist__put(evlist);
}
return 0;
}
diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c
index a99716862168..236bbbad5773 100644
--- a/tools/perf/tests/pmu-events.c
+++ b/tools/perf/tests/pmu-events.c
@@ -797,7 +797,7 @@ static int check_parse_id(const char *id, struct parse_events_error *error)
/*warn_if_reordered=*/true, /*fake_tp=*/false);
free(dup);
- evlist__delete(evlist);
+ evlist__put(evlist);
return ret;
}
@@ -844,7 +844,7 @@ static int test__parsing_callback(const struct pmu_metric *pm,
cpus = perf_cpu_map__new("0");
if (!cpus) {
- evlist__delete(evlist);
+ evlist__put(evlist);
return -ENOMEM;
}
@@ -899,7 +899,7 @@ static int test__parsing_callback(const struct pmu_metric *pm,
/* ... cleanup. */
evlist__free_stats(evlist);
perf_cpu_map__put(cpus);
- evlist__delete(evlist);
+ evlist__put(evlist);
return err;
}
diff --git a/tools/perf/tests/pmu.c b/tools/perf/tests/pmu.c
index 0ebf2d7b2cb4..3d931c1f99dd 100644
--- a/tools/perf/tests/pmu.c
+++ b/tools/perf/tests/pmu.c
@@ -287,7 +287,7 @@ static int test__pmu_usr_chgs(struct test_suite *test __maybe_unused, int subtes
ret = TEST_OK;
err_out:
parse_events_terms__exit(&terms);
- evlist__delete(evlist);
+ evlist__put(evlist);
test_pmu_put(dir, pmu);
return ret;
}
@@ -339,7 +339,7 @@ static int test__pmu_events(struct test_suite *test __maybe_unused, int subtest
ret = TEST_OK;
err_out:
parse_events_error__exit(&err);
- evlist__delete(evlist);
+ evlist__put(evlist);
test_pmu_put(dir, pmu);
return ret;
}
diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c
index b6e46975379c..bb6b62cf51d1 100644
--- a/tools/perf/tests/sw-clock.c
+++ b/tools/perf/tests/sw-clock.c
@@ -59,7 +59,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
evsel = evsel__new(&attr);
if (evsel == NULL) {
pr_debug("evsel__new\n");
- goto out_delete_evlist;
+ goto out_put_evlist;
}
evlist__add(evlist, evsel);
@@ -68,7 +68,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
if (!cpus || !threads) {
err = -ENOMEM;
pr_debug("Not enough memory to create thread/cpu maps\n");
- goto out_delete_evlist;
+ goto out_put_evlist;
}
perf_evlist__set_maps(&evlist->core, cpus, threads);
@@ -80,14 +80,14 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
pr_debug("Couldn't open evlist: %s\nHint: check %s, using %" PRIu64 " in this test.\n",
str_error_r(errno, sbuf, sizeof(sbuf)),
knob, (u64)attr.sample_freq);
- goto out_delete_evlist;
+ goto out_put_evlist;
}
err = evlist__mmap(evlist, 128);
if (err < 0) {
pr_debug("failed to mmap event: %d (%s)\n", errno,
str_error_r(errno, sbuf, sizeof(sbuf)));
- goto out_delete_evlist;
+ goto out_put_evlist;
}
evlist__enable(evlist);
@@ -113,7 +113,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
if (err < 0) {
pr_debug("Error during parse sample\n");
perf_sample__exit(&sample);
- goto out_delete_evlist;
+ goto out_put_evlist;
}
total_periods += sample.period;
@@ -131,10 +131,10 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
err = -1;
}
-out_delete_evlist:
+out_put_evlist:
perf_cpu_map__put(cpus);
perf_thread_map__put(threads);
- evlist__delete(evlist);
+ evlist__put(evlist);
return err;
}
diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c
index 72a8289e846d..306151c83af8 100644
--- a/tools/perf/tests/switch-tracking.c
+++ b/tools/perf/tests/switch-tracking.c
@@ -579,7 +579,7 @@ static int test__switch_tracking(struct test_suite *test __maybe_unused, int sub
out:
if (evlist) {
evlist__disable(evlist);
- evlist__delete(evlist);
+ evlist__put(evlist);
}
perf_cpu_map__put(cpus);
perf_thread_map__put(threads);
diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c
index 4053ff2813bb..a46650b10689 100644
--- a/tools/perf/tests/task-exit.c
+++ b/tools/perf/tests/task-exit.c
@@ -74,7 +74,7 @@ static int test__task_exit(struct test_suite *test __maybe_unused, int subtest _
if (!cpus || !threads) {
err = -ENOMEM;
pr_debug("Not enough memory to create thread/cpu maps\n");
- goto out_delete_evlist;
+ goto out_put_evlist;
}
perf_evlist__set_maps(&evlist->core, cpus, threads);
@@ -82,7 +82,7 @@ static int test__task_exit(struct test_suite *test __maybe_unused, int subtest _
err = evlist__prepare_workload(evlist, &target, argv, false, workload_exec_failed_signal);
if (err < 0) {
pr_debug("Couldn't run the workload!\n");
- goto out_delete_evlist;
+ goto out_put_evlist;
}
evsel = evlist__first(evlist);
@@ -101,14 +101,14 @@ static int test__task_exit(struct test_suite *test __maybe_unused, int subtest _
if (err < 0) {
pr_debug("Couldn't open the evlist: %s\n",
str_error_r(-err, sbuf, sizeof(sbuf)));
- goto out_delete_evlist;
+ goto out_put_evlist;
}
if (evlist__mmap(evlist, 128) < 0) {
pr_debug("failed to mmap events: %d (%s)\n", errno,
str_error_r(errno, sbuf, sizeof(sbuf)));
err = -1;
- goto out_delete_evlist;
+ goto out_put_evlist;
}
evlist__start_workload(evlist);
@@ -133,7 +133,7 @@ static int test__task_exit(struct test_suite *test __maybe_unused, int subtest _
if (retry_count++ > 1000) {
pr_debug("Failed after retrying 1000 times\n");
err = -1;
- goto out_delete_evlist;
+ goto out_put_evlist;
}
goto retry;
@@ -144,10 +144,10 @@ static int test__task_exit(struct test_suite *test __maybe_unused, int subtest _
err = -1;
}
-out_delete_evlist:
+out_put_evlist:
perf_cpu_map__put(cpus);
perf_thread_map__put(threads);
- evlist__delete(evlist);
+ evlist__put(evlist);
return err;
}
diff --git a/tools/perf/tests/tool_pmu.c b/tools/perf/tests/tool_pmu.c
index 1e900ef92e37..e78ff9dcea97 100644
--- a/tools/perf/tests/tool_pmu.c
+++ b/tools/perf/tests/tool_pmu.c
@@ -67,7 +67,7 @@ static int do_test(enum tool_pmu_event ev, bool with_pmu)
out:
parse_events_error__exit(&err);
- evlist__delete(evlist);
+ evlist__put(evlist);
return ret;
}
diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c
index f54502ebef4b..4ecf5d750313 100644
--- a/tools/perf/tests/topology.c
+++ b/tools/perf/tests/topology.c
@@ -57,7 +57,7 @@ static int session_write_header(char *path)
!perf_session__write_header(session, session->evlist,
perf_data__fd(&data), true));
- evlist__delete(session->evlist);
+ evlist__put(session->evlist);
perf_session__delete(session);
return 0;
diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c
index 1b5664d1481f..652a45aac828 100644
--- a/tools/perf/util/cgroup.c
+++ b/tools/perf/util/cgroup.c
@@ -520,8 +520,8 @@ int evlist__expand_cgroup(struct evlist *evlist, const char *str, bool open_cgro
cgrp_event_expanded = true;
out_err:
- evlist__delete(orig_list);
- evlist__delete(tmp_list);
+ evlist__put(orig_list);
+ evlist__put(tmp_list);
metricgroup__rblist_exit(&orig_metric_events);
release_cgroup_list();
diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c
index 3b8f2df823a9..a85ae53db7c5 100644
--- a/tools/perf/util/data-convert-bt.c
+++ b/tools/perf/util/data-convert-bt.c
@@ -1363,7 +1363,7 @@ static void cleanup_events(struct perf_session *session)
zfree(&evsel->priv);
}
- evlist__delete(evlist);
+ evlist__put(evlist);
session->evlist = NULL;
}
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 35d65fe50e06..b5a7895debf5 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -75,7 +75,7 @@ int sigqueue(pid_t pid, int sig, const union sigval value);
#define FD(e, x, y) (*(int *)xyarray__entry(e->core.fd, x, y))
#define SID(e, x, y) xyarray__entry(e->core.sample_id, x, y)
-void evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus,
+static void evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus,
struct perf_thread_map *threads)
{
perf_evlist__init(&evlist->core);
@@ -88,6 +88,7 @@ void evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus,
evlist->nr_br_cntr = -1;
metricgroup__rblist_init(&evlist->metric_events);
INIT_LIST_HEAD(&evlist->deferred_samples);
+ refcount_set(&evlist->refcnt, 1);
}
struct evlist *evlist__new(void)
@@ -139,7 +140,7 @@ struct evlist *evlist__new_default(const struct target *target, bool sample_call
return evlist;
out_err:
- evlist__delete(evlist);
+ evlist__put(evlist);
return NULL;
}
@@ -148,13 +149,19 @@ struct evlist *evlist__new_dummy(void)
struct evlist *evlist = evlist__new();
if (evlist && evlist__add_dummy(evlist)) {
- evlist__delete(evlist);
+ evlist__put(evlist);
evlist = NULL;
}
return evlist;
}
+struct evlist *evlist__get(struct evlist *evlist)
+{
+ refcount_inc(&evlist->refcnt);
+ return evlist;
+}
+
/**
* evlist__set_id_pos - set the positions of event ids.
* @evlist: selected event list
@@ -193,7 +200,7 @@ static void evlist__purge(struct evlist *evlist)
evlist->core.nr_entries = 0;
}
-void evlist__exit(struct evlist *evlist)
+static void evlist__exit(struct evlist *evlist)
{
metricgroup__rblist_exit(&evlist->metric_events);
event_enable_timer__exit(&evlist->eet);
@@ -202,11 +209,14 @@ void evlist__exit(struct evlist *evlist)
perf_evlist__exit(&evlist->core);
}
-void evlist__delete(struct evlist *evlist)
+void evlist__put(struct evlist *evlist)
{
if (evlist == NULL)
return;
+ if (!refcount_dec_and_test(&evlist->refcnt))
+ return;
+
evlist__free_stats(evlist);
evlist__munmap(evlist);
evlist__close(evlist);
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index e54761c670b6..a9820a6aad5b 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -61,6 +61,7 @@ struct event_enable_timer;
struct evlist {
struct perf_evlist core;
+ refcount_t refcnt;
bool enabled;
bool no_affinity;
int id_pos;
@@ -109,10 +110,8 @@ struct evsel_str_handler {
struct evlist *evlist__new(void);
struct evlist *evlist__new_default(const struct target *target, bool sample_callchains);
struct evlist *evlist__new_dummy(void);
-void evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus,
- struct perf_thread_map *threads);
-void evlist__exit(struct evlist *evlist);
-void evlist__delete(struct evlist *evlist);
+struct evlist *evlist__get(struct evlist *evlist);
+void evlist__put(struct evlist *evlist);
void evlist__add(struct evlist *evlist, struct evsel *entry);
void evlist__remove(struct evlist *evlist, struct evsel *evsel);
diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
index 644769e92708..cf54bbbc8ddc 100644
--- a/tools/perf/util/expr.c
+++ b/tools/perf/util/expr.c
@@ -450,7 +450,7 @@ double expr__has_event(const struct expr_parse_ctx *ctx, bool compute_ids, const
ret = parse_event(tmp, id) ? 0 : 1;
}
out:
- evlist__delete(tmp);
+ evlist__put(tmp);
return ret;
}
--git a/tools/perf/util/header.c b/tools/perf/util/header.c
index f30e48eb3fc3..f9887d2fc8ed 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -4909,12 +4909,12 @@ int perf_session__read_header(struct perf_session *session)
evsel = evsel__new(&f_attr.attr);
if (evsel == NULL)
- goto out_delete_evlist;
+ goto out_put_evlist;
evsel->needs_swap = header->needs_swap;
/*
* Do it before so that if perf_evsel__alloc_id fails, this
- * entry gets purged too at evlist__delete().
+ * entry gets purged too at evlist__put().
*/
evlist__add(session->evlist, evsel);
@@ -4925,7 +4925,7 @@ int perf_session__read_header(struct perf_session *session)
* hattr->ids threads.
*/
if (perf_evsel__alloc_id(&evsel->core, 1, nr_ids))
- goto out_delete_evlist;
+ goto out_put_evlist;
lseek(fd, f_attr.ids.offset, SEEK_SET);
@@ -4944,7 +4944,7 @@ int perf_session__read_header(struct perf_session *session)
perf_file_section__process);
if (evlist__prepare_tracepoint_events(session->evlist, session->tevent.pevent))
- goto out_delete_evlist;
+ goto out_put_evlist;
#else
perf_header__process_sections(header, fd, NULL, perf_file_section__process);
#endif
@@ -4953,8 +4953,8 @@ int perf_session__read_header(struct perf_session *session)
out_errno:
return -errno;
-out_delete_evlist:
- evlist__delete(session->evlist);
+out_put_evlist:
+ evlist__put(session->evlist);
session->evlist = NULL;
return -ENOMEM;
}
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
index 4db9578efd81..191ec2d8a250 100644
--- a/tools/perf/util/metricgroup.c
+++ b/tools/perf/util/metricgroup.c
@@ -214,7 +214,7 @@ static void metric__free(struct metric *m)
zfree(&m->metric_refs);
expr__ctx_free(m->pctx);
zfree(&m->modifier);
- evlist__delete(m->evlist);
+ evlist__put(m->evlist);
free(m);
}
@@ -1335,7 +1335,7 @@ static int parse_ids(bool metric_no_merge, bool fake_pmu,
parsed_evlist = NULL;
err_out:
parse_events_error__exit(&parse_error);
- evlist__delete(parsed_evlist);
+ evlist__put(parsed_evlist);
strbuf_release(&events);
return ret;
}
@@ -1546,7 +1546,7 @@ static int parse_groups(struct evlist *perf_evlist,
if (combined_evlist) {
evlist__splice_list_tail(perf_evlist, &combined_evlist->core.entries);
- evlist__delete(combined_evlist);
+ evlist__put(combined_evlist);
}
list_for_each_entry(m, &metric_list, nd) {
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 1497e1f2a08c..f0809be63ad8 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -2316,7 +2316,7 @@ int __parse_events(struct evlist *evlist, const char *str, const char *pmu_filte
/*
* There are 2 users - builtin-record and builtin-test objects.
- * Both call evlist__delete in case of error, so we dont
+ * Both call evlist__put in case of error, so we dont
* need to bother.
*/
return ret;
@@ -2519,7 +2519,7 @@ int parse_events_option_new_evlist(const struct option *opt, const char *str, in
}
ret = parse_events_option(opt, str, unset);
if (ret) {
- evlist__delete(*args->evlistp);
+ evlist__put(*args->evlistp);
*args->evlistp = NULL;
}
diff --git a/tools/perf/util/perf_api_probe.c b/tools/perf/util/perf_api_probe.c
index e1904a330b28..f61c4ec52827 100644
--- a/tools/perf/util/perf_api_probe.c
+++ b/tools/perf/util/perf_api_probe.c
@@ -57,7 +57,7 @@ static int perf_do_probe_api(setup_probe_fn_t fn, struct perf_cpu cpu, const cha
err = 0;
out_delete:
- evlist__delete(evlist);
+ evlist__put(evlist);
return err;
}
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index 1e6c99efff90..3f0758d5bd90 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -1272,7 +1272,7 @@ static int pyrf_evsel__setup_types(void)
struct pyrf_evlist {
PyObject_HEAD
- struct evlist evlist;
+ struct evlist *evlist;
};
static int pyrf_evlist__init(struct pyrf_evlist *pevlist,
@@ -1285,15 +1285,22 @@ static int pyrf_evlist__init(struct pyrf_evlist *pevlist,
if (!PyArg_ParseTuple(args, "OO", &pcpus, &pthreads))
return -1;
+ evlist__put(pevlist->evlist);
+ pevlist->evlist = evlist__new();
+ if (!pevlist->evlist) {
+ PyErr_NoMemory();
+ return -1;
+ }
threads = ((struct pyrf_thread_map *)pthreads)->threads;
cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
- evlist__init(&pevlist->evlist, cpus, threads);
+ perf_evlist__set_maps(&pevlist->evlist->core, cpus, threads);
+
return 0;
}
static void pyrf_evlist__delete(struct pyrf_evlist *pevlist)
{
- evlist__exit(&pevlist->evlist);
+ evlist__put(pevlist->evlist);
Py_TYPE(pevlist)->tp_free((PyObject*)pevlist);
}
@@ -1302,7 +1309,7 @@ static PyObject *pyrf_evlist__all_cpus(struct pyrf_evlist *pevlist)
struct pyrf_cpu_map *pcpu_map = PyObject_New(struct pyrf_cpu_map, &pyrf_cpu_map__type);
if (pcpu_map)
- pcpu_map->cpus = perf_cpu_map__get(pevlist->evlist.core.all_cpus);
+ pcpu_map->cpus = perf_cpu_map__get(pevlist->evlist->core.all_cpus);
return (PyObject *)pcpu_map;
}
@@ -1315,7 +1322,7 @@ static PyObject *pyrf_evlist__metrics(struct pyrf_evlist *pevlist)
if (!list)
return NULL;
- for (node = rb_first_cached(&pevlist->evlist.metric_events.entries); node;
+ for (node = rb_first_cached(&pevlist->evlist->metric_events.entries); node;
node = rb_next(node)) {
struct metric_event *me = container_of(node, struct metric_event, nd);
struct list_head *pos;
@@ -1421,7 +1428,7 @@ static PyObject *pyrf_evlist__compute_metric(struct pyrf_evlist *pevlist,
if (!PyArg_ParseTuple(args, "sii", &metric, &cpu, &thread))
return NULL;
- for (node = rb_first_cached(&pevlist->evlist.metric_events.entries);
+ for (node = rb_first_cached(&pevlist->evlist->metric_events.entries);
mexp == NULL && node;
node = rb_next(node)) {
struct metric_event *me = container_of(node, struct metric_event, nd);
@@ -1437,7 +1444,7 @@ static PyObject *pyrf_evlist__compute_metric(struct pyrf_evlist *pevlist,
if (e->metric_events[0] == NULL)
continue;
- evlist__for_each_entry(&pevlist->evlist, pos2) {
+ evlist__for_each_entry(pevlist->evlist, pos2) {
if (pos2->metric_leader != e->metric_events[0])
continue;
cpu_idx = perf_cpu_map__idx(pos2->core.cpus,
@@ -1482,7 +1489,7 @@ static PyObject *pyrf_evlist__compute_metric(struct pyrf_evlist *pevlist,
static PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist,
PyObject *args, PyObject *kwargs)
{
- struct evlist *evlist = &pevlist->evlist;
+ struct evlist *evlist = pevlist->evlist;
static char *kwlist[] = { "pages", "overwrite", NULL };
int pages = 128, overwrite = false;
@@ -1502,7 +1509,7 @@ static PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist,
static PyObject *pyrf_evlist__poll(struct pyrf_evlist *pevlist,
PyObject *args, PyObject *kwargs)
{
- struct evlist *evlist = &pevlist->evlist;
+ struct evlist *evlist = pevlist->evlist;
static char *kwlist[] = { "timeout", NULL };
int timeout = -1, n;
@@ -1522,7 +1529,7 @@ static PyObject *pyrf_evlist__get_pollfd(struct pyrf_evlist *pevlist,
PyObject *args __maybe_unused,
PyObject *kwargs __maybe_unused)
{
- struct evlist *evlist = &pevlist->evlist;
+ struct evlist *evlist = pevlist->evlist;
PyObject *list = PyList_New(0);
int i;
@@ -1551,7 +1558,7 @@ static PyObject *pyrf_evlist__add(struct pyrf_evlist *pevlist,
PyObject *args,
PyObject *kwargs __maybe_unused)
{
- struct evlist *evlist = &pevlist->evlist;
+ struct evlist *evlist = pevlist->evlist;
PyObject *pevsel;
struct evsel *evsel;
@@ -1583,7 +1590,7 @@ static struct mmap *get_md(struct evlist *evlist, int cpu)
static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
PyObject *args, PyObject *kwargs)
{
- struct evlist *evlist = &pevlist->evlist;
+ struct evlist *evlist = pevlist->evlist;
union perf_event *event;
int sample_id_all = 1, cpu;
static char *kwlist[] = { "cpu", "sample_id_all", NULL };
@@ -1640,7 +1647,7 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
static PyObject *pyrf_evlist__open(struct pyrf_evlist *pevlist,
PyObject *args, PyObject *kwargs)
{
- struct evlist *evlist = &pevlist->evlist;
+ struct evlist *evlist = pevlist->evlist;
if (evlist__open(evlist) < 0) {
PyErr_SetFromErrno(PyExc_OSError);
@@ -1653,7 +1660,7 @@ static PyObject *pyrf_evlist__open(struct pyrf_evlist *pevlist,
static PyObject *pyrf_evlist__close(struct pyrf_evlist *pevlist)
{
- struct evlist *evlist = &pevlist->evlist;
+ struct evlist *evlist = pevlist->evlist;
evlist__close(evlist);
@@ -1679,7 +1686,7 @@ static PyObject *pyrf_evlist__config(struct pyrf_evlist *pevlist)
.no_buffering = true,
.no_inherit = true,
};
- struct evlist *evlist = &pevlist->evlist;
+ struct evlist *evlist = pevlist->evlist;
evlist__config(evlist, &opts, &callchain_param);
Py_INCREF(Py_None);
@@ -1688,14 +1695,14 @@ static PyObject *pyrf_evlist__config(struct pyrf_evlist *pevlist)
static PyObject *pyrf_evlist__disable(struct pyrf_evlist *pevlist)
{
- evlist__disable(&pevlist->evlist);
+ evlist__disable(pevlist->evlist);
Py_INCREF(Py_None);
return Py_None;
}
static PyObject *pyrf_evlist__enable(struct pyrf_evlist *pevlist)
{
- evlist__enable(&pevlist->evlist);
+ evlist__enable(pevlist->evlist);
Py_INCREF(Py_None);
return Py_None;
}
@@ -1786,7 +1793,23 @@ static Py_ssize_t pyrf_evlist__length(PyObject *obj)
{
struct pyrf_evlist *pevlist = (void *)obj;
- return pevlist->evlist.core.nr_entries;
+ return pevlist->evlist->core.nr_entries;
+}
+
+static PyObject *pyrf_evsel__from_evsel(struct evsel *evsel)
+{
+ struct pyrf_evsel *pevsel = PyObject_New(struct pyrf_evsel, &pyrf_evsel__type);
+
+ if (!pevsel)
+ return NULL;
+
+ memset(&pevsel->evsel, 0, sizeof(pevsel->evsel));
+ evsel__init(&pevsel->evsel, &evsel->core.attr, evsel->core.idx);
+
+ evsel__clone(&pevsel->evsel, evsel);
+ if (evsel__is_group_leader(evsel))
+ evsel__set_leader(&pevsel->evsel, &pevsel->evsel);
+ return (PyObject *)pevsel;
}
static PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i)
@@ -1794,17 +1817,16 @@ static PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i)
struct pyrf_evlist *pevlist = (void *)obj;
struct evsel *pos;
- if (i >= pevlist->evlist.core.nr_entries) {
+ if (i >= pevlist->evlist->core.nr_entries) {
PyErr_SetString(PyExc_IndexError, "Index out of range");
return NULL;
}
- evlist__for_each_entry(&pevlist->evlist, pos) {
+ evlist__for_each_entry(pevlist->evlist, pos) {
if (i-- == 0)
break;
}
-
- return Py_BuildValue("O", container_of(pos, struct pyrf_evsel, evsel));
+ return pyrf_evsel__from_evsel(pos);
}
static PyObject *pyrf_evlist__str(PyObject *self)
@@ -1816,7 +1838,7 @@ static PyObject *pyrf_evlist__str(PyObject *self)
PyObject *result;
strbuf_addstr(&sb, "evlist([");
- evlist__for_each_entry(&pevlist->evlist, pos) {
+ evlist__for_each_entry(pevlist->evlist, pos) {
if (!first)
strbuf_addch(&sb, ',');
if (!pos->pmu)
@@ -1957,157 +1979,74 @@ static PyObject *pyrf__tracepoint(struct pyrf_evsel *pevsel,
return PyLong_FromLong(tp_pmu__id(sys, name));
}
-static PyObject *pyrf_evsel__from_evsel(struct evsel *evsel)
-{
- struct pyrf_evsel *pevsel = PyObject_New(struct pyrf_evsel, &pyrf_evsel__type);
-
- if (!pevsel)
- return NULL;
-
- memset(&pevsel->evsel, 0, sizeof(pevsel->evsel));
- evsel__init(&pevsel->evsel, &evsel->core.attr, evsel->core.idx);
-
- evsel__clone(&pevsel->evsel, evsel);
- if (evsel__is_group_leader(evsel))
- evsel__set_leader(&pevsel->evsel, &pevsel->evsel);
- return (PyObject *)pevsel;
-}
-
-static int evlist__pos(struct evlist *evlist, struct evsel *evsel)
-{
- struct evsel *pos;
- int idx = 0;
-
- evlist__for_each_entry(evlist, pos) {
- if (evsel == pos)
- return idx;
- idx++;
- }
- return -1;
-}
-
-static struct evsel *evlist__at(struct evlist *evlist, int idx)
-{
- struct evsel *pos;
- int idx2 = 0;
-
- evlist__for_each_entry(evlist, pos) {
- if (idx == idx2)
- return pos;
- idx2++;
- }
- return NULL;
-}
-
static PyObject *pyrf_evlist__from_evlist(struct evlist *evlist)
{
struct pyrf_evlist *pevlist = PyObject_New(struct pyrf_evlist, &pyrf_evlist__type);
- struct evsel *pos;
- struct rb_node *node;
if (!pevlist)
return NULL;
- memset(&pevlist->evlist, 0, sizeof(pevlist->evlist));
- evlist__init(&pevlist->evlist, evlist->core.all_cpus, evlist->core.threads);
- evlist__for_each_entry(evlist, pos) {
- struct pyrf_evsel *pevsel = (void *)pyrf_evsel__from_evsel(pos);
-
- evlist__add(&pevlist->evlist, &pevsel->evsel);
- }
- evlist__for_each_entry(&pevlist->evlist, pos) {
- struct evsel *leader = evsel__leader(pos);
-
- if (pos != leader) {
- int idx = evlist__pos(evlist, leader);
-
- if (idx >= 0)
- evsel__set_leader(pos, evlist__at(&pevlist->evlist, idx));
- else if (leader == NULL)
- evsel__set_leader(pos, pos);
- }
-
- leader = pos->metric_leader;
-
- if (pos != leader) {
- int idx = evlist__pos(evlist, leader);
-
- if (idx >= 0)
- pos->metric_leader = evlist__at(&pevlist->evlist, idx);
- else if (leader == NULL)
- pos->metric_leader = pos;
- }
- }
- metricgroup__copy_metric_events(&pevlist->evlist, /*cgrp=*/NULL,
- &pevlist->evlist.metric_events,
- &evlist->metric_events);
- for (node = rb_first_cached(&pevlist->evlist.metric_events.entries); node;
- node = rb_next(node)) {
- struct metric_event *me = container_of(node, struct metric_event, nd);
- struct list_head *mpos;
- int idx = evlist__pos(evlist, me->evsel);
-
- if (idx >= 0)
- me->evsel = evlist__at(&pevlist->evlist, idx);
- list_for_each(mpos, &me->head) {
- struct metric_expr *e = container_of(mpos, struct metric_expr, nd);
-
- for (int j = 0; e->metric_events[j]; j++) {
- idx = evlist__pos(evlist, e->metric_events[j]);
- if (idx >= 0)
- e->metric_events[j] = evlist__at(&pevlist->evlist, idx);
- }
- }
- }
+ pevlist->evlist = evlist__get(evlist);
return (PyObject *)pevlist;
}
static PyObject *pyrf__parse_events(PyObject *self, PyObject *args)
{
const char *input;
- struct evlist evlist = {};
+ struct evlist *evlist = evlist__new();
struct parse_events_error err;
PyObject *result;
PyObject *pcpus = NULL, *pthreads = NULL;
struct perf_cpu_map *cpus;
struct perf_thread_map *threads;
- if (!PyArg_ParseTuple(args, "s|OO", &input, &pcpus, &pthreads))
+ if (!evlist)
+ return PyErr_NoMemory();
+
+ if (!PyArg_ParseTuple(args, "s|OO", &input, &pcpus, &pthreads)) {
+ evlist__put(evlist);
return NULL;
+ }
threads = pthreads ? ((struct pyrf_thread_map *)pthreads)->threads : NULL;
cpus = pcpus ? ((struct pyrf_cpu_map *)pcpus)->cpus : NULL;
parse_events_error__init(&err);
- evlist__init(&evlist, cpus, threads);
- if (parse_events(&evlist, input, &err)) {
+ perf_evlist__set_maps(&evlist->core, cpus, threads);
+ if (parse_events(evlist, input, &err)) {
parse_events_error__print(&err, input);
PyErr_SetFromErrno(PyExc_OSError);
+ evlist__put(evlist);
return NULL;
}
- result = pyrf_evlist__from_evlist(&evlist);
- evlist__exit(&evlist);
+ result = pyrf_evlist__from_evlist(evlist);
+ evlist__put(evlist);
return result;
}
static PyObject *pyrf__parse_metrics(PyObject *self, PyObject *args)
{
const char *input, *pmu = NULL;
- struct evlist evlist = {};
+ struct evlist *evlist = evlist__new();
PyObject *result;
PyObject *pcpus = NULL, *pthreads = NULL;
struct perf_cpu_map *cpus;
struct perf_thread_map *threads;
int ret;
- if (!PyArg_ParseTuple(args, "s|sOO", &input, &pmu, &pcpus, &pthreads))
+ if (!evlist)
+ return PyErr_NoMemory();
+
+ if (!PyArg_ParseTuple(args, "s|sOO", &input, &pmu, &pcpus, &pthreads)) {
+ evlist__put(evlist);
return NULL;
+ }
threads = pthreads ? ((struct pyrf_thread_map *)pthreads)->threads : NULL;
cpus = pcpus ? ((struct pyrf_cpu_map *)pcpus)->cpus : NULL;
- evlist__init(&evlist, cpus, threads);
- ret = metricgroup__parse_groups(&evlist, pmu ?: "all", input,
+ perf_evlist__set_maps(&evlist->core, cpus, threads);
+ ret = metricgroup__parse_groups(evlist, pmu ?: "all", input,
/*metric_no_group=*/ false,
/*metric_no_merge=*/ false,
/*metric_no_threshold=*/ true,
@@ -2115,12 +2054,13 @@ static PyObject *pyrf__parse_metrics(PyObject *self, PyObject *args)
/*system_wide=*/true,
/*hardware_aware_grouping=*/ false);
if (ret) {
+ evlist__put(evlist);
errno = -ret;
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
- result = pyrf_evlist__from_evlist(&evlist);
- evlist__exit(&evlist);
+ result = pyrf_evlist__from_evlist(evlist);
+ evlist__put(evlist);
return result;
}
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c
index e867de8ddaaa..8a5fc7d5e43c 100644
--- a/tools/perf/util/record.c
+++ b/tools/perf/util/record.c
@@ -264,7 +264,7 @@ bool evlist__can_select_event(struct evlist *evlist, const char *str)
ret = true;
out_delete:
- evlist__delete(temp_evlist);
+ evlist__put(temp_evlist);
return ret;
}
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index fe0de2a0277f..1ac6cd43c38b 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -264,7 +264,7 @@ void perf_session__delete(struct perf_session *session)
machines__exit(&session->machines);
if (session->data) {
if (perf_data__is_read(session->data))
- evlist__delete(session->evlist);
+ evlist__put(session->evlist);
perf_data__close(session->data);
}
#ifdef HAVE_LIBTRACEEVENT
diff --git a/tools/perf/util/sideband_evlist.c b/tools/perf/util/sideband_evlist.c
index 388846f17bc1..b84a5463e039 100644
--- a/tools/perf/util/sideband_evlist.c
+++ b/tools/perf/util/sideband_evlist.c
@@ -102,7 +102,7 @@ int evlist__start_sb_thread(struct evlist *evlist, struct target *target)
return 0;
if (evlist__create_maps(evlist, target))
- goto out_delete_evlist;
+ goto out_put_evlist;
if (evlist->core.nr_entries > 1) {
bool can_sample_identifier = perf_can_sample_identifier();
@@ -116,25 +116,25 @@ int evlist__start_sb_thread(struct evlist *evlist, struct target *target)
evlist__for_each_entry(evlist, counter) {
if (evsel__open(counter, evlist->core.user_requested_cpus,
evlist->core.threads) < 0)
- goto out_delete_evlist;
+ goto out_put_evlist;
}
if (evlist__mmap(evlist, UINT_MAX))
- goto out_delete_evlist;
+ goto out_put_evlist;
evlist__for_each_entry(evlist, counter) {
if (evsel__enable(counter))
- goto out_delete_evlist;
+ goto out_put_evlist;
}
evlist->thread.done = 0;
if (pthread_create(&evlist->thread.th, NULL, perf_evlist__poll_thread, evlist))
- goto out_delete_evlist;
+ goto out_put_evlist;
return 0;
-out_delete_evlist:
- evlist__delete(evlist);
+out_put_evlist:
+ evlist__put(evlist);
evlist = NULL;
return -1;
}
@@ -145,5 +145,5 @@ void evlist__stop_sb_thread(struct evlist *evlist)
return;
evlist->thread.done = 1;
pthread_join(evlist->thread.th, NULL);
- evlist__delete(evlist);
+ evlist__put(evlist);
}
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [PATCH v6 11/59] perf evsel: Add reference count
From: Ian Rogers @ 2026-04-25 17:48 UTC (permalink / raw)
To: acme, adrian.hunter, james.clark, leo.yan, namhyung, tmricht
Cc: alice.mei.rogers, dapeng1.mi, linux-arm-kernel, linux-kernel,
linux-perf-users, mingo, peterz, Ian Rogers
In-Reply-To: <20260425174858.3922152-1-irogers@google.com>
As with evlist this a no-op for most of the perf tool. The reference
count is set to 1 at allocation, the put will see the 1, decrement it
and perform the delete. The purpose for adding the reference count is
for the python code. Prior to this change the python code would clone
evsels, but this has issues if events are opened, etc. leading to
assertion failures. With a reference count the same evsel can be used
and the reference count incremented for the python usage. To not
change the python evsel API getset functions are added for the evsel
members, no set function is provided for size as it doesn't make sense
to alter this.
Signed-off-by: Ian Rogers <irogers@google.com>
---
v2:
1. Fixed Potential Crash in pyrf_event__new : Initialized
pevent->evsel = NULL; to avoid garbage pointer dereference if
evlist__event2evsel() fails in read_on_cpu .
2. Fixed Memory Leak in pyrf_evsel__init : Added
evsel__put(pevsel->evsel) before overwriting it to handle repeated
__init__ calls.
3. Fixed Exception Contract: Added PyErr_NoMemory() when evsel__new()
fails in pyrf_evsel__init .
4. Fixed NULL Pointer Dereference on Property Access: Added a custom
tp_getattro ( pyrf_evsel__getattro ) to pyrf_evsel__type to check
if pevsel->evsel is NULL and raise a ValueError if so, covering all
property accesses.
5. Fixed Reference Count in pyrf_evlist__add : Added evsel__get(evsel)
when adding to the evlist .
6. Fixed Reference Count in pyrf_evlist__read_on_cpu : Added
evsel__get(evsel) when assigning to pevent->evsel .
---
tools/perf/builtin-trace.c | 12 +-
tools/perf/tests/evsel-tp-sched.c | 4 +-
tools/perf/tests/openat-syscall-all-cpus.c | 6 +-
tools/perf/tests/openat-syscall.c | 6 +-
tools/perf/util/bpf_counter_cgroup.c | 2 +-
tools/perf/util/cgroup.c | 2 +-
tools/perf/util/evlist.c | 2 +-
tools/perf/util/evsel.c | 26 ++-
tools/perf/util/evsel.h | 11 +-
tools/perf/util/parse-events.y | 2 +-
tools/perf/util/pfm.c | 2 +-
tools/perf/util/print-events.c | 2 +-
tools/perf/util/python.c | 231 +++++++++++++++++----
tools/perf/util/session.c | 1 +
14 files changed, 237 insertions(+), 72 deletions(-)
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index da703d762433..6ea935c13538 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -448,10 +448,10 @@ static int evsel__init_tp_ptr_field(struct evsel *evsel, struct tp_field *field,
({ struct syscall_tp *sc = __evsel__syscall_tp(evsel);\
evsel__init_tp_ptr_field(evsel, &sc->name, #name); })
-static void evsel__delete_priv(struct evsel *evsel)
+static void evsel__put_and_free_priv(struct evsel *evsel)
{
zfree(&evsel->priv);
- evsel__delete(evsel);
+ evsel__put(evsel);
}
static int evsel__init_syscall_tp(struct evsel *evsel)
@@ -531,7 +531,7 @@ static struct evsel *perf_evsel__raw_syscall_newtp(const char *direction, void *
return evsel;
out_delete:
- evsel__delete_priv(evsel);
+ evsel__put_and_free_priv(evsel);
return NULL;
}
@@ -3584,7 +3584,7 @@ static bool evlist__add_vfs_getname(struct evlist *evlist)
list_del_init(&evsel->core.node);
evsel->evlist = NULL;
- evsel__delete(evsel);
+ evsel__put(evsel);
}
return found;
@@ -3698,9 +3698,9 @@ static int trace__add_syscall_newtp(struct trace *trace)
return ret;
out_delete_sys_exit:
- evsel__delete_priv(sys_exit);
+ evsel__put_and_free_priv(sys_exit);
out_delete_sys_enter:
- evsel__delete_priv(sys_enter);
+ evsel__put_and_free_priv(sys_enter);
goto out;
}
diff --git a/tools/perf/tests/evsel-tp-sched.c b/tools/perf/tests/evsel-tp-sched.c
index 226196fb9677..9e456f88a13a 100644
--- a/tools/perf/tests/evsel-tp-sched.c
+++ b/tools/perf/tests/evsel-tp-sched.c
@@ -64,7 +64,7 @@ static int test__perf_evsel__tp_sched_test(struct test_suite *test __maybe_unuse
if (evsel__test_field(evsel, "next_prio", 4, true))
ret = TEST_FAIL;
- evsel__delete(evsel);
+ evsel__put(evsel);
evsel = evsel__newtp("sched", "sched_wakeup");
@@ -85,7 +85,7 @@ static int test__perf_evsel__tp_sched_test(struct test_suite *test __maybe_unuse
if (evsel__test_field(evsel, "target_cpu", 4, true))
ret = TEST_FAIL;
- evsel__delete(evsel);
+ evsel__put(evsel);
return ret;
}
diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c
index 0be43f8db3bd..cc63df2b3bc5 100644
--- a/tools/perf/tests/openat-syscall-all-cpus.c
+++ b/tools/perf/tests/openat-syscall-all-cpus.c
@@ -59,7 +59,7 @@ static int test__openat_syscall_event_on_all_cpus(struct test_suite *test __mayb
"tweak /proc/sys/kernel/perf_event_paranoid?\n",
str_error_r(errno, sbuf, sizeof(sbuf)));
err = TEST_SKIP;
- goto out_evsel_delete;
+ goto out_evsel_put;
}
perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
@@ -116,8 +116,8 @@ static int test__openat_syscall_event_on_all_cpus(struct test_suite *test __mayb
evsel__free_counts(evsel);
out_close_fd:
perf_evsel__close_fd(&evsel->core);
-out_evsel_delete:
- evsel__delete(evsel);
+out_evsel_put:
+ evsel__put(evsel);
out_cpu_map_delete:
perf_cpu_map__put(cpus);
out_thread_map_delete:
diff --git a/tools/perf/tests/openat-syscall.c b/tools/perf/tests/openat-syscall.c
index b54cbe5f1808..9f16f0dd3a29 100644
--- a/tools/perf/tests/openat-syscall.c
+++ b/tools/perf/tests/openat-syscall.c
@@ -42,7 +42,7 @@ static int test__openat_syscall_event(struct test_suite *test __maybe_unused,
"tweak /proc/sys/kernel/perf_event_paranoid?\n",
str_error_r(errno, sbuf, sizeof(sbuf)));
err = TEST_SKIP;
- goto out_evsel_delete;
+ goto out_evsel_put;
}
for (i = 0; i < nr_openat_calls; ++i) {
@@ -64,8 +64,8 @@ static int test__openat_syscall_event(struct test_suite *test __maybe_unused,
err = TEST_OK;
out_close_fd:
perf_evsel__close_fd(&evsel->core);
-out_evsel_delete:
- evsel__delete(evsel);
+out_evsel_put:
+ evsel__put(evsel);
out_thread_map_delete:
perf_thread_map__put(threads);
return err;
diff --git a/tools/perf/util/bpf_counter_cgroup.c b/tools/perf/util/bpf_counter_cgroup.c
index 519fee3dc3d0..339df94ef438 100644
--- a/tools/perf/util/bpf_counter_cgroup.c
+++ b/tools/perf/util/bpf_counter_cgroup.c
@@ -316,7 +316,7 @@ static int bperf_cgrp__destroy(struct evsel *evsel)
return 0;
bperf_cgroup_bpf__destroy(skel);
- evsel__delete(cgrp_switch); // it'll destroy on_switch progs too
+ evsel__put(cgrp_switch); // it'll destroy on_switch progs too
return 0;
}
diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c
index 652a45aac828..914744724467 100644
--- a/tools/perf/util/cgroup.c
+++ b/tools/perf/util/cgroup.c
@@ -469,7 +469,7 @@ int evlist__expand_cgroup(struct evlist *evlist, const char *str, bool open_cgro
/* copy the list and set to the new cgroup. */
evlist__for_each_entry(orig_list, pos) {
- struct evsel *evsel = evsel__clone(/*dest=*/NULL, pos);
+ struct evsel *evsel = evsel__clone(pos);
if (evsel == NULL)
goto out_err;
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index b5a7895debf5..a362f338f104 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -194,7 +194,7 @@ static void evlist__purge(struct evlist *evlist)
evlist__for_each_entry_safe(evlist, n, pos) {
list_del_init(&pos->core.node);
pos->evlist = NULL;
- evsel__delete(pos);
+ evsel__put(pos);
}
evlist->core.nr_entries = 0;
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index e03727d395e9..a54aae079c22 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -388,10 +388,11 @@ bool evsel__is_function_event(struct evsel *evsel)
#undef FUNCTION_EVENT
}
-void evsel__init(struct evsel *evsel,
+static void evsel__init(struct evsel *evsel,
struct perf_event_attr *attr, int idx)
{
perf_evsel__init(&evsel->core, attr, idx);
+ refcount_set(&evsel->refcnt, 1);
evsel->tracking = !idx;
evsel->unit = strdup("");
evsel->scale = 1.0;
@@ -472,7 +473,7 @@ static int evsel__copy_config_terms(struct evsel *dst, struct evsel *src)
* The assumption is that @orig is not configured nor opened yet.
* So we only care about the attributes that can be set while it's parsed.
*/
-struct evsel *evsel__clone(struct evsel *dest, struct evsel *orig)
+struct evsel *evsel__clone(struct evsel *orig)
{
struct evsel *evsel;
@@ -485,11 +486,7 @@ struct evsel *evsel__clone(struct evsel *dest, struct evsel *orig)
if (orig->bpf_obj)
return NULL;
- if (dest)
- evsel = dest;
- else
- evsel = evsel__new(&orig->core.attr);
-
+ evsel = evsel__new(&orig->core.attr);
if (evsel == NULL)
return NULL;
@@ -574,7 +571,7 @@ struct evsel *evsel__clone(struct evsel *dest, struct evsel *orig)
return evsel;
out_err:
- evsel__delete(evsel);
+ evsel__put(evsel);
return NULL;
}
@@ -633,6 +630,12 @@ struct evsel *evsel__newtp_idx(const char *sys, const char *name, int idx, bool
return ERR_PTR(err);
}
+struct evsel *evsel__get(struct evsel *evsel)
+{
+ refcount_inc(&evsel->refcnt);
+ return evsel;
+}
+
#ifdef HAVE_LIBTRACEEVENT
struct tep_event *evsel__tp_format(struct evsel *evsel)
{
@@ -1857,7 +1860,7 @@ void evsel__set_priv_destructor(void (*destructor)(void *priv))
evsel__priv_destructor = destructor;
}
-void evsel__exit(struct evsel *evsel)
+static void evsel__exit(struct evsel *evsel)
{
assert(list_empty(&evsel->core.node));
assert(evsel->evlist == NULL);
@@ -1892,11 +1895,14 @@ void evsel__exit(struct evsel *evsel)
xyarray__delete(evsel->start_times);
}
-void evsel__delete(struct evsel *evsel)
+void evsel__put(struct evsel *evsel)
{
if (!evsel)
return;
+ if (!refcount_dec_and_test(&evsel->refcnt))
+ return;
+
evsel__exit(evsel);
free(evsel);
}
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index b099c8e5dd86..35b1bbca9036 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -6,6 +6,7 @@
#include <linux/list.h>
#include <linux/perf_event.h>
+#include <linux/refcount.h>
#include <linux/types.h>
#include <sys/types.h>
@@ -47,6 +48,7 @@ typedef int (evsel__sb_cb_t)(union perf_event *event, void *data);
struct evsel {
struct perf_evsel core;
struct evlist *evlist;
+ refcount_t refcnt;
off_t id_offset;
int id_pos;
int is_pos;
@@ -262,7 +264,7 @@ static inline struct evsel *evsel__new(struct perf_event_attr *attr)
return evsel__new_idx(attr, 0);
}
-struct evsel *evsel__clone(struct evsel *dest, struct evsel *orig);
+struct evsel *evsel__clone(struct evsel *orig);
int copy_config_terms(struct list_head *dst, struct list_head *src);
void free_config_terms(struct list_head *config_terms);
@@ -277,14 +279,13 @@ static inline struct evsel *evsel__newtp(const char *sys, const char *name)
return evsel__newtp_idx(sys, name, 0, true);
}
+struct evsel *evsel__get(struct evsel *evsel);
+void evsel__put(struct evsel *evsel);
+
#ifdef HAVE_LIBTRACEEVENT
struct tep_event *evsel__tp_format(struct evsel *evsel);
#endif
-void evsel__init(struct evsel *evsel, struct perf_event_attr *attr, int idx);
-void evsel__exit(struct evsel *evsel);
-void evsel__delete(struct evsel *evsel);
-
void evsel__set_priv_destructor(void (*destructor)(void *priv));
struct callchain_param;
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index c194de5ec1ec..b531b1f0ceb3 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -47,7 +47,7 @@ static void free_list_evsel(struct list_head* list_evsel)
list_for_each_entry_safe(evsel, tmp, list_evsel, core.node) {
list_del_init(&evsel->core.node);
- evsel__delete(evsel);
+ evsel__put(evsel);
}
free(list_evsel);
}
diff --git a/tools/perf/util/pfm.c b/tools/perf/util/pfm.c
index d9043f4afbe7..5f53c2f68a96 100644
--- a/tools/perf/util/pfm.c
+++ b/tools/perf/util/pfm.c
@@ -159,7 +159,7 @@ static bool is_libpfm_event_supported(const char *name, struct perf_cpu_map *cpu
result = false;
evsel__close(evsel);
- evsel__delete(evsel);
+ evsel__put(evsel);
return result;
}
diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c
index cb27e2898aa0..0242243681b6 100644
--- a/tools/perf/util/print-events.c
+++ b/tools/perf/util/print-events.c
@@ -174,7 +174,7 @@ bool is_event_supported(u8 type, u64 config)
}
evsel__close(evsel);
- evsel__delete(evsel);
+ evsel__put(evsel);
}
perf_thread_map__put(tmap);
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index 3f0758d5bd90..8585ae992e6b 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -274,6 +274,7 @@ static PyMemberDef pyrf_sample_event__members[] = {
static void pyrf_sample_event__delete(struct pyrf_event *pevent)
{
+ evsel__put(pevent->evsel);
perf_sample__exit(&pevent->sample);
Py_TYPE(pevent)->tp_free((PyObject*)pevent);
}
@@ -506,8 +507,10 @@ static PyObject *pyrf_event__new(const union perf_event *event)
ptype = pyrf_event__type[event->header.type];
pevent = PyObject_New(struct pyrf_event, ptype);
- if (pevent != NULL)
+ if (pevent != NULL) {
memcpy(&pevent->event, event, event->header.size);
+ pevent->evsel = NULL;
+ }
return (PyObject *)pevent;
}
@@ -945,7 +948,7 @@ static int pyrf_counts_values__setup_types(void)
struct pyrf_evsel {
PyObject_HEAD
- struct evsel evsel;
+ struct evsel *evsel;
};
static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
@@ -1053,20 +1056,25 @@ static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
attr.sample_id_all = sample_id_all;
attr.size = sizeof(attr);
- evsel__init(&pevsel->evsel, &attr, idx);
+ evsel__put(pevsel->evsel);
+ pevsel->evsel = evsel__new(&attr);
+ if (!pevsel->evsel) {
+ PyErr_NoMemory();
+ return -1;
+ }
return 0;
}
static void pyrf_evsel__delete(struct pyrf_evsel *pevsel)
{
- evsel__exit(&pevsel->evsel);
+ evsel__put(pevsel->evsel);
Py_TYPE(pevsel)->tp_free((PyObject*)pevsel);
}
static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel,
PyObject *args, PyObject *kwargs)
{
- struct evsel *evsel = &pevsel->evsel;
+ struct evsel *evsel = pevsel->evsel;
struct perf_cpu_map *cpus = NULL;
struct perf_thread_map *threads = NULL;
PyObject *pcpus = NULL, *pthreads = NULL;
@@ -1102,7 +1110,7 @@ static PyObject *pyrf_evsel__cpus(struct pyrf_evsel *pevsel)
struct pyrf_cpu_map *pcpu_map = PyObject_New(struct pyrf_cpu_map, &pyrf_cpu_map__type);
if (pcpu_map)
- pcpu_map->cpus = perf_cpu_map__get(pevsel->evsel.core.cpus);
+ pcpu_map->cpus = perf_cpu_map__get(pevsel->evsel->core.cpus);
return (PyObject *)pcpu_map;
}
@@ -1113,7 +1121,7 @@ static PyObject *pyrf_evsel__threads(struct pyrf_evsel *pevsel)
PyObject_New(struct pyrf_thread_map, &pyrf_thread_map__type);
if (pthread_map)
- pthread_map->threads = perf_thread_map__get(pevsel->evsel.core.threads);
+ pthread_map->threads = perf_thread_map__get(pevsel->evsel->core.threads);
return (PyObject *)pthread_map;
}
@@ -1147,7 +1155,7 @@ static int evsel__ensure_counts(struct evsel *evsel)
static PyObject *pyrf_evsel__read(struct pyrf_evsel *pevsel,
PyObject *args, PyObject *kwargs)
{
- struct evsel *evsel = &pevsel->evsel;
+ struct evsel *evsel = pevsel->evsel;
int cpu = 0, cpu_idx, thread = 0, thread_idx;
struct perf_counts_values *old_count, *new_count;
struct pyrf_counts_values *count_values = PyObject_New(struct pyrf_counts_values,
@@ -1192,7 +1200,7 @@ static PyObject *pyrf_evsel__read(struct pyrf_evsel *pevsel,
static PyObject *pyrf_evsel__str(PyObject *self)
{
struct pyrf_evsel *pevsel = (void *)self;
- struct evsel *evsel = &pevsel->evsel;
+ struct evsel *evsel = pevsel->evsel;
return PyUnicode_FromFormat("evsel(%s/%s/)", evsel__pmu_name(evsel), evsel__name(evsel));
}
@@ -1225,30 +1233,183 @@ static PyMethodDef pyrf_evsel__methods[] = {
{ .ml_name = NULL, }
};
-#define evsel_member_def(member, ptype, help) \
- { #member, ptype, \
- offsetof(struct pyrf_evsel, evsel.member), \
- 0, help }
+static PyObject *pyrf_evsel__get_tracking(PyObject *self, void */*closure*/)
+{
+ struct pyrf_evsel *pevsel = (void *)self;
-#define evsel_attr_member_def(member, ptype, help) \
- { #member, ptype, \
- offsetof(struct pyrf_evsel, evsel.core.attr.member), \
- 0, help }
+ if (pevsel->evsel->tracking)
+ Py_RETURN_TRUE;
+ else
+ Py_RETURN_FALSE;
+}
-static PyMemberDef pyrf_evsel__members[] = {
- evsel_member_def(tracking, T_BOOL, "tracking event."),
- evsel_attr_member_def(type, T_UINT, "attribute type."),
- evsel_attr_member_def(size, T_UINT, "attribute size."),
- evsel_attr_member_def(config, T_ULONGLONG, "attribute config."),
- evsel_attr_member_def(sample_period, T_ULONGLONG, "attribute sample_period."),
- evsel_attr_member_def(sample_type, T_ULONGLONG, "attribute sample_type."),
- evsel_attr_member_def(read_format, T_ULONGLONG, "attribute read_format."),
- evsel_attr_member_def(wakeup_events, T_UINT, "attribute wakeup_events."),
- { .name = NULL, },
+static int pyrf_evsel__set_tracking(PyObject *self, PyObject *val, void */*closure*/)
+{
+ struct pyrf_evsel *pevsel = (void *)self;
+
+ pevsel->evsel->tracking = Py_IsTrue(val) ? true : false;
+ return 0;
+}
+
+static int pyrf_evsel__set_attr_config(PyObject *self, PyObject *val, void */*closure*/)
+{
+ struct pyrf_evsel *pevsel = (void *)self;
+
+ pevsel->evsel->core.attr.config = PyLong_AsUnsignedLongLong(val);
+ return PyErr_Occurred() ? -1 : 0;
+}
+
+static PyObject *pyrf_evsel__get_attr_config(PyObject *self, void */*closure*/)
+{
+ struct pyrf_evsel *pevsel = (void *)self;
+
+ return PyLong_FromUnsignedLongLong(pevsel->evsel->core.attr.config);
+}
+
+static int pyrf_evsel__set_attr_read_format(PyObject *self, PyObject *val, void */*closure*/)
+{
+ struct pyrf_evsel *pevsel = (void *)self;
+
+ pevsel->evsel->core.attr.read_format = PyLong_AsUnsignedLongLong(val);
+ return PyErr_Occurred() ? -1 : 0;
+}
+
+static PyObject *pyrf_evsel__get_attr_read_format(PyObject *self, void */*closure*/)
+{
+ struct pyrf_evsel *pevsel = (void *)self;
+
+ return PyLong_FromUnsignedLongLong(pevsel->evsel->core.attr.read_format);
+}
+
+static int pyrf_evsel__set_attr_sample_period(PyObject *self, PyObject *val, void */*closure*/)
+{
+ struct pyrf_evsel *pevsel = (void *)self;
+
+ pevsel->evsel->core.attr.sample_period = PyLong_AsUnsignedLongLong(val);
+ return PyErr_Occurred() ? -1 : 0;
+}
+
+static PyObject *pyrf_evsel__get_attr_sample_period(PyObject *self, void */*closure*/)
+{
+ struct pyrf_evsel *pevsel = (void *)self;
+
+ return PyLong_FromUnsignedLongLong(pevsel->evsel->core.attr.sample_period);
+}
+
+static int pyrf_evsel__set_attr_sample_type(PyObject *self, PyObject *val, void */*closure*/)
+{
+ struct pyrf_evsel *pevsel = (void *)self;
+
+ pevsel->evsel->core.attr.sample_type = PyLong_AsUnsignedLongLong(val);
+ return PyErr_Occurred() ? -1 : 0;
+}
+
+static PyObject *pyrf_evsel__get_attr_sample_type(PyObject *self, void */*closure*/)
+{
+ struct pyrf_evsel *pevsel = (void *)self;
+
+ return PyLong_FromUnsignedLongLong(pevsel->evsel->core.attr.sample_type);
+}
+
+static PyObject *pyrf_evsel__get_attr_size(PyObject *self, void */*closure*/)
+{
+ struct pyrf_evsel *pevsel = (void *)self;
+
+ return PyLong_FromUnsignedLong(pevsel->evsel->core.attr.size);
+}
+
+static int pyrf_evsel__set_attr_type(PyObject *self, PyObject *val, void */*closure*/)
+{
+ struct pyrf_evsel *pevsel = (void *)self;
+
+ pevsel->evsel->core.attr.type = PyLong_AsUnsignedLong(val);
+ return PyErr_Occurred() ? -1 : 0;
+}
+
+static PyObject *pyrf_evsel__get_attr_type(PyObject *self, void */*closure*/)
+{
+ struct pyrf_evsel *pevsel = (void *)self;
+
+ return PyLong_FromUnsignedLong(pevsel->evsel->core.attr.type);
+}
+
+static int pyrf_evsel__set_attr_wakeup_events(PyObject *self, PyObject *val, void */*closure*/)
+{
+ struct pyrf_evsel *pevsel = (void *)self;
+
+ pevsel->evsel->core.attr.wakeup_events = PyLong_AsUnsignedLong(val);
+ return PyErr_Occurred() ? -1 : 0;
+}
+
+static PyObject *pyrf_evsel__get_attr_wakeup_events(PyObject *self, void */*closure*/)
+{
+ struct pyrf_evsel *pevsel = (void *)self;
+
+ return PyLong_FromUnsignedLong(pevsel->evsel->core.attr.wakeup_events);
+}
+
+static PyGetSetDef pyrf_evsel__getset[] = {
+ {
+ .name = "tracking",
+ .get = pyrf_evsel__get_tracking,
+ .set = pyrf_evsel__set_tracking,
+ .doc = "tracking event.",
+ },
+ {
+ .name = "config",
+ .get = pyrf_evsel__get_attr_config,
+ .set = pyrf_evsel__set_attr_config,
+ .doc = "attribute config.",
+ },
+ {
+ .name = "read_format",
+ .get = pyrf_evsel__get_attr_read_format,
+ .set = pyrf_evsel__set_attr_read_format,
+ .doc = "attribute read_format.",
+ },
+ {
+ .name = "sample_period",
+ .get = pyrf_evsel__get_attr_sample_period,
+ .set = pyrf_evsel__set_attr_sample_period,
+ .doc = "attribute sample_period.",
+ },
+ {
+ .name = "sample_type",
+ .get = pyrf_evsel__get_attr_sample_type,
+ .set = pyrf_evsel__set_attr_sample_type,
+ .doc = "attribute sample_type.",
+ },
+ {
+ .name = "size",
+ .get = pyrf_evsel__get_attr_size,
+ .doc = "attribute size.",
+ },
+ {
+ .name = "type",
+ .get = pyrf_evsel__get_attr_type,
+ .set = pyrf_evsel__set_attr_type,
+ .doc = "attribute type.",
+ },
+ {
+ .name = "wakeup_events",
+ .get = pyrf_evsel__get_attr_wakeup_events,
+ .set = pyrf_evsel__set_attr_wakeup_events,
+ .doc = "attribute wakeup_events.",
+ },
+ { .name = NULL},
};
static const char pyrf_evsel__doc[] = PyDoc_STR("perf event selector list object.");
+static PyObject *pyrf_evsel__getattro(struct pyrf_evsel *pevsel, PyObject *attr_name)
+{
+ if (!pevsel->evsel) {
+ PyErr_SetString(PyExc_ValueError, "evsel not initialized");
+ return NULL;
+ }
+ return PyObject_GenericGetAttr((PyObject *) pevsel, attr_name);
+}
+
static PyTypeObject pyrf_evsel__type = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "perf.evsel",
@@ -1256,11 +1417,12 @@ static PyTypeObject pyrf_evsel__type = {
.tp_dealloc = (destructor)pyrf_evsel__delete,
.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
.tp_doc = pyrf_evsel__doc,
- .tp_members = pyrf_evsel__members,
+ .tp_getset = pyrf_evsel__getset,
.tp_methods = pyrf_evsel__methods,
.tp_init = (initproc)pyrf_evsel__init,
.tp_str = pyrf_evsel__str,
.tp_repr = pyrf_evsel__str,
+ .tp_getattro = (getattrofunc) pyrf_evsel__getattro,
};
static int pyrf_evsel__setup_types(void)
@@ -1566,9 +1728,9 @@ static PyObject *pyrf_evlist__add(struct pyrf_evlist *pevlist,
return NULL;
Py_INCREF(pevsel);
- evsel = &((struct pyrf_evsel *)pevsel)->evsel;
+ evsel = ((struct pyrf_evsel *)pevsel)->evsel;
evsel->core.idx = evlist->core.nr_entries;
- evlist__add(evlist, evsel);
+ evlist__add(evlist, evsel__get(evsel));
return Py_BuildValue("i", evlist->core.nr_entries);
}
@@ -1626,7 +1788,7 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
return Py_None;
}
- pevent->evsel = evsel;
+ pevent->evsel = evsel__get(evsel);
perf_mmap__consume(&md->core);
@@ -1803,12 +1965,7 @@ static PyObject *pyrf_evsel__from_evsel(struct evsel *evsel)
if (!pevsel)
return NULL;
- memset(&pevsel->evsel, 0, sizeof(pevsel->evsel));
- evsel__init(&pevsel->evsel, &evsel->core.attr, evsel->core.idx);
-
- evsel__clone(&pevsel->evsel, evsel);
- if (evsel__is_group_leader(evsel))
- evsel__set_leader(&pevsel->evsel, &pevsel->evsel);
+ pevsel->evsel = evsel__get(evsel);
return (PyObject *)pevsel;
}
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 1ac6cd43c38b..deb5b9dfe44c 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1373,6 +1373,7 @@ static int evlist__deliver_deferred_callchain(struct evlist *evlist,
sample->evsel = evlist__id2evsel(evlist, sample->id);
ret = tool->callchain_deferred(tool, event, sample,
sample->evsel, machine);
+ evsel__put(sample->evsel);
sample->evsel = saved_evsel;
return ret;
}
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [PATCH v6 13/59] perf python: Use evsel in sample in pyrf_event
From: Ian Rogers @ 2026-04-25 17:48 UTC (permalink / raw)
To: acme, adrian.hunter, james.clark, leo.yan, namhyung, tmricht
Cc: alice.mei.rogers, dapeng1.mi, linux-arm-kernel, linux-kernel,
linux-perf-users, mingo, peterz, Ian Rogers
In-Reply-To: <20260425174858.3922152-1-irogers@google.com>
Avoid a duplicated evsel by using the one in sample. Add
evsel__get/put to the evsel in perf_sample.
Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/perf/util/evsel.c | 2 +-
tools/perf/util/python.c | 10 +++-------
tools/perf/util/sample.c | 17 ++++++++++++-----
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 3015b9b4b4da..9b16d832810f 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -3235,7 +3235,7 @@ int evsel__parse_sample(struct evsel *evsel, union perf_event *event,
union u64_swap u;
perf_sample__init(data, /*all=*/true);
- data->evsel = evsel;
+ data->evsel = evsel__get(evsel);
data->cpu = data->pid = data->tid = -1;
data->stream_id = data->id = data->time = -1ULL;
data->period = evsel->core.attr.sample_period;
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index 0162d8a625de..0424290f8b77 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -43,7 +43,6 @@ PyMODINIT_FUNC PyInit_perf(void);
struct pyrf_event {
PyObject_HEAD
- struct evsel *evsel;
struct perf_sample sample;
union perf_event event;
};
@@ -274,7 +273,6 @@ static PyMemberDef pyrf_sample_event__members[] = {
static void pyrf_sample_event__delete(struct pyrf_event *pevent)
{
- evsel__put(pevent->evsel);
perf_sample__exit(&pevent->sample);
Py_TYPE(pevent)->tp_free((PyObject*)pevent);
}
@@ -296,7 +294,7 @@ static PyObject *pyrf_sample_event__repr(const struct pyrf_event *pevent)
#ifdef HAVE_LIBTRACEEVENT
static bool is_tracepoint(const struct pyrf_event *pevent)
{
- return pevent->evsel->core.attr.type == PERF_TYPE_TRACEPOINT;
+ return pevent->sample.evsel->core.attr.type == PERF_TYPE_TRACEPOINT;
}
static PyObject*
@@ -343,7 +341,7 @@ tracepoint_field(const struct pyrf_event *pe, struct tep_format_field *field)
static PyObject*
get_tracepoint_field(struct pyrf_event *pevent, PyObject *attr_name)
{
- struct evsel *evsel = pevent->evsel;
+ struct evsel *evsel = pevent->sample.evsel;
struct tep_event *tp_format = evsel__tp_format(evsel);
struct tep_format_field *field;
@@ -509,7 +507,7 @@ static PyObject *pyrf_event__new(const union perf_event *event)
pevent = PyObject_New(struct pyrf_event, ptype);
if (pevent != NULL) {
memcpy(&pevent->event, event, event->header.size);
- pevent->evsel = NULL;
+ perf_sample__init(&pevent->sample, /*all=*/false);
}
return (PyObject *)pevent;
}
@@ -1788,8 +1786,6 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
return Py_None;
}
- pevent->evsel = evsel__get(evsel);
-
perf_mmap__consume(&md->core);
err = evsel__parse_sample(evsel, &pevent->event, &pevent->sample);
diff --git a/tools/perf/util/sample.c b/tools/perf/util/sample.c
index cf73329326d7..7ec534dedc5c 100644
--- a/tools/perf/util/sample.c
+++ b/tools/perf/util/sample.c
@@ -1,18 +1,23 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include "sample.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <elf.h>
+#include <linux/zalloc.h>
+
#include "debug.h"
+#include "evsel.h"
#include "thread.h"
-#include <elf.h>
+#include "../../arch/x86/include/asm/insn.h"
+
#ifndef EM_CSKY
#define EM_CSKY 252
#endif
#ifndef EM_LOONGARCH
#define EM_LOONGARCH 258
#endif
-#include <linux/zalloc.h>
-#include <stdlib.h>
-#include <string.h>
-#include "../../arch/x86/include/asm/insn.h"
void perf_sample__init(struct perf_sample *sample, bool all)
{
@@ -29,6 +34,8 @@ void perf_sample__init(struct perf_sample *sample, bool all)
void perf_sample__exit(struct perf_sample *sample)
{
+ evsel__put(sample->evsel);
+ sample->evsel = NULL;
zfree(&sample->user_regs);
zfree(&sample->intr_regs);
if (sample->merged_callchain) {
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [PATCH v6 14/59] perf python: Add wrapper for perf_data file abstraction
From: Ian Rogers @ 2026-04-25 17:48 UTC (permalink / raw)
To: acme, adrian.hunter, james.clark, leo.yan, namhyung, tmricht
Cc: alice.mei.rogers, dapeng1.mi, linux-arm-kernel, linux-kernel,
linux-perf-users, mingo, peterz, Ian Rogers
In-Reply-To: <20260425174858.3922152-1-irogers@google.com>
The perf_data struct is needed for session supported.
Assisted-by: Gemini:gemini-3.1-pro-preview
Signed-off-by: Ian Rogers <irogers@google.com>
---
v2:
1. Fixed Memory & FD Leaks in pyrf_data__init : Added cleanup of old
state (closing file and freeing path) if __init__ is called
multiple times on the same object.
2. Fixed Invalid Free in pyrf_data__delete : Ensured pdata->data.path
is always dynamically allocated via strdup() , even for the default
"perf.data" . This avoids passing a static string literal to free().
3. Fixed NULL Pointer Dereference in pyrf_data__str : Added a check
for NULL path to prevent segfaults if str() or repr() is called on
an uninitialized object.
4. Guarded fd Argument Usage: Added a check to ensure that if an fd is
provided, it corresponds to a pipe, failing gracefully with a
ValueError otherwise.
---
tools/perf/util/python.c | 93 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 92 insertions(+), 1 deletion(-)
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index 0424290f8b77..a2cdd92e0548 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -10,6 +10,7 @@
#include "callchain.h"
#include "counts.h"
+#include "data.h"
#include "event.h"
#include "evlist.h"
#include "evsel.h"
@@ -2296,6 +2297,92 @@ static PyObject *pyrf__metrics(PyObject *self, PyObject *args)
return list;
}
+struct pyrf_data {
+ PyObject_HEAD
+
+ struct perf_data data;
+};
+
+static int pyrf_data__init(struct pyrf_data *pdata, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "path", "fd", NULL };
+ char *path = NULL;
+ int fd = -1;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|si", kwlist, &path, &fd))
+ return -1;
+
+ if (pdata->data.open)
+ perf_data__close(&pdata->data);
+ free((char *)pdata->data.path);
+
+ if (!path)
+ path = "perf.data";
+
+ pdata->data.path = strdup(path);
+ if (!pdata->data.path) {
+ PyErr_NoMemory();
+ return -1;
+ }
+
+ if (fd != -1) {
+ struct stat st;
+
+ if (fstat(fd, &st) < 0 || !S_ISFIFO(st.st_mode)) {
+ PyErr_SetString(PyExc_ValueError,
+ "fd argument is only supported for pipes");
+ free((char *)pdata->data.path);
+ pdata->data.path = NULL;
+ return -1;
+ }
+ }
+
+ pdata->data.mode = PERF_DATA_MODE_READ;
+ pdata->data.file.fd = fd;
+ if (perf_data__open(&pdata->data) < 0) {
+ PyErr_Format(PyExc_IOError, "Failed to open perf data: %s",
+ pdata->data.path ? pdata->data.path : "perf.data");
+ return -1;
+ }
+ return 0;
+}
+
+static void pyrf_data__delete(struct pyrf_data *pdata)
+{
+ perf_data__close(&pdata->data);
+ free((char *)pdata->data.path);
+ Py_TYPE(pdata)->tp_free((PyObject *)pdata);
+}
+
+static PyObject *pyrf_data__str(PyObject *self)
+{
+ const struct pyrf_data *pdata = (const struct pyrf_data *)self;
+
+ if (!pdata->data.path)
+ return PyUnicode_FromString("[uninitialized]");
+ return PyUnicode_FromString(pdata->data.path);
+}
+
+static const char pyrf_data__doc[] = PyDoc_STR("perf data file object.");
+
+static PyTypeObject pyrf_data__type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "perf.data",
+ .tp_basicsize = sizeof(struct pyrf_data),
+ .tp_dealloc = (destructor)pyrf_data__delete,
+ .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
+ .tp_doc = pyrf_data__doc,
+ .tp_init = (initproc)pyrf_data__init,
+ .tp_repr = pyrf_data__str,
+ .tp_str = pyrf_data__str,
+};
+
+static int pyrf_data__setup_types(void)
+{
+ pyrf_data__type.tp_new = PyType_GenericNew;
+ return PyType_Ready(&pyrf_data__type);
+}
+
static PyMethodDef perf__methods[] = {
{
.ml_name = "metrics",
@@ -2358,7 +2445,8 @@ PyMODINIT_FUNC PyInit_perf(void)
pyrf_cpu_map__setup_types() < 0 ||
pyrf_pmu_iterator__setup_types() < 0 ||
pyrf_pmu__setup_types() < 0 ||
- pyrf_counts_values__setup_types() < 0)
+ pyrf_counts_values__setup_types() < 0 ||
+ pyrf_data__setup_types() < 0)
return module;
/* The page_size is placed in util object. */
@@ -2406,6 +2494,9 @@ PyMODINIT_FUNC PyInit_perf(void)
Py_INCREF(&pyrf_counts_values__type);
PyModule_AddObject(module, "counts_values", (PyObject *)&pyrf_counts_values__type);
+ Py_INCREF(&pyrf_data__type);
+ PyModule_AddObject(module, "data", (PyObject *)&pyrf_data__type);
+
dict = PyModule_GetDict(module);
if (dict == NULL)
goto error;
--
2.54.0.545.g6539524ca2-goog
^ 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