All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv3 00/14] dm-zoned: multiple drive support
From: Hannes Reinecke @ 2020-05-29 17:38 UTC (permalink / raw)
  To: Mike Snitzer; +Cc: Damien LeMoal, dm-devel

Hi all,

here's the second version of my patchset to support multiple zoned
drives with dm-zoned.
This patchset:
- Converts the zone array to using xarray for better scalability
- Separates out shared structures into per-device structure
- Enforce drive-locality for allocating and reclaiming zones
- Lifts the restriction of 2 devices to handle an arbitrary number
  of drives.

This gives me a near-perfect scalability by increasing the write
speed from 150MB/s (for a cache and one zoned drive) to 300MB/s
(for a cache and two zoned drives).

Changes to v1:
- Include reviews from Damien
- Reshuffle patches
Changes to v2:
- Add reviews from Damien
- Merge patches 'dynamic device allocation' and
  'support arbitrary number of devices'
- Fix memory leak when reading tertiary superblocks

Hannes Reinecke (14):
  dm-zoned: add debugging message for reading superblocks
  dm-zoned: secondary superblock must reside on the same devices than
    primary superblock
  dm-zoned: improve logging messages for reclaim
  dm-zoned: add a 'reserved' zone flag
  dm-zoned: convert to xarray
  dm-zoned: temporary superblock for tertiary devices
  dm-zoned: add device pointer to struct dm_zone
  dm-zoned: add metadata pointer to struct dmz_dev
  dm-zoned: per-device reclaim
  dm-zoned: move random and sequential zones into struct dmz_dev
  dm-zoned: support arbitrary number of devices
  dm-zoned: allocate zone by device index
  dm-zoned: select reclaim zone based on device index
  dm-zoned: prefer full zones for reclaim

 drivers/md/dm-zoned-metadata.c | 453 +++++++++++++++++++++++++----------------
 drivers/md/dm-zoned-reclaim.c  |  95 +++++----
 drivers/md/dm-zoned-target.c   | 169 +++++++++------
 drivers/md/dm-zoned.h          |  77 ++++---
 4 files changed, 485 insertions(+), 309 deletions(-)

-- 
2.16.4

^ permalink raw reply

* [PATCH for-next 1/1] null_blk: force complete for timeout request
From: Dongli Zhang @ 2020-05-29 17:31 UTC (permalink / raw)
  To: linux-block; +Cc: axboe, linux-kernel

The commit 7b11eab041da ("blk-mq: blk-mq: provide forced completion
method") exports new API to force a request to complete without error
injection.

There should be no error injection when completing a request by timeout
handler.

Otherwise, the below would hang because timeout handler is failed.

echo 100 > /sys/kernel/debug/fail_io_timeout/probability
echo 1000 > /sys/kernel/debug/fail_io_timeout/times
echo 1 > /sys/block/nullb0/io-timeout-fail
dd if=/dev/zero of=/dev/nullb0 bs=512 count=1 oflag=direct

With this patch, the timeout handler is able to complete the IO.

Signed-off-by: Dongli Zhang <dongli.zhang@oracle.com>
---
 drivers/block/null_blk_main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/block/null_blk_main.c b/drivers/block/null_blk_main.c
index 6126f771ae99..87b31f9ca362 100644
--- a/drivers/block/null_blk_main.c
+++ b/drivers/block/null_blk_main.c
@@ -1423,7 +1423,7 @@ static bool should_requeue_request(struct request *rq)
 static enum blk_eh_timer_return null_timeout_rq(struct request *rq, bool res)
 {
 	pr_info("rq %p timed out\n", rq);
-	blk_mq_complete_request(rq);
+	blk_mq_force_complete_rq(rq);
 	return BLK_EH_DONE;
 }
 
-- 
2.17.1


^ permalink raw reply related

* [xen-unstable-smoke test] 150495: regressions - trouble: blocked/fail
From: osstest service owner @ 2020-05-29 17:37 UTC (permalink / raw)
  To: xen-devel, osstest-admin

flight 150495 xen-unstable-smoke real [real]
http://logs.test-lab.xenproject.org/osstest/logs/150495/

Regressions :-(

Tests which did not succeed and are blocking,
including tests which could not be run:
 build-arm64-xsm               6 xen-build                fail REGR. vs. 150438
 build-amd64                   6 xen-build                fail REGR. vs. 150438
 build-armhf                   6 xen-build                fail REGR. vs. 150438

Tests which did not succeed, but are not blocking:
 test-arm64-arm64-xl-xsm       1 build-check(1)               blocked  n/a
 build-amd64-libvirt           1 build-check(1)               blocked  n/a
 test-armhf-armhf-xl           1 build-check(1)               blocked  n/a
 test-amd64-amd64-libvirt      1 build-check(1)               blocked  n/a
 test-amd64-amd64-xl-qemuu-debianhvm-amd64  1 build-check(1)        blocked n/a

version targeted for testing:
 xen                  51f9df5c19f2b8a780aa2547cdf3d20736bfddcc
baseline version:
 xen                  1497e78068421d83956f8e82fb6e1bf1fc3b1199

Last test of basis   150438  2020-05-28 14:01:19 Z    1 days
Failing since        150465  2020-05-29 09:02:14 Z    0 days    6 attempts
Testing same since   150495  2020-05-29 16:03:10 Z    0 days    1 attempts

------------------------------------------------------------
People who touched revisions under test:
  Andrew Cooper <andrew.cooper3@citrix.com>
  Andrew Cooper <andrew.cooper@citrix.com>
  Jan Beulich <jbeulich@suse.com>
  Juergen Gross <jgross@suse.com>
  Julien Grall <jgrall@amazon.com>
  Roger Pau Monné <roger.pau@citrix.com>
  Wei Liu <wl@xen.org>

jobs:
 build-arm64-xsm                                              fail    
 build-amd64                                                  fail    
 build-armhf                                                  fail    
 build-amd64-libvirt                                          blocked 
 test-armhf-armhf-xl                                          blocked 
 test-arm64-arm64-xl-xsm                                      blocked 
 test-amd64-amd64-xl-qemuu-debianhvm-amd64                    blocked 
 test-amd64-amd64-libvirt                                     blocked 


------------------------------------------------------------
sg-report-flight on osstest.test-lab.xenproject.org
logs: /home/logs/logs
images: /home/logs/images

Logs, config files, etc. are available at
    http://logs.test-lab.xenproject.org/osstest/logs

Explanation of these reports, and of osstest in general, is at
    http://xenbits.xen.org/gitweb/?p=osstest.git;a=blob;f=README.email;hb=master
    http://xenbits.xen.org/gitweb/?p=osstest.git;a=blob;f=README;hb=master

Test harness code can be found at
    http://xenbits.xen.org/gitweb?p=osstest.git;a=summary


Not pushing.

(No revision log; it would be 442 lines long.)


^ permalink raw reply

* Re: [PATCH] rtw88: 8822c: remove CCK TX setting when switch channel
From: Kalle Valo @ 2020-05-29 17:37 UTC (permalink / raw)
  To: yhchuang; +Cc: linux-wireless, briannorris
In-Reply-To: <20200522091234.24495-1-yhchuang@realtek.com>

<yhchuang@realtek.com> wrote:

> From: Chien-Hsun Liao <ben.liao@realtek.com>
> 
> The CCK TX setting when switch channel will fix the CCK to
> path A only, so if the antenna is configured to path B
> (e.g. iw phy set antenna 0x2 0x3 "TX B/RX AB"), then the CCK
> packets can never be delivered to the air if only path B is
> connected with an antenna (it can possibly be transmitted
> through path A, but as path B is configured, the expected
> behavior is incorrect).
> 
> This can also solve the racing issue of CCK TX setting between
> driver and firmware. The CCK TX setting in driver should be
> removed. Otherwise, the CCK TX setting would be wrong when the
> racing occurs.
> 
> Fixes: 297bcf8222f2 ("rtw88: add support for set/get antennas")
> Signed-off-by: Chien-Hsun Liao <ben.liao@realtek.com>
> Signed-off-by: Yan-Hsuan Chuang <yhchuang@realtek.com>

Patch applied to wireless-drivers-next.git, thanks.

7967af8de39d rtw88: 8822c: remove CCK TX setting when switch channel

-- 
https://patchwork.kernel.org/patch/11565095/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches


^ permalink raw reply

* Re: Git fetches whole repository and not just latest
From: Jonathan Nieder @ 2020-05-29 17:29 UTC (permalink / raw)
  To: Andy Shevchenko; +Cc: git, Konstantin Ryabitsev
In-Reply-To: <CAHp75Ves8x9_1=fVo_+dB92GpAGLcbGVqeo2gjRbBnzTzM0uzg@mail.gmail.com>

Hi Andy,

Andy Shevchenko wrote:

> So, I have a local repository which has many remotes added (~20 or
> so). Most of them are from the same Git server, but few are from
> different servers.
[...]
> origin, for example, almost everyday now gets in full (1.21 GiB!),
> while others have no pattern.
>
> I would like to know if it's problem of proxy, or that specific Git
> server or is it (new) bug in Git?

What Git version are you using?  Can you test 2.27.0-rc2?

I believe this is fixed by

	commit 2f0a093dd640e0dad0b261dae2427f2541b5426c
	Author: Jonathan Tan <jonathantanmy@google.com>
	Date:   Mon Apr 27 17:01:10 2020 -0700

	    fetch-pack: in protocol v2, reset in_vain upon ACK

which is part of 2.27.0-rc0.

Thanks and hope that helps,
Jonathan

^ permalink raw reply

* Re: [PATCH net-next 00/11] New DSA driver for VSC9953 Seville switch
From: Vladimir Oltean @ 2020-05-29 17:28 UTC (permalink / raw)
  To: Mark Brown
  Cc: David S. Miller, Russell King - ARM Linux admin, Claudiu Manoil,
	Vivien Didelot, Florian Fainelli, Andrew Lunn, Allan W. Nielsen,
	Antoine Tenart, netdev, fido_max, Alexandre Belloni,
	radu-andrei.bulie, Horatiu Vultur, Alexandru Marginean,
	Microchip Linux Driver Support, Madalin Bucur (OSS)
In-Reply-To: <20200529165952.GQ4610@sirena.org.uk>

Hi Mark,

On Fri, 29 May 2020 at 19:59, Mark Brown <broonie@kernel.org> wrote:
>
> On Fri, May 29, 2020 at 05:51:52PM +0100, Mark Brown wrote:
>
> > [1/1] regmap: add helper for per-port regfield initialization
> >       commit: 8baebfc2aca26e3fa67ab28343671b82be42b22c
>
> Let me know if you need a pull request for this, I figured it was too
> late to deal with the cross tree issues for the merge window.

Thanks a lot for merging this. I plan to resend this series again (on
the last mile!) during the weekend, with the feedback collected so
far, so I'm not sure what is the best path to make sure Dave also has
this patch in his tree so I don't break net-next.

-Vladimir

^ permalink raw reply

* Re: [PATCH v4 1/4] scsi: ufs: remove max_t in ufs_get_device_desc
From: Stanley Chu @ 2020-05-29 17:37 UTC (permalink / raw)
  To: Bean Huo
  Cc: alim.akhtar, avri.altman, asutoshd, jejb, martin.petersen,
	beanhuo, bvanassche, tomas.winkler, cang, linux-scsi,
	linux-kernel
In-Reply-To: <20200529164054.27552-2-huobean@gmail.com>

On Fri, 2020-05-29 at 18:40 +0200, Bean Huo wrote:
> From: Bean Huo <beanhuo@micron.com>
> 
> For the UFS device, the maximum descriptor size is 255, max_t called
> in ufs_get_device_desc() is useless.
> 
> Signed-off-by: Bart van Assche <bvanassche@acm.org>
> Signed-off-by: Bean Huo <beanhuo@micron.com>
> Acked-by: Avri Altman <avri.altman@wdc.com>

Reviewed-by: Stanley Chu <stanley.chu@mediatek.com>

^ permalink raw reply

* [bpf PATCH 2/3] bpf, selftests: verifier bounds tests need to be updated
From: John Fastabend @ 2020-05-29 17:28 UTC (permalink / raw)
  To: yhs, alexei.starovoitov, daniel; +Cc: bpf, john.fastabend, kernel-team
In-Reply-To: <159077324869.6014.6516130782021506562.stgit@john-Precision-5820-Tower>

After previous fix for zero extension test_verifier tests #65 and #66 now
fail. Before the fix we can see the alu32 mov op at insn 10

10: R0_w=map_value(id=0,off=0,ks=8,vs=8,imm=0)
    R1_w=invP(id=0,
              smin_value=4294967168,smax_value=4294967423,
              umin_value=4294967168,umax_value=4294967423,
              var_off=(0x0; 0x1ffffffff),
              s32_min_value=-2147483648,s32_max_value=2147483647,
              u32_min_value=0,u32_max_value=-1)
    R10=fp0 fp-8_w=mmmmmmmm
10: (bc) w1 = w1
11: R0_w=map_value(id=0,off=0,ks=8,vs=8,imm=0)
    R1_w=invP(id=0,
              smin_value=0,smax_value=2147483647,
              umin_value=0,umax_value=4294967295,
              var_off=(0x0; 0xffffffff),
              s32_min_value=-2147483648,s32_max_value=2147483647,
              u32_min_value=0,u32_max_value=-1)
    R10=fp0 fp-8_w=mmmmmmmm

After the fix at insn 10 because we have 's32_min_value < 0' the following
step 11 now has 'smax_value=U32_MAX' where before we pulled the s32_max_value
bound into the smax_value as seen above in 11 with smax_value=2147483647.

10: R0_w=map_value(id=0,off=0,ks=8,vs=8,imm=0)
    R1_w=inv(id=0,
             smin_value=4294967168,smax_value=4294967423,
             umin_value=4294967168,umax_value=4294967423,
             var_off=(0x0; 0x1ffffffff),
             s32_min_value=-2147483648, s32_max_value=2147483647,
             u32_min_value=0,u32_max_value=-1)
    R10=fp0 fp-8_w=mmmmmmmm
10: (bc) w1 = w1
11: R0_w=map_value(id=0,off=0,ks=8,vs=8,imm=0)
    R1_w=inv(id=0,
             smin_value=0,smax_value=4294967295,
             umin_value=0,umax_value=4294967295,
             var_off=(0x0; 0xffffffff),
             s32_min_value=-2147483648, s32_max_value=2147483647,
             u32_min_value=0, u32_max_value=-1)
    R10=fp0 fp-8_w=mmmmmmmm

The fall out of this is by the time we get to the failing instruction at
step 14 where previously we had the following:

14: R0_w=map_value(id=0,off=0,ks=8,vs=8,imm=0)
    R1_w=inv(id=0,
             smin_value=72057594021150720,smax_value=72057594029539328,
             umin_value=72057594021150720,umax_value=72057594029539328,
             var_off=(0xffffffff000000; 0xffffff),
             s32_min_value=-16777216,s32_max_value=-1,
             u32_min_value=-16777216,u32_max_value=-1)
    R10=fp0 fp-8_w=mmmmmmmm
14: (0f) r0 += r1

We now have,

14: R0_w=map_value(id=0,off=0,ks=8,vs=8,imm=0)
    R1_w=inv(id=0,
             smin_value=0,smax_value=72057594037927935,
             umin_value=0,umax_value=72057594037927935,
             var_off=(0x0; 0xffffffffffffff),
             s32_min_value=-2147483648,s32_max_value=2147483647,
             u32_min_value=0,u32_max_value=-1)
    R10=fp0 fp-8_w=mmmmmmmm
14: (0f) r0 += r1

In the original step 14 'smin_value=72057594021150720' this trips the logic
in the verifier function check_reg_sane_offset(),

 if (smin >= BPF_MAX_VAR_OFF || smin <= -BPF_MAX_VAR_OFF) {
	verbose(env, "value %lld makes %s pointer be out of bounds\n",
		smin, reg_type_str[type]);
	return false;
 }

Specifically, the 'smin <= -BPF_MAX_VAR_OFF' check. But with the fix
at step 14 we have bounds 'smin_value=0' so the above check is not tripped
because BPF_MAX_VAR_OFF=1<<29.

We have a smin_value=0 here because at step 10 the smaller smin_value=0 means
the subtractions at steps 11 and 12 bring the smin_value negative.

11: (17) r1 -= 2147483584
12: (17) r1 -= 2147483584
13: (77) r1 >>= 8

Then the shift clears the top bit and smin_value is set to 0. Note we still
have the smax_value in the fixed code so any reads will fail. An alternative
would be to have reg_sane_check() do both smin and smax value tests.

To fix the test we can omit the 'r1 >>=8' at line 13. This will change the
err string, but keeps the intention of the test as suggseted by the title,
"check after truncation of boundary-crossing range". If the verifier logic
changes a different value is likely to be thrown in the error or the error
will no longer be thrown forcing this test to be examined. With this change
we see the new state at step 13.

13: R0_w=map_value(id=0,off=0,ks=8,vs=8,imm=0)
    R1_w=invP(id=0,
              smin_value=-4294967168,smax_value=127,
              umin_value=0,umax_value=18446744073709551615,
              s32_min_value=-2147483648,s32_max_value=2147483647,
              u32_min_value=0,u32_max_value=-1)
    R10=fp0 fp-8_w=mmmmmmmm

Giving the expected out of bounds error, "value -4294967168 makes map_value
pointer be out of bounds" However, for unpriv case we see a different error
now because of the mixed signed bounds pointer arithmatic. This seems OK so
I've only added the unpriv_errstr for this. Another optino may have been to
do addition on r1 instead of subtraction but I favor the approach above
slightly.

Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
 tools/testing/selftests/bpf/verifier/bounds.c |   24 ++++++++++--------------
 1 file changed, 10 insertions(+), 14 deletions(-)

diff --git a/tools/testing/selftests/bpf/verifier/bounds.c b/tools/testing/selftests/bpf/verifier/bounds.c
index a253a06..fafa540 100644
--- a/tools/testing/selftests/bpf/verifier/bounds.c
+++ b/tools/testing/selftests/bpf/verifier/bounds.c
@@ -238,7 +238,7 @@
 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 	BPF_LD_MAP_FD(BPF_REG_1, 0),
 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
-	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
+	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
 	/* r1 = [0x00, 0xff] */
 	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
@@ -253,10 +253,6 @@
 	 *      [0xffff'ffff'0000'0080, 0xffff'ffff'ffff'ffff]
 	 */
 	BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
-	/* r1 = 0 or
-	 *      [0x00ff'ffff'ff00'0000, 0x00ff'ffff'ffff'ffff]
-	 */
-	BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
 	/* error on OOB pointer computation */
 	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
 	/* exit */
@@ -265,8 +261,10 @@
 	},
 	.fixup_map_hash_8b = { 3 },
 	/* not actually fully unbounded, but the bound is very high */
-	.errstr = "value 72057594021150720 makes map_value pointer be out of bounds",
-	.result = REJECT
+	.errstr_unpriv = "R1 has unknown scalar with mixed signed bounds, pointer arithmetic with it prohibited for !root",
+	.result_unpriv = REJECT,
+	.errstr = "value -4294967168 makes map_value pointer be out of bounds",
+	.result = REJECT,
 },
 {
 	"bounds check after truncation of boundary-crossing range (2)",
@@ -276,7 +274,7 @@
 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 	BPF_LD_MAP_FD(BPF_REG_1, 0),
 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
-	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
+	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
 	/* r1 = [0x00, 0xff] */
 	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
@@ -293,10 +291,6 @@
 	 *      [0xffff'ffff'0000'0080, 0xffff'ffff'ffff'ffff]
 	 */
 	BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
-	/* r1 = 0 or
-	 *      [0x00ff'ffff'ff00'0000, 0x00ff'ffff'ffff'ffff]
-	 */
-	BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
 	/* error on OOB pointer computation */
 	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
 	/* exit */
@@ -305,8 +299,10 @@
 	},
 	.fixup_map_hash_8b = { 3 },
 	/* not actually fully unbounded, but the bound is very high */
-	.errstr = "value 72057594021150720 makes map_value pointer be out of bounds",
-	.result = REJECT
+	.errstr_unpriv = "R1 has unknown scalar with mixed signed bounds, pointer arithmetic with it prohibited for !root",
+	.result_unpriv = REJECT,
+	.errstr = "value -4294967168 makes map_value pointer be out of bounds",
+	.result = REJECT,
 },
 {
 	"bounds check after wrapping 32-bit addition",


^ permalink raw reply related

* [bpf PATCH 0/3] verifier fix for assigning 32bit reg to 64bit reg
From: John Fastabend @ 2020-05-29 17:28 UTC (permalink / raw)
  To: yhs, alexei.starovoitov, daniel; +Cc: bpf, john.fastabend, kernel-team

These add a fix for 32 bit to 64 bit assignment introduced with
latest alu32 bounds tracking. The initial fix was proposed by
Yonghong and then I updated it slightly and added a test fix.

@Yonghong feel free to add your signed-off-by back if you want
or at minimal a ACK would be good.

---

John Fastabend (3):
      bpf: fix a verifier issue when assigning 32bit reg states to 64bit ones
      bpf, selftests: verifier bounds tests need to be updated
      bpf, selftests: add a verifier test for assigning 32bit reg states to 64bit ones


 kernel/bpf/verifier.c                         |   10 +++--
 tools/testing/selftests/bpf/verifier/bounds.c |   46 +++++++++++++++++--------
 2 files changed, 37 insertions(+), 19 deletions(-)

--
Signature

^ permalink raw reply

* [bpf PATCH 3/3] bpf, selftests: add a verifier test for assigning 32bit reg states to 64bit ones
From: John Fastabend @ 2020-05-29 17:29 UTC (permalink / raw)
  To: yhs, alexei.starovoitov, daniel; +Cc: bpf, john.fastabend, kernel-team
In-Reply-To: <159077324869.6014.6516130782021506562.stgit@john-Precision-5820-Tower>

Added a verifier test for assigning 32bit reg states to
64bit where 32bit reg holds a constant value of 0.

Without previous kernel verifier.c fix, the test in
this patch will fail.

Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
 tools/testing/selftests/bpf/verifier/bounds.c |   22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/tools/testing/selftests/bpf/verifier/bounds.c b/tools/testing/selftests/bpf/verifier/bounds.c
index fafa540..58f4aa59 100644
--- a/tools/testing/selftests/bpf/verifier/bounds.c
+++ b/tools/testing/selftests/bpf/verifier/bounds.c
@@ -535,3 +535,25 @@
 	},
 	.result = ACCEPT
 },
+{
+	"assigning 32bit bounds to 64bit for wA = 0, wB = wA",
+	.insns = {
+	BPF_LDX_MEM(BPF_W, BPF_REG_8, BPF_REG_1,
+		    offsetof(struct __sk_buff, data_end)),
+	BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
+		    offsetof(struct __sk_buff, data)),
+	BPF_MOV32_IMM(BPF_REG_9, 0),
+	BPF_MOV32_REG(BPF_REG_2, BPF_REG_9),
+	BPF_MOV64_REG(BPF_REG_6, BPF_REG_7),
+	BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_2),
+	BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
+	BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 8),
+	BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_8, 1),
+	BPF_LDX_MEM(BPF_W, BPF_REG_5, BPF_REG_6, 0),
+	BPF_MOV64_IMM(BPF_REG_0, 0),
+	BPF_EXIT_INSN(),
+	},
+	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
+	.result = ACCEPT,
+	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
+},


^ permalink raw reply related

* Re: [PATCH 1/6] x86/entry: Introduce local_db_{save,restore}()
From: Andy Lutomirski @ 2020-05-29 17:28 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Andrew Cooper, tglx, linux-kernel, x86, Lai Jiangshan,
	sean.j.christopherson, daniel.thompson
In-Reply-To: <20200528213352.GC4496@worktop.programming.kicks-ass.net>



> On May 28, 2020, at 2:34 PM, Peter Zijlstra <peterz@infradead.org> wrote:
> 
> On Thu, May 28, 2020 at 11:15:50PM +0200, Peter Zijlstra wrote:
>>> On Thu, May 28, 2020 at 09:52:30PM +0100, Andrew Cooper wrote:
>>> On 28/05/2020 21:19, Peter Zijlstra wrote:
>>>> --- a/arch/x86/include/asm/debugreg.h
>>>> +++ b/arch/x86/include/asm/debugreg.h
>>>> @@ -113,6 +113,31 @@ static inline void debug_stack_usage_inc
>>>> static inline void debug_stack_usage_dec(void) { }
>>>> #endif /* X86_64 */
>>>> 
>>>> +static __always_inline void local_db_save(unsigned long *dr7)
>>>> +{
>>>> +    get_debugreg(*dr7, 7);
>>>> +    if (*dr7)
>>>> +        set_debugreg(0, 7);
>>> 
>>> %dr7 has an architecturally stuck bit in it.
>>> 
>>> You want *dr7 != 0x400 to avoid writing 0 unconditionally.
>> 
>> Do we have to have that bit set when writing it? Otherwise I might
>> actually prefer masking it out.
> 
> I'm an idiot, we write a plain 9..
> 
>>> Also, API wise, wouldn't it be nicer to write "dr7 = local_db_save()"
>>> rather than having a void function returning a single long via pointer?
>> 
>> Probably.. I started with local_irq_save() and .. well, n/m. I'll change
>> it ;-)
> 
> How's this?
> 
> ---
> --- a/arch/x86/include/asm/debugreg.h
> +++ b/arch/x86/include/asm/debugreg.h
> @@ -113,6 +113,36 @@ static inline void debug_stack_usage_inc
> static inline void debug_stack_usage_dec(void) { }
> #endif /* X86_64 */
> 
> +static __always_inline unsigned long local_db_save(void)
> +{
> +    unsigned long dr7;
> +
> +    get_debugreg(&dr7, 7);
> +    dr7 ^= 0x400;

Why xor?  This seems extra confusing.

> +    if (dr7)
> +        set_debugreg(0, 7);
> +    /*
> +     * Ensure the compiler doesn't lower the above statements into
> +     * the critical section; disabling breakpoints late would not
> +     * be good.
> +     */
> +    barrier();
> +
> +    return dr7;
> +}
> +
> +static __always_inline void local_db_restore(unsigned long dr7)
> +{
> +    /*
> +     * Ensure the compiler doesn't raise this statement into
> +     * the critical section; enabling breakpoints early would
> +     * not be good.
> +     */
> +    barrier();
> +    if (dr7)
> +        set_debugreg(dr7, 7);
> +}
> +
> #ifdef CONFIG_CPU_SUP_AMD
> extern void set_dr_addr_mask(unsigned long mask, int dr);
> #else
> --- a/arch/x86/kernel/traps.c
> +++ b/arch/x86/kernel/traps.c
> @@ -727,15 +727,7 @@ static __always_inline void debug_enter(
>     * Entry text is excluded for HW_BP_X and cpu_entry_area, which
>     * includes the entry stack is excluded for everything.
>     */
> -    get_debugreg(*dr7, 7);
> -    set_debugreg(0, 7);
> -
> -    /*
> -     * Ensure the compiler doesn't lower the above statements into
> -     * the critical section; disabling breakpoints late would not
> -     * be good.
> -     */
> -    barrier();
> +    *dr7 = local_db_save();
> 
>    /*
>     * The Intel SDM says:
> @@ -756,13 +748,7 @@ static __always_inline void debug_enter(
> 
> static __always_inline void debug_exit(unsigned long dr7)
> {
> -    /*
> -     * Ensure the compiler doesn't raise this statement into
> -     * the critical section; enabling breakpoints early would
> -     * not be good.
> -     */
> -    barrier();
> -    set_debugreg(dr7, 7);
> +    local_db_restore(dr7);
> }
> 
> /*
> 

^ permalink raw reply

* Re: [PATCH v2] hwmon:(adm1275) Enable adm1278 ADM1278_TEMP1_EN
From: Guenter Roeck @ 2020-05-29 17:30 UTC (permalink / raw)
  To: Manikandan Elumalai, linux-hwmon, linux-aspeed, linux-kernel,
	openbmc
  Cc: saipsdasari, patrickw3, vijaykhemka, manikandan.e
In-Reply-To: <20200529124607.GA3469@cnn>

On 5/29/20 5:46 AM, Manikandan Elumalai wrote:
> The adm1278 temperature sysfs attribute need it for one of the openbmc platform . 
> This functionality is not enabled by default, so PMON_CONFIG needs to be modified in order to enable it.
> 
> Signed-off-by   : Manikandan Elumalai <manikandan.hcl.ers.epl@gmail.com>

This is not valid.

> 
> v2:
>    - Add Signed-off-by.
>    - Removed ADM1278_TEMP1_EN check.

checkpatch reports:

> ---WARNING: Possible unwrapped commit description (prefer a maximum 75 chars per line)
#14:
The adm1278 temperature sysfs attribute need it for one of the openbmc platform .

CHECK: Alignment should match open parenthesis
#45: FILE: drivers/hwmon/pmbus/adm1275.c:679:
+		ret = i2c_smbus_write_byte_data(client,
+					ADM1275_PMON_CONFIG,

WARNING: suspect code indent for conditional statements (16, 16)
#47: FILE: drivers/hwmon/pmbus/adm1275.c:681:
+		if (ret < 0) {
+		dev_err(&client->dev,

ERROR: Missing Signed-off-by: line(s)

total: 1 errors, 2 warnings, 1 checks, 33 lines checked

Please follow published guidelines when submitting patches.

>  drivers/hwmon/pmbus/adm1275.c | 21 +++++++++++++++++----
>  1 file changed, 17 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/hwmon/pmbus/adm1275.c b/drivers/hwmon/pmbus/adm1275.c
> index 5caa37fb..ab5fceb 100644
> --- a/drivers/hwmon/pmbus/adm1275.c
> +++ b/drivers/hwmon/pmbus/adm1275.c
> @@ -666,7 +666,23 @@ static int adm1275_probe(struct i2c_client *client,
>  		tindex = 3;
>  
>  		info->func[0] |= PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT |
> -			PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT;
> +			PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
> +			PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
> +
> +		config = i2c_smbus_read_byte_data(client, ADM1275_PMON_CONFIG);
> +		if (config < 0)
> +			return config;
> +
> +		/* Enable TEMP1 by default */
> +		config |= ADM1278_TEMP1_EN;
> +		ret = i2c_smbus_write_byte_data(client,
> +					ADM1275_PMON_CONFIG,
> +					config);
> +		if (ret < 0) {
> +		dev_err(&client->dev,
> +			"Failed to enable temperature config\n");
> +		return -ENODEV;
> +		}

This can be handled in a single operation, together with ADM1278_VOUT_EN
below. There is no need for two separate write operations.

Guenter

> 
>  		/* Enable VOUT if not enabled (it is disabled by default) */
>  		if (!(config & ADM1278_VOUT_EN)) {
> @@ -681,9 +697,6 @@ static int adm1275_probe(struct i2c_client *client,
>  			}
>  		}
>  
> -		if (config & ADM1278_TEMP1_EN)
> -			info->func[0] |=
> -				PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
>  		if (config & ADM1278_VIN_EN)
>  			info->func[0] |= PMBUS_HAVE_VIN;
>  		break;
> 


^ permalink raw reply

* [bpf PATCH 1/3] bpf: fix a verifier issue when assigning 32bit reg states to 64bit ones
From: John Fastabend @ 2020-05-29 17:28 UTC (permalink / raw)
  To: yhs, alexei.starovoitov, daniel; +Cc: bpf, john.fastabend, kernel-team
In-Reply-To: <159077324869.6014.6516130782021506562.stgit@john-Precision-5820-Tower>

With the latest trunk llvm (llvm 11), I hit a verifier issue for
test_prog subtest test_verif_scale1.

The following simplified example illustrate the issue:
    w9 = 0  /* R9_w=inv0 */
    r8 = *(u32 *)(r1 + 80)  /* __sk_buff->data_end */
    r7 = *(u32 *)(r1 + 76)  /* __sk_buff->data */
    ......
    w2 = w9 /* R2_w=inv0 */
    r6 = r7 /* R6_w=pkt(id=0,off=0,r=0,imm=0) */
    r6 += r2 /* R6_w=inv(id=0) */
    r3 = r6 /* R3_w=inv(id=0) */
    r3 += 14 /* R3_w=inv(id=0) */
    if r3 > r8 goto end
    r5 = *(u32 *)(r6 + 0) /* R6_w=inv(id=0) */
       <== error here: R6 invalid mem access 'inv'
    ...
  end:

In real test_verif_scale1 code, "w9 = 0" and "w2 = w9" are in
different basic blocks.

In the above, after "r6 += r2", r6 becomes a scalar, which eventually
caused the memory access error. The correct register state should be
a pkt pointer.

The inprecise register state starts at "w2 = w9".
The 32bit register w9 is 0, in __reg_assign_32_into_64(),
the 64bit reg->smax_value is assigned to be U32_MAX.
The 64bit reg->smin_value is 0 and the 64bit register
itself remains constant based on reg->var_off.

In adjust_ptr_min_max_vals(), the verifier checks for a known constant,
smin_val must be equal to smax_val. Since they are not equal,
the verifier decides r6 is a unknown scalar, which caused later failure.

The llvm10 does not have this issue as it generates different code:
    w9 = 0  /* R9_w=inv0 */
    r8 = *(u32 *)(r1 + 80)  /* __sk_buff->data_end */
    r7 = *(u32 *)(r1 + 76)  /* __sk_buff->data */
    ......
    r6 = r7 /* R6_w=pkt(id=0,off=0,r=0,imm=0) */
    r6 += r9 /* R6_w=pkt(id=0,off=0,r=0,imm=0) */
    r3 = r6 /* R3_w=pkt(id=0,off=0,r=0,imm=0) */
    r3 += 14 /* R3_w=pkt(id=0,off=14,r=0,imm=0) */
    if r3 > r8 goto end
    ...

To fix the above issue, we can include zero in the test condition for
assigning the s32_max_value and s32_min_value to their 64-bit equivalents
smax_value and smin_value.

Further, fix the condition to avoid doing zero extension bounds checks
when s32_min_value <= 0. This could allow for the case where bounds
32-bit bounds (-1,1) get incorrectly translated to (0,1) 64-bit bounds.
When in-fact the -1 min value needs to force U32_MAX bound.

Fixes: 3f50f132d840 ("bpf: Verifier, do explicit ALU32 bounds tracking")
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
 kernel/bpf/verifier.c |   10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index d2e27db..d0bdd55 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -1217,14 +1217,14 @@ static void __reg_assign_32_into_64(struct bpf_reg_state *reg)
 	 * but must be positive otherwise set to worse case bounds
 	 * and refine later from tnum.
 	 */
-	if (reg->s32_min_value > 0)
-		reg->smin_value = reg->s32_min_value;
-	else
-		reg->smin_value = 0;
-	if (reg->s32_max_value > 0)
+	if (reg->s32_min_value >= 0 && reg->s32_max_value >= 0)
 		reg->smax_value = reg->s32_max_value;
 	else
 		reg->smax_value = U32_MAX;
+	if (reg->s32_min_value >= 0)
+		reg->smin_value = reg->s32_min_value;
+	else
+		reg->smin_value = 0;
 }
 
 static void __reg_combine_32_into_64(struct bpf_reg_state *reg)


^ permalink raw reply related

* Re: [PATCH] rtw88: 8822c: fix missing brace warning for old compilers
From: Kalle Valo @ 2020-05-29 17:36 UTC (permalink / raw)
  To: yhchuang; +Cc: linux-wireless, tehuang, oliver.sang
In-Reply-To: <20200522035521.12295-1-yhchuang@realtek.com>

<yhchuang@realtek.com> wrote:

> From: Yan-Hsuan Chuang <yhchuang@realtek.com>
> 
> For older versions of gcc, the array = {0}; will cause warnings:
> 
> drivers/net/wireless/realtek/rtw88/rtw8822c.c: In function 'rtw8822c_power_trim':
> >> drivers/net/wireless/realtek/rtw88/rtw8822c.c:1039:2: warning:
> >> missing braces around initializer [-Wmissing-braces]
> s8 bb_gain[2][8] = {0};
> ^
> drivers/net/wireless/realtek/rtw88/rtw8822c.c:1039:2: warning: (near
> initialization for 'bb_gain[0]') [-Wmissing-braces]
> 
> Fixes: 5ad4d8957b69 ("rtw88: set power trim according to efuse PG values")
> Reported-by: kbuild test robot <lkp@intel.com>
> Signed-off-by: Yan-Hsuan Chuang <yhchuang@realtek.com>
> Acked-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>

Patch applied to wireless-drivers-next.git, thanks.

4e1a341580f2 rtw88: 8822c: fix missing brace warning for old compilers

-- 
https://patchwork.kernel.org/patch/11564651/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches


^ permalink raw reply

* Re: [PATCH v2 1/3] rtw88: coex: 8723d: set antanna control owner
From: Kalle Valo @ 2020-05-29 17:36 UTC (permalink / raw)
  To: yhchuang; +Cc: linux-wireless, pkshih, kai.heng.feng, bigeasy, vicamo.yang
In-Reply-To: <20200529025009.2468-2-yhchuang@realtek.com>

<yhchuang@realtek.com> wrote:

> From: Ping-Ke Shih <pkshih@realtek.com>
> 
> Without setting antenna control owner, the WiFi could be disconnected if
> the BT has traffic. Because the antenna is switched to BT side for its
> traffic, and the WiFi will have no chance to transfer data. Set control
> owner to prevent WiFi disconnect issue.
> 
> Fixes: f5df1a8b4376 ("rtw88: 8723d: Add 8723DE to Kconfig and Makefile")
> Tested-by: You-Sheng Yang <vicamo.yang@canonical.com>
> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
> Signed-off-by: Yan-Hsuan Chuang <yhchuang@realtek.com>

3 patches applied to wireless-drivers-next.git, thanks.

efad661168c7 rtw88: coex: 8723d: set antanna control owner
2647d2827f2a rtw88: coex: 8723d: handle BT inquiry cases
7a242fb69821 rtw88: fix EAPOL 4-way failure by finish IQK earlier

-- 
https://patchwork.kernel.org/patch/11577459/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches


^ permalink raw reply

* Re: [PATCH v14 1/1] perf tools: add support for libpfm4
From: Ian Rogers @ 2020-05-29 17:36 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, Ingo Molnar, Mark Rutland, Alexander Shishkin,
	Jiri Olsa, Namhyung Kim, Alexei Starovoitov, Daniel Borkmann,
	Martin KaFai Lau, Yonghong Song, Andrii Nakryiko,
	Greg Kroah-Hartman, Thomas Gleixner, Igor Lubashev,
	Alexey Budankov, Florian Fainelli, Adrian Hunter, Andi Kleen,
	Jiwei Sun, yuzhoujian, Kan Liang, Jin Yao, Leo Yan, John Garry,
	LKML, Networking, bpf, linux-perf-users, Stephane Eranian
In-Reply-To: <20200529172310.GE537@kernel.org>

On Fri, May 29, 2020 at 10:23 AM Arnaldo Carvalho de Melo
<acme@kernel.org> wrote:
>
> Em Fri, May 29, 2020 at 10:03:51AM -0700, Ian Rogers escreveu:
> > On Tue, May 5, 2020 at 11:29 AM Ian Rogers <irogers@google.com> wrote:
> > >
> > > From: Stephane Eranian <eranian@google.com>
> > >
> > > This patch links perf with the libpfm4 library if it is available
> > > and LIBPFM4 is passed to the build. The libpfm4 library
> > > contains hardware event tables for all processors supported by
> > > perf_events. It is a helper library that helps convert from a
> > > symbolic event name to the event encoding required by the
> > > underlying kernel interface. This library is open-source and
> > > available from: http://perfmon2.sf.net.
> > >
> > > With this patch, it is possible to specify full hardware events
> > > by name. Hardware filters are also supported. Events must be
> > > specified via the --pfm-events and not -e option. Both options
> > > are active at the same time and it is possible to mix and match:
> > >
> > > $ perf stat --pfm-events inst_retired:any_p:c=1:i -e cycles ....
> > >
> > > Signed-off-by: Stephane Eranian <eranian@google.com>
> > > Reviewed-by: Ian Rogers <irogers@google.com>
> >
> > Ping.
>
> Check my tmp.perf/core branch, I had to make some adjustments, mostly in
> the 'perf test' entries as I merged a java demangle test that touched
> the same files,
>
> I'm now doing the build tests.
>
> - Arnaldo


Looks great, thanks Arnaldo!
Ian

> > Thanks,
> > Ian
> >
> > > ---
> > >  tools/perf/Documentation/perf-record.txt |  11 +
> > >  tools/perf/Documentation/perf-stat.txt   |  10 +
> > >  tools/perf/Documentation/perf-top.txt    |  11 +
> > >  tools/perf/Makefile.config               |  13 ++
> > >  tools/perf/Makefile.perf                 |   2 +
> > >  tools/perf/builtin-record.c              |   6 +
> > >  tools/perf/builtin-stat.c                |   6 +
> > >  tools/perf/builtin-top.c                 |   6 +
> > >  tools/perf/tests/Build                   |   1 +
> > >  tools/perf/tests/builtin-test.c          |   9 +
> > >  tools/perf/tests/pfm.c                   | 203 ++++++++++++++++
> > >  tools/perf/tests/tests.h                 |   3 +
> > >  tools/perf/util/Build                    |   2 +
> > >  tools/perf/util/evsel.c                  |   2 +-
> > >  tools/perf/util/evsel.h                  |   1 +
> > >  tools/perf/util/parse-events.c           |  30 ++-
> > >  tools/perf/util/parse-events.h           |   4 +
> > >  tools/perf/util/pfm.c                    | 281 +++++++++++++++++++++++
> > >  tools/perf/util/pfm.h                    |  37 +++
> > >  19 files changed, 630 insertions(+), 8 deletions(-)
> > >  create mode 100644 tools/perf/tests/pfm.c
> > >  create mode 100644 tools/perf/util/pfm.c
> > >  create mode 100644 tools/perf/util/pfm.h
> > >
> > > diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
> > > index 561ef55743e2..492b6b6f2b77 100644
> > > --- a/tools/perf/Documentation/perf-record.txt
> > > +++ b/tools/perf/Documentation/perf-record.txt
> > > @@ -613,6 +613,17 @@ appended unit character - B/K/M/G
> > >         The number of threads to run when synthesizing events for existing processes.
> > >         By default, the number of threads equals 1.
> > >
> > > +ifdef::HAVE_LIBPFM[]
> > > +--pfm-events events::
> > > +Select a PMU event using libpfm4 syntax (see http://perfmon2.sf.net)
> > > +including support for event filters. For example '--pfm-events
> > > +inst_retired:any_p:u:c=1:i'. More than one event can be passed to the
> > > +option using the comma separator. Hardware events and generic hardware
> > > +events cannot be mixed together. The latter must be used with the -e
> > > +option. The -e option and this one can be mixed and matched.  Events
> > > +can be grouped using the {} notation.
> > > +endif::HAVE_LIBPFM[]
> > > +
> > >  SEE ALSO
> > >  --------
> > >  linkperf:perf-stat[1], linkperf:perf-list[1], linkperf:perf-intel-pt[1]
> > > diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
> > > index 3fb5028aef08..b69af18dccd0 100644
> > > --- a/tools/perf/Documentation/perf-stat.txt
> > > +++ b/tools/perf/Documentation/perf-stat.txt
> > > @@ -71,6 +71,16 @@ report::
> > >  --tid=<tid>::
> > >          stat events on existing thread id (comma separated list)
> > >
> > > +ifdef::HAVE_LIBPFM[]
> > > +--pfm-events events::
> > > +Select a PMU event using libpfm4 syntax (see http://perfmon2.sf.net)
> > > +including support for event filters. For example '--pfm-events
> > > +inst_retired:any_p:u:c=1:i'. More than one event can be passed to the
> > > +option using the comma separator. Hardware events and generic hardware
> > > +events cannot be mixed together. The latter must be used with the -e
> > > +option. The -e option and this one can be mixed and matched.  Events
> > > +can be grouped using the {} notation.
> > > +endif::HAVE_LIBPFM[]
> > >
> > >  -a::
> > >  --all-cpus::
> > > diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt
> > > index 20227dabc208..ee2024691d46 100644
> > > --- a/tools/perf/Documentation/perf-top.txt
> > > +++ b/tools/perf/Documentation/perf-top.txt
> > > @@ -329,6 +329,17 @@ Default is to monitor all CPUS.
> > >         The known limitations include exception handing such as
> > >         setjmp/longjmp will have calls/returns not match.
> > >
> > > +ifdef::HAVE_LIBPFM[]
> > > +--pfm-events events::
> > > +Select a PMU event using libpfm4 syntax (see http://perfmon2.sf.net)
> > > +including support for event filters. For example '--pfm-events
> > > +inst_retired:any_p:u:c=1:i'. More than one event can be passed to the
> > > +option using the comma separator. Hardware events and generic hardware
> > > +events cannot be mixed together. The latter must be used with the -e
> > > +option. The -e option and this one can be mixed and matched.  Events
> > > +can be grouped using the {} notation.
> > > +endif::HAVE_LIBPFM[]
> > > +
> > >  INTERACTIVE PROMPTING KEYS
> > >  --------------------------
> > >
> > > diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
> > > index 12a8204d63c6..b67804fee1e3 100644
> > > --- a/tools/perf/Makefile.config
> > > +++ b/tools/perf/Makefile.config
> > > @@ -1012,6 +1012,19 @@ ifdef LIBCLANGLLVM
> > >    endif
> > >  endif
> > >
> > > +ifdef LIBPFM4
> > > +  $(call feature_check,libpfm4)
> > > +  ifeq ($(feature-libpfm4), 1)
> > > +    CFLAGS += -DHAVE_LIBPFM
> > > +    EXTLIBS += -lpfm
> > > +    ASCIIDOC_EXTRA = -aHAVE_LIBPFM=1
> > > +    $(call detected,CONFIG_LIBPFM4)
> > > +  else
> > > +    msg := $(warning libpfm4 not found, disables libpfm4 support. Please install libpfm4-dev);
> > > +    NO_LIBPFM4 := 1
> > > +  endif
> > > +endif
> > > +
> > >  # Among the variables below, these:
> > >  #   perfexecdir
> > >  #   perf_include_dir
> > > diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
> > > index 94a495594e99..dc82578c8773 100644
> > > --- a/tools/perf/Makefile.perf
> > > +++ b/tools/perf/Makefile.perf
> > > @@ -118,6 +118,8 @@ include ../scripts/utilities.mak
> > >  #
> > >  # Define LIBBPF_DYNAMIC to enable libbpf dynamic linking.
> > >  #
> > > +# Define LIBPFM4 to enable libpfm4 events extension.
> > > +#
> > >
> > >  # As per kernel Makefile, avoid funny character set dependencies
> > >  unexport LC_ALL
> > > diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
> > > index e4efdbf1a81e..98387cce3207 100644
> > > --- a/tools/perf/builtin-record.c
> > > +++ b/tools/perf/builtin-record.c
> > > @@ -45,6 +45,7 @@
> > >  #include "util/units.h"
> > >  #include "util/bpf-event.h"
> > >  #include "util/util.h"
> > > +#include "util/pfm.h"
> > >  #include "asm/bug.h"
> > >  #include "perf.h"
> > >
> > > @@ -2506,6 +2507,11 @@ static struct option __record_options[] = {
> > >         OPT_UINTEGER(0, "num-thread-synthesize",
> > >                      &record.opts.nr_threads_synthesize,
> > >                      "number of threads to run for event synthesis"),
> > > +#ifdef HAVE_LIBPFM
> > > +       OPT_CALLBACK(0, "pfm-events", &record.evlist, "event",
> > > +               "libpfm4 event selector. use 'perf list' to list available events",
> > > +               parse_libpfm_events_option),
> > > +#endif
> > >         OPT_END()
> > >  };
> > >
> > > diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
> > > index e0c1ad23c768..f6e2dd57f48e 100644
> > > --- a/tools/perf/builtin-stat.c
> > > +++ b/tools/perf/builtin-stat.c
> > > @@ -66,6 +66,7 @@
> > >  #include "util/time-utils.h"
> > >  #include "util/top.h"
> > >  #include "util/affinity.h"
> > > +#include "util/pfm.h"
> > >  #include "asm/bug.h"
> > >
> > >  #include <linux/time64.h>
> > > @@ -935,6 +936,11 @@ static struct option stat_options[] = {
> > >                     "Use with 'percore' event qualifier to show the event "
> > >                     "counts of one hardware thread by sum up total hardware "
> > >                     "threads of same physical core"),
> > > +#ifdef HAVE_LIBPFM
> > > +       OPT_CALLBACK(0, "pfm-events", &evsel_list, "event",
> > > +               "libpfm4 event selector. use 'perf list' to list available events",
> > > +               parse_libpfm_events_option),
> > > +#endif
> > >         OPT_END()
> > >  };
> > >
> > > diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
> > > index 372c38254654..20c41d9040ee 100644
> > > --- a/tools/perf/builtin-top.c
> > > +++ b/tools/perf/builtin-top.c
> > > @@ -53,6 +53,7 @@
> > >
> > >  #include "util/debug.h"
> > >  #include "util/ordered-events.h"
> > > +#include "util/pfm.h"
> > >
> > >  #include <assert.h>
> > >  #include <elf.h>
> > > @@ -1575,6 +1576,11 @@ int cmd_top(int argc, const char **argv)
> > >                     "WARNING: should be used on grouped events."),
> > >         OPT_BOOLEAN(0, "stitch-lbr", &top.stitch_lbr,
> > >                     "Enable LBR callgraph stitching approach"),
> > > +#ifdef HAVE_LIBPFM
> > > +       OPT_CALLBACK(0, "pfm-events", &top.evlist, "event",
> > > +               "libpfm4 event selector. use 'perf list' to list available events",
> > > +               parse_libpfm_events_option),
> > > +#endif
> > >         OPTS_EVSWITCH(&top.evswitch),
> > >         OPT_END()
> > >         };
> > > diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
> > > index c75557aeef0e..4e74a363b0b0 100644
> > > --- a/tools/perf/tests/Build
> > > +++ b/tools/perf/tests/Build
> > > @@ -57,6 +57,7 @@ perf-y += maps.o
> > >  perf-y += time-utils-test.o
> > >  perf-y += genelf.o
> > >  perf-y += api-io.o
> > > +perf-y += pfm.o
> > >
> > >  $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
> > >         $(call rule_mkdir)
> > > diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
> > > index 3471ec52ea11..57c6f8b31624 100644
> > > --- a/tools/perf/tests/builtin-test.c
> > > +++ b/tools/perf/tests/builtin-test.c
> > > @@ -317,6 +317,15 @@ static struct test generic_tests[] = {
> > >                 .desc = "maps__merge_in",
> > >                 .func = test__maps__merge_in,
> > >         },
> > > +       {
> > > +               .desc = "Test libpfm4 support",
> > > +               .func = test__pfm,
> > > +               .subtest = {
> > > +                       .skip_if_fail   = true,
> > > +                       .get_nr         = test__pfm_subtest_get_nr,
> > > +                       .get_desc       = test__pfm_subtest_get_desc,
> > > +               }
> > > +       },
> > >         {
> > >                 .func = NULL,
> > >         },
> > > diff --git a/tools/perf/tests/pfm.c b/tools/perf/tests/pfm.c
> > > new file mode 100644
> > > index 000000000000..76a53126efdf
> > > --- /dev/null
> > > +++ b/tools/perf/tests/pfm.c
> > > @@ -0,0 +1,203 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +/*
> > > + * Test support for libpfm4 event encodings.
> > > + *
> > > + * Copyright 2020 Google LLC.
> > > + */
> > > +#include "tests.h"
> > > +#include "util/debug.h"
> > > +#include "util/evlist.h"
> > > +#include "util/pfm.h"
> > > +
> > > +#include <linux/kernel.h>
> > > +
> > > +#ifdef HAVE_LIBPFM
> > > +static int test__pfm_events(void);
> > > +static int test__pfm_group(void);
> > > +#endif
> > > +
> > > +static const struct {
> > > +       int (*func)(void);
> > > +       const char *desc;
> > > +} pfm_testcase_table[] = {
> > > +#ifdef HAVE_LIBPFM
> > > +       {
> > > +               .func = test__pfm_events,
> > > +               .desc = "test of individual --pfm-events",
> > > +       },
> > > +       {
> > > +               .func = test__pfm_group,
> > > +               .desc = "test groups of --pfm-events",
> > > +       },
> > > +#endif
> > > +};
> > > +
> > > +#ifdef HAVE_LIBPFM
> > > +static int count_pfm_events(struct perf_evlist *evlist)
> > > +{
> > > +       struct perf_evsel *evsel;
> > > +       int count = 0;
> > > +
> > > +       perf_evlist__for_each_entry(evlist, evsel) {
> > > +               count++;
> > > +       }
> > > +       return count;
> > > +}
> > > +
> > > +static int test__pfm_events(void)
> > > +{
> > > +       struct evlist *evlist;
> > > +       struct option opt;
> > > +       size_t i;
> > > +       const struct {
> > > +               const char *events;
> > > +               int nr_events;
> > > +       } table[] = {
> > > +               {
> > > +                       .events = "",
> > > +                       .nr_events = 0,
> > > +               },
> > > +               {
> > > +                       .events = "instructions",
> > > +                       .nr_events = 1,
> > > +               },
> > > +               {
> > > +                       .events = "instructions,cycles",
> > > +                       .nr_events = 2,
> > > +               },
> > > +               {
> > > +                       .events = "stereolab",
> > > +                       .nr_events = 0,
> > > +               },
> > > +               {
> > > +                       .events = "instructions,instructions",
> > > +                       .nr_events = 2,
> > > +               },
> > > +               {
> > > +                       .events = "stereolab,instructions",
> > > +                       .nr_events = 0,
> > > +               },
> > > +               {
> > > +                       .events = "instructions,stereolab",
> > > +                       .nr_events = 1,
> > > +               },
> > > +       };
> > > +
> > > +       for (i = 0; i < ARRAY_SIZE(table); i++) {
> > > +               evlist = evlist__new();
> > > +               if (evlist == NULL)
> > > +                       return -ENOMEM;
> > > +
> > > +               opt.value = evlist;
> > > +               parse_libpfm_events_option(&opt,
> > > +                                       table[i].events,
> > > +                                       0);
> > > +               TEST_ASSERT_EQUAL(table[i].events,
> > > +                               count_pfm_events(&evlist->core),
> > > +                               table[i].nr_events);
> > > +               TEST_ASSERT_EQUAL(table[i].events,
> > > +                               evlist->nr_groups,
> > > +                               0);
> > > +
> > > +               evlist__delete(evlist);
> > > +       }
> > > +       return 0;
> > > +}
> > > +
> > > +static int test__pfm_group(void)
> > > +{
> > > +       struct evlist *evlist;
> > > +       struct option opt;
> > > +       size_t i;
> > > +       const struct {
> > > +               const char *events;
> > > +               int nr_events;
> > > +               int nr_groups;
> > > +       } table[] = {
> > > +               {
> > > +                       .events = "{},",
> > > +                       .nr_events = 0,
> > > +                       .nr_groups = 0,
> > > +               },
> > > +               {
> > > +                       .events = "{instructions}",
> > > +                       .nr_events = 1,
> > > +                       .nr_groups = 1,
> > > +               },
> > > +               {
> > > +                       .events = "{instructions},{}",
> > > +                       .nr_events = 1,
> > > +                       .nr_groups = 1,
> > > +               },
> > > +               {
> > > +                       .events = "{},{instructions}",
> > > +                       .nr_events = 0,
> > > +                       .nr_groups = 0,
> > > +               },
> > > +               {
> > > +                       .events = "{instructions},{instructions}",
> > > +                       .nr_events = 2,
> > > +                       .nr_groups = 2,
> > > +               },
> > > +               {
> > > +                       .events = "{instructions,cycles},{instructions,cycles}",
> > > +                       .nr_events = 4,
> > > +                       .nr_groups = 2,
> > > +               },
> > > +               {
> > > +                       .events = "{stereolab}",
> > > +                       .nr_events = 0,
> > > +                       .nr_groups = 0,
> > > +               },
> > > +               {
> > > +                       .events =
> > > +                       "{instructions,cycles},{instructions,stereolab}",
> > > +                       .nr_events = 3,
> > > +                       .nr_groups = 1,
> > > +               },
> > > +       };
> > > +
> > > +       for (i = 0; i < ARRAY_SIZE(table); i++) {
> > > +               evlist = evlist__new();
> > > +               if (evlist == NULL)
> > > +                       return -ENOMEM;
> > > +
> > > +               opt.value = evlist;
> > > +               parse_libpfm_events_option(&opt,
> > > +                                       table[i].events,
> > > +                                       0);
> > > +               TEST_ASSERT_EQUAL(table[i].events,
> > > +                               count_pfm_events(&evlist->core),
> > > +                               table[i].nr_events);
> > > +               TEST_ASSERT_EQUAL(table[i].events,
> > > +                               evlist->nr_groups,
> > > +                               table[i].nr_groups);
> > > +
> > > +               evlist__delete(evlist);
> > > +       }
> > > +       return 0;
> > > +}
> > > +#endif
> > > +
> > > +const char *test__pfm_subtest_get_desc(int i)
> > > +{
> > > +       if (i < 0 || i >= (int)ARRAY_SIZE(pfm_testcase_table))
> > > +               return NULL;
> > > +       return pfm_testcase_table[i].desc;
> > > +}
> > > +
> > > +int test__pfm_subtest_get_nr(void)
> > > +{
> > > +       return (int)ARRAY_SIZE(pfm_testcase_table);
> > > +}
> > > +
> > > +int test__pfm(struct test *test __maybe_unused, int i __maybe_unused)
> > > +{
> > > +#ifdef HAVE_LIBPFM
> > > +       if (i < 0 || i >= (int)ARRAY_SIZE(pfm_testcase_table))
> > > +               return TEST_FAIL;
> > > +       return pfm_testcase_table[i].func();
> > > +#else
> > > +       return TEST_SKIP;
> > > +#endif
> > > +}
> > > diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
> > > index d6d4ac34eeb7..a2ae0d2e6087 100644
> > > --- a/tools/perf/tests/tests.h
> > > +++ b/tools/perf/tests/tests.h
> > > @@ -113,6 +113,9 @@ int test__maps__merge_in(struct test *t, int subtest);
> > >  int test__time_utils(struct test *t, int subtest);
> > >  int test__jit_write_elf(struct test *test, int subtest);
> > >  int test__api_io(struct test *test, int subtest);
> > > +int test__pfm(struct test *test, int subtest);
> > > +const char *test__pfm_subtest_get_desc(int subtest);
> > > +int test__pfm_subtest_get_nr(void);
> > >
> > >  bool test__bp_signal_is_supported(void);
> > >  bool test__bp_account_is_supported(void);
> > > diff --git a/tools/perf/util/Build b/tools/perf/util/Build
> > > index ca07a162d602..dfda916f0b4c 100644
> > > --- a/tools/perf/util/Build
> > > +++ b/tools/perf/util/Build
> > > @@ -179,6 +179,8 @@ perf-$(CONFIG_LIBBPF) += bpf-event.o
> > >
> > >  perf-$(CONFIG_CXX) += c++/
> > >
> > > +perf-$(CONFIG_LIBPFM4) += pfm.o
> > > +
> > >  CFLAGS_config.o   += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))"
> > >  CFLAGS_llvm-utils.o += -DPERF_INCLUDE_DIR="BUILD_STR($(perf_include_dir_SQ))"
> > >
> > > diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
> > > index f3e60c45d59a..d7ea1a7e74cd 100644
> > > --- a/tools/perf/util/evsel.c
> > > +++ b/tools/perf/util/evsel.c
> > > @@ -2416,7 +2416,7 @@ bool evsel__fallback(struct evsel *evsel, int err, char *msg, size_t msgsize)
> > >
> > >                 /* Is there already the separator in the name. */
> > >                 if (strchr(name, '/') ||
> > > -                   strchr(name, ':'))
> > > +                   (strchr(name, ':') && !evsel->is_libpfm_event))
> > >                         sep = "";
> > >
> > >                 if (asprintf(&new_name, "%s%su", name, sep) < 0)
> > > diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
> > > index 351c0aaf2a11..5a4f20ddeb49 100644
> > > --- a/tools/perf/util/evsel.h
> > > +++ b/tools/perf/util/evsel.h
> > > @@ -76,6 +76,7 @@ struct evsel {
> > >         bool                    ignore_missing_thread;
> > >         bool                    forced_leader;
> > >         bool                    use_uncore_alias;
> > > +       bool                    is_libpfm_event;
> > >         /* parse modifier helper */
> > >         int                     exclude_GH;
> > >         int                     sample_read;
> > > diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
> > > index b7a0518d607d..0ee3338a0449 100644
> > > --- a/tools/perf/util/parse-events.c
> > > +++ b/tools/perf/util/parse-events.c
> > > @@ -36,6 +36,7 @@
> > >  #include "metricgroup.h"
> > >  #include "util/evsel_config.h"
> > >  #include "util/event.h"
> > > +#include "util/pfm.h"
> > >
> > >  #define MAX_NAME_LEN 100
> > >
> > > @@ -344,6 +345,7 @@ static char *get_config_name(struct list_head *head_terms)
> > >  static struct evsel *
> > >  __add_event(struct list_head *list, int *idx,
> > >             struct perf_event_attr *attr,
> > > +           bool init_attr,
> > >             char *name, struct perf_pmu *pmu,
> > >             struct list_head *config_terms, bool auto_merge_stats,
> > >             const char *cpu_list)
> > > @@ -352,7 +354,8 @@ __add_event(struct list_head *list, int *idx,
> > >         struct perf_cpu_map *cpus = pmu ? pmu->cpus :
> > >                                cpu_list ? perf_cpu_map__new(cpu_list) : NULL;
> > >
> > > -       event_attr_init(attr);
> > > +       if (init_attr)
> > > +               event_attr_init(attr);
> > >
> > >         evsel = perf_evsel__new_idx(attr, *idx);
> > >         if (!evsel)
> > > @@ -370,15 +373,25 @@ __add_event(struct list_head *list, int *idx,
> > >         if (config_terms)
> > >                 list_splice(config_terms, &evsel->config_terms);
> > >
> > > -       list_add_tail(&evsel->core.node, list);
> > > +       if (list)
> > > +               list_add_tail(&evsel->core.node, list);
> > > +
> > >         return evsel;
> > >  }
> > >
> > > +struct evsel *parse_events__add_event(int idx, struct perf_event_attr *attr,
> > > +                                       char *name, struct perf_pmu *pmu)
> > > +{
> > > +       return __add_event(NULL, &idx, attr, false, name, pmu, NULL, false,
> > > +                          NULL);
> > > +}
> > > +
> > >  static int add_event(struct list_head *list, int *idx,
> > >                      struct perf_event_attr *attr, char *name,
> > >                      struct list_head *config_terms)
> > >  {
> > > -       return __add_event(list, idx, attr, name, NULL, config_terms, false, NULL) ? 0 : -ENOMEM;
> > > +       return __add_event(list, idx, attr, true, name, NULL, config_terms,
> > > +                          false, NULL) ? 0 : -ENOMEM;
> > >  }
> > >
> > >  static int add_event_tool(struct list_head *list, int *idx,
> > > @@ -390,7 +403,8 @@ static int add_event_tool(struct list_head *list, int *idx,
> > >                 .config = PERF_COUNT_SW_DUMMY,
> > >         };
> > >
> > > -       evsel = __add_event(list, idx, &attr, NULL, NULL, NULL, false, "0");
> > > +       evsel = __add_event(list, idx, &attr, true, NULL, NULL, NULL, false,
> > > +                           "0");
> > >         if (!evsel)
> > >                 return -ENOMEM;
> > >         evsel->tool_event = tool_event;
> > > @@ -1446,8 +1460,8 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
> > >
> > >         if (!head_config) {
> > >                 attr.type = pmu->type;
> > > -               evsel = __add_event(list, &parse_state->idx, &attr, NULL, pmu, NULL,
> > > -                                   auto_merge_stats, NULL);
> > > +               evsel = __add_event(list, &parse_state->idx, &attr, true, NULL,
> > > +                                   pmu, NULL, auto_merge_stats, NULL);
> > >                 if (evsel) {
> > >                         evsel->pmu_name = name ? strdup(name) : NULL;
> > >                         evsel->use_uncore_alias = use_uncore_alias;
> > > @@ -1488,7 +1502,7 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
> > >                 return -EINVAL;
> > >         }
> > >
> > > -       evsel = __add_event(list, &parse_state->idx, &attr,
> > > +       evsel = __add_event(list, &parse_state->idx, &attr, true,
> > >                             get_config_name(head_config), pmu,
> > >                             &config_terms, auto_merge_stats, NULL);
> > >         if (evsel) {
> > > @@ -2817,6 +2831,8 @@ void print_events(const char *event_glob, bool name_only, bool quiet_flag,
> > >         print_sdt_events(NULL, NULL, name_only);
> > >
> > >         metricgroup__print(true, true, NULL, name_only, details_flag);
> > > +
> > > +       print_libpfm_events(name_only, long_desc);
> > >  }
> > >
> > >  int parse_events__is_hardcoded_term(struct parse_events_term *term)
> > > diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
> > > index 6ead9661238c..04e3f627c081 100644
> > > --- a/tools/perf/util/parse-events.h
> > > +++ b/tools/perf/util/parse-events.h
> > > @@ -17,6 +17,7 @@ struct evlist;
> > >  struct parse_events_error;
> > >
> > >  struct option;
> > > +struct perf_pmu;
> > >
> > >  struct tracepoint_path {
> > >         char *system;
> > > @@ -187,6 +188,9 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
> > >                          bool auto_merge_stats,
> > >                          bool use_alias);
> > >
> > > +struct evsel *parse_events__add_event(int idx, struct perf_event_attr *attr,
> > > +                                       char *name, struct perf_pmu *pmu);
> > > +
> > >  int parse_events_multi_pmu_add(struct parse_events_state *parse_state,
> > >                                char *str,
> > >                                struct list_head **listp);
> > > diff --git a/tools/perf/util/pfm.c b/tools/perf/util/pfm.c
> > > new file mode 100644
> > > index 000000000000..d735acb6c29c
> > > --- /dev/null
> > > +++ b/tools/perf/util/pfm.c
> > > @@ -0,0 +1,281 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +/*
> > > + * Support for libpfm4 event encoding.
> > > + *
> > > + * Copyright 2020 Google LLC.
> > > + */
> > > +#include "util/cpumap.h"
> > > +#include "util/debug.h"
> > > +#include "util/event.h"
> > > +#include "util/evlist.h"
> > > +#include "util/evsel.h"
> > > +#include "util/parse-events.h"
> > > +#include "util/pmu.h"
> > > +#include "util/pfm.h"
> > > +
> > > +#include <string.h>
> > > +#include <linux/kernel.h>
> > > +#include <perfmon/pfmlib_perf_event.h>
> > > +
> > > +static void libpfm_initialize(void)
> > > +{
> > > +       int ret;
> > > +
> > > +       ret = pfm_initialize();
> > > +       if (ret != PFM_SUCCESS) {
> > > +               ui__warning("libpfm failed to initialize: %s\n",
> > > +                       pfm_strerror(ret));
> > > +       }
> > > +}
> > > +
> > > +int parse_libpfm_events_option(const struct option *opt, const char *str,
> > > +                       int unset __maybe_unused)
> > > +{
> > > +       struct evlist *evlist = *(struct evlist **)opt->value;
> > > +       struct perf_event_attr attr;
> > > +       struct perf_pmu *pmu;
> > > +       struct evsel *evsel, *grp_leader = NULL;
> > > +       char *p, *q, *p_orig;
> > > +       const char *sep;
> > > +       int grp_evt = -1;
> > > +       int ret;
> > > +
> > > +       libpfm_initialize();
> > > +
> > > +       p_orig = p = strdup(str);
> > > +       if (!p)
> > > +               return -1;
> > > +       /*
> > > +        * force loading of the PMU list
> > > +        */
> > > +       perf_pmu__scan(NULL);
> > > +
> > > +       for (q = p; strsep(&p, ",{}"); q = p) {
> > > +               sep = p ? str + (p - p_orig - 1) : "";
> > > +               if (*sep == '{') {
> > > +                       if (grp_evt > -1) {
> > > +                               ui__error(
> > > +                                       "nested event groups not supported\n");
> > > +                               goto error;
> > > +                       }
> > > +                       grp_evt++;
> > > +               }
> > > +
> > > +               /* no event */
> > > +               if (*q == '\0')
> > > +                       continue;
> > > +
> > > +               memset(&attr, 0, sizeof(attr));
> > > +               event_attr_init(&attr);
> > > +
> > > +               ret = pfm_get_perf_event_encoding(q, PFM_PLM0|PFM_PLM3,
> > > +                                               &attr, NULL, NULL);
> > > +
> > > +               if (ret != PFM_SUCCESS) {
> > > +                       ui__error("failed to parse event %s : %s\n", str,
> > > +                                 pfm_strerror(ret));
> > > +                       goto error;
> > > +               }
> > > +
> > > +               pmu = perf_pmu__find_by_type((unsigned int)attr.type);
> > > +               evsel = parse_events__add_event(evlist->core.nr_entries,
> > > +                                               &attr, q, pmu);
> > > +               if (evsel == NULL)
> > > +                       goto error;
> > > +
> > > +               evsel->is_libpfm_event = true;
> > > +
> > > +               evlist__add(evlist, evsel);
> > > +
> > > +               if (grp_evt == 0)
> > > +                       grp_leader = evsel;
> > > +
> > > +               if (grp_evt > -1) {
> > > +                       evsel->leader = grp_leader;
> > > +                       grp_leader->core.nr_members++;
> > > +                       grp_evt++;
> > > +               }
> > > +
> > > +               if (*sep == '}') {
> > > +                       if (grp_evt < 0) {
> > > +                               ui__error(
> > > +                                  "cannot close a non-existing event group\n");
> > > +                               goto error;
> > > +                       }
> > > +                       evlist->nr_groups++;
> > > +                       grp_leader = NULL;
> > > +                       grp_evt = -1;
> > > +               }
> > > +       }
> > > +       return 0;
> > > +error:
> > > +       free(p_orig);
> > > +       return -1;
> > > +}
> > > +
> > > +static const char *srcs[PFM_ATTR_CTRL_MAX] = {
> > > +       [PFM_ATTR_CTRL_UNKNOWN] = "???",
> > > +       [PFM_ATTR_CTRL_PMU] = "PMU",
> > > +       [PFM_ATTR_CTRL_PERF_EVENT] = "perf_event",
> > > +};
> > > +
> > > +static void
> > > +print_attr_flags(pfm_event_attr_info_t *info)
> > > +{
> > > +       int n = 0;
> > > +
> > > +       if (info->is_dfl) {
> > > +               printf("[default] ");
> > > +               n++;
> > > +       }
> > > +
> > > +       if (info->is_precise) {
> > > +               printf("[precise] ");
> > > +               n++;
> > > +       }
> > > +
> > > +       if (!n)
> > > +               printf("- ");
> > > +}
> > > +
> > > +static void
> > > +print_libpfm_events_detailed(pfm_event_info_t *info, bool long_desc)
> > > +{
> > > +       pfm_event_attr_info_t ainfo;
> > > +       const char *src;
> > > +       int j, ret;
> > > +
> > > +       ainfo.size = sizeof(ainfo);
> > > +
> > > +       printf("  %s\n", info->name);
> > > +       printf("    [%s]\n", info->desc);
> > > +       if (long_desc) {
> > > +               if (info->equiv)
> > > +                       printf("      Equiv: %s\n", info->equiv);
> > > +
> > > +               printf("      Code  : 0x%"PRIx64"\n", info->code);
> > > +       }
> > > +       pfm_for_each_event_attr(j, info) {
> > > +               ret = pfm_get_event_attr_info(info->idx, j,
> > > +                                             PFM_OS_PERF_EVENT_EXT, &ainfo);
> > > +               if (ret != PFM_SUCCESS)
> > > +                       continue;
> > > +
> > > +               if (ainfo.type == PFM_ATTR_UMASK) {
> > > +                       printf("      %s:%s\n", info->name, ainfo.name);
> > > +                       printf("        [%s]\n", ainfo.desc);
> > > +               }
> > > +
> > > +               if (!long_desc)
> > > +                       continue;
> > > +
> > > +               if (ainfo.ctrl >= PFM_ATTR_CTRL_MAX)
> > > +                       ainfo.ctrl = PFM_ATTR_CTRL_UNKNOWN;
> > > +
> > > +               src = srcs[ainfo.ctrl];
> > > +               switch (ainfo.type) {
> > > +               case PFM_ATTR_UMASK:
> > > +                       printf("        Umask : 0x%02"PRIx64" : %s: ",
> > > +                               ainfo.code, src);
> > > +                       print_attr_flags(&ainfo);
> > > +                       putchar('\n');
> > > +                       break;
> > > +               case PFM_ATTR_MOD_BOOL:
> > > +                       printf("      Modif : %s: [%s] : %s (boolean)\n", src,
> > > +                               ainfo.name, ainfo.desc);
> > > +                       break;
> > > +               case PFM_ATTR_MOD_INTEGER:
> > > +                       printf("      Modif : %s: [%s] : %s (integer)\n", src,
> > > +                               ainfo.name, ainfo.desc);
> > > +                       break;
> > > +               case PFM_ATTR_NONE:
> > > +               case PFM_ATTR_RAW_UMASK:
> > > +               case PFM_ATTR_MAX:
> > > +               default:
> > > +                       printf("      Attr  : %s: [%s] : %s\n", src,
> > > +                               ainfo.name, ainfo.desc);
> > > +               }
> > > +       }
> > > +}
> > > +
> > > +/*
> > > + * list all pmu::event:umask, pmu::event
> > > + * printed events may not be all valid combinations of umask for an event
> > > + */
> > > +static void
> > > +print_libpfm_events_raw(pfm_pmu_info_t *pinfo, pfm_event_info_t *info)
> > > +{
> > > +       pfm_event_attr_info_t ainfo;
> > > +       int j, ret;
> > > +       bool has_umask = false;
> > > +
> > > +       ainfo.size = sizeof(ainfo);
> > > +
> > > +       pfm_for_each_event_attr(j, info) {
> > > +               ret = pfm_get_event_attr_info(info->idx, j,
> > > +                                             PFM_OS_PERF_EVENT_EXT, &ainfo);
> > > +               if (ret != PFM_SUCCESS)
> > > +                       continue;
> > > +
> > > +               if (ainfo.type != PFM_ATTR_UMASK)
> > > +                       continue;
> > > +
> > > +               printf("%s::%s:%s\n", pinfo->name, info->name, ainfo.name);
> > > +               has_umask = true;
> > > +       }
> > > +       if (!has_umask)
> > > +               printf("%s::%s\n", pinfo->name, info->name);
> > > +}
> > > +
> > > +void print_libpfm_events(bool name_only, bool long_desc)
> > > +{
> > > +       pfm_event_info_t info;
> > > +       pfm_pmu_info_t pinfo;
> > > +       int i, p, ret;
> > > +
> > > +       libpfm_initialize();
> > > +
> > > +       /* initialize to zero to indicate ABI version */
> > > +       info.size  = sizeof(info);
> > > +       pinfo.size = sizeof(pinfo);
> > > +
> > > +       if (!name_only)
> > > +               puts("\nList of pre-defined events (to be used in --pfm-events):\n");
> > > +
> > > +       pfm_for_all_pmus(p) {
> > > +               bool printed_pmu = false;
> > > +
> > > +               ret = pfm_get_pmu_info(p, &pinfo);
> > > +               if (ret != PFM_SUCCESS)
> > > +                       continue;
> > > +
> > > +               /* only print events that are supported by host HW */
> > > +               if (!pinfo.is_present)
> > > +                       continue;
> > > +
> > > +               /* handled by perf directly */
> > > +               if (pinfo.pmu == PFM_PMU_PERF_EVENT)
> > > +                       continue;
> > > +
> > > +               for (i = pinfo.first_event; i != -1;
> > > +                    i = pfm_get_event_next(i)) {
> > > +
> > > +                       ret = pfm_get_event_info(i, PFM_OS_PERF_EVENT_EXT,
> > > +                                               &info);
> > > +                       if (ret != PFM_SUCCESS)
> > > +                               continue;
> > > +
> > > +                       if (!name_only && !printed_pmu) {
> > > +                               printf("%s:\n", pinfo.name);
> > > +                               printed_pmu = true;
> > > +                       }
> > > +
> > > +                       if (!name_only)
> > > +                               print_libpfm_events_detailed(&info, long_desc);
> > > +                       else
> > > +                               print_libpfm_events_raw(&pinfo, &info);
> > > +               }
> > > +               if (!name_only && printed_pmu)
> > > +                       putchar('\n');
> > > +       }
> > > +}
> > > diff --git a/tools/perf/util/pfm.h b/tools/perf/util/pfm.h
> > > new file mode 100644
> > > index 000000000000..7d70dda87012
> > > --- /dev/null
> > > +++ b/tools/perf/util/pfm.h
> > > @@ -0,0 +1,37 @@
> > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > +/*
> > > + * Support for libpfm4 event encoding.
> > > + *
> > > + * Copyright 2020 Google LLC.
> > > + */
> > > +#ifndef __PERF_PFM_H
> > > +#define __PERF_PFM_H
> > > +
> > > +#include <subcmd/parse-options.h>
> > > +
> > > +#ifdef HAVE_LIBPFM
> > > +int parse_libpfm_events_option(const struct option *opt, const char *str,
> > > +                       int unset);
> > > +
> > > +void print_libpfm_events(bool name_only, bool long_desc);
> > > +
> > > +#else
> > > +#include <linux/compiler.h>
> > > +
> > > +static inline int parse_libpfm_events_option(
> > > +       const struct option *opt __maybe_unused,
> > > +       const char *str __maybe_unused,
> > > +       int unset __maybe_unused)
> > > +{
> > > +       return 0;
> > > +}
> > > +
> > > +static inline void print_libpfm_events(bool name_only __maybe_unused,
> > > +                                      bool long_desc __maybe_unused)
> > > +{
> > > +}
> > > +
> > > +#endif
> > > +
> > > +
> > > +#endif /* __PERF_PFM_H */
> > > --
> > > 2.26.2.526.g744177e7f7-goog
> > >
>
> --
>
> - Arnaldo

^ permalink raw reply

* Re: [PATCH v14 1/1] perf tools: add support for libpfm4
From: Arnaldo Carvalho de Melo @ 2020-05-29 17:36 UTC (permalink / raw)
  To: Ian Rogers
  Cc: Peter Zijlstra, Ingo Molnar, Mark Rutland, Alexander Shishkin,
	Jiri Olsa, Namhyung Kim, Alexei Starovoitov, Daniel Borkmann,
	Martin KaFai Lau, Yonghong Song, Andrii Nakryiko,
	Greg Kroah-Hartman, Thomas Gleixner, Igor Lubashev,
	Alexey Budankov, Florian Fainelli, Adrian Hunter, Andi Kleen,
	Jiwei Sun, yuzhoujian, Kan Liang, Jin Yao, Leo Yan, John Garry,
	LKML, Networking, bpf, linux-perf-users, Stephane Eranian
In-Reply-To: <20200529172310.GE537@kernel.org>

Em Fri, May 29, 2020 at 02:23:10PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Fri, May 29, 2020 at 10:03:51AM -0700, Ian Rogers escreveu:
> > On Tue, May 5, 2020 at 11:29 AM Ian Rogers <irogers@google.com> wrote:
> > >
> > > From: Stephane Eranian <eranian@google.com>
> > >
> > > This patch links perf with the libpfm4 library if it is available
> > > and LIBPFM4 is passed to the build. The libpfm4 library
> > > contains hardware event tables for all processors supported by
> > > perf_events. It is a helper library that helps convert from a
> > > symbolic event name to the event encoding required by the
> > > underlying kernel interface. This library is open-source and
> > > available from: http://perfmon2.sf.net.
> > >
> > > With this patch, it is possible to specify full hardware events
> > > by name. Hardware filters are also supported. Events must be
> > > specified via the --pfm-events and not -e option. Both options
> > > are active at the same time and it is possible to mix and match:
> > >
> > > $ perf stat --pfm-events inst_retired:any_p:c=1:i -e cycles ....
> > >
> > > Signed-off-by: Stephane Eranian <eranian@google.com>
> > > Reviewed-by: Ian Rogers <irogers@google.com>
> > 
> > Ping.
> 
> Check my tmp.perf/core branch, I had to make some adjustments, mostly in
> the 'perf test' entries as I merged a java demangle test that touched
> the same files,
> 
> I'm now doing the build tests.

Talking about build  tests, you forgot to add it there, like I did
below, I'll eventually do it, as it is opt-in, no biggie at this point.

I'll install libpfm-devel that is in fedora and do further tests, later
today.

- Arnaldo

commit a01c205e3c4cd6d134317413f2dc3129c4ab7a5a
Author: Arnaldo Carvalho de Melo <acme@redhat.com>
Date:   Fri May 29 11:31:23 2020 -0300

    perf build: Add NO_SYSCALL_TABLE=1 to the build tests
    
    So that we make sure that even on x86-64 and other architectures where
    that is the default method we test build the fallback to libaudit that
    other architectures use.
    
    I.e. now this line got added to:
    
      $ make -C tools/perf build-test
      <SNIP>
           make_no_syscall_tbl_O: cd . && make NO_SYSCALL_TABLE=1 FEATURES_DUMP=/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j12 O=/tmp/tmp.W0HtKR1mfr DESTDIR=/tmp/tmp.lNezgCVPzW
      <SNIP>
      $
    
    Cc: Adrian Hunter <adrian.hunter@intel.com>
    Cc: Ingo Molnar <mingo@kernel.org>
    Cc: Jiri Olsa <jolsa@kernel.org>
    Cc: Namhyung Kim <namhyung@kernel.org>
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index 29ce0da7fca6..a4ffa3c7fcb6 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -88,6 +88,7 @@ make_no_libbpf_DEBUG := NO_LIBBPF=1 DEBUG=1
 make_no_libcrypto   := NO_LIBCRYPTO=1
 make_with_babeltrace:= LIBBABELTRACE=1
 make_no_sdt	    := NO_SDT=1
+make_no_syscall_tbl := NO_SYSCALL_TABLE=1
 make_with_clangllvm := LIBCLANGLLVM=1
 make_tags           := tags
 make_cscope         := cscope
@@ -113,7 +114,7 @@ make_minimal        += NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1
 make_minimal        += NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1
 make_minimal        += NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1
 make_minimal        += NO_LIBCRYPTO=1 NO_SDT=1 NO_JVMTI=1 NO_LIBZSTD=1
-make_minimal        += NO_LIBCAP=1
+make_minimal        += NO_LIBCAP=1 NO_SYSCALL_TABLE=1
 
 # $(run) contains all available tests
 run := make_pure
@@ -146,6 +147,7 @@ run += make_no_libbionic
 run += make_no_auxtrace
 run += make_no_libbpf
 run += make_no_libbpf_DEBUG
+run += make_no_syscall_tbl
 run += make_with_babeltrace
 run += make_with_clangllvm
 run += make_help

^ permalink raw reply related

* Re: [PATCH] dt-bindings: leds: fix macro names for pca955x
From: Rob Herring @ 2020-05-29 17:27 UTC (permalink / raw)
  To: Flavio Suligoi
  Cc: linux-kernel, Dan Murphy, devicetree, Pavel Machek,
	Jacek Anaszewski, Rob Herring, linux-leds
In-Reply-To: <20200526092052.24172-1-f.suligoi@asem.it>

On Tue, 26 May 2020 11:20:52 +0200, Flavio Suligoi wrote:
> The documentation reports the wrong macro names
> related to the pca9532 instead of the pca955x
> 
> Signed-off-by: Flavio Suligoi <f.suligoi@asem.it>
> ---
>  Documentation/devicetree/bindings/leds/leds-pca955x.txt | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 

Acked-by: Rob Herring <robh@kernel.org>

^ permalink raw reply

* Re: [PATCH net 3/3] mptcp: remove msk from the token container at destruction time.
From: Mat Martineau @ 2020-05-29 17:36 UTC (permalink / raw)
  To: Paolo Abeni; +Cc: netdev, David S. Miller, Jakub Kicinski
In-Reply-To: <73105e38dc7e9153dc3b58a3c4ccc59de3a10947.1590766645.git.pabeni@redhat.com>

On Fri, 29 May 2020, Paolo Abeni wrote:

> Currently we remote the msk from the token container only
> via mptcp_close(). The MPTCP master socket can be destroyed
> also via other paths (e.g. if not yet accepted, when shutting
> down the listener socket). When we hit the latter scenario,
> dangling msk references are left into the token container,
> leading to memory corruption and/or UaF.
>
> This change addresses the issue by moving the token removal
> into the msk destructor.
>
> Fixes: 79c0949e9a09 ("mptcp: Add key generation and token tree")
> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
> ---
> net/mptcp/protocol.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com>

--
Mat Martineau
Intel

^ permalink raw reply

* Re: [PATCH v14 1/1] perf tools: add support for libpfm4
From: Ian Rogers @ 2020-05-29 17:36 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, Ingo Molnar, Mark Rutland, Alexander Shishkin,
	Jiri Olsa, Namhyung Kim, Alexei Starovoitov, Daniel Borkmann,
	Martin KaFai Lau, Yonghong Song, Andrii Nakryiko,
	Greg Kroah-Hartman, Thomas Gleixner, Igor Lubashev,
	Alexey Budankov, Florian Fainelli, Adrian Hunter, Andi Kleen,
	Jiwei Sun, yuzhoujian <yuzhoujian>
In-Reply-To: <20200529172310.GE537@kernel.org>

On Fri, May 29, 2020 at 10:23 AM Arnaldo Carvalho de Melo
<acme@kernel.org> wrote:
>
> Em Fri, May 29, 2020 at 10:03:51AM -0700, Ian Rogers escreveu:
> > On Tue, May 5, 2020 at 11:29 AM Ian Rogers <irogers@google.com> wrote:
> > >
> > > From: Stephane Eranian <eranian@google.com>
> > >
> > > This patch links perf with the libpfm4 library if it is available
> > > and LIBPFM4 is passed to the build. The libpfm4 library
> > > contains hardware event tables for all processors supported by
> > > perf_events. It is a helper library that helps convert from a
> > > symbolic event name to the event encoding required by the
> > > underlying kernel interface. This library is open-source and
> > > available from: http://perfmon2.sf.net.
> > >
> > > With this patch, it is possible to specify full hardware events
> > > by name. Hardware filters are also supported. Events must be
> > > specified via the --pfm-events and not -e option. Both options
> > > are active at the same time and it is possible to mix and match:
> > >
> > > $ perf stat --pfm-events inst_retired:any_p:c=1:i -e cycles ....
> > >
> > > Signed-off-by: Stephane Eranian <eranian@google.com>
> > > Reviewed-by: Ian Rogers <irogers@google.com>
> >
> > Ping.
>
> Check my tmp.perf/core branch, I had to make some adjustments, mostly in
> the 'perf test' entries as I merged a java demangle test that touched
> the same files,
>
> I'm now doing the build tests.
>
> - Arnaldo


Looks great, thanks Arnaldo!
Ian

> > Thanks,
> > Ian
> >
> > > ---
> > >  tools/perf/Documentation/perf-record.txt |  11 +
> > >  tools/perf/Documentation/perf-stat.txt   |  10 +
> > >  tools/perf/Documentation/perf-top.txt    |  11 +
> > >  tools/perf/Makefile.config               |  13 ++
> > >  tools/perf/Makefile.perf                 |   2 +
> > >  tools/perf/builtin-record.c              |   6 +
> > >  tools/perf/builtin-stat.c                |   6 +
> > >  tools/perf/builtin-top.c                 |   6 +
> > >  tools/perf/tests/Build                   |   1 +
> > >  tools/perf/tests/builtin-test.c          |   9 +
> > >  tools/perf/tests/pfm.c                   | 203 ++++++++++++++++
> > >  tools/perf/tests/tests.h                 |   3 +
> > >  tools/perf/util/Build                    |   2 +
> > >  tools/perf/util/evsel.c                  |   2 +-
> > >  tools/perf/util/evsel.h                  |   1 +
> > >  tools/perf/util/parse-events.c           |  30 ++-
> > >  tools/perf/util/parse-events.h           |   4 +
> > >  tools/perf/util/pfm.c                    | 281 +++++++++++++++++++++++
> > >  tools/perf/util/pfm.h                    |  37 +++
> > >  19 files changed, 630 insertions(+), 8 deletions(-)
> > >  create mode 100644 tools/perf/tests/pfm.c
> > >  create mode 100644 tools/perf/util/pfm.c
> > >  create mode 100644 tools/perf/util/pfm.h
> > >
> > > diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
> > > index 561ef55743e2..492b6b6f2b77 100644
> > > --- a/tools/perf/Documentation/perf-record.txt
> > > +++ b/tools/perf/Documentation/perf-record.txt
> > > @@ -613,6 +613,17 @@ appended unit character - B/K/M/G
> > >         The number of threads to run when synthesizing events for existing processes.
> > >         By default, the number of threads equals 1.
> > >
> > > +ifdef::HAVE_LIBPFM[]
> > > +--pfm-events events::
> > > +Select a PMU event using libpfm4 syntax (see http://perfmon2.sf.net)
> > > +including support for event filters. For example '--pfm-events
> > > +inst_retired:any_p:u:c=1:i'. More than one event can be passed to the
> > > +option using the comma separator. Hardware events and generic hardware
> > > +events cannot be mixed together. The latter must be used with the -e
> > > +option. The -e option and this one can be mixed and matched.  Events
> > > +can be grouped using the {} notation.
> > > +endif::HAVE_LIBPFM[]
> > > +
> > >  SEE ALSO
> > >  --------
> > >  linkperf:perf-stat[1], linkperf:perf-list[1], linkperf:perf-intel-pt[1]
> > > diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
> > > index 3fb5028aef08..b69af18dccd0 100644
> > > --- a/tools/perf/Documentation/perf-stat.txt
> > > +++ b/tools/perf/Documentation/perf-stat.txt
> > > @@ -71,6 +71,16 @@ report::
> > >  --tid=<tid>::
> > >          stat events on existing thread id (comma separated list)
> > >
> > > +ifdef::HAVE_LIBPFM[]
> > > +--pfm-events events::
> > > +Select a PMU event using libpfm4 syntax (see http://perfmon2.sf.net)
> > > +including support for event filters. For example '--pfm-events
> > > +inst_retired:any_p:u:c=1:i'. More than one event can be passed to the
> > > +option using the comma separator. Hardware events and generic hardware
> > > +events cannot be mixed together. The latter must be used with the -e
> > > +option. The -e option and this one can be mixed and matched.  Events
> > > +can be grouped using the {} notation.
> > > +endif::HAVE_LIBPFM[]
> > >
> > >  -a::
> > >  --all-cpus::
> > > diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt
> > > index 20227dabc208..ee2024691d46 100644
> > > --- a/tools/perf/Documentation/perf-top.txt
> > > +++ b/tools/perf/Documentation/perf-top.txt
> > > @@ -329,6 +329,17 @@ Default is to monitor all CPUS.
> > >         The known limitations include exception handing such as
> > >         setjmp/longjmp will have calls/returns not match.
> > >
> > > +ifdef::HAVE_LIBPFM[]
> > > +--pfm-events events::
> > > +Select a PMU event using libpfm4 syntax (see http://perfmon2.sf.net)
> > > +including support for event filters. For example '--pfm-events
> > > +inst_retired:any_p:u:c=1:i'. More than one event can be passed to the
> > > +option using the comma separator. Hardware events and generic hardware
> > > +events cannot be mixed together. The latter must be used with the -e
> > > +option. The -e option and this one can be mixed and matched.  Events
> > > +can be grouped using the {} notation.
> > > +endif::HAVE_LIBPFM[]
> > > +
> > >  INTERACTIVE PROMPTING KEYS
> > >  --------------------------
> > >
> > > diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
> > > index 12a8204d63c6..b67804fee1e3 100644
> > > --- a/tools/perf/Makefile.config
> > > +++ b/tools/perf/Makefile.config
> > > @@ -1012,6 +1012,19 @@ ifdef LIBCLANGLLVM
> > >    endif
> > >  endif
> > >
> > > +ifdef LIBPFM4
> > > +  $(call feature_check,libpfm4)
> > > +  ifeq ($(feature-libpfm4), 1)
> > > +    CFLAGS += -DHAVE_LIBPFM
> > > +    EXTLIBS += -lpfm
> > > +    ASCIIDOC_EXTRA = -aHAVE_LIBPFM=1
> > > +    $(call detected,CONFIG_LIBPFM4)
> > > +  else
> > > +    msg := $(warning libpfm4 not found, disables libpfm4 support. Please install libpfm4-dev);
> > > +    NO_LIBPFM4 := 1
> > > +  endif
> > > +endif
> > > +
> > >  # Among the variables below, these:
> > >  #   perfexecdir
> > >  #   perf_include_dir
> > > diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
> > > index 94a495594e99..dc82578c8773 100644
> > > --- a/tools/perf/Makefile.perf
> > > +++ b/tools/perf/Makefile.perf
> > > @@ -118,6 +118,8 @@ include ../scripts/utilities.mak
> > >  #
> > >  # Define LIBBPF_DYNAMIC to enable libbpf dynamic linking.
> > >  #
> > > +# Define LIBPFM4 to enable libpfm4 events extension.
> > > +#
> > >
> > >  # As per kernel Makefile, avoid funny character set dependencies
> > >  unexport LC_ALL
> > > diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
> > > index e4efdbf1a81e..98387cce3207 100644
> > > --- a/tools/perf/builtin-record.c
> > > +++ b/tools/perf/builtin-record.c
> > > @@ -45,6 +45,7 @@
> > >  #include "util/units.h"
> > >  #include "util/bpf-event.h"
> > >  #include "util/util.h"
> > > +#include "util/pfm.h"
> > >  #include "asm/bug.h"
> > >  #include "perf.h"
> > >
> > > @@ -2506,6 +2507,11 @@ static struct option __record_options[] = {
> > >         OPT_UINTEGER(0, "num-thread-synthesize",
> > >                      &record.opts.nr_threads_synthesize,
> > >                      "number of threads to run for event synthesis"),
> > > +#ifdef HAVE_LIBPFM
> > > +       OPT_CALLBACK(0, "pfm-events", &record.evlist, "event",
> > > +               "libpfm4 event selector. use 'perf list' to list available events",
> > > +               parse_libpfm_events_option),
> > > +#endif
> > >         OPT_END()
> > >  };
> > >
> > > diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
> > > index e0c1ad23c768..f6e2dd57f48e 100644
> > > --- a/tools/perf/builtin-stat.c
> > > +++ b/tools/perf/builtin-stat.c
> > > @@ -66,6 +66,7 @@
> > >  #include "util/time-utils.h"
> > >  #include "util/top.h"
> > >  #include "util/affinity.h"
> > > +#include "util/pfm.h"
> > >  #include "asm/bug.h"
> > >
> > >  #include <linux/time64.h>
> > > @@ -935,6 +936,11 @@ static struct option stat_options[] = {
> > >                     "Use with 'percore' event qualifier to show the event "
> > >                     "counts of one hardware thread by sum up total hardware "
> > >                     "threads of same physical core"),
> > > +#ifdef HAVE_LIBPFM
> > > +       OPT_CALLBACK(0, "pfm-events", &evsel_list, "event",
> > > +               "libpfm4 event selector. use 'perf list' to list available events",
> > > +               parse_libpfm_events_option),
> > > +#endif
> > >         OPT_END()
> > >  };
> > >
> > > diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
> > > index 372c38254654..20c41d9040ee 100644
> > > --- a/tools/perf/builtin-top.c
> > > +++ b/tools/perf/builtin-top.c
> > > @@ -53,6 +53,7 @@
> > >
> > >  #include "util/debug.h"
> > >  #include "util/ordered-events.h"
> > > +#include "util/pfm.h"
> > >
> > >  #include <assert.h>
> > >  #include <elf.h>
> > > @@ -1575,6 +1576,11 @@ int cmd_top(int argc, const char **argv)
> > >                     "WARNING: should be used on grouped events."),
> > >         OPT_BOOLEAN(0, "stitch-lbr", &top.stitch_lbr,
> > >                     "Enable LBR callgraph stitching approach"),
> > > +#ifdef HAVE_LIBPFM
> > > +       OPT_CALLBACK(0, "pfm-events", &top.evlist, "event",
> > > +               "libpfm4 event selector. use 'perf list' to list available events",
> > > +               parse_libpfm_events_option),
> > > +#endif
> > >         OPTS_EVSWITCH(&top.evswitch),
> > >         OPT_END()
> > >         };
> > > diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
> > > index c75557aeef0e..4e74a363b0b0 100644
> > > --- a/tools/perf/tests/Build
> > > +++ b/tools/perf/tests/Build
> > > @@ -57,6 +57,7 @@ perf-y += maps.o
> > >  perf-y += time-utils-test.o
> > >  perf-y += genelf.o
> > >  perf-y += api-io.o
> > > +perf-y += pfm.o
> > >
> > >  $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
> > >         $(call rule_mkdir)
> > > diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
> > > index 3471ec52ea11..57c6f8b31624 100644
> > > --- a/tools/perf/tests/builtin-test.c
> > > +++ b/tools/perf/tests/builtin-test.c
> > > @@ -317,6 +317,15 @@ static struct test generic_tests[] = {
> > >                 .desc = "maps__merge_in",
> > >                 .func = test__maps__merge_in,
> > >         },
> > > +       {
> > > +               .desc = "Test libpfm4 support",
> > > +               .func = test__pfm,
> > > +               .subtest = {
> > > +                       .skip_if_fail   = true,
> > > +                       .get_nr         = test__pfm_subtest_get_nr,
> > > +                       .get_desc       = test__pfm_subtest_get_desc,
> > > +               }
> > > +       },
> > >         {
> > >                 .func = NULL,
> > >         },
> > > diff --git a/tools/perf/tests/pfm.c b/tools/perf/tests/pfm.c
> > > new file mode 100644
> > > index 000000000000..76a53126efdf
> > > --- /dev/null
> > > +++ b/tools/perf/tests/pfm.c
> > > @@ -0,0 +1,203 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +/*
> > > + * Test support for libpfm4 event encodings.
> > > + *
> > > + * Copyright 2020 Google LLC.
> > > + */
> > > +#include "tests.h"
> > > +#include "util/debug.h"
> > > +#include "util/evlist.h"
> > > +#include "util/pfm.h"
> > > +
> > > +#include <linux/kernel.h>
> > > +
> > > +#ifdef HAVE_LIBPFM
> > > +static int test__pfm_events(void);
> > > +static int test__pfm_group(void);
> > > +#endif
> > > +
> > > +static const struct {
> > > +       int (*func)(void);
> > > +       const char *desc;
> > > +} pfm_testcase_table[] = {
> > > +#ifdef HAVE_LIBPFM
> > > +       {
> > > +               .func = test__pfm_events,
> > > +               .desc = "test of individual --pfm-events",
> > > +       },
> > > +       {
> > > +               .func = test__pfm_group,
> > > +               .desc = "test groups of --pfm-events",
> > > +       },
> > > +#endif
> > > +};
> > > +
> > > +#ifdef HAVE_LIBPFM
> > > +static int count_pfm_events(struct perf_evlist *evlist)
> > > +{
> > > +       struct perf_evsel *evsel;
> > > +       int count = 0;
> > > +
> > > +       perf_evlist__for_each_entry(evlist, evsel) {
> > > +               count++;
> > > +       }
> > > +       return count;
> > > +}
> > > +
> > > +static int test__pfm_events(void)
> > > +{
> > > +       struct evlist *evlist;
> > > +       struct option opt;
> > > +       size_t i;
> > > +       const struct {
> > > +               const char *events;
> > > +               int nr_events;
> > > +       } table[] = {
> > > +               {
> > > +                       .events = "",
> > > +                       .nr_events = 0,
> > > +               },
> > > +               {
> > > +                       .events = "instructions",
> > > +                       .nr_events = 1,
> > > +               },
> > > +               {
> > > +                       .events = "instructions,cycles",
> > > +                       .nr_events = 2,
> > > +               },
> > > +               {
> > > +                       .events = "stereolab",
> > > +                       .nr_events = 0,
> > > +               },
> > > +               {
> > > +                       .events = "instructions,instructions",
> > > +                       .nr_events = 2,
> > > +               },
> > > +               {
> > > +                       .events = "stereolab,instructions",
> > > +                       .nr_events = 0,
> > > +               },
> > > +               {
> > > +                       .events = "instructions,stereolab",
> > > +                       .nr_events = 1,
> > > +               },
> > > +       };
> > > +
> > > +       for (i = 0; i < ARRAY_SIZE(table); i++) {
> > > +               evlist = evlist__new();
> > > +               if (evlist == NULL)
> > > +                       return -ENOMEM;
> > > +
> > > +               opt.value = evlist;
> > > +               parse_libpfm_events_option(&opt,
> > > +                                       table[i].events,
> > > +                                       0);
> > > +               TEST_ASSERT_EQUAL(table[i].events,
> > > +                               count_pfm_events(&evlist->core),
> > > +                               table[i].nr_events);
> > > +               TEST_ASSERT_EQUAL(table[i].events,
> > > +                               evlist->nr_groups,
> > > +                               0);
> > > +
> > > +               evlist__delete(evlist);
> > > +       }
> > > +       return 0;
> > > +}
> > > +
> > > +static int test__pfm_group(void)
> > > +{
> > > +       struct evlist *evlist;
> > > +       struct option opt;
> > > +       size_t i;
> > > +       const struct {
> > > +               const char *events;
> > > +               int nr_events;
> > > +               int nr_groups;
> > > +       } table[] = {
> > > +               {
> > > +                       .events = "{},",
> > > +                       .nr_events = 0,
> > > +                       .nr_groups = 0,
> > > +               },
> > > +               {
> > > +                       .events = "{instructions}",
> > > +                       .nr_events = 1,
> > > +                       .nr_groups = 1,
> > > +               },
> > > +               {
> > > +                       .events = "{instructions},{}",
> > > +                       .nr_events = 1,
> > > +                       .nr_groups = 1,
> > > +               },
> > > +               {
> > > +                       .events = "{},{instructions}",
> > > +                       .nr_events = 0,
> > > +                       .nr_groups = 0,
> > > +               },
> > > +               {
> > > +                       .events = "{instructions},{instructions}",
> > > +                       .nr_events = 2,
> > > +                       .nr_groups = 2,
> > > +               },
> > > +               {
> > > +                       .events = "{instructions,cycles},{instructions,cycles}",
> > > +                       .nr_events = 4,
> > > +                       .nr_groups = 2,
> > > +               },
> > > +               {
> > > +                       .events = "{stereolab}",
> > > +                       .nr_events = 0,
> > > +                       .nr_groups = 0,
> > > +               },
> > > +               {
> > > +                       .events =
> > > +                       "{instructions,cycles},{instructions,stereolab}",
> > > +                       .nr_events = 3,
> > > +                       .nr_groups = 1,
> > > +               },
> > > +       };
> > > +
> > > +       for (i = 0; i < ARRAY_SIZE(table); i++) {
> > > +               evlist = evlist__new();
> > > +               if (evlist == NULL)
> > > +                       return -ENOMEM;
> > > +
> > > +               opt.value = evlist;
> > > +               parse_libpfm_events_option(&opt,
> > > +                                       table[i].events,
> > > +                                       0);
> > > +               TEST_ASSERT_EQUAL(table[i].events,
> > > +                               count_pfm_events(&evlist->core),
> > > +                               table[i].nr_events);
> > > +               TEST_ASSERT_EQUAL(table[i].events,
> > > +                               evlist->nr_groups,
> > > +                               table[i].nr_groups);
> > > +
> > > +               evlist__delete(evlist);
> > > +       }
> > > +       return 0;
> > > +}
> > > +#endif
> > > +
> > > +const char *test__pfm_subtest_get_desc(int i)
> > > +{
> > > +       if (i < 0 || i >= (int)ARRAY_SIZE(pfm_testcase_table))
> > > +               return NULL;
> > > +       return pfm_testcase_table[i].desc;
> > > +}
> > > +
> > > +int test__pfm_subtest_get_nr(void)
> > > +{
> > > +       return (int)ARRAY_SIZE(pfm_testcase_table);
> > > +}
> > > +
> > > +int test__pfm(struct test *test __maybe_unused, int i __maybe_unused)
> > > +{
> > > +#ifdef HAVE_LIBPFM
> > > +       if (i < 0 || i >= (int)ARRAY_SIZE(pfm_testcase_table))
> > > +               return TEST_FAIL;
> > > +       return pfm_testcase_table[i].func();
> > > +#else
> > > +       return TEST_SKIP;
> > > +#endif
> > > +}
> > > diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
> > > index d6d4ac34eeb7..a2ae0d2e6087 100644
> > > --- a/tools/perf/tests/tests.h
> > > +++ b/tools/perf/tests/tests.h
> > > @@ -113,6 +113,9 @@ int test__maps__merge_in(struct test *t, int subtest);
> > >  int test__time_utils(struct test *t, int subtest);
> > >  int test__jit_write_elf(struct test *test, int subtest);
> > >  int test__api_io(struct test *test, int subtest);
> > > +int test__pfm(struct test *test, int subtest);
> > > +const char *test__pfm_subtest_get_desc(int subtest);
> > > +int test__pfm_subtest_get_nr(void);
> > >
> > >  bool test__bp_signal_is_supported(void);
> > >  bool test__bp_account_is_supported(void);
> > > diff --git a/tools/perf/util/Build b/tools/perf/util/Build
> > > index ca07a162d602..dfda916f0b4c 100644
> > > --- a/tools/perf/util/Build
> > > +++ b/tools/perf/util/Build
> > > @@ -179,6 +179,8 @@ perf-$(CONFIG_LIBBPF) += bpf-event.o
> > >
> > >  perf-$(CONFIG_CXX) += c++/
> > >
> > > +perf-$(CONFIG_LIBPFM4) += pfm.o
> > > +
> > >  CFLAGS_config.o   += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))"
> > >  CFLAGS_llvm-utils.o += -DPERF_INCLUDE_DIR="BUILD_STR($(perf_include_dir_SQ))"
> > >
> > > diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
> > > index f3e60c45d59a..d7ea1a7e74cd 100644
> > > --- a/tools/perf/util/evsel.c
> > > +++ b/tools/perf/util/evsel.c
> > > @@ -2416,7 +2416,7 @@ bool evsel__fallback(struct evsel *evsel, int err, char *msg, size_t msgsize)
> > >
> > >                 /* Is there already the separator in the name. */
> > >                 if (strchr(name, '/') ||
> > > -                   strchr(name, ':'))
> > > +                   (strchr(name, ':') && !evsel->is_libpfm_event))
> > >                         sep = "";
> > >
> > >                 if (asprintf(&new_name, "%s%su", name, sep) < 0)
> > > diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
> > > index 351c0aaf2a11..5a4f20ddeb49 100644
> > > --- a/tools/perf/util/evsel.h
> > > +++ b/tools/perf/util/evsel.h
> > > @@ -76,6 +76,7 @@ struct evsel {
> > >         bool                    ignore_missing_thread;
> > >         bool                    forced_leader;
> > >         bool                    use_uncore_alias;
> > > +       bool                    is_libpfm_event;
> > >         /* parse modifier helper */
> > >         int                     exclude_GH;
> > >         int                     sample_read;
> > > diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
> > > index b7a0518d607d..0ee3338a0449 100644
> > > --- a/tools/perf/util/parse-events.c
> > > +++ b/tools/perf/util/parse-events.c
> > > @@ -36,6 +36,7 @@
> > >  #include "metricgroup.h"
> > >  #include "util/evsel_config.h"
> > >  #include "util/event.h"
> > > +#include "util/pfm.h"
> > >
> > >  #define MAX_NAME_LEN 100
> > >
> > > @@ -344,6 +345,7 @@ static char *get_config_name(struct list_head *head_terms)
> > >  static struct evsel *
> > >  __add_event(struct list_head *list, int *idx,
> > >             struct perf_event_attr *attr,
> > > +           bool init_attr,
> > >             char *name, struct perf_pmu *pmu,
> > >             struct list_head *config_terms, bool auto_merge_stats,
> > >             const char *cpu_list)
> > > @@ -352,7 +354,8 @@ __add_event(struct list_head *list, int *idx,
> > >         struct perf_cpu_map *cpus = pmu ? pmu->cpus :
> > >                                cpu_list ? perf_cpu_map__new(cpu_list) : NULL;
> > >
> > > -       event_attr_init(attr);
> > > +       if (init_attr)
> > > +               event_attr_init(attr);
> > >
> > >         evsel = perf_evsel__new_idx(attr, *idx);
> > >         if (!evsel)
> > > @@ -370,15 +373,25 @@ __add_event(struct list_head *list, int *idx,
> > >         if (config_terms)
> > >                 list_splice(config_terms, &evsel->config_terms);
> > >
> > > -       list_add_tail(&evsel->core.node, list);
> > > +       if (list)
> > > +               list_add_tail(&evsel->core.node, list);
> > > +
> > >         return evsel;
> > >  }
> > >
> > > +struct evsel *parse_events__add_event(int idx, struct perf_event_attr *attr,
> > > +                                       char *name, struct perf_pmu *pmu)
> > > +{
> > > +       return __add_event(NULL, &idx, attr, false, name, pmu, NULL, false,
> > > +                          NULL);
> > > +}
> > > +
> > >  static int add_event(struct list_head *list, int *idx,
> > >                      struct perf_event_attr *attr, char *name,
> > >                      struct list_head *config_terms)
> > >  {
> > > -       return __add_event(list, idx, attr, name, NULL, config_terms, false, NULL) ? 0 : -ENOMEM;
> > > +       return __add_event(list, idx, attr, true, name, NULL, config_terms,
> > > +                          false, NULL) ? 0 : -ENOMEM;
> > >  }
> > >
> > >  static int add_event_tool(struct list_head *list, int *idx,
> > > @@ -390,7 +403,8 @@ static int add_event_tool(struct list_head *list, int *idx,
> > >                 .config = PERF_COUNT_SW_DUMMY,
> > >         };
> > >
> > > -       evsel = __add_event(list, idx, &attr, NULL, NULL, NULL, false, "0");
> > > +       evsel = __add_event(list, idx, &attr, true, NULL, NULL, NULL, false,
> > > +                           "0");
> > >         if (!evsel)
> > >                 return -ENOMEM;
> > >         evsel->tool_event = tool_event;
> > > @@ -1446,8 +1460,8 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
> > >
> > >         if (!head_config) {
> > >                 attr.type = pmu->type;
> > > -               evsel = __add_event(list, &parse_state->idx, &attr, NULL, pmu, NULL,
> > > -                                   auto_merge_stats, NULL);
> > > +               evsel = __add_event(list, &parse_state->idx, &attr, true, NULL,
> > > +                                   pmu, NULL, auto_merge_stats, NULL);
> > >                 if (evsel) {
> > >                         evsel->pmu_name = name ? strdup(name) : NULL;
> > >                         evsel->use_uncore_alias = use_uncore_alias;
> > > @@ -1488,7 +1502,7 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
> > >                 return -EINVAL;
> > >         }
> > >
> > > -       evsel = __add_event(list, &parse_state->idx, &attr,
> > > +       evsel = __add_event(list, &parse_state->idx, &attr, true,
> > >                             get_config_name(head_config), pmu,
> > >                             &config_terms, auto_merge_stats, NULL);
> > >         if (evsel) {
> > > @@ -2817,6 +2831,8 @@ void print_events(const char *event_glob, bool name_only, bool quiet_flag,
> > >         print_sdt_events(NULL, NULL, name_only);
> > >
> > >         metricgroup__print(true, true, NULL, name_only, details_flag);
> > > +
> > > +       print_libpfm_events(name_only, long_desc);
> > >  }
> > >
> > >  int parse_events__is_hardcoded_term(struct parse_events_term *term)
> > > diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
> > > index 6ead9661238c..04e3f627c081 100644
> > > --- a/tools/perf/util/parse-events.h
> > > +++ b/tools/perf/util/parse-events.h
> > > @@ -17,6 +17,7 @@ struct evlist;
> > >  struct parse_events_error;
> > >
> > >  struct option;
> > > +struct perf_pmu;
> > >
> > >  struct tracepoint_path {
> > >         char *system;
> > > @@ -187,6 +188,9 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
> > >                          bool auto_merge_stats,
> > >                          bool use_alias);
> > >
> > > +struct evsel *parse_events__add_event(int idx, struct perf_event_attr *attr,
> > > +                                       char *name, struct perf_pmu *pmu);
> > > +
> > >  int parse_events_multi_pmu_add(struct parse_events_state *parse_state,
> > >                                char *str,
> > >                                struct list_head **listp);
> > > diff --git a/tools/perf/util/pfm.c b/tools/perf/util/pfm.c
> > > new file mode 100644
> > > index 000000000000..d735acb6c29c
> > > --- /dev/null
> > > +++ b/tools/perf/util/pfm.c
> > > @@ -0,0 +1,281 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +/*
> > > + * Support for libpfm4 event encoding.
> > > + *
> > > + * Copyright 2020 Google LLC.
> > > + */
> > > +#include "util/cpumap.h"
> > > +#include "util/debug.h"
> > > +#include "util/event.h"
> > > +#include "util/evlist.h"
> > > +#include "util/evsel.h"
> > > +#include "util/parse-events.h"
> > > +#include "util/pmu.h"
> > > +#include "util/pfm.h"
> > > +
> > > +#include <string.h>
> > > +#include <linux/kernel.h>
> > > +#include <perfmon/pfmlib_perf_event.h>
> > > +
> > > +static void libpfm_initialize(void)
> > > +{
> > > +       int ret;
> > > +
> > > +       ret = pfm_initialize();
> > > +       if (ret != PFM_SUCCESS) {
> > > +               ui__warning("libpfm failed to initialize: %s\n",
> > > +                       pfm_strerror(ret));
> > > +       }
> > > +}
> > > +
> > > +int parse_libpfm_events_option(const struct option *opt, const char *str,
> > > +                       int unset __maybe_unused)
> > > +{
> > > +       struct evlist *evlist = *(struct evlist **)opt->value;
> > > +       struct perf_event_attr attr;
> > > +       struct perf_pmu *pmu;
> > > +       struct evsel *evsel, *grp_leader = NULL;
> > > +       char *p, *q, *p_orig;
> > > +       const char *sep;
> > > +       int grp_evt = -1;
> > > +       int ret;
> > > +
> > > +       libpfm_initialize();
> > > +
> > > +       p_orig = p = strdup(str);
> > > +       if (!p)
> > > +               return -1;
> > > +       /*
> > > +        * force loading of the PMU list
> > > +        */
> > > +       perf_pmu__scan(NULL);
> > > +
> > > +       for (q = p; strsep(&p, ",{}"); q = p) {
> > > +               sep = p ? str + (p - p_orig - 1) : "";
> > > +               if (*sep == '{') {
> > > +                       if (grp_evt > -1) {
> > > +                               ui__error(
> > > +                                       "nested event groups not supported\n");
> > > +                               goto error;
> > > +                       }
> > > +                       grp_evt++;
> > > +               }
> > > +
> > > +               /* no event */
> > > +               if (*q == '\0')
> > > +                       continue;
> > > +
> > > +               memset(&attr, 0, sizeof(attr));
> > > +               event_attr_init(&attr);
> > > +
> > > +               ret = pfm_get_perf_event_encoding(q, PFM_PLM0|PFM_PLM3,
> > > +                                               &attr, NULL, NULL);
> > > +
> > > +               if (ret != PFM_SUCCESS) {
> > > +                       ui__error("failed to parse event %s : %s\n", str,
> > > +                                 pfm_strerror(ret));
> > > +                       goto error;
> > > +               }
> > > +
> > > +               pmu = perf_pmu__find_by_type((unsigned int)attr.type);
> > > +               evsel = parse_events__add_event(evlist->core.nr_entries,
> > > +                                               &attr, q, pmu);
> > > +               if (evsel == NULL)
> > > +                       goto error;
> > > +
> > > +               evsel->is_libpfm_event = true;
> > > +
> > > +               evlist__add(evlist, evsel);
> > > +
> > > +               if (grp_evt == 0)
> > > +                       grp_leader = evsel;
> > > +
> > > +               if (grp_evt > -1) {
> > > +                       evsel->leader = grp_leader;
> > > +                       grp_leader->core.nr_members++;
> > > +                       grp_evt++;
> > > +               }
> > > +
> > > +               if (*sep == '}') {
> > > +                       if (grp_evt < 0) {
> > > +                               ui__error(
> > > +                                  "cannot close a non-existing event group\n");
> > > +                               goto error;
> > > +                       }
> > > +                       evlist->nr_groups++;
> > > +                       grp_leader = NULL;
> > > +                       grp_evt = -1;
> > > +               }
> > > +       }
> > > +       return 0;
> > > +error:
> > > +       free(p_orig);
> > > +       return -1;
> > > +}
> > > +
> > > +static const char *srcs[PFM_ATTR_CTRL_MAX] = {
> > > +       [PFM_ATTR_CTRL_UNKNOWN] = "???",
> > > +       [PFM_ATTR_CTRL_PMU] = "PMU",
> > > +       [PFM_ATTR_CTRL_PERF_EVENT] = "perf_event",
> > > +};
> > > +
> > > +static void
> > > +print_attr_flags(pfm_event_attr_info_t *info)
> > > +{
> > > +       int n = 0;
> > > +
> > > +       if (info->is_dfl) {
> > > +               printf("[default] ");
> > > +               n++;
> > > +       }
> > > +
> > > +       if (info->is_precise) {
> > > +               printf("[precise] ");
> > > +               n++;
> > > +       }
> > > +
> > > +       if (!n)
> > > +               printf("- ");
> > > +}
> > > +
> > > +static void
> > > +print_libpfm_events_detailed(pfm_event_info_t *info, bool long_desc)
> > > +{
> > > +       pfm_event_attr_info_t ainfo;
> > > +       const char *src;
> > > +       int j, ret;
> > > +
> > > +       ainfo.size = sizeof(ainfo);
> > > +
> > > +       printf("  %s\n", info->name);
> > > +       printf("    [%s]\n", info->desc);
> > > +       if (long_desc) {
> > > +               if (info->equiv)
> > > +                       printf("      Equiv: %s\n", info->equiv);
> > > +
> > > +               printf("      Code  : 0x%"PRIx64"\n", info->code);
> > > +       }
> > > +       pfm_for_each_event_attr(j, info) {
> > > +               ret = pfm_get_event_attr_info(info->idx, j,
> > > +                                             PFM_OS_PERF_EVENT_EXT, &ainfo);
> > > +               if (ret != PFM_SUCCESS)
> > > +                       continue;
> > > +
> > > +               if (ainfo.type == PFM_ATTR_UMASK) {
> > > +                       printf("      %s:%s\n", info->name, ainfo.name);
> > > +                       printf("        [%s]\n", ainfo.desc);
> > > +               }
> > > +
> > > +               if (!long_desc)
> > > +                       continue;
> > > +
> > > +               if (ainfo.ctrl >= PFM_ATTR_CTRL_MAX)
> > > +                       ainfo.ctrl = PFM_ATTR_CTRL_UNKNOWN;
> > > +
> > > +               src = srcs[ainfo.ctrl];
> > > +               switch (ainfo.type) {
> > > +               case PFM_ATTR_UMASK:
> > > +                       printf("        Umask : 0x%02"PRIx64" : %s: ",
> > > +                               ainfo.code, src);
> > > +                       print_attr_flags(&ainfo);
> > > +                       putchar('\n');
> > > +                       break;
> > > +               case PFM_ATTR_MOD_BOOL:
> > > +                       printf("      Modif : %s: [%s] : %s (boolean)\n", src,
> > > +                               ainfo.name, ainfo.desc);
> > > +                       break;
> > > +               case PFM_ATTR_MOD_INTEGER:
> > > +                       printf("      Modif : %s: [%s] : %s (integer)\n", src,
> > > +                               ainfo.name, ainfo.desc);
> > > +                       break;
> > > +               case PFM_ATTR_NONE:
> > > +               case PFM_ATTR_RAW_UMASK:
> > > +               case PFM_ATTR_MAX:
> > > +               default:
> > > +                       printf("      Attr  : %s: [%s] : %s\n", src,
> > > +                               ainfo.name, ainfo.desc);
> > > +               }
> > > +       }
> > > +}
> > > +
> > > +/*
> > > + * list all pmu::event:umask, pmu::event
> > > + * printed events may not be all valid combinations of umask for an event
> > > + */
> > > +static void
> > > +print_libpfm_events_raw(pfm_pmu_info_t *pinfo, pfm_event_info_t *info)
> > > +{
> > > +       pfm_event_attr_info_t ainfo;
> > > +       int j, ret;
> > > +       bool has_umask = false;
> > > +
> > > +       ainfo.size = sizeof(ainfo);
> > > +
> > > +       pfm_for_each_event_attr(j, info) {
> > > +               ret = pfm_get_event_attr_info(info->idx, j,
> > > +                                             PFM_OS_PERF_EVENT_EXT, &ainfo);
> > > +               if (ret != PFM_SUCCESS)
> > > +                       continue;
> > > +
> > > +               if (ainfo.type != PFM_ATTR_UMASK)
> > > +                       continue;
> > > +
> > > +               printf("%s::%s:%s\n", pinfo->name, info->name, ainfo.name);
> > > +               has_umask = true;
> > > +       }
> > > +       if (!has_umask)
> > > +               printf("%s::%s\n", pinfo->name, info->name);
> > > +}
> > > +
> > > +void print_libpfm_events(bool name_only, bool long_desc)
> > > +{
> > > +       pfm_event_info_t info;
> > > +       pfm_pmu_info_t pinfo;
> > > +       int i, p, ret;
> > > +
> > > +       libpfm_initialize();
> > > +
> > > +       /* initialize to zero to indicate ABI version */
> > > +       info.size  = sizeof(info);
> > > +       pinfo.size = sizeof(pinfo);
> > > +
> > > +       if (!name_only)
> > > +               puts("\nList of pre-defined events (to be used in --pfm-events):\n");
> > > +
> > > +       pfm_for_all_pmus(p) {
> > > +               bool printed_pmu = false;
> > > +
> > > +               ret = pfm_get_pmu_info(p, &pinfo);
> > > +               if (ret != PFM_SUCCESS)
> > > +                       continue;
> > > +
> > > +               /* only print events that are supported by host HW */
> > > +               if (!pinfo.is_present)
> > > +                       continue;
> > > +
> > > +               /* handled by perf directly */
> > > +               if (pinfo.pmu == PFM_PMU_PERF_EVENT)
> > > +                       continue;
> > > +
> > > +               for (i = pinfo.first_event; i != -1;
> > > +                    i = pfm_get_event_next(i)) {
> > > +
> > > +                       ret = pfm_get_event_info(i, PFM_OS_PERF_EVENT_EXT,
> > > +                                               &info);
> > > +                       if (ret != PFM_SUCCESS)
> > > +                               continue;
> > > +
> > > +                       if (!name_only && !printed_pmu) {
> > > +                               printf("%s:\n", pinfo.name);
> > > +                               printed_pmu = true;
> > > +                       }
> > > +
> > > +                       if (!name_only)
> > > +                               print_libpfm_events_detailed(&info, long_desc);
> > > +                       else
> > > +                               print_libpfm_events_raw(&pinfo, &info);
> > > +               }
> > > +               if (!name_only && printed_pmu)
> > > +                       putchar('\n');
> > > +       }
> > > +}
> > > diff --git a/tools/perf/util/pfm.h b/tools/perf/util/pfm.h
> > > new file mode 100644
> > > index 000000000000..7d70dda87012
> > > --- /dev/null
> > > +++ b/tools/perf/util/pfm.h
> > > @@ -0,0 +1,37 @@
> > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > +/*
> > > + * Support for libpfm4 event encoding.
> > > + *
> > > + * Copyright 2020 Google LLC.
> > > + */
> > > +#ifndef __PERF_PFM_H
> > > +#define __PERF_PFM_H
> > > +
> > > +#include <subcmd/parse-options.h>
> > > +
> > > +#ifdef HAVE_LIBPFM
> > > +int parse_libpfm_events_option(const struct option *opt, const char *str,
> > > +                       int unset);
> > > +
> > > +void print_libpfm_events(bool name_only, bool long_desc);
> > > +
> > > +#else
> > > +#include <linux/compiler.h>
> > > +
> > > +static inline int parse_libpfm_events_option(
> > > +       const struct option *opt __maybe_unused,
> > > +       const char *str __maybe_unused,
> > > +       int unset __maybe_unused)
> > > +{
> > > +       return 0;
> > > +}
> > > +
> > > +static inline void print_libpfm_events(bool name_only __maybe_unused,
> > > +                                      bool long_desc __maybe_unused)
> > > +{
> > > +}
> > > +
> > > +#endif
> > > +
> > > +
> > > +#endif /* __PERF_PFM_H */
> > > --
> > > 2.26.2.526.g744177e7f7-goog
> > >
>
> --
>
> - Arnaldo

^ permalink raw reply

* Re: [PATCH v14 1/1] perf tools: add support for libpfm4
From: Arnaldo Carvalho de Melo @ 2020-05-29 17:36 UTC (permalink / raw)
  To: Ian Rogers
  Cc: Peter Zijlstra, Ingo Molnar, Mark Rutland, Alexander Shishkin,
	Jiri Olsa, Namhyung Kim, Alexei Starovoitov, Daniel Borkmann,
	Martin KaFai Lau, Yonghong Song, Andrii Nakryiko,
	Greg Kroah-Hartman, Thomas Gleixner, Igor Lubashev,
	Alexey Budankov, Florian Fainelli, Adrian Hunter, Andi Kleen,
	Jiwei Sun, yuzhoujian <yuzhoujian>
In-Reply-To: <20200529172310.GE537@kernel.org>

Em Fri, May 29, 2020 at 02:23:10PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Fri, May 29, 2020 at 10:03:51AM -0700, Ian Rogers escreveu:
> > On Tue, May 5, 2020 at 11:29 AM Ian Rogers <irogers@google.com> wrote:
> > >
> > > From: Stephane Eranian <eranian@google.com>
> > >
> > > This patch links perf with the libpfm4 library if it is available
> > > and LIBPFM4 is passed to the build. The libpfm4 library
> > > contains hardware event tables for all processors supported by
> > > perf_events. It is a helper library that helps convert from a
> > > symbolic event name to the event encoding required by the
> > > underlying kernel interface. This library is open-source and
> > > available from: http://perfmon2.sf.net.
> > >
> > > With this patch, it is possible to specify full hardware events
> > > by name. Hardware filters are also supported. Events must be
> > > specified via the --pfm-events and not -e option. Both options
> > > are active at the same time and it is possible to mix and match:
> > >
> > > $ perf stat --pfm-events inst_retired:any_p:c=1:i -e cycles ....
> > >
> > > Signed-off-by: Stephane Eranian <eranian@google.com>
> > > Reviewed-by: Ian Rogers <irogers@google.com>
> > 
> > Ping.
> 
> Check my tmp.perf/core branch, I had to make some adjustments, mostly in
> the 'perf test' entries as I merged a java demangle test that touched
> the same files,
> 
> I'm now doing the build tests.

Talking about build  tests, you forgot to add it there, like I did
below, I'll eventually do it, as it is opt-in, no biggie at this point.

I'll install libpfm-devel that is in fedora and do further tests, later
today.

- Arnaldo

commit a01c205e3c4cd6d134317413f2dc3129c4ab7a5a
Author: Arnaldo Carvalho de Melo <acme@redhat.com>
Date:   Fri May 29 11:31:23 2020 -0300

    perf build: Add NO_SYSCALL_TABLE=1 to the build tests
    
    So that we make sure that even on x86-64 and other architectures where
    that is the default method we test build the fallback to libaudit that
    other architectures use.
    
    I.e. now this line got added to:
    
      $ make -C tools/perf build-test
      <SNIP>
           make_no_syscall_tbl_O: cd . && make NO_SYSCALL_TABLE=1 FEATURES_DUMP=/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j12 O=/tmp/tmp.W0HtKR1mfr DESTDIR=/tmp/tmp.lNezgCVPzW
      <SNIP>
      $
    
    Cc: Adrian Hunter <adrian.hunter@intel.com>
    Cc: Ingo Molnar <mingo@kernel.org>
    Cc: Jiri Olsa <jolsa@kernel.org>
    Cc: Namhyung Kim <namhyung@kernel.org>
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index 29ce0da7fca6..a4ffa3c7fcb6 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -88,6 +88,7 @@ make_no_libbpf_DEBUG := NO_LIBBPF=1 DEBUG=1
 make_no_libcrypto   := NO_LIBCRYPTO=1
 make_with_babeltrace:= LIBBABELTRACE=1
 make_no_sdt	    := NO_SDT=1
+make_no_syscall_tbl := NO_SYSCALL_TABLE=1
 make_with_clangllvm := LIBCLANGLLVM=1
 make_tags           := tags
 make_cscope         := cscope
@@ -113,7 +114,7 @@ make_minimal        += NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1
 make_minimal        += NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1
 make_minimal        += NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1
 make_minimal        += NO_LIBCRYPTO=1 NO_SDT=1 NO_JVMTI=1 NO_LIBZSTD=1
-make_minimal        += NO_LIBCAP=1
+make_minimal        += NO_LIBCAP=1 NO_SYSCALL_TABLE=1
 
 # $(run) contains all available tests
 run := make_pure
@@ -146,6 +147,7 @@ run += make_no_libbionic
 run += make_no_auxtrace
 run += make_no_libbpf
 run += make_no_libbpf_DEBUG
+run += make_no_syscall_tbl
 run += make_with_babeltrace
 run += make_with_clangllvm
 run += make_help

^ permalink raw reply related

* Re: [PATCH v6 00/16] spi: dw: Add generic DW DMA controller support
From: Serge Semin @ 2020-05-29 17:35 UTC (permalink / raw)
  To: Mark Brown
  Cc: Serge Semin, Ekaterina Skachko, Feng Tang, devicetree,
	Thomas Bogendoerfer, Georgy Vlasov, Pavel Parkhomenko,
	Alexey Kolotnikov, linux-spi, linux-kernel, Vadim Vlasov,
	Alexey Malahov, linux-mips, Andy Shevchenko, Rob Herring,
	Ramil Zaripov, Arnd Bergmann, Maxim Kaurkin
In-Reply-To: <20200529173325.GR4610@sirena.org.uk>

On Fri, May 29, 2020 at 06:33:25PM +0100, Mark Brown wrote:
> On Fri, May 29, 2020 at 08:26:42PM +0300, Serge Semin wrote:
> 
> > You must have missed the patch 16:
> > 0e8332aaf059 dt-bindings: spi: Convert DW SPI binding to DT schema
> > As you can see it has been acked by Rob. So you can also merge it into your
> > repo. Though It has to be rebased first due to the Dinh Nguyen patches
> > recently merged in. Do you want me to do the rebasing?
> 
> Please rebase.  TBH I'd not noticed Rob's review so I just left it
> waiting for that, there's such a huge backlog there it didn't occur to
> me that it might've been reviewed.

Ok. I'll do the rebasing shortly. (also have to add the optional reset properties
into the bindings)

-Sergey

^ permalink raw reply

* Re: [PATCH net 2/3] mptcp: fix race between MP_JOIN and close
From: Mat Martineau @ 2020-05-29 17:35 UTC (permalink / raw)
  To: Paolo Abeni; +Cc: netdev, David S. Miller, Jakub Kicinski
In-Reply-To: <bfd9f8f6fc4d6eb84012d8e04c48d974ed7080ea.1590766645.git.pabeni@redhat.com>

On Fri, 29 May 2020, Paolo Abeni wrote:

> If a MP_JOIN subflow completes the 3whs while another
> CPU is closing the master msk, we can hit the
> following race:
>
> CPU1                                    CPU2
>
> close()
> mptcp_close
>                                        subflow_syn_recv_sock
>                                         mptcp_token_get_sock
>                                         mptcp_finish_join
>                                          inet_sk_state_load
>  mptcp_token_destroy
>  inet_sk_state_store(TCP_CLOSE)
>  __mptcp_flush_join_list()
>                                          mptcp_sock_graft
>                                          list_add_tail
>  sk_common_release
>   sock_orphan()
> <socket free>
>
> The MP_JOIN socket will be leaked. Additionally we can hit
> UaF for the msk 'struct socket' referenced via the 'conn'
> field.
>
> This change try to address the issue introducing some
> synchronization between the MP_JOIN 3whs and mptcp_close
> via the join_list spinlock. If we detect the msk is closing
> the MP_JOIN socket is closed, too.
>
> Fixes: f296234c98a8 ("mptcp: Add handling of incoming MP_JOIN requests")
> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
> ---
> net/mptcp/protocol.c | 42 +++++++++++++++++++++++++++---------------
> 1 file changed, 27 insertions(+), 15 deletions(-)
>

Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com>

--
Mat Martineau
Intel

^ permalink raw reply

* Re: [PATCH] wlcore: fix runtime pm imbalance in __wl1271_op_remove_interface
From: Kalle Valo @ 2020-05-29 17:35 UTC (permalink / raw)
  To: Dinghao Liu
  Cc: dinghao.liu, kjlu, David S. Miller, Jakub Kicinski,
	Thomas Gleixner, Johannes Berg, Fuqian Huang, Tony Lindgren,
	Jason A. Donenfeld, Emmanuel Grumbach, Maital Hahn,
	linux-wireless, netdev, linux-kernel
In-Reply-To: <20200520130806.14789-1-dinghao.liu@zju.edu.cn>

Dinghao Liu <dinghao.liu@zju.edu.cn> wrote:

> When wl12xx_cmd_role_disable() returns an error code,
> a pairing runtime PM usage counter decrement is needed to
> keep the counter balanced.
> 
> Signed-off-by: Dinghao Liu <dinghao.liu@zju.edu.cn>
> Acked-by: Tony Lindgren <tony@atomide.com>

Patch applied to wireless-drivers-next.git, thanks.

53df5271f239 wlcore: fix runtime pm imbalance in __wl1271_op_remove_interface

-- 
https://patchwork.kernel.org/patch/11560399/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches


^ permalink raw reply

* Re: Xenomai-3.1 make fails when configured -mx32 on 64bit kernel
From: Jan Kiszka @ 2020-05-29 17:35 UTC (permalink / raw)
  To: Rosenow, Jim, xenomai@xenomai.org
In-Reply-To: <90c644a07db5444384a22e8d26c075e1@mts.com>

On 29.05.20 16:49, Rosenow, Jim via Xenomai wrote:
> Kernel version:
> Linux debian-10-64bit 4.4.218-xenomai-3.1 #1 SMP PREEMPT Fri May 29 04:49:06 CDT 2020 x86_64 GNU/Linux
> 
> Ipipe version:
> ipipe-core-4.4.218-cip44-x86-23.patch
> 
> 32bit configured -m32 builds and runs as does the default 64bit version:
> ../configure --enable-pshared --enable-smp CFLAGS="-m32" LDFLAGS="-m32"
> 
> 32bit configured -mx32 does not build, see below.
> Thanks,
> Jim
> 
> ../configure --enable-pshared --enable-smp CFLAGS="-mx32" LDFLAGS="-mx32"
> 
> root@debian-10-64bit:~/Xenomai/xenomai-3.1/build# make
> Making all in doc
> make[1]: Entering directory '/root/Xenomai/xenomai-3.1/build/doc'
> Making all in gitdoc
> make[2]: Entering directory '/root/Xenomai/xenomai-3.1/build/doc/gitdoc'
> make[2]: Leaving directory '/root/Xenomai/xenomai-3.1/build/doc/gitdoc'
> Making all in doxygen
> make[2]: Entering directory '/root/Xenomai/xenomai-3.1/build/doc/doxygen'
> make[2]: Nothing to be done for 'all'.
> make[2]: Leaving directory '/root/Xenomai/xenomai-3.1/build/doc/doxygen'
> Making all in asciidoc
> make[2]: Entering directory '/root/Xenomai/xenomai-3.1/build/doc/asciidoc'
> make[2]: Nothing to be done for 'all'.
> make[2]: Leaving directory '/root/Xenomai/xenomai-3.1/build/doc/asciidoc'
> make[2]: Entering directory '/root/Xenomai/xenomai-3.1/build/doc'
> make[2]: Nothing to be done for 'all-am'.
> make[2]: Leaving directory '/root/Xenomai/xenomai-3.1/build/doc'
> make[1]: Leaving directory '/root/Xenomai/xenomai-3.1/build/doc'
> Making all in lib
> make[1]: Entering directory '/root/Xenomai/xenomai-3.1/build/lib'
> Making all in boilerplate
> make[2]: Entering directory '/root/Xenomai/xenomai-3.1/build/lib/boilerplate'
> make  all-recursive
> make[3]: Entering directory '/root/Xenomai/xenomai-3.1/build/lib/boilerplate'
> Making all in init
> make[4]: Entering directory '/root/Xenomai/xenomai-3.1/build/lib/boilerplate/init'
>   CC       libbootstrap_a-bootstrap.o
>   AR       libbootstrap.a
> ar: `u' modifier ignored since `D' is the default (see `U')
>   CC       libbootstrap_pic_la-bootstrap.lo
>   CCLD     libbootstrap-pic.la
> ar: `u' modifier ignored since `D' is the default (see `U')
> make[4]: Leaving directory '/root/Xenomai/xenomai-3.1/build/lib/boilerplate/init'
> make[4]: Entering directory '/root/Xenomai/xenomai-3.1/build/lib/boilerplate'
>   CC       libavl_la-avl.lo
>   CCLD     libavl.la
> ar: `u' modifier ignored since `D' is the default (see `U')
>   CC       libversion_la-version.lo
>   CCLD     libversion.la
> ar: `u' modifier ignored since `D' is the default (see `U')
>   CC       iniparser/libiniparser_la-dictionary.lo
>   CC       iniparser/libiniparser_la-iniparser.lo
>   CCLD     libiniparser.la
> ar: `u' modifier ignored since `D' is the default (see `U')
>   CC       libboilerplate_la-ancillaries.lo
>   CC       libboilerplate_la-heapmem.lo
>   CC       libboilerplate_la-hash.lo
>   CC       libboilerplate_la-setup.lo
>   CC       libboilerplate_la-time.lo
>   CC       libshavl_la-avl.lo
>   CCLD     libshavl.la
> ar: `u' modifier ignored since `D' is the default (see `U')
>   CC       tlsf/libtlsf_la-tlsf.lo
>   CCLD     libtlsf.la
> ar: `u' modifier ignored since `D' is the default (see `U')
>   CCLD     libboilerplate.la
> ar: `u' modifier ignored since `D' is the default (see `U')
>   CC       version-version.o
>   CCLD     version
> make[4]: Leaving directory '/root/Xenomai/xenomai-3.1/build/lib/boilerplate'
> make[3]: Leaving directory '/root/Xenomai/xenomai-3.1/build/lib/boilerplate'
> make[2]: Leaving directory '/root/Xenomai/xenomai-3.1/build/lib/boilerplate'
> Making all in cobalt
> make[2]: Entering directory '/root/Xenomai/xenomai-3.1/build/lib/cobalt'
> Making all in arch
> make[3]: Entering directory '/root/Xenomai/xenomai-3.1/build/lib/cobalt/arch'
> Making all in x86
> make[4]: Entering directory '/root/Xenomai/xenomai-3.1/build/lib/cobalt/arch/x86'
> Making all in include
> make[5]: Entering directory '/root/Xenomai/xenomai-3.1/build/lib/cobalt/arch/x86/include'
> Making all in asm
> make[6]: Entering directory '/root/Xenomai/xenomai-3.1/build/lib/cobalt/arch/x86/include/asm'
> Making all in xenomai
> make[7]: Entering directory '/root/Xenomai/xenomai-3.1/build/lib/cobalt/arch/x86/include/asm/xenomai'
> make[7]: Nothing to be done for 'all'.
> make[7]: Leaving directory '/root/Xenomai/xenomai-3.1/build/lib/cobalt/arch/x86/include/asm/xenomai'
> make[7]: Entering directory '/root/Xenomai/xenomai-3.1/build/lib/cobalt/arch/x86/include/asm'
> make[7]: Nothing to be done for 'all-am'.
> make[7]: Leaving directory '/root/Xenomai/xenomai-3.1/build/lib/cobalt/arch/x86/include/asm'
> make[6]: Leaving directory '/root/Xenomai/xenomai-3.1/build/lib/cobalt/arch/x86/include/asm'
> make[6]: Entering directory '/root/Xenomai/xenomai-3.1/build/lib/cobalt/arch/x86/include'
> make[6]: Nothing to be done for 'all-am'.
> make[6]: Leaving directory '/root/Xenomai/xenomai-3.1/build/lib/cobalt/arch/x86/include'
> make[5]: Leaving directory '/root/Xenomai/xenomai-3.1/build/lib/cobalt/arch/x86/include'
> make[5]: Entering directory '/root/Xenomai/xenomai-3.1/build/lib/cobalt/arch/x86'
>   CC       libarch_la-features.lo
>   CCLD     libarch.la
> ar: `u' modifier ignored since `D' is the default (see `U')
> make[5]: Leaving directory '/root/Xenomai/xenomai-3.1/build/lib/cobalt/arch/x86'
> make[4]: Leaving directory '/root/Xenomai/xenomai-3.1/build/lib/cobalt/arch/x86'
> make[4]: Entering directory '/root/Xenomai/xenomai-3.1/build/lib/cobalt/arch'
> make[4]: Nothing to be done for 'all-am'.
> make[4]: Leaving directory '/root/Xenomai/xenomai-3.1/build/lib/cobalt/arch'
> make[3]: Leaving directory '/root/Xenomai/xenomai-3.1/build/lib/cobalt/arch'
> make[3]: Entering directory '/root/Xenomai/xenomai-3.1/build/lib/cobalt'
>   CC       libcobalt_la-attr.lo
>   CC       libcobalt_la-clock.lo
> In file included from ../../../lib/cobalt/clock.c:32:
> /root/Xenomai/xenomai-3.1/lib/cobalt/arch/x86/include/asm/xenomai/tsc.h: In function ‘cobalt_read_tsc’:
> /root/Xenomai/xenomai-3.1/lib/cobalt/arch/x86/include/asm/xenomai/tsc.h:34:54: error: left shift count >= width of type [-Werror=shift-count-overflow]
>   return ((unsigned long)__a) | (((unsigned long)__d) << 32);
>                                                       ^~
> In file included from ../../../lib/cobalt/clock.c:31:
> ../../../lib/cobalt/clock.c: In function ‘__cobalt_clock_getres’:
> /root/Xenomai/xenomai-3.1/kernel/cobalt/arch/x86/include/asm/xenomai/uapi/syscall.h:22:28: error: ‘__COBALT_X32_BASE’ undeclared (first use in this function)
>  #define __xn_syscall_base  __COBALT_X32_BASE
>                             ^~~~~~~~~~~~~~~~~
> /root/Xenomai/xenomai-3.1/lib/cobalt/arch/x86/include/asm/xenomai/syscall.h:196:10: note: in definition of macro ‘DO_SYSCALL’
>    : "0" (name) ASM_ARGS_##nr  \
>           ^~~~
> /root/Xenomai/xenomai-3.1/kernel/cobalt/arch/x86/include/asm/xenomai/uapi/syscall.h:27:60: note: in expansion of macro ‘__xn_syscall_base’
>  #define __xn_syscode(__nr) (__COBALT_SYSCALL_BIT | (__nr + __xn_syscall_base))
>                                                             ^~~~~~~~~~~~~~~~~
> /root/Xenomai/xenomai-3.1/lib/cobalt/arch/x86/include/asm/xenomai/syscall.h:202:13: note: in expansion of macro ‘__xn_syscode’
>   DO_SYSCALL(__xn_syscode(op), nr, args)
>              ^~~~~~~~~~~~
> /root/Xenomai/xenomai-3.1/lib/cobalt/arch/x86/include/asm/xenomai/syscall.h:211:37: note: in expansion of macro ‘XENOMAI_DO_SYSCALL’
>  #define XENOMAI_SYSCALL2(op,a1,a2)  XENOMAI_DO_SYSCALL(2,op,a1,a2)
>                                      ^~~~~~~~~~~~~~~~~~
> ../../../lib/cobalt/clock.c:104:9: note: in expansion of macro ‘XENOMAI_SYSCALL2’
>   ret = -XENOMAI_SYSCALL2(sc_cobalt_clock_getres, clock_id, tp);
>          ^~~~~~~~~~~~~~~~
> /root/Xenomai/xenomai-3.1/kernel/cobalt/arch/x86/include/asm/xenomai/uapi/syscall.h:22:28: note: each undeclared identifier is reported only once for each function it appears in
>  #define __xn_syscall_base  __COBALT_X32_BASE
>                             ^~~~~~~~~~~~~~~~~
> /root/Xenomai/xenomai-3.1/lib/cobalt/arch/x86/include/asm/xenomai/syscall.h:196:10: note: in definition of macro ‘DO_SYSCALL’
>    : "0" (name) ASM_ARGS_##nr  \
>           ^~~~
> /root/Xenomai/xenomai-3.1/kernel/cobalt/arch/x86/include/asm/xenomai/uapi/syscall.h:27:60: note: in expansion of macro ‘__xn_syscall_base’
>  #define __xn_syscode(__nr) (__COBALT_SYSCALL_BIT | (__nr + __xn_syscall_base))
>                                                             ^~~~~~~~~~~~~~~~~
> /root/Xenomai/xenomai-3.1/lib/cobalt/arch/x86/include/asm/xenomai/syscall.h:202:13: note: in expansion of macro ‘__xn_syscode’
>   DO_SYSCALL(__xn_syscode(op), nr, args)
>              ^~~~~~~~~~~~
> /root/Xenomai/xenomai-3.1/lib/cobalt/arch/x86/include/asm/xenomai/syscall.h:211:37: note: in expansion of macro ‘XENOMAI_DO_SYSCALL’
>  #define XENOMAI_SYSCALL2(op,a1,a2)  XENOMAI_DO_SYSCALL(2,op,a1,a2)
>                                      ^~~~~~~~~~~~~~~~~~
> ../../../lib/cobalt/clock.c:104:9: note: in expansion of macro ‘XENOMAI_SYSCALL2’
>   ret = -XENOMAI_SYSCALL2(sc_cobalt_clock_getres, clock_id, tp);
>          ^~~~~~~~~~~~~~~~
> ../../../lib/cobalt/clock.c: In function ‘__cobalt_clock_gettime’:
> /root/Xenomai/xenomai-3.1/kernel/cobalt/arch/x86/include/asm/xenomai/uapi/syscall.h:22:28: error: ‘__COBALT_X32_BASE’ undeclared (first use in this function)
>  #define __xn_syscall_base  __COBALT_X32_BASE
>                             ^~~~~~~~~~~~~~~~~
> /root/Xenomai/xenomai-3.1/lib/cobalt/arch/x86/include/asm/xenomai/syscall.h:196:10: note: in definition of macro ‘DO_SYSCALL’
>    : "0" (name) ASM_ARGS_##nr  \
>           ^~~~
> /root/Xenomai/xenomai-3.1/kernel/cobalt/arch/x86/include/asm/xenomai/uapi/syscall.h:27:60: note: in expansion of macro ‘__xn_syscall_base’
>  #define __xn_syscode(__nr) (__COBALT_SYSCALL_BIT | (__nr + __xn_syscall_base))
>                                                             ^~~~~~~~~~~~~~~~~
> /root/Xenomai/xenomai-3.1/lib/cobalt/arch/x86/include/asm/xenomai/syscall.h:202:13: note: in expansion of macro ‘__xn_syscode’
>   DO_SYSCALL(__xn_syscode(op), nr, args)
>              ^~~~~~~~~~~~
> /root/Xenomai/xenomai-3.1/lib/cobalt/arch/x86/include/asm/xenomai/syscall.h:211:37: note: in expansion of macro ‘XENOMAI_DO_SYSCALL’
>  #define XENOMAI_SYSCALL2(op,a1,a2)  XENOMAI_DO_SYSCALL(2,op,a1,a2)
>                                      ^~~~~~~~~~~~~~~~~~
> ../../../lib/cobalt/clock.c:204:10: note: in expansion of macro ‘XENOMAI_SYSCALL2’
>    ret = -XENOMAI_SYSCALL2(sc_cobalt_clock_gettime, clock_id, tp);
>           ^~~~~~~~~~~~~~~~
> ../../../lib/cobalt/clock.c: In function ‘__cobalt_clock_settime’:
> /root/Xenomai/xenomai-3.1/kernel/cobalt/arch/x86/include/asm/xenomai/uapi/syscall.h:22:28: error: ‘__COBALT_X32_BASE’ undeclared (first use in this function)
>  #define __xn_syscall_base  __COBALT_X32_BASE
>                             ^~~~~~~~~~~~~~~~~
> /root/Xenomai/xenomai-3.1/lib/cobalt/arch/x86/include/asm/xenomai/syscall.h:196:10: note: in definition of macro ‘DO_SYSCALL’
>    : "0" (name) ASM_ARGS_##nr  \
>           ^~~~
> /root/Xenomai/xenomai-3.1/kernel/cobalt/arch/x86/include/asm/xenomai/uapi/syscall.h:27:60: note: in expansion of macro ‘__xn_syscall_base’
>  #define __xn_syscode(__nr) (__COBALT_SYSCALL_BIT | (__nr + __xn_syscall_base))
>                                                             ^~~~~~~~~~~~~~~~~
> /root/Xenomai/xenomai-3.1/lib/cobalt/arch/x86/include/asm/xenomai/syscall.h:202:13: note: in expansion of macro ‘__xn_syscode’
>   DO_SYSCALL(__xn_syscode(op), nr, args)
>              ^~~~~~~~~~~~
> /root/Xenomai/xenomai-3.1/lib/cobalt/arch/x86/include/asm/xenomai/syscall.h:211:37: note: in expansion of macro ‘XENOMAI_DO_SYSCALL’
>  #define XENOMAI_SYSCALL2(op,a1,a2)  XENOMAI_DO_SYSCALL(2,op,a1,a2)
>                                      ^~~~~~~~~~~~~~~~~~
> ../../../lib/cobalt/clock.c:240:9: note: in expansion of macro ‘XENOMAI_SYSCALL2’
>   ret = -XENOMAI_SYSCALL2(sc_cobalt_clock_settime, clock_id, tp);
>          ^~~~~~~~~~~~~~~~
> ../../../lib/cobalt/clock.c: In function ‘__cobalt_clock_adjtime’:
> /root/Xenomai/xenomai-3.1/kernel/cobalt/arch/x86/include/asm/xenomai/uapi/syscall.h:22:28: error: ‘__COBALT_X32_BASE’ undeclared (first use in this function)
>  #define __xn_syscall_base  __COBALT_X32_BASE
>                             ^~~~~~~~~~~~~~~~~
> /root/Xenomai/xenomai-3.1/lib/cobalt/arch/x86/include/asm/xenomai/syscall.h:196:10: note: in definition of macro ‘DO_SYSCALL’
>    : "0" (name) ASM_ARGS_##nr  \
>           ^~~~
> /root/Xenomai/xenomai-3.1/kernel/cobalt/arch/x86/include/asm/xenomai/uapi/syscall.h:27:60: note: in expansion of macro ‘__xn_syscall_base’
>  #define __xn_syscode(__nr) (__COBALT_SYSCALL_BIT | (__nr + __xn_syscall_base))
>                                                             ^~~~~~~~~~~~~~~~~
> /root/Xenomai/xenomai-3.1/lib/cobalt/arch/x86/include/asm/xenomai/syscall.h:202:13: note: in expansion of macro ‘__xn_syscode’
>   DO_SYSCALL(__xn_syscode(op), nr, args)
>              ^~~~~~~~~~~~
> /root/Xenomai/xenomai-3.1/lib/cobalt/arch/x86/include/asm/xenomai/syscall.h:211:37: note: in expansion of macro ‘XENOMAI_DO_SYSCALL’
>  #define XENOMAI_SYSCALL2(op,a1,a2)  XENOMAI_DO_SYSCALL(2,op,a1,a2)
>                                      ^~~~~~~~~~~~~~~~~~
> ../../../lib/cobalt/clock.c:255:9: note: in expansion of macro ‘XENOMAI_SYSCALL2’
>   ret = -XENOMAI_SYSCALL2(sc_cobalt_clock_adjtime, clock_id, tx);
>          ^~~~~~~~~~~~~~~~
> ../../../lib/cobalt/clock.c: In function ‘__cobalt_clock_nanosleep’:
> /root/Xenomai/xenomai-3.1/kernel/cobalt/arch/x86/include/asm/xenomai/uapi/syscall.h:22:28: error: ‘__COBALT_X32_BASE’ undeclared (first use in this function)
>  #define __xn_syscall_base  __COBALT_X32_BASE
>                             ^~~~~~~~~~~~~~~~~
> /root/Xenomai/xenomai-3.1/lib/cobalt/arch/x86/include/asm/xenomai/syscall.h:196:10: note: in definition of macro ‘DO_SYSCALL’
>    : "0" (name) ASM_ARGS_##nr  \
>           ^~~~
> /root/Xenomai/xenomai-3.1/kernel/cobalt/arch/x86/include/asm/xenomai/uapi/syscall.h:27:60: note: in expansion of macro ‘__xn_syscall_base’
>  #define __xn_syscode(__nr) (__COBALT_SYSCALL_BIT | (__nr + __xn_syscall_base))
>                                                             ^~~~~~~~~~~~~~~~~
> /root/Xenomai/xenomai-3.1/lib/cobalt/arch/x86/include/asm/xenomai/syscall.h:202:13: note: in expansion of macro ‘__xn_syscode’
>   DO_SYSCALL(__xn_syscode(op), nr, args)
>              ^~~~~~~~~~~~
> /root/Xenomai/xenomai-3.1/lib/cobalt/arch/x86/include/asm/xenomai/syscall.h:213:42: note: in expansion of macro ‘XENOMAI_DO_SYSCALL’
>  #define XENOMAI_SYSCALL4(op,a1,a2,a3,a4) XENOMAI_DO_SYSCALL(4,op,a1,a2,a3,a4)
>                                           ^~~~~~~~~~~~~~~~~~
> ../../../lib/cobalt/clock.c:312:9: note: in expansion of macro ‘XENOMAI_SYSCALL4’
>   ret = -XENOMAI_SYSCALL4(sc_cobalt_clock_nanosleep,
>          ^~~~~~~~~~~~~~~~
> cc1: all warnings being treated as errors
> make[3]: *** [Makefile:632: libcobalt_la-clock.lo] Error 1
> make[3]: Leaving directory '/root/Xenomai/xenomai-3.1/build/lib/cobalt'
> make[2]: *** [Makefile:805: all-recursive] Error 1
> make[2]: Leaving directory '/root/Xenomai/xenomai-3.1/build/lib/cobalt'
> make[1]: *** [Makefile:426: all-recursive] Error 1
> make[1]: Leaving directory '/root/Xenomai/xenomai-3.1/build/lib'
> make: *** [Makefile:459: all-recursive] Error 1
> 

Indeed, something regressed. No one tests this path.

Are you seriously considering x32? It's a dead end [1], and I would
rather consider removing it. Or someone needs to pick up the ball, fix
this and also ensure it's hooked up in CI and eventually testing - at
least as long as our test environment support it.

Jan

[1] https://lwn.net/Articles/774734/

-- 
Siemens AG, Corporate Technology, CT RDA IOT SES-DE
Corporate Competence Center Embedded Linux


^ permalink raw reply


This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.