* [PATCH iproute2-next] tc-netem: fix limit description in man page
From: Marcelo Ricardo Leitner @ 2018-05-16 0:49 UTC (permalink / raw)
To: netdev
As the kernel code says, limit is actually the amount of packets it can
hold queued at a time, as per:
static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
struct sk_buff **to_free)
{
...
if (unlikely(sch->q.qlen >= sch->limit))
return qdisc_drop_all(skb, sch, to_free);
So lets fix the description of the field in the man page.
Signed-off-by: Marcelo Ricardo Leitner <mleitner@redhat.com>
---
man/man8/tc-netem.8 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/man/man8/tc-netem.8 b/man/man8/tc-netem.8
index b31384f57a9b36769c0037c465cc6b5bbe8c8b6e..f2cd86b6ed8ae82b8cc2fbd2ecbe41d2fcbad507 100644
--- a/man/man8/tc-netem.8
+++ b/man/man8/tc-netem.8
@@ -65,7 +65,7 @@ netem has the following options:
.SS limit packets
-limits the effect of selected options to the indicated number of next packets.
+maximum number of packets the qdisc may hold queued at a time.
.SS delay
adds the chosen delay to the packets outgoing to chosen network interface. The
--
2.14.3
^ permalink raw reply related
* Re: [PATCH v2] {net, IB}/mlx5: Use 'kvfree()' for memory allocated by 'kvzalloc()'
From: Saeed Mahameed @ 2018-05-16 0:12 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Christophe JAILLET, Saeed Mahameed, Matan Barak, Leon Romanovsky,
Doug Ledford, David S. Miller, Linux Netdev List,
RDMA mailing list, linux-kernel, kernel-janitors
In-Reply-To: <20180515222125.GA20160@ziepe.ca>
On Tue, May 15, 2018 at 3:21 PM, Jason Gunthorpe <jgg@ziepe.ca> wrote:
> On Sun, May 13, 2018 at 09:00:41AM +0200, Christophe JAILLET wrote:
>> When 'kvzalloc()' is used to allocate memory, 'kvfree()' must be used to
>> free it.
>>
>> Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
>> ---
>> v1 -> v2: More places to update have been added to the patch
>> ---
>> drivers/infiniband/hw/mlx5/cq.c | 2 +-
>> drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c | 2 +-
>> drivers/net/ethernet/mellanox/mlx5/core/vport.c | 6 +++---
>> 3 files changed, 5 insertions(+), 5 deletions(-)
>
> I agree with Eric on the need for fixes lines in v3..
>
>> diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c
>> index 77d257ec899b..6d52ea03574e 100644
>> --- a/drivers/infiniband/hw/mlx5/cq.c
>> +++ b/drivers/infiniband/hw/mlx5/cq.c
>> @@ -849,7 +849,7 @@ static int create_cq_user(struct mlx5_ib_dev *dev, struct ib_udata *udata,
>> return 0;
>>
>> err_cqb:
>> - kfree(*cqb);
>> + kvfree(*cqb);
>
> For the infiniband part:
>
> Acked-by: Jason Gunthorpe <jgg@mellanox.com>
>
> Since this is mostly ethernet, can it go through netdev? thanks
>
for the mlx5 core parts:
Acked-by: Saeed Mahameed <saeedm@mellanox.com>
Yes i will take v3 to mlx5-next branch.
> Jason
> --
> To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH net-next v2 2/2] drivers: net: Remove device_node checks with of_mdiobus_register()
From: Grygorii Strashko @ 2018-05-16 0:01 UTC (permalink / raw)
To: Florian Fainelli, netdev
Cc: Andrew Lunn, Vivien Didelot, David S. Miller, Nicolas Ferre,
Fugang Duan, Sergei Shtylyov, Giuseppe Cavallaro,
Alexandre Torgue, Jose Abreu, Woojung Huh,
Microchip Linux Driver Support, Rob Herring, Frank Rowand,
Antoine Tenart, Tobias Jordan, Russell King, Geert Uytterhoeven,
Thomas
In-Reply-To: <20180515235619.27773-3-f.fainelli@gmail.com>
On 05/15/2018 06:56 PM, Florian Fainelli wrote:
> A number of drivers have the following pattern:
>
> if (np)
> of_mdiobus_register()
> else
> mdiobus_register()
>
> which the implementation of of_mdiobus_register() now takes care of.
> Remove that pattern in drivers that strictly adhere to it.
>
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> ---
> drivers/net/dsa/bcm_sf2.c | 8 ++------
> drivers/net/dsa/mv88e6xxx/chip.c | 5 +----
> drivers/net/ethernet/cadence/macb_main.c | 12 +++---------
> drivers/net/ethernet/freescale/fec_main.c | 8 ++------
> drivers/net/ethernet/marvell/mvmdio.c | 5 +----
> drivers/net/ethernet/renesas/sh_eth.c | 11 +++--------
> drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 5 +----
> drivers/net/ethernet/ti/davinci_mdio.c | 8 +++-----
for drivers/net/ethernet/ti/davinci_mdio.c:
Reviewed-by: Grygorii Strashko <grygorii.strashko@ti.com>
> drivers/net/phy/mdio-gpio.c | 6 +-----
> drivers/net/phy/mdio-mscc-miim.c | 6 +-----
> drivers/net/usb/lan78xx.c | 7 ++-----
> 11 files changed, 20 insertions(+), 61 deletions(-)
--
regards,
-grygorii
^ permalink raw reply
* Re: [PATCH net-next 3/3] udp: only use paged allocation with scatter-gather
From: Willem de Bruijn @ 2018-05-15 23:57 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Network Development, David Miller, Willem de Bruijn
In-Reply-To: <CAF=yD-LXn7OTJu6-zrCwg0eJs80_4L9EShy9xJkYT3YpL3UmDw@mail.gmail.com>
On Tue, May 15, 2018 at 4:04 PM, Willem de Bruijn
<willemdebruijn.kernel@gmail.com> wrote:
> On Tue, May 15, 2018 at 10:14 AM, Willem de Bruijn
> <willemdebruijn.kernel@gmail.com> wrote:
>> On Mon, May 14, 2018 at 7:45 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>>>
>>>
>>> On 05/14/2018 04:30 PM, Willem de Bruijn wrote:
>>>
>>>> I don't quite follow. The reported crash happens in the protocol layer,
>>>> because of this check. With pagedlen we have not allocated
>>>> sufficient space for the skb_put.
>>>>
>>>> if (!(rt->dst.dev->features&NETIF_F_SG)) {
>>>> unsigned int off;
>>>>
>>>> off = skb->len;
>>>> if (getfrag(from, skb_put(skb, copy),
>>>> offset, copy, off, skb) < 0) {
>>>> __skb_trim(skb, off);
>>>> err = -EFAULT;
>>>> goto error;
>>>> }
>>>> } else {
>>>> int i = skb_shinfo(skb)->nr_frags;
>>>>
>>>> Are you referring to a separate potential issue in the gso layer?
>>>> If a bonding device advertises SG, but a slave does not, then
>>>> skb_segment on the slave should build linear segs? I have not
>>>> tested that.
>>>
>>> Given that the device attribute could change under us, we need to not
>>> crash, even if initially we thought NETIF_F_SG was available.
>>>
>>> Unless you want to hold RTNL in UDP xmit :)
>>>
>>> Ideally, GSO should be always on, as we did for TCP.
>>>
>>> Otherwise, I can guarantee syzkaller will hit again.
>>
>> Ah, right. Thanks, Eric!
>>
>> I'll read that feature bit only once.
>
> This issue is actually deeper and not specific to gso.
> With corking it is trivial to turn off sg in between calls.
>
> I'll need to send a separate fix for that.
This would do it. The extra branch is unfortunate, but I see no easy
way around it for the corking case.
It will obviously not build a linear skb, but validate_xmit_skb will clean
that up for such edge cases.
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 66340ab750e6..e7daec7c7421 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1040,7 +1040,8 @@ static int __ip_append_data(struct sock *sk,
if (copy > length)
copy = length;
- if (!(rt->dst.dev->features&NETIF_F_SG)) {
+ if (!(rt->dst.dev->features&NETIF_F_SG) &&
+ skb_tailroom(skb) >= copy) {
unsigned int off;
^ permalink raw reply related
* [PATCH net-next v2 1/2] of: mdio: Fall back to mdiobus_register() with NULL device_node
From: Florian Fainelli @ 2018-05-15 23:56 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, Andrew Lunn, Vivien Didelot, David S. Miller,
Nicolas Ferre, Fugang Duan, Sergei Shtylyov, Giuseppe Cavallaro,
Alexandre Torgue, Jose Abreu, Grygorii Strashko, Woojung Huh,
Microchip Linux Driver Support, Rob Herring, Frank Rowand,
Antoine Tenart, Tobias Jordan, Russell King <r
In-Reply-To: <20180515235619.27773-1-f.fainelli@gmail.com>
When the device_node specified is NULL, fall back to mdiobus_register().
We have a number of drivers having a similar pattern which is:
if (np)
of_mdiobus_register()
else
mdiobus_register()
so incorporate that behavior within the core of_mdiobus_register()
function. This is also consistent with the stub version that we defined
when CONFIG_OF=n.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/of/of_mdio.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
index 8c0c92712fc9..d963baf8e53a 100644
--- a/drivers/of/of_mdio.c
+++ b/drivers/of/of_mdio.c
@@ -204,6 +204,9 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
bool scanphys = false;
int addr, rc;
+ if (!np)
+ return mdiobus_register(mdio);
+
/* Do not continue if the node is disabled */
if (!of_device_is_available(np))
return -ENODEV;
--
2.14.1
^ permalink raw reply related
* [PATCH net-next v2 0/2] of: mdio: Fall back to mdiobus_register() with NULL device_node
From: Florian Fainelli @ 2018-05-15 23:56 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, Andrew Lunn, Vivien Didelot, David S. Miller,
Nicolas Ferre, Fugang Duan, Sergei Shtylyov, Giuseppe Cavallaro,
Alexandre Torgue, Jose Abreu, Grygorii Strashko, Woojung Huh,
Microchip Linux Driver Support, Rob Herring, Frank Rowand,
Antoine Tenart, Tobias Jordan, Russell King <r
Hi all,
This patch series updates of_mdiobus_register() such that when the device_node
argument is NULL, it calls mdiobus_register() directly. This is consistent with
the behavior of of_mdiobus_register() when CONFIG_OF=n.
I only converted the most obvious drivers, there are others that have a much
less obvious behavior and specifically attempt to deal with CONFIG_ACPI.
Changes in v2:
- fixed build error in davincin_mdio.c (Grygorii)
- reworked first patch a bit: commit message, subject and removed useless
code comment
Florian Fainelli (2):
of: mdio: Fall back to mdiobus_register() with NULL device_node
drivers: net: Remove device_node checks with of_mdiobus_register()
drivers/net/dsa/bcm_sf2.c | 8 ++------
drivers/net/dsa/mv88e6xxx/chip.c | 5 +----
drivers/net/ethernet/cadence/macb_main.c | 12 +++---------
drivers/net/ethernet/freescale/fec_main.c | 8 ++------
drivers/net/ethernet/marvell/mvmdio.c | 5 +----
drivers/net/ethernet/renesas/sh_eth.c | 11 +++--------
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 5 +----
drivers/net/ethernet/ti/davinci_mdio.c | 8 +++-----
drivers/net/phy/mdio-gpio.c | 6 +-----
drivers/net/phy/mdio-mscc-miim.c | 6 +-----
drivers/net/usb/lan78xx.c | 7 ++-----
drivers/of/of_mdio.c | 3 +++
12 files changed, 23 insertions(+), 61 deletions(-)
--
2.14.1
^ permalink raw reply
* [PATCH net-next v2 2/2] drivers: net: Remove device_node checks with of_mdiobus_register()
From: Florian Fainelli @ 2018-05-15 23:56 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, Andrew Lunn, Vivien Didelot, David S. Miller,
Nicolas Ferre, Fugang Duan, Sergei Shtylyov, Giuseppe Cavallaro,
Alexandre Torgue, Jose Abreu, Grygorii Strashko, Woojung Huh,
Microchip Linux Driver Support, Rob Herring, Frank Rowand,
Antoine Tenart, Tobias Jordan, Russell King <r
In-Reply-To: <20180515235619.27773-1-f.fainelli@gmail.com>
A number of drivers have the following pattern:
if (np)
of_mdiobus_register()
else
mdiobus_register()
which the implementation of of_mdiobus_register() now takes care of.
Remove that pattern in drivers that strictly adhere to it.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/dsa/bcm_sf2.c | 8 ++------
drivers/net/dsa/mv88e6xxx/chip.c | 5 +----
drivers/net/ethernet/cadence/macb_main.c | 12 +++---------
drivers/net/ethernet/freescale/fec_main.c | 8 ++------
drivers/net/ethernet/marvell/mvmdio.c | 5 +----
drivers/net/ethernet/renesas/sh_eth.c | 11 +++--------
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 5 +----
drivers/net/ethernet/ti/davinci_mdio.c | 8 +++-----
drivers/net/phy/mdio-gpio.c | 6 +-----
drivers/net/phy/mdio-mscc-miim.c | 6 +-----
drivers/net/usb/lan78xx.c | 7 ++-----
11 files changed, 20 insertions(+), 61 deletions(-)
diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
index ac621f44237a..02e8982519ce 100644
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -450,12 +450,8 @@ static int bcm_sf2_mdio_register(struct dsa_switch *ds)
priv->slave_mii_bus->parent = ds->dev->parent;
priv->slave_mii_bus->phy_mask = ~priv->indir_phy_mask;
- if (dn)
- err = of_mdiobus_register(priv->slave_mii_bus, dn);
- else
- err = mdiobus_register(priv->slave_mii_bus);
-
- if (err)
+ err = of_mdiobus_register(priv->slave_mii_bus, dn);
+ if (err && dn)
of_node_put(dn);
return err;
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index b23c11d9f4b2..2bb3f03ee1cb 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2454,10 +2454,7 @@ static int mv88e6xxx_mdio_register(struct mv88e6xxx_chip *chip,
return err;
}
- if (np)
- err = of_mdiobus_register(bus, np);
- else
- err = mdiobus_register(bus);
+ err = of_mdiobus_register(bus, np);
if (err) {
dev_err(chip->dev, "Cannot register MDIO bus (%d)\n", err);
mv88e6xxx_g2_irq_mdio_free(chip, bus);
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index b4c9268100bb..3e93df5d4e3b 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -591,16 +591,10 @@ static int macb_mii_init(struct macb *bp)
dev_set_drvdata(&bp->dev->dev, bp->mii_bus);
np = bp->pdev->dev.of_node;
+ if (pdata)
+ bp->mii_bus->phy_mask = pdata->phy_mask;
- if (np) {
- err = of_mdiobus_register(bp->mii_bus, np);
- } else {
- if (pdata)
- bp->mii_bus->phy_mask = pdata->phy_mask;
-
- err = mdiobus_register(bp->mii_bus);
- }
-
+ err = of_mdiobus_register(bp->mii_bus, np);
if (err)
goto err_out_free_mdiobus;
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index d4604bc8eb5b..f3e43db0d6cb 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -2052,13 +2052,9 @@ static int fec_enet_mii_init(struct platform_device *pdev)
fep->mii_bus->parent = &pdev->dev;
node = of_get_child_by_name(pdev->dev.of_node, "mdio");
- if (node) {
- err = of_mdiobus_register(fep->mii_bus, node);
+ err = of_mdiobus_register(fep->mii_bus, node);
+ if (node)
of_node_put(node);
- } else {
- err = mdiobus_register(fep->mii_bus);
- }
-
if (err)
goto err_out_free_mdiobus;
diff --git a/drivers/net/ethernet/marvell/mvmdio.c b/drivers/net/ethernet/marvell/mvmdio.c
index 0495487f7b42..c5dac6bd2be4 100644
--- a/drivers/net/ethernet/marvell/mvmdio.c
+++ b/drivers/net/ethernet/marvell/mvmdio.c
@@ -348,10 +348,7 @@ static int orion_mdio_probe(struct platform_device *pdev)
goto out_mdio;
}
- if (pdev->dev.of_node)
- ret = of_mdiobus_register(bus, pdev->dev.of_node);
- else
- ret = mdiobus_register(bus);
+ ret = of_mdiobus_register(bus, pdev->dev.of_node);
if (ret < 0) {
dev_err(&pdev->dev, "Cannot register MDIO bus (%d)\n", ret);
goto out_mdio;
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index 5970d9e5ddf1..8dd41e08a6c6 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -3025,15 +3025,10 @@ static int sh_mdio_init(struct sh_eth_private *mdp,
pdev->name, pdev->id);
/* register MDIO bus */
- if (dev->of_node) {
- ret = of_mdiobus_register(mdp->mii_bus, dev->of_node);
- } else {
- if (pd->phy_irq > 0)
- mdp->mii_bus->irq[pd->phy] = pd->phy_irq;
-
- ret = mdiobus_register(mdp->mii_bus);
- }
+ if (pd->phy_irq > 0)
+ mdp->mii_bus->irq[pd->phy] = pd->phy_irq;
+ ret = of_mdiobus_register(mdp->mii_bus, dev->of_node);
if (ret)
goto out_free_bus;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index f5f37bfa1d58..5df1a608e566 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -233,10 +233,7 @@ int stmmac_mdio_register(struct net_device *ndev)
new_bus->phy_mask = mdio_bus_data->phy_mask;
new_bus->parent = priv->device;
- if (mdio_node)
- err = of_mdiobus_register(new_bus, mdio_node);
- else
- err = mdiobus_register(new_bus);
+ err = of_mdiobus_register(new_bus, mdio_node);
if (err != 0) {
dev_err(dev, "Cannot register the MDIO bus\n");
goto bus_register_fail;
diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c
index 98a1c97fb95e..8ac72831af05 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -429,12 +429,10 @@ static int davinci_mdio_probe(struct platform_device *pdev)
* defined to support backward compatibility with DTs which assume that
* Davinci MDIO will always scan the bus for PHYs detection.
*/
- if (dev->of_node && of_get_child_count(dev->of_node)) {
+ if (dev->of_node && of_get_child_count(dev->of_node))
data->skip_scan = true;
- ret = of_mdiobus_register(data->bus, dev->of_node);
- } else {
- ret = mdiobus_register(data->bus);
- }
+
+ ret = of_mdiobus_register(data->bus, dev->of_node);
if (ret)
goto bail_out;
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c
index b501221819e1..4e4c8daf44c3 100644
--- a/drivers/net/phy/mdio-gpio.c
+++ b/drivers/net/phy/mdio-gpio.c
@@ -179,11 +179,7 @@ static int mdio_gpio_probe(struct platform_device *pdev)
if (!new_bus)
return -ENODEV;
- if (pdev->dev.of_node)
- ret = of_mdiobus_register(new_bus, pdev->dev.of_node);
- else
- ret = mdiobus_register(new_bus);
-
+ ret = of_mdiobus_register(new_bus, pdev->dev.of_node);
if (ret)
mdio_gpio_bus_deinit(&pdev->dev);
diff --git a/drivers/net/phy/mdio-mscc-miim.c b/drivers/net/phy/mdio-mscc-miim.c
index 8c689ccfdbca..badbc99bedd3 100644
--- a/drivers/net/phy/mdio-mscc-miim.c
+++ b/drivers/net/phy/mdio-mscc-miim.c
@@ -151,11 +151,7 @@ static int mscc_miim_probe(struct platform_device *pdev)
}
}
- if (pdev->dev.of_node)
- ret = of_mdiobus_register(bus, pdev->dev.of_node);
- else
- ret = mdiobus_register(bus);
-
+ ret = of_mdiobus_register(bus, pdev->dev.of_node);
if (ret < 0) {
dev_err(&pdev->dev, "Cannot register MDIO bus (%d)\n", ret);
return ret;
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
index 91761436709a..8dff87ec6d99 100644
--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -1843,12 +1843,9 @@ static int lan78xx_mdio_init(struct lan78xx_net *dev)
}
node = of_get_child_by_name(dev->udev->dev.of_node, "mdio");
- if (node) {
- ret = of_mdiobus_register(dev->mdiobus, node);
+ ret = of_mdiobus_register(dev->mdiobus, node);
+ if (node)
of_node_put(node);
- } else {
- ret = mdiobus_register(dev->mdiobus);
- }
if (ret) {
netdev_err(dev->net, "can't register MDIO bus\n");
goto exit1;
--
2.14.1
^ permalink raw reply related
* [PATCH net-next 3/3] net: phy: Allow MDIO_MOXART and MDIO_SUN4I with COMPILE_TEST
From: Florian Fainelli @ 2018-05-15 23:48 UTC (permalink / raw)
To: netdev; +Cc: Florian Fainelli, David S. Miller, Andrew Lunn, open list
In-Reply-To: <20180515234825.11240-1-f.fainelli@gmail.com>
Those drivers build just fine with COMPILE_TEST, so make that possible.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/phy/Kconfig | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 0e2305ccc91f..343989f9f9d9 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -118,7 +118,7 @@ config MDIO_I2C
config MDIO_MOXART
tristate "MOXA ART MDIO interface support"
- depends on ARCH_MOXART
+ depends on ARCH_MOXART || COMPILE_TEST
help
This driver supports the MDIO interface found in the network
interface units of the MOXA ART SoC
@@ -142,7 +142,7 @@ config MDIO_OCTEON
config MDIO_SUN4I
tristate "Allwinner sun4i MDIO interface support"
- depends on ARCH_SUNXI
+ depends on ARCH_SUNXI || COMPILE_TEST
help
This driver supports the MDIO interface found in the network
interface units of the Allwinner SoC that have an EMAC (A10,
--
2.14.1
^ permalink raw reply related
* [PATCH net-next 2/3] net: ethernet: freescale: Allow FEC with COMPILE_TEST
From: Florian Fainelli @ 2018-05-15 23:48 UTC (permalink / raw)
To: netdev; +Cc: Florian Fainelli, David S. Miller, Andrew Lunn, open list
In-Reply-To: <20180515234825.11240-1-f.fainelli@gmail.com>
The Freescale FEC driver builds fine with COMPILE_TEST, so make that
possible.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/ethernet/freescale/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/freescale/Kconfig b/drivers/net/ethernet/freescale/Kconfig
index 6e490fd2345d..a580a3dcbe59 100644
--- a/drivers/net/ethernet/freescale/Kconfig
+++ b/drivers/net/ethernet/freescale/Kconfig
@@ -22,7 +22,7 @@ if NET_VENDOR_FREESCALE
config FEC
tristate "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
depends on (M523x || M527x || M5272 || M528x || M520x || M532x || \
- ARCH_MXC || SOC_IMX28)
+ ARCH_MXC || SOC_IMX28 || COMPILE_TEST)
default ARCH_MXC || SOC_IMX28 if ARM
select PHYLIB
imply PTP_1588_CLOCK
--
2.14.1
^ permalink raw reply related
* [PATCH net-next 1/3] net: ethernet: ti: Allow most drivers with COMPILE_TEST
From: Florian Fainelli @ 2018-05-15 23:48 UTC (permalink / raw)
To: netdev; +Cc: Florian Fainelli, David S. Miller, Andrew Lunn, open list
In-Reply-To: <20180515234825.11240-1-f.fainelli@gmail.com>
Most of the TI drivers build just fine with COMPILE_TEST, cpmac (AR7) is
the exception because it uses a header file from
arch/mips/include/asm/mach-ar7/ar7.h.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/ethernet/ti/Kconfig | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig
index 48a541eb0af2..1f8626999ac6 100644
--- a/drivers/net/ethernet/ti/Kconfig
+++ b/drivers/net/ethernet/ti/Kconfig
@@ -18,7 +18,7 @@ if NET_VENDOR_TI
config TI_DAVINCI_EMAC
tristate "TI DaVinci EMAC Support"
- depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 )
+ depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 ) || COMPILE_TEST
select TI_DAVINCI_MDIO
select TI_DAVINCI_CPDMA
select PHYLIB
@@ -30,7 +30,7 @@ config TI_DAVINCI_EMAC
config TI_DAVINCI_MDIO
tristate "TI DaVinci MDIO Support"
- depends on ARCH_DAVINCI || ARCH_OMAP2PLUS || ARCH_KEYSTONE
+ depends on ARCH_DAVINCI || ARCH_OMAP2PLUS || ARCH_KEYSTONE || COMPILE_TEST
select PHYLIB
---help---
This driver supports TI's DaVinci MDIO module.
@@ -40,7 +40,7 @@ config TI_DAVINCI_MDIO
config TI_DAVINCI_CPDMA
tristate "TI DaVinci CPDMA Support"
- depends on ARCH_DAVINCI || ARCH_OMAP2PLUS
+ depends on ARCH_DAVINCI || ARCH_OMAP2PLUS || COMPILE_TEST
---help---
This driver supports TI's DaVinci CPDMA dma engine.
@@ -60,7 +60,7 @@ config TI_CPSW_ALE
config TI_CPSW
tristate "TI CPSW Switch Support"
- depends on ARCH_DAVINCI || ARCH_OMAP2PLUS
+ depends on ARCH_DAVINCI || ARCH_OMAP2PLUS || COMPILE_TEST
select TI_DAVINCI_CPDMA
select TI_DAVINCI_MDIO
select TI_CPSW_PHY_SEL
@@ -75,7 +75,7 @@ config TI_CPSW
config TI_CPTS
bool "TI Common Platform Time Sync (CPTS) Support"
- depends on TI_CPSW || TI_KEYSTONE_NETCP
+ depends on TI_CPSW || TI_KEYSTONE_NETCP || COMPILE_TEST
depends on POSIX_TIMERS
---help---
This driver supports the Common Platform Time Sync unit of
@@ -95,8 +95,8 @@ config TI_KEYSTONE_NETCP
tristate "TI Keystone NETCP Core Support"
select TI_CPSW_ALE
select TI_DAVINCI_MDIO
- depends on OF
- depends on KEYSTONE_NAVIGATOR_DMA && KEYSTONE_NAVIGATOR_QMSS
+ depends on OF && KEYSTONE_NAVIGATOR_DMA && KEYSTONE_NAVIGATOR_QMSS || \
+ COMPILE_TEST
---help---
This driver supports TI's Keystone NETCP Core.
--
2.14.1
^ permalink raw reply related
* [PATCH net-next 0/3] net: Allow more drivers with COMPILE_TEST
From: Florian Fainelli @ 2018-05-15 23:48 UTC (permalink / raw)
To: netdev; +Cc: Florian Fainelli, David S. Miller, Andrew Lunn, open list
Hi David,
This patch series includes more drivers to be build tested with COMPILE_TEST
enabled. This helps cover some of the issues I just ran into with missing
a driver *sigh*.
Florian Fainelli (3):
net: ethernet: ti: Allow most drivers with COMPILE_TEST
net: ethernet: freescale: Allow FEC with COMPILE_TEST
net: phy: Allow MDIO_MOXART and MDIO_SUN4I with COMPILE_TEST
drivers/net/ethernet/freescale/Kconfig | 2 +-
drivers/net/ethernet/ti/Kconfig | 14 +++++++-------
drivers/net/phy/Kconfig | 4 ++--
3 files changed, 10 insertions(+), 10 deletions(-)
--
2.14.1
^ permalink raw reply
* [PATCH bpf-next 2/7] bpf: introduce bpf subcommand BPF_PERF_EVENT_QUERY
From: Yonghong Song @ 2018-05-15 23:45 UTC (permalink / raw)
To: peterz, ast, daniel, netdev; +Cc: kernel-team
In-Reply-To: <20180515234521.856763-1-yhs@fb.com>
Currently, suppose a userspace application has loaded a bpf program
and attached it to a tracepoint/kprobe/uprobe, and a bpf
introspection tool, e.g., bpftool, wants to show which bpf program
is attached to which tracepoint/kprobe/uprobe. Such attachment
information will be really useful to understand the overall bpf
deployment in the system.
There is a name field (16 bytes) for each program, which could
be used to encode the attachment point. There are some drawbacks
for this approaches. First, bpftool user (e.g., an admin) may not
really understand the association between the name and the
attachment point. Second, if one program is attached to multiple
places, encoding a proper name which can imply all these
attachments becomes difficult.
This patch introduces a new bpf subcommand BPF_PERF_EVENT_QUERY.
Given a pid and fd, if the <pid, fd> is associated with a
tracepoint/kprobe/uprobea perf event, BPF_PERF_EVENT_QUERY will return
. prog_id
. tracepoint name, or
. k[ret]probe funcname + offset or kernel addr, or
. u[ret]probe filename + offset
to the userspace.
The user can use "bpftool prog" to find more information about
bpf program itself with prog_id.
Signed-off-by: Yonghong Song <yhs@fb.com>
---
include/linux/trace_events.h | 15 ++++++
include/uapi/linux/bpf.h | 25 ++++++++++
kernel/bpf/syscall.c | 113 +++++++++++++++++++++++++++++++++++++++++++
kernel/trace/bpf_trace.c | 53 ++++++++++++++++++++
kernel/trace/trace_kprobe.c | 29 +++++++++++
kernel/trace/trace_uprobe.c | 22 +++++++++
6 files changed, 257 insertions(+)
diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h
index 2bde3ef..ec1f604 100644
--- a/include/linux/trace_events.h
+++ b/include/linux/trace_events.h
@@ -473,6 +473,9 @@ int perf_event_query_prog_array(struct perf_event *event, void __user *info);
int bpf_probe_register(struct bpf_raw_event_map *btp, struct bpf_prog *prog);
int bpf_probe_unregister(struct bpf_raw_event_map *btp, struct bpf_prog *prog);
struct bpf_raw_event_map *bpf_find_raw_tracepoint(const char *name);
+int bpf_get_perf_event_info(struct file *file, u32 *prog_id, u32 *prog_info,
+ const char **buf, u64 *probe_offset,
+ u64 *probe_addr);
#else
static inline unsigned int trace_call_bpf(struct trace_event_call *call, void *ctx)
{
@@ -504,6 +507,12 @@ static inline struct bpf_raw_event_map *bpf_find_raw_tracepoint(const char *name
{
return NULL;
}
+static inline int bpf_get_perf_event_info(struct file *file, u32 *prog_id,
+ u32 *prog_info, const char **buf,
+ u64 *probe_offset, u64 *probe_addr)
+{
+ return -EOPNOTSUPP;
+}
#endif
enum {
@@ -560,10 +569,16 @@ extern void perf_trace_del(struct perf_event *event, int flags);
#ifdef CONFIG_KPROBE_EVENTS
extern int perf_kprobe_init(struct perf_event *event, bool is_retprobe);
extern void perf_kprobe_destroy(struct perf_event *event);
+extern int bpf_get_kprobe_info(struct perf_event *event, u32 *prog_info,
+ const char **symbol, u64 *probe_offset,
+ u64 *probe_addr, bool perf_type_tracepoint);
#endif
#ifdef CONFIG_UPROBE_EVENTS
extern int perf_uprobe_init(struct perf_event *event, bool is_retprobe);
extern void perf_uprobe_destroy(struct perf_event *event);
+extern int bpf_get_uprobe_info(struct perf_event *event, u32 *prog_info,
+ const char **filename, u64 *probe_offset,
+ bool perf_type_tracepoint);
#endif
extern int ftrace_profile_set_filter(struct perf_event *event, int event_id,
char *filter_str);
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index d94d333..b78eca1 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -97,6 +97,7 @@ enum bpf_cmd {
BPF_RAW_TRACEPOINT_OPEN,
BPF_BTF_LOAD,
BPF_BTF_GET_FD_BY_ID,
+ BPF_PERF_EVENT_QUERY,
};
enum bpf_map_type {
@@ -379,6 +380,22 @@ union bpf_attr {
__u32 btf_log_size;
__u32 btf_log_level;
};
+
+ struct {
+ int pid; /* input: pid */
+ int fd; /* input: fd */
+ __u32 flags; /* input: flags */
+ __u32 buf_len; /* input: buf len */
+ __aligned_u64 buf; /* input/output:
+ * tp_name for tracepoint
+ * symbol for kprobe
+ * filename for uprobe
+ */
+ __u32 prog_id; /* output: prod_id */
+ __u32 prog_info; /* output: BPF_PERF_INFO_* */
+ __u64 probe_offset; /* output: probe_offset */
+ __u64 probe_addr; /* output: probe_addr */
+ } perf_event_query;
} __attribute__((aligned(8)));
/* The description below is an attempt at providing documentation to eBPF
@@ -2450,4 +2467,12 @@ struct bpf_fib_lookup {
__u8 dmac[6]; /* ETH_ALEN */
};
+enum {
+ BPF_PERF_INFO_TP_NAME, /* tp name */
+ BPF_PERF_INFO_KPROBE, /* (symbol + offset) or addr */
+ BPF_PERF_INFO_KRETPROBE, /* (symbol + offset) or addr */
+ BPF_PERF_INFO_UPROBE, /* filename + offset */
+ BPF_PERF_INFO_URETPROBE, /* filename + offset */
+};
+
#endif /* _UAPI__LINUX_BPF_H__ */
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index e2aeb5e..347e4d2 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -18,7 +18,9 @@
#include <linux/vmalloc.h>
#include <linux/mmzone.h>
#include <linux/anon_inodes.h>
+#include <linux/fdtable.h>
#include <linux/file.h>
+#include <linux/fs.h>
#include <linux/license.h>
#include <linux/filter.h>
#include <linux/version.h>
@@ -2093,6 +2095,114 @@ static int bpf_btf_get_fd_by_id(const union bpf_attr *attr)
return btf_get_fd_by_id(attr->btf_id);
}
+static int bpf_perf_event_info_copy(const union bpf_attr *attr,
+ union bpf_attr __user *uattr,
+ u32 prog_id, u32 prog_info,
+ const char *buf, u64 probe_offset,
+ u64 probe_addr)
+{
+ __u64 __user *ubuf;
+ int len;
+
+ ubuf = u64_to_user_ptr(attr->perf_event_query.buf);
+ if (buf) {
+ len = strlen(buf);
+ if (attr->perf_event_query.buf_len < len + 1)
+ return -ENOSPC;
+ if (copy_to_user(ubuf, buf, len + 1))
+ return -EFAULT;
+ } else if (attr->perf_event_query.buf_len) {
+ /* copy '\0' to ubuf */
+ __u8 zero = 0;
+
+ if (copy_to_user(ubuf, &zero, 1))
+ return -EFAULT;
+ }
+
+ if (copy_to_user(&uattr->perf_event_query.prog_id, &prog_id,
+ sizeof(prog_id)) ||
+ copy_to_user(&uattr->perf_event_query.prog_info, &prog_info,
+ sizeof(prog_info)) ||
+ copy_to_user(&uattr->perf_event_query.probe_offset, &probe_offset,
+ sizeof(probe_offset)) ||
+ copy_to_user(&uattr->perf_event_query.probe_addr, &probe_addr,
+ sizeof(probe_addr)))
+ return -EFAULT;
+
+ return 0;
+}
+
+#define BPF_PERF_EVENT_QUERY_LAST_FIELD perf_event_query.probe_addr
+
+static int bpf_perf_event_query(const union bpf_attr *attr,
+ union bpf_attr __user *uattr)
+{
+ pid_t pid = attr->perf_event_query.pid;
+ int fd = attr->perf_event_query.fd;
+ struct files_struct *files;
+ struct task_struct *task;
+ struct file *file;
+ int err;
+
+ if (CHECK_ATTR(BPF_PERF_EVENT_QUERY))
+ return -EINVAL;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ task = get_pid_task(find_vpid(pid), PIDTYPE_PID);
+ if (!task)
+ return -ENOENT;
+
+ files = get_files_struct(task);
+ put_task_struct(task);
+ if (!files)
+ return -ENOENT;
+
+ err = 0;
+ spin_lock(&files->file_lock);
+ file = fcheck_files(files, fd);
+ if (!file)
+ err = -ENOENT;
+ else
+ get_file(file);
+ spin_unlock(&files->file_lock);
+ put_files_struct(files);
+
+ if (err)
+ goto out;
+
+ if (file->f_op == &bpf_raw_tp_fops) {
+ struct bpf_raw_tracepoint *raw_tp = file->private_data;
+ struct bpf_raw_event_map *btp = raw_tp->btp;
+
+ if (!raw_tp->prog)
+ err = -ENOENT;
+ else
+ err = bpf_perf_event_info_copy(attr, uattr,
+ raw_tp->prog->aux->id,
+ BPF_PERF_INFO_TP_NAME,
+ btp->tp->name, 0, 0);
+ } else {
+ u64 probe_offset, probe_addr;
+ u32 prog_id, prog_info;
+ const char *buf;
+
+ err = bpf_get_perf_event_info(file, &prog_id, &prog_info,
+ &buf, &probe_offset,
+ &probe_addr);
+ if (!err)
+ err = bpf_perf_event_info_copy(attr, uattr, prog_id,
+ prog_info, buf,
+ probe_offset,
+ probe_addr);
+ }
+
+ fput(file);
+out:
+ return err;
+}
+
SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, size)
{
union bpf_attr attr = {};
@@ -2179,6 +2289,9 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, siz
case BPF_BTF_GET_FD_BY_ID:
err = bpf_btf_get_fd_by_id(&attr);
break;
+ case BPF_PERF_EVENT_QUERY:
+ err = bpf_perf_event_query(&attr, uattr);
+ break;
default:
err = -EINVAL;
break;
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index ce2cbbf..7e8121e 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -14,6 +14,7 @@
#include <linux/uaccess.h>
#include <linux/ctype.h>
#include <linux/kprobes.h>
+#include <linux/syscalls.h>
#include <linux/error-injection.h>
#include "trace_probe.h"
@@ -1163,3 +1164,55 @@ int bpf_probe_unregister(struct bpf_raw_event_map *btp, struct bpf_prog *prog)
mutex_unlock(&bpf_event_mutex);
return err;
}
+
+int bpf_get_perf_event_info(struct file *file, u32 *prog_id, u32 *prog_info,
+ const char **buf, u64 *probe_offset,
+ u64 *probe_addr)
+{
+ bool is_tracepoint, is_syscall_tp;
+ struct perf_event *event;
+ struct bpf_prog *prog;
+ int flags, err = 0;
+
+ event = perf_get_event(file);
+ if (IS_ERR(event))
+ return PTR_ERR(event);
+
+ prog = event->prog;
+ if (!prog)
+ return -ENOENT;
+
+ /* not supporting BPF_PROG_TYPE_PERF_EVENT yet */
+ if (prog->type == BPF_PROG_TYPE_PERF_EVENT)
+ return -EOPNOTSUPP;
+
+ *prog_id = prog->aux->id;
+ flags = event->tp_event->flags;
+ is_tracepoint = flags & TRACE_EVENT_FL_TRACEPOINT;
+ is_syscall_tp = is_syscall_trace_event(event->tp_event);
+
+ if (is_tracepoint || is_syscall_tp) {
+ *buf = is_tracepoint ? event->tp_event->tp->name
+ : event->tp_event->name;
+ *prog_info = BPF_PERF_INFO_TP_NAME;
+ *probe_offset = 0x0;
+ *probe_addr = 0x0;
+ } else {
+ /* kprobe/uprobe */
+ err = -EOPNOTSUPP;
+#ifdef CONFIG_KPROBE_EVENTS
+ if (flags & TRACE_EVENT_FL_KPROBE)
+ err = bpf_get_kprobe_info(event, prog_info, buf,
+ probe_offset, probe_addr,
+ event->attr.type == PERF_TYPE_TRACEPOINT);
+#endif
+#ifdef CONFIG_UPROBE_EVENTS
+ if (flags & TRACE_EVENT_FL_UPROBE)
+ err = bpf_get_uprobe_info(event, prog_info, buf,
+ probe_offset,
+ event->attr.type == PERF_TYPE_TRACEPOINT);
+#endif
+ }
+
+ return err;
+}
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 02aed76..595d154 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -1287,6 +1287,35 @@ kretprobe_perf_func(struct trace_kprobe *tk, struct kretprobe_instance *ri,
head, NULL);
}
NOKPROBE_SYMBOL(kretprobe_perf_func);
+
+int bpf_get_kprobe_info(struct perf_event *event, u32 *prog_info,
+ const char **symbol, u64 *probe_offset,
+ u64 *probe_addr, bool perf_type_tracepoint)
+{
+ const char *pevent = trace_event_name(event->tp_event);
+ const char *group = event->tp_event->class->system;
+ struct trace_kprobe *tk;
+
+ if (perf_type_tracepoint)
+ tk = find_trace_kprobe(pevent, group);
+ else
+ tk = event->tp_event->data;
+ if (!tk)
+ return -EINVAL;
+
+ *prog_info = trace_kprobe_is_return(tk) ? BPF_PERF_INFO_KRETPROBE
+ : BPF_PERF_INFO_KPROBE;
+ if (tk->symbol) {
+ *symbol = tk->symbol;
+ *probe_offset = tk->rp.kp.offset;
+ *probe_addr = 0;
+ } else {
+ *symbol = NULL;
+ *probe_offset = 0;
+ *probe_addr = (u64)tk->rp.kp.addr;
+ }
+ return 0;
+}
#endif /* CONFIG_PERF_EVENTS */
/*
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index ac89287..e781a9f 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -1161,6 +1161,28 @@ static void uretprobe_perf_func(struct trace_uprobe *tu, unsigned long func,
{
__uprobe_perf_func(tu, func, regs, ucb, dsize);
}
+
+int bpf_get_uprobe_info(struct perf_event *event, u32 *prog_info,
+ const char **filename, u64 *probe_offset,
+ bool perf_type_tracepoint)
+{
+ const char *pevent = trace_event_name(event->tp_event);
+ const char *group = event->tp_event->class->system;
+ struct trace_uprobe *tu;
+
+ if (perf_type_tracepoint)
+ tu = find_probe_event(pevent, group);
+ else
+ tu = event->tp_event->data;
+ if (!tu)
+ return -EINVAL;
+
+ *prog_info = is_ret_probe(tu) ? BPF_PERF_INFO_URETPROBE
+ : BPF_PERF_INFO_UPROBE;
+ *filename = tu->filename;
+ *probe_offset = tu->offset;
+ return 0;
+}
#endif /* CONFIG_PERF_EVENTS */
static int
--
2.9.5
^ permalink raw reply related
* [PATCH bpf-next 7/7] tools/bpftool: add perf subcommand
From: Yonghong Song @ 2018-05-15 23:45 UTC (permalink / raw)
To: peterz, ast, daniel, netdev; +Cc: kernel-team
In-Reply-To: <20180515234521.856763-1-yhs@fb.com>
The new command "bpftool perf [show]" will traverse
all processes under /proc, and if any fd is associated
with a perf event, it will print out related perf event
information.
Below is an example to show the results using bcc commands.
Running the following 4 bcc commands:
kprobe: trace.py '__x64_sys_nanosleep'
kretprobe: trace.py 'r::__x64_sys_nanosleep'
tracepoint: trace.py 't:syscalls:sys_enter_nanosleep'
uprobe: trace.py 'p:/home/yhs/a.out:main'
The bpftool command line and result:
$ bpftool perf
21711: prog_id 5 kprobe func __x64_sys_write offset 0
21765: prog_id 7 kretprobe func __x64_sys_nanosleep offset 0
21767: prog_id 8 tracepoint sys_enter_nanosleep
21800: prog_id 9 uprobe filename /home/yhs/a.out offset 1159
$ bpftool -j perf
{"pid":21711,"prog_id":5,"prog_info":"kprobe","func":"__x64_sys_write","offset":0}, \
{"pid":21765,"prog_id":7,"prog_info":"kretprobe","func":"__x64_sys_nanosleep","offset":0}, \
{"pid":21767,"prog_id":8,"prog_info":"tracepoint","tracepoint":"sys_enter_nanosleep"}, \
{"pid":21800,"prog_id":9,"prog_info":"uprobe","filename":"/home/yhs/a.out","offset":1159}
$ bpftool prog
5: kprobe name probe___x64_sys tag e495a0c82f2c7a8d gpl
loaded_at 2018-05-15T04:46:37-0700 uid 0
xlated 200B not jited memlock 4096B map_ids 4
7: kprobe name probe___x64_sys tag f2fdee479a503abf gpl
loaded_at 2018-05-15T04:48:32-0700 uid 0
xlated 200B not jited memlock 4096B map_ids 7
8: tracepoint name tracepoint__sys tag 5390badef2395fcf gpl
loaded_at 2018-05-15T04:48:48-0700 uid 0
xlated 200B not jited memlock 4096B map_ids 8
9: kprobe name probe_main_1 tag 0a87bdc2e2953b6d gpl
loaded_at 2018-05-15T04:49:52-0700 uid 0
xlated 200B not jited memlock 4096B map_ids 9
$ ps ax | grep "python ./trace.py"
21711 pts/0 T 0:03 python ./trace.py __x64_sys_write
21765 pts/0 S+ 0:00 python ./trace.py r::__x64_sys_nanosleep
21767 pts/2 S+ 0:00 python ./trace.py t:syscalls:sys_enter_nanosleep
21800 pts/3 S+ 0:00 python ./trace.py p:/home/yhs/a.out:main
22374 pts/1 S+ 0:00 grep --color=auto python ./trace.py
Signed-off-by: Yonghong Song <yhs@fb.com>
---
tools/bpf/bpftool/main.c | 3 +-
tools/bpf/bpftool/main.h | 1 +
tools/bpf/bpftool/perf.c | 188 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 191 insertions(+), 1 deletion(-)
create mode 100644 tools/bpf/bpftool/perf.c
diff --git a/tools/bpf/bpftool/main.c b/tools/bpf/bpftool/main.c
index 1ec852d..eea7f14 100644
--- a/tools/bpf/bpftool/main.c
+++ b/tools/bpf/bpftool/main.c
@@ -87,7 +87,7 @@ static int do_help(int argc, char **argv)
" %s batch file FILE\n"
" %s version\n"
"\n"
- " OBJECT := { prog | map | cgroup }\n"
+ " OBJECT := { prog | map | cgroup | perf }\n"
" " HELP_SPEC_OPTIONS "\n"
"",
bin_name, bin_name, bin_name);
@@ -216,6 +216,7 @@ static const struct cmd cmds[] = {
{ "prog", do_prog },
{ "map", do_map },
{ "cgroup", do_cgroup },
+ { "perf", do_perf },
{ "version", do_version },
{ 0 }
};
diff --git a/tools/bpf/bpftool/main.h b/tools/bpf/bpftool/main.h
index 6173cd9..63fdb31 100644
--- a/tools/bpf/bpftool/main.h
+++ b/tools/bpf/bpftool/main.h
@@ -119,6 +119,7 @@ int do_prog(int argc, char **arg);
int do_map(int argc, char **arg);
int do_event_pipe(int argc, char **argv);
int do_cgroup(int argc, char **arg);
+int do_perf(int argc, char **arg);
int prog_parse_fd(int *argc, char ***argv);
int map_parse_fd_and_info(int *argc, char ***argv, void *info, __u32 *info_len);
diff --git a/tools/bpf/bpftool/perf.c b/tools/bpf/bpftool/perf.c
new file mode 100644
index 0000000..6d676e4
--- /dev/null
+++ b/tools/bpf/bpftool/perf.c
@@ -0,0 +1,188 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (C) 2018 Facebook
+// Author: Yonghong Song <yhs@fb.com>
+
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <ftw.h>
+
+#include <bpf.h>
+
+#include "main.h"
+
+static void print_perf_json(int pid, __u32 prog_id, __u32 prog_info,
+ char *buf, __u64 probe_offset, __u64 probe_addr)
+{
+ jsonw_start_object(json_wtr);
+ jsonw_int_field(json_wtr, "pid", pid);
+ jsonw_uint_field(json_wtr, "prog_id", prog_id);
+ switch (prog_info) {
+ case BPF_PERF_INFO_TP_NAME:
+ jsonw_string_field(json_wtr, "prog_info", "tracepoint");
+ jsonw_string_field(json_wtr, "tracepoint", buf);
+ break;
+ case BPF_PERF_INFO_KPROBE:
+ jsonw_string_field(json_wtr, "prog_info", "kprobe");
+ if (buf[0] != '\0') {
+ jsonw_string_field(json_wtr, "func", buf);
+ jsonw_lluint_field(json_wtr, "offset", probe_offset);
+ } else {
+ jsonw_lluint_field(json_wtr, "addr", probe_addr);
+ }
+ break;
+ case BPF_PERF_INFO_KRETPROBE:
+ jsonw_string_field(json_wtr, "prog_info", "kretprobe");
+ if (buf[0] != '\0') {
+ jsonw_string_field(json_wtr, "func", buf);
+ jsonw_lluint_field(json_wtr, "offset", probe_offset);
+ } else {
+ jsonw_lluint_field(json_wtr, "addr", probe_addr);
+ }
+ break;
+ case BPF_PERF_INFO_UPROBE:
+ jsonw_string_field(json_wtr, "prog_info", "uprobe");
+ jsonw_string_field(json_wtr, "filename", buf);
+ jsonw_lluint_field(json_wtr, "offset", probe_offset);
+ break;
+ case BPF_PERF_INFO_URETPROBE:
+ jsonw_string_field(json_wtr, "prog_info", "uretprobe");
+ jsonw_string_field(json_wtr, "filename", buf);
+ jsonw_lluint_field(json_wtr, "offset", probe_offset);
+ break;
+ }
+ jsonw_end_object(json_wtr);
+}
+
+static void print_perf_plain(int pid, __u32 prog_id, __u32 prog_info,
+ char *buf, __u64 probe_offset, __u64 probe_addr)
+{
+ printf("%d: prog_id %u ", pid, prog_id);
+ switch (prog_info) {
+ case BPF_PERF_INFO_TP_NAME:
+ printf("tracepoint %s\n", buf);
+ break;
+ case BPF_PERF_INFO_KPROBE:
+ if (buf[0] != '\0')
+ printf("kprobe func %s offset %llu\n", buf,
+ probe_offset);
+ else
+ printf("kprobe addr %llu\n", probe_addr);
+ break;
+ case BPF_PERF_INFO_KRETPROBE:
+ if (buf[0] != '\0')
+ printf("kretprobe func %s offset %llu\n", buf,
+ probe_offset);
+ else
+ printf("kretprobe addr %llu\n", probe_addr);
+ break;
+ case BPF_PERF_INFO_UPROBE:
+ printf("uprobe filename %s offset %llu\n", buf, probe_offset);
+ break;
+ case BPF_PERF_INFO_URETPROBE:
+ printf("uretprobe filename %s offset %llu\n", buf,
+ probe_offset);
+ break;
+ }
+}
+
+static int show_proc(const char *fpath, const struct stat *sb,
+ int tflag, struct FTW *ftwbuf)
+{
+ __u64 probe_offset, probe_addr;
+ __u32 prog_id, prog_info;
+ int err, pid = 0, fd = 0;
+ const char *pch;
+ char buf[4096];
+
+ /* prefix always /proc */
+ pch = fpath + 5;
+ if (*pch == '\0')
+ return 0;
+
+ /* pid should be all numbers */
+ pch++;
+ while (*pch >= '0' && *pch <= '9') {
+ pid = pid * 10 + *pch - '0';
+ pch++;
+ }
+ if (*pch == '\0')
+ return 0;
+ if (*pch != '/')
+ return FTW_SKIP_SUBTREE;
+
+ /* check /proc/<pid>/fd directory */
+ pch++;
+ if (*pch == '\0' || *pch != 'f')
+ return FTW_SKIP_SUBTREE;
+ pch++;
+ if (*pch == '\0' || *pch != 'd')
+ return FTW_SKIP_SUBTREE;
+ pch++;
+ if (*pch == '\0')
+ return 0;
+ if (*pch != '/')
+ return FTW_SKIP_SUBTREE;
+
+ /* check /proc/<pid>/fd/<fd_num> */
+ pch++;
+ while (*pch >= '0' && *pch <= '9') {
+ fd = fd * 10 + *pch - '0';
+ pch++;
+ }
+ if (*pch != '\0')
+ return FTW_SKIP_SUBTREE;
+
+ /* query (pid, fd) for potential perf events */
+ err = bpf_trace_event_query(pid, fd, buf, sizeof(buf),
+ &prog_id, &prog_info, &probe_offset, &probe_addr);
+ if (err < 0)
+ return 0;
+
+ if (json_output)
+ print_perf_json(pid, prog_id, prog_info, buf, probe_offset,
+ probe_addr);
+ else
+ print_perf_plain(pid, prog_id, prog_info, buf, probe_offset,
+ probe_addr);
+
+ return 0;
+}
+
+static int do_show(int argc, char **argv)
+{
+ int nopenfd = 16;
+ int flags = FTW_ACTIONRETVAL | FTW_PHYS;
+
+ if (nftw("/proc", show_proc, nopenfd, flags) == -1) {
+ perror("nftw");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int do_help(int argc, char **argv)
+{
+ fprintf(stderr,
+ "Usage: %s %s { show | help }\n"
+ "",
+ bin_name, argv[-2]);
+
+ return 0;
+}
+
+static const struct cmd cmds[] = {
+ { "show", do_show },
+ { "help", do_help },
+ { 0 }
+};
+
+int do_perf(int argc, char **argv)
+{
+ return cmd_select(cmds, argc, argv, do_help);
+}
--
2.9.5
^ permalink raw reply related
* [PATCH bpf-next 6/7] tools/bpf: add two BPF_PERF_EVENT_QUERY tests in test_progs
From: Yonghong Song @ 2018-05-15 23:45 UTC (permalink / raw)
To: peterz, ast, daniel, netdev; +Cc: kernel-team
In-Reply-To: <20180515234521.856763-1-yhs@fb.com>
The new tests are added to query perf_event information
for raw_tracepoint and tracepoint attachment. For tracepoint,
both syscalls and non-syscalls tracepoints are queries as
they are treated slightly differently inside the kernel.
Signed-off-by: Yonghong Song <yhs@fb.com>
---
tools/testing/selftests/bpf/test_progs.c | 133 +++++++++++++++++++++++++++++++
1 file changed, 133 insertions(+)
diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c
index 3ecf733..138d1e9 100644
--- a/tools/testing/selftests/bpf/test_progs.c
+++ b/tools/testing/selftests/bpf/test_progs.c
@@ -1542,6 +1542,137 @@ static void test_get_stack_raw_tp(void)
bpf_object__close(obj);
}
+static void test_query_trace_event_rawtp(void)
+{
+ const char *file = "./test_get_stack_rawtp.o";
+ struct perf_event_attr attr = {};
+ int efd, err, prog_fd, pmu_fd;
+ struct bpf_object *obj;
+ __u32 duration = 0;
+ char buf[256];
+ __u32 prog_id, prog_info;
+ __u64 probe_offset, probe_addr;
+
+ err = bpf_prog_load(file, BPF_PROG_TYPE_RAW_TRACEPOINT, &obj, &prog_fd);
+ if (CHECK(err, "prog_load raw tp", "err %d errno %d\n", err, errno))
+ return;
+
+ efd = bpf_raw_tracepoint_open("sys_enter", prog_fd);
+ if (CHECK(efd < 0, "raw_tp_open", "err %d errno %d\n", efd, errno))
+ goto close_prog;
+
+ attr.sample_type = PERF_SAMPLE_RAW;
+ attr.type = PERF_TYPE_SOFTWARE;
+ attr.config = PERF_COUNT_SW_BPF_OUTPUT;
+ pmu_fd = syscall(__NR_perf_event_open, &attr, getpid(), -1, -1, 0);
+ if (CHECK(pmu_fd < 0, "perf_event_open", "err %d errno %d\n", pmu_fd,
+ errno))
+ goto close_prog;
+
+ err = ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0);
+ if (CHECK(err < 0, "ioctl PERF_EVENT_IOC_ENABLE", "err %d errno %d\n",
+ err, errno))
+ goto close_prog;
+
+ /* query (getpid(), efd */
+ err = bpf_trace_event_query(getpid(), efd, buf, 256, &prog_id,
+ &prog_info, &probe_offset, &probe_addr);
+ if (CHECK(err < 0, "bpf_trace_event_query", "err %d errno %d\n", err,
+ errno))
+ goto close_prog;
+
+ err = (prog_info == BPF_PERF_INFO_TP_NAME) &&
+ (strcmp(buf, "sys_enter") == 0);
+ if (CHECK(!err, "check_results", "prog_info %d tp_name %s\n",
+ prog_info, buf))
+ goto close_prog;
+
+ goto close_prog_noerr;
+close_prog:
+ error_cnt++;
+close_prog_noerr:
+ bpf_object__close(obj);
+}
+
+static void test_query_trace_event_tp_core(const char *probe_name,
+ const char *tp_name)
+{
+ const char *file = "./test_tracepoint.o";
+ int err, bytes, efd, prog_fd, pmu_fd;
+ struct perf_event_attr attr = {};
+ struct bpf_object *obj;
+ __u32 duration = 0;
+ char buf[256];
+ __u32 prog_id, prog_info;
+ __u64 probe_offset, probe_addr;
+
+ err = bpf_prog_load(file, BPF_PROG_TYPE_TRACEPOINT, &obj, &prog_fd);
+ if (CHECK(err, "bpf_prog_load", "err %d errno %d\n", err, errno))
+ goto close_prog;
+
+ snprintf(buf, sizeof(buf),
+ "/sys/kernel/debug/tracing/events/%s/id", probe_name);
+ efd = open(buf, O_RDONLY, 0);
+ if (CHECK(efd < 0, "open", "err %d errno %d\n", efd, errno))
+ goto close_prog;
+ bytes = read(efd, buf, sizeof(buf));
+ close(efd);
+ if (CHECK(bytes <= 0 || bytes >= sizeof(buf), "read",
+ "bytes %d errno %d\n", bytes, errno))
+ goto close_prog;
+
+ attr.config = strtol(buf, NULL, 0);
+ attr.type = PERF_TYPE_TRACEPOINT;
+ attr.sample_type = PERF_SAMPLE_RAW;
+ attr.sample_period = 1;
+ attr.wakeup_events = 1;
+ pmu_fd = syscall(__NR_perf_event_open, &attr, -1 /* pid */,
+ 0 /* cpu 0 */, -1 /* group id */,
+ 0 /* flags */);
+ if (CHECK(err, "perf_event_open", "err %d errno %d\n", err, errno))
+ goto close_pmu;
+
+ err = ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0);
+ if (CHECK(err, "perf_event_ioc_enable", "err %d errno %d\n", err,
+ errno))
+ goto close_pmu;
+
+ err = ioctl(pmu_fd, PERF_EVENT_IOC_SET_BPF, prog_fd);
+ if (CHECK(err, "perf_event_ioc_set_bpf", "err %d errno %d\n", err,
+ errno))
+ goto close_pmu;
+
+ /* query (getpid(), pmu_fd */
+ err = bpf_trace_event_query(getpid(), pmu_fd, buf, 256, &prog_id,
+ &prog_info, &probe_offset, &probe_addr);
+ if (CHECK(err < 0, "bpf_trace_event_query", "err %d errno %d\n", err,
+ errno))
+ goto close_pmu;
+
+ err = (prog_info == BPF_PERF_INFO_TP_NAME) && !strcmp(buf, tp_name);
+ if (CHECK(!err, "check_results", "prog_info %d tp_name %s\n",
+ prog_info, buf))
+ goto close_pmu;
+
+ close(pmu_fd);
+ goto close_prog_noerr;
+
+close_pmu:
+ close(pmu_fd);
+close_prog:
+ error_cnt++;
+close_prog_noerr:
+ bpf_object__close(obj);
+}
+
+static void test_query_trace_event_tp(void)
+{
+ test_query_trace_event_tp_core("sched/sched_switch",
+ "sched_switch");
+ test_query_trace_event_tp_core("syscalls/sys_enter_read",
+ "sys_enter_read");
+}
+
int main(void)
{
jit_enabled = is_jit_enabled();
@@ -1561,6 +1692,8 @@ int main(void)
test_stacktrace_build_id_nmi();
test_stacktrace_map_raw_tp();
test_get_stack_raw_tp();
+ test_query_trace_event_rawtp();
+ test_query_trace_event_tp();
printf("Summary: %d PASSED, %d FAILED\n", pass_cnt, error_cnt);
return error_cnt ? EXIT_FAILURE : EXIT_SUCCESS;
--
2.9.5
^ permalink raw reply related
* [PATCH bpf-next 5/7] samples/bpf: add a samples/bpf test for BPF_PERF_EVENT_QUERY
From: Yonghong Song @ 2018-05-15 23:45 UTC (permalink / raw)
To: peterz, ast, daniel, netdev; +Cc: kernel-team
In-Reply-To: <20180515234521.856763-1-yhs@fb.com>
This is mostly to test kprobe/uprobe which needs kernel headers.
Signed-off-by: Yonghong Song <yhs@fb.com>
---
samples/bpf/Makefile | 4 +
samples/bpf/perf_event_query_kern.c | 19 ++
samples/bpf/perf_event_query_user.c | 376 ++++++++++++++++++++++++++++++++++++
3 files changed, 399 insertions(+)
create mode 100644 samples/bpf/perf_event_query_kern.c
create mode 100644 samples/bpf/perf_event_query_user.c
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index 62d1aa1..c23e8fe 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -51,6 +51,7 @@ hostprogs-y += cpustat
hostprogs-y += xdp_adjust_tail
hostprogs-y += xdpsock
hostprogs-y += xdp_fwd
+hostprogs-y += perf_event_query
# Libbpf dependencies
LIBBPF = $(TOOLS_PATH)/lib/bpf/libbpf.a
@@ -105,6 +106,7 @@ cpustat-objs := bpf_load.o cpustat_user.o
xdp_adjust_tail-objs := xdp_adjust_tail_user.o
xdpsock-objs := bpf_load.o xdpsock_user.o
xdp_fwd-objs := bpf_load.o xdp_fwd_user.o
+perf_event_query-objs := bpf_load.o perf_event_query_user.o $(TRACE_HELPERS)
# Tell kbuild to always build the programs
always := $(hostprogs-y)
@@ -160,6 +162,7 @@ always += cpustat_kern.o
always += xdp_adjust_tail_kern.o
always += xdpsock_kern.o
always += xdp_fwd_kern.o
+always += perf_event_query_kern.o
HOSTCFLAGS += -I$(objtree)/usr/include
HOSTCFLAGS += -I$(srctree)/tools/lib/
@@ -175,6 +178,7 @@ HOSTCFLAGS_offwaketime_user.o += -I$(srctree)/tools/lib/bpf/
HOSTCFLAGS_spintest_user.o += -I$(srctree)/tools/lib/bpf/
HOSTCFLAGS_trace_event_user.o += -I$(srctree)/tools/lib/bpf/
HOSTCFLAGS_sampleip_user.o += -I$(srctree)/tools/lib/bpf/
+HOSTCFLAGS_perf_event_query_user.o += -I$(srctree)/tools/lib/bpf/
HOST_LOADLIBES += $(LIBBPF) -lelf
HOSTLOADLIBES_tracex4 += -lrt
diff --git a/samples/bpf/perf_event_query_kern.c b/samples/bpf/perf_event_query_kern.c
new file mode 100644
index 0000000..f4b0a9e
--- /dev/null
+++ b/samples/bpf/perf_event_query_kern.c
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/version.h>
+#include <linux/ptrace.h>
+#include <uapi/linux/bpf.h>
+#include "bpf_helpers.h"
+
+SEC("kprobe/blk_start_request")
+int bpf_prog1(struct pt_regs *ctx)
+{
+ return 0;
+}
+
+SEC("kretprobe/blk_account_io_completion")
+int bpf_prog2(struct pt_regs *ctx)
+{
+ return 0;
+}
+char _license[] SEC("license") = "GPL";
+u32 _version SEC("version") = LINUX_VERSION_CODE;
diff --git a/samples/bpf/perf_event_query_user.c b/samples/bpf/perf_event_query_user.c
new file mode 100644
index 0000000..bf46578
--- /dev/null
+++ b/samples/bpf/perf_event_query_user.c
@@ -0,0 +1,376 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <string.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include <linux/bpf.h>
+#include <sys/ioctl.h>
+#include <sys/resource.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "libbpf.h"
+#include "bpf_load.h"
+#include "bpf_util.h"
+#include "perf-sys.h"
+#include "trace_helpers.h"
+
+#define CHECK_PERROR_RET(condition) ({ \
+ int __ret = !!(condition); \
+ if (__ret) { \
+ printf("FAIL: %s:\n", __func__); \
+ perror(" "); \
+ return -1; \
+ } \
+})
+
+#define CHECK_AND_RET(condition) ({ \
+ int __ret = !!(condition); \
+ if (__ret) \
+ return -1; \
+})
+
+static __u64 ptr_to_u64(void *ptr)
+{
+ return (__u64) (unsigned long) ptr;
+}
+
+#define PMU_TYPE_FILE "/sys/bus/event_source/devices/%s/type"
+static int bpf_find_probe_type(const char *event_type)
+{
+ char buf[256];
+ int fd, ret;
+
+ ret = snprintf(buf, sizeof(buf), PMU_TYPE_FILE, event_type);
+ CHECK_PERROR_RET(ret < 0 || ret >= sizeof(buf));
+
+ fd = open(buf, O_RDONLY);
+ CHECK_PERROR_RET(fd < 0);
+
+ ret = read(fd, buf, sizeof(buf));
+ close(fd);
+ CHECK_PERROR_RET(ret < 0 || ret >= sizeof(buf));
+
+ errno = 0;
+ ret = (int)strtol(buf, NULL, 10);
+ CHECK_PERROR_RET(errno);
+ return ret;
+}
+
+#define PMU_RETPROBE_FILE "/sys/bus/event_source/devices/%s/format/retprobe"
+static int bpf_get_retprobe_bit(const char *event_type)
+{
+ char buf[256];
+ int fd, ret;
+
+ ret = snprintf(buf, sizeof(buf), PMU_RETPROBE_FILE, event_type);
+ CHECK_PERROR_RET(ret < 0 || ret >= sizeof(buf));
+
+ fd = open(buf, O_RDONLY);
+ CHECK_PERROR_RET(fd < 0);
+
+ ret = read(fd, buf, sizeof(buf));
+ close(fd);
+ CHECK_PERROR_RET(ret < 0 || ret >= sizeof(buf));
+ CHECK_PERROR_RET(strlen(buf) < strlen("config:"));
+
+ errno = 0;
+ ret = (int)strtol(buf + strlen("config:"), NULL, 10);
+ CHECK_PERROR_RET(errno);
+ return ret;
+}
+
+static int test_debug_fs_kprobe(int fd_idx, const char *fn_name,
+ __u32 expected_prog_info)
+{
+ __u64 probe_offset, probe_addr;
+ __u32 prog_id, prog_info;
+ char buf[256];
+ int err;
+
+ err = bpf_trace_event_query(getpid(), event_fd[fd_idx], buf, 256,
+ &prog_id, &prog_info, &probe_offset, &probe_addr);
+ if (err < 0) {
+ printf("FAIL: %s, for event_fd idx %d, fn_name %s\n",
+ __func__, fd_idx, fn_name);
+ perror(" :");
+ return -1;
+ }
+ if (strcmp(buf, fn_name) != 0 ||
+ prog_info != expected_prog_info ||
+ probe_offset != 0x0 || probe_addr != 0x0) {
+ printf("FAIL: bpf_trace_event_query(event_fd[1]):\n");
+ printf("buf: %s, prog_info: %u, probe_offset: 0x%llx,"
+ " probe_addr: 0x%llx\n",
+ buf, prog_info, probe_offset, probe_addr);
+ return -1;
+ }
+ return 0;
+}
+
+static int test_nondebug_fs_kuprobe_common(const char *event_type,
+ const char *name, __u64 offset, __u64 addr, bool is_return,
+ char *buf, int buf_len, __u32 *prog_id, __u32 *prog_info,
+ __u64 *probe_offset, __u64 *probe_addr)
+{
+ int is_return_bit = bpf_get_retprobe_bit(event_type);
+ int type = bpf_find_probe_type(event_type);
+ struct perf_event_attr attr = {};
+ int fd;
+
+ if (type < 0 || is_return_bit < 0) {
+ printf("FAIL: %s incorrect type (%d) or is_return_bit (%d)\n",
+ __func__, type, is_return_bit);
+ return -1;
+ }
+
+ attr.sample_period = 1;
+ attr.wakeup_events = 1;
+ if (is_return)
+ attr.config |= 1 << is_return_bit;
+
+ if (name) {
+ attr.config1 = ptr_to_u64((void *)name);
+ attr.config2 = offset;
+ } else {
+ attr.config1 = 0;
+ attr.config2 = addr;
+ }
+ attr.size = sizeof(attr);
+ attr.type = type;
+
+ fd = sys_perf_event_open(&attr, -1, 0, -1, 0);
+ CHECK_PERROR_RET(fd < 0);
+
+ CHECK_PERROR_RET(ioctl(fd, PERF_EVENT_IOC_ENABLE, 0) < 0);
+ CHECK_PERROR_RET(ioctl(fd, PERF_EVENT_IOC_SET_BPF, prog_fd[0]) < 0);
+ CHECK_PERROR_RET(bpf_trace_event_query(getpid(), fd, buf, buf_len,
+ prog_id, prog_info, probe_offset, probe_addr) < 0);
+
+ return 0;
+}
+
+static int test_nondebug_fs_probe(const char *event_type, const char *name,
+ __u64 offset, __u64 addr, bool is_return,
+ __u32 expected_prog_info,
+ __u32 expected_ret_prog_info,
+ char *buf, int buf_len)
+{
+ __u64 probe_offset, probe_addr;
+ __u32 prog_id, prog_info;
+ int err;
+
+ err = test_nondebug_fs_kuprobe_common(event_type, name,
+ offset, addr, is_return,
+ buf, buf_len, &prog_id, &prog_info, &probe_offset,
+ &probe_addr);
+ if (err < 0) {
+ printf("FAIL: %s, "
+ "for name %s, offset 0x%llx, addr 0x%llx, is_return %d\n",
+ __func__, name ? name : "", offset, addr, is_return);
+ perror(" :");
+ return -1;
+ }
+ if ((is_return && prog_info != expected_ret_prog_info) ||
+ (!is_return && prog_info != expected_prog_info)) {
+ printf("FAIL: %s, incorrect prog_info %u\n",
+ __func__, prog_info);
+ return -1;
+ }
+ if (name) {
+ if (strcmp(name, buf) != 0) {
+ printf("FAIL: %s, incorrect buf %s\n", __func__, buf);
+ return -1;
+ }
+ if (probe_offset != offset) {
+ printf("FAIL: %s, incorrect probe_offset 0x%llx\n",
+ __func__, probe_offset);
+ return -1;
+ }
+ } else {
+ if (buf && buf[0] != '\0') {
+ printf("FAIL: %s, incorrect buf %p\n",
+ __func__, buf);
+ return -1;
+ }
+
+ if (probe_addr != addr) {
+ printf("FAIL: %s, incorrect probe_addr 0x%llx\n",
+ __func__, probe_addr);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int test_debug_fs_uprobe(char *binary_path, long offset, bool is_return)
+{
+ struct perf_event_attr attr = {};
+ const char *event_type = "uprobe";
+ char buf[256], event_alias[256];
+ __u64 probe_offset, probe_addr;
+ __u32 prog_id, prog_info;
+ int err, res, kfd, efd;
+ ssize_t bytes;
+
+ snprintf(buf, sizeof(buf), "/sys/kernel/debug/tracing/%s_events",
+ event_type);
+ kfd = open(buf, O_WRONLY | O_APPEND, 0);
+ CHECK_PERROR_RET(kfd < 0);
+
+ res = snprintf(event_alias, sizeof(event_alias), "test_%d", getpid());
+ CHECK_PERROR_RET(res < 0 || res >= sizeof(event_alias));
+
+ res = snprintf(buf, sizeof(buf), "%c:%ss/%s %s:0x%lx",
+ is_return ? 'r' : 'p', event_type, event_alias,
+ binary_path, offset);
+ CHECK_PERROR_RET(res < 0 || res >= sizeof(buf));
+ CHECK_PERROR_RET(write(kfd, buf, strlen(buf)) < 0);
+
+ close(kfd);
+ kfd = -1;
+
+ snprintf(buf, sizeof(buf), "/sys/kernel/debug/tracing/events/%ss/%s/id",
+ event_type, event_alias);
+ efd = open(buf, O_RDONLY, 0);
+ CHECK_PERROR_RET(efd < 0);
+
+ bytes = read(efd, buf, sizeof(buf));
+ CHECK_PERROR_RET(bytes <= 0 || bytes >= sizeof(buf));
+ close(efd);
+ buf[bytes] = '\0';
+
+ attr.config = strtol(buf, NULL, 0);
+ attr.type = PERF_TYPE_TRACEPOINT;
+ attr.sample_period = 1;
+ attr.wakeup_events = 1;
+ kfd = sys_perf_event_open(&attr, -1, 0, -1, PERF_FLAG_FD_CLOEXEC);
+ CHECK_PERROR_RET(kfd < 0);
+ CHECK_PERROR_RET(ioctl(kfd, PERF_EVENT_IOC_SET_BPF, prog_fd[0]) < 0);
+ CHECK_PERROR_RET(ioctl(kfd, PERF_EVENT_IOC_ENABLE, 0) < 0);
+
+ err = bpf_trace_event_query(getpid(), kfd, buf, 256,
+ &prog_id, &prog_info, &probe_offset, &probe_addr);
+ if (err < 0) {
+ printf("FAIL: %s, binary_path %s\n", __func__, binary_path);
+ perror(" :");
+ return -1;
+ }
+ if ((is_return && prog_info != BPF_PERF_INFO_URETPROBE) ||
+ (!is_return && prog_info != BPF_PERF_INFO_UPROBE)) {
+ printf("FAIL: %s, incorrect prog_info %u\n", __func__,
+ prog_info);
+ return -1;
+ }
+ if (strcmp(binary_path, buf) != 0) {
+ printf("FAIL: %s, incorrect buf %s\n", __func__, buf);
+ return -1;
+ }
+ if (probe_offset != offset) {
+ printf("FAIL: %s, incorrect probe_offset 0x%llx\n", __func__,
+ probe_offset);
+ return -1;
+ }
+
+ close(kfd);
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ struct rlimit r = {1024*1024, RLIM_INFINITY};
+ extern char __executable_start;
+ __u64 uprobe_file_offset;
+ char filename[256], buf[256];
+
+ snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
+ if (setrlimit(RLIMIT_MEMLOCK, &r)) {
+ perror("setrlimit(RLIMIT_MEMLOCK)");
+ return 1;
+ }
+
+ if (load_kallsyms()) {
+ printf("failed to process /proc/kallsyms\n");
+ return 1;
+ }
+
+ if (load_bpf_file(filename)) {
+ printf("%s", bpf_log_buf);
+ return 1;
+ }
+
+ /* test two functions in the corresponding *_kern.c file */
+ CHECK_AND_RET(test_debug_fs_kprobe(0, "blk_start_request",
+ BPF_PERF_INFO_KPROBE));
+ CHECK_AND_RET(test_debug_fs_kprobe(1, "blk_account_io_completion",
+ BPF_PERF_INFO_KRETPROBE));
+
+ /* test nondebug fs kprobe */
+ CHECK_AND_RET(test_nondebug_fs_probe("kprobe", "bpf_check", 0x0, 0x0,
+ false, BPF_PERF_INFO_KPROBE,
+ BPF_PERF_INFO_KRETPROBE,
+ buf, sizeof(buf)));
+#ifdef __x86_64__
+ /* set a kprobe on "bpf_check + 0x5", which is x64 specific */
+ CHECK_AND_RET(test_nondebug_fs_probe("kprobe", "bpf_check", 0x5, 0x0,
+ false, BPF_PERF_INFO_KPROBE,
+ BPF_PERF_INFO_KRETPROBE,
+ buf, sizeof(buf)));
+#endif
+ CHECK_AND_RET(test_nondebug_fs_probe("kprobe", "bpf_check", 0x0, 0x0,
+ true, BPF_PERF_INFO_KPROBE,
+ BPF_PERF_INFO_KRETPROBE,
+ buf, sizeof(buf)));
+ CHECK_AND_RET(test_nondebug_fs_probe("kprobe", NULL, 0x0,
+ ksym_get_addr("bpf_check"), false,
+ BPF_PERF_INFO_KPROBE,
+ BPF_PERF_INFO_KRETPROBE,
+ buf, sizeof(buf)));
+ CHECK_AND_RET(test_nondebug_fs_probe("kprobe", NULL, 0x0,
+ ksym_get_addr("bpf_check"), false,
+ BPF_PERF_INFO_KPROBE,
+ BPF_PERF_INFO_KRETPROBE,
+ NULL, 0));
+ CHECK_AND_RET(test_nondebug_fs_probe("kprobe", NULL, 0x0,
+ ksym_get_addr("bpf_check"), true,
+ BPF_PERF_INFO_KPROBE,
+ BPF_PERF_INFO_KRETPROBE,
+ buf, sizeof(buf)));
+ CHECK_AND_RET(test_nondebug_fs_probe("kprobe", NULL, 0x0,
+ ksym_get_addr("bpf_check"), true,
+ BPF_PERF_INFO_KPROBE,
+ BPF_PERF_INFO_KRETPROBE,
+ 0, 0));
+
+ /* test nondebug fs uprobe */
+ /* the calculation of uprobe file offset is based on gcc 7.3.1 on x64
+ * and the default linker script, which defines __executable_start as
+ * the start of the .text section. The calculation could be different
+ * on different systems with different compilers. The right way is
+ * to parse the ELF file. We took a shortcut here.
+ */
+ uprobe_file_offset = (__u64)main - (__u64)&__executable_start;
+ CHECK_AND_RET(test_nondebug_fs_probe("uprobe", (char *)argv[0],
+ uprobe_file_offset, 0x0, false,
+ BPF_PERF_INFO_UPROBE,
+ BPF_PERF_INFO_URETPROBE,
+ buf, sizeof(buf)));
+ CHECK_AND_RET(test_nondebug_fs_probe("uprobe", (char *)argv[0],
+ uprobe_file_offset, 0x0, true,
+ BPF_PERF_INFO_UPROBE,
+ BPF_PERF_INFO_URETPROBE,
+ buf, sizeof(buf)));
+
+ /* test debug fs uprobe */
+ CHECK_AND_RET(test_debug_fs_uprobe((char *)argv[0], uprobe_file_offset,
+ false));
+ CHECK_AND_RET(test_debug_fs_uprobe((char *)argv[0], uprobe_file_offset,
+ true));
+
+ return 0;
+}
--
2.9.5
^ permalink raw reply related
* [PATCH bpf-next 0/7] bpf: implement BPF_PERF_EVENT_QUERY for perf event query
From: Yonghong Song @ 2018-05-15 23:45 UTC (permalink / raw)
To: peterz, ast, daniel, netdev; +Cc: kernel-team
Currently, suppose a userspace application has loaded a bpf program
and attached it to a tracepoint/kprobe/uprobe, and a bpf
introspection tool, e.g., bpftool, wants to show which bpf program
is attached to which tracepoint/kprobe/uprobe. Such attachment
information will be really useful to understand the overall bpf
deployment in the system.
There is a name field (16 bytes) for each program, which could
be used to encode the attachment point. There are some drawbacks
for this approaches. First, bpftool user (e.g., an admin) may not
really understand the association between the name and the
attachment point. Second, if one program is attached to multiple
places, encoding a proper name which can imply all these
attachments becomes difficult.
This patch introduces a new bpf subcommand BPF_PERF_EVENT_QUERY.
Given a pid and fd, if the <pid, fd> is associated with a
tracepoint/kprobe/uprobea perf event, BPF_PERF_EVENT_QUERY will return
. prog_id
. tracepoint name, or
. k[ret]probe funcname + offset or kernel addr, or
. u[ret]probe filename + offset
to the userspace.
The user can use "bpftool prog" to find more information about
bpf program itself with prog_id.
Patch #1 adds function perf_get_event() in kernel/events/core.c.
Patch #2 implements the bpf subcommand BPF_PERF_EVENT_QUERY.
Patch #3 syncs tools bpf.h header and also add bpf_trace_event_query()
in the libbpf library for samples/selftests/bpftool to use.
Patch #4 adds ksym_get_addr() utility function.
Patch #5 add a test in samples/bpf for querying k[ret]probes and
u[ret]probes.
Patch #6 add a test in tools/testing/selftests/bpf for querying
raw_tracepoint and tracepoint.
Patch #7 add a new subcommand "perf" to bpftool.
Yonghong Song (7):
perf/core: add perf_get_event() to return perf_event given a struct
file
bpf: introduce bpf subcommand BPF_PERF_EVENT_QUERY
tools/bpf: sync kernel header bpf.h and add bpf_trace_event_query in
libbpf
tools/bpf: add ksym_get_addr() in trace_helpers
samples/bpf: add a samples/bpf test for BPF_PERF_EVENT_QUERY
tools/bpf: add two BPF_PERF_EVENT_QUERY tests in test_progs
tools/bpftool: add perf subcommand
include/linux/perf_event.h | 5 +
include/linux/trace_events.h | 15 ++
include/uapi/linux/bpf.h | 25 ++
kernel/bpf/syscall.c | 113 +++++++++
kernel/events/core.c | 8 +
kernel/trace/bpf_trace.c | 53 ++++
kernel/trace/trace_kprobe.c | 29 +++
kernel/trace/trace_uprobe.c | 22 ++
samples/bpf/Makefile | 4 +
samples/bpf/perf_event_query_kern.c | 19 ++
samples/bpf/perf_event_query_user.c | 376 ++++++++++++++++++++++++++++
tools/bpf/bpftool/main.c | 3 +-
tools/bpf/bpftool/main.h | 1 +
tools/bpf/bpftool/perf.c | 188 ++++++++++++++
tools/include/uapi/linux/bpf.h | 25 ++
tools/lib/bpf/bpf.c | 23 ++
tools/lib/bpf/bpf.h | 3 +
tools/testing/selftests/bpf/test_progs.c | 133 ++++++++++
tools/testing/selftests/bpf/trace_helpers.c | 12 +
tools/testing/selftests/bpf/trace_helpers.h | 1 +
20 files changed, 1057 insertions(+), 1 deletion(-)
create mode 100644 samples/bpf/perf_event_query_kern.c
create mode 100644 samples/bpf/perf_event_query_user.c
create mode 100644 tools/bpf/bpftool/perf.c
--
2.9.5
^ permalink raw reply
* [PATCH bpf-next 4/7] tools/bpf: add ksym_get_addr() in trace_helpers
From: Yonghong Song @ 2018-05-15 23:45 UTC (permalink / raw)
To: peterz, ast, daniel, netdev; +Cc: kernel-team
In-Reply-To: <20180515234521.856763-1-yhs@fb.com>
Given a kernel function name, ksym_get_addr() will return the kernel
address for this function, or 0 if it cannot find this function name
in /proc/kallsyms. This function will be used later when a kernel
address is used to initiate a kprobe perf event.
Signed-off-by: Yonghong Song <yhs@fb.com>
---
tools/testing/selftests/bpf/trace_helpers.c | 12 ++++++++++++
tools/testing/selftests/bpf/trace_helpers.h | 1 +
2 files changed, 13 insertions(+)
diff --git a/tools/testing/selftests/bpf/trace_helpers.c b/tools/testing/selftests/bpf/trace_helpers.c
index 8fb4fe8..3868dcb 100644
--- a/tools/testing/selftests/bpf/trace_helpers.c
+++ b/tools/testing/selftests/bpf/trace_helpers.c
@@ -72,6 +72,18 @@ struct ksym *ksym_search(long key)
return &syms[0];
}
+long ksym_get_addr(const char *name)
+{
+ int i;
+
+ for (i = 0; i < sym_cnt; i++) {
+ if (strcmp(syms[i].name, name) == 0)
+ return syms[i].addr;
+ }
+
+ return 0;
+}
+
static int page_size;
static int page_cnt = 8;
static struct perf_event_mmap_page *header;
diff --git a/tools/testing/selftests/bpf/trace_helpers.h b/tools/testing/selftests/bpf/trace_helpers.h
index 36d90e3..3b4bcf7 100644
--- a/tools/testing/selftests/bpf/trace_helpers.h
+++ b/tools/testing/selftests/bpf/trace_helpers.h
@@ -11,6 +11,7 @@ struct ksym {
int load_kallsyms(void);
struct ksym *ksym_search(long key);
+long ksym_get_addr(const char *name);
typedef enum bpf_perf_event_ret (*perf_event_print_fn)(void *data, int size);
--
2.9.5
^ permalink raw reply related
* [PATCH bpf-next 1/7] perf/core: add perf_get_event() to return perf_event given a struct file
From: Yonghong Song @ 2018-05-15 23:45 UTC (permalink / raw)
To: peterz, ast, daniel, netdev; +Cc: kernel-team
In-Reply-To: <20180515234521.856763-1-yhs@fb.com>
A new extern function, perf_get_event(), is added to return a perf event
given a struct file. This function will be used in later patches.
Signed-off-by: Yonghong Song <yhs@fb.com>
---
include/linux/perf_event.h | 5 +++++
kernel/events/core.c | 8 ++++++++
2 files changed, 13 insertions(+)
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index e71e99e..b5c1ad3 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -868,6 +868,7 @@ extern void perf_event_exit_task(struct task_struct *child);
extern void perf_event_free_task(struct task_struct *task);
extern void perf_event_delayed_put(struct task_struct *task);
extern struct file *perf_event_get(unsigned int fd);
+extern struct perf_event *perf_get_event(struct file *file);
extern const struct perf_event_attr *perf_event_attrs(struct perf_event *event);
extern void perf_event_print_debug(void);
extern void perf_pmu_disable(struct pmu *pmu);
@@ -1289,6 +1290,10 @@ static inline void perf_event_exit_task(struct task_struct *child) { }
static inline void perf_event_free_task(struct task_struct *task) { }
static inline void perf_event_delayed_put(struct task_struct *task) { }
static inline struct file *perf_event_get(unsigned int fd) { return ERR_PTR(-EINVAL); }
+static inline struct perf_event *perf_get_event(struct file *file)
+{
+ return ERR_PTR(-EINVAL);
+}
static inline const struct perf_event_attr *perf_event_attrs(struct perf_event *event)
{
return ERR_PTR(-EINVAL);
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 67612ce..1e3cddb 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -11212,6 +11212,14 @@ struct file *perf_event_get(unsigned int fd)
return file;
}
+struct perf_event *perf_get_event(struct file *file)
+{
+ if (file->f_op != &perf_fops)
+ return ERR_PTR(-EINVAL);
+
+ return file->private_data;
+}
+
const struct perf_event_attr *perf_event_attrs(struct perf_event *event)
{
if (!event)
--
2.9.5
^ permalink raw reply related
* [PATCH bpf-next 3/7] tools/bpf: sync kernel header bpf.h and add bpf_trace_event_query in libbpf
From: Yonghong Song @ 2018-05-15 23:45 UTC (permalink / raw)
To: peterz, ast, daniel, netdev; +Cc: kernel-team
In-Reply-To: <20180515234521.856763-1-yhs@fb.com>
Sync kernel header bpf.h to tools/include/uapi/linux/bpf.h and
implement bpf_trace_event_query() in libbpf. The test programs
in samples/bpf and tools/testing/selftests/bpf, and later bpftool
will use this libbpf function to query kernel.
Signed-off-by: Yonghong Song <yhs@fb.com>
---
tools/include/uapi/linux/bpf.h | 25 +++++++++++++++++++++++++
tools/lib/bpf/bpf.c | 23 +++++++++++++++++++++++
tools/lib/bpf/bpf.h | 3 +++
3 files changed, 51 insertions(+)
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 1205d86..a209f01 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -97,6 +97,7 @@ enum bpf_cmd {
BPF_RAW_TRACEPOINT_OPEN,
BPF_BTF_LOAD,
BPF_BTF_GET_FD_BY_ID,
+ BPF_PERF_EVENT_QUERY,
};
enum bpf_map_type {
@@ -379,6 +380,22 @@ union bpf_attr {
__u32 btf_log_size;
__u32 btf_log_level;
};
+
+ struct {
+ int pid; /* input: pid */
+ int fd; /* input: fd */
+ __u32 flags; /* input: flags */
+ __u32 buf_len; /* input: buf len */
+ __aligned_u64 buf; /* input/output:
+ * tp_name for tracepoint
+ * symbol for kprobe
+ * filename for uprobe
+ */
+ __u32 prog_id; /* output: prod_id */
+ __u32 prog_info; /* output: BPF_PERF_INFO_* */
+ __u64 probe_offset; /* output: probe_offset */
+ __u64 probe_addr; /* output: probe_addr */
+ } perf_event_query;
} __attribute__((aligned(8)));
/* The description below is an attempt at providing documentation to eBPF
@@ -2450,4 +2467,12 @@ struct bpf_fib_lookup {
__u8 dmac[6]; /* ETH_ALEN */
};
+enum {
+ BPF_PERF_INFO_TP_NAME, /* tp name */
+ BPF_PERF_INFO_KPROBE, /* (symbol + offset) or addr */
+ BPF_PERF_INFO_KRETPROBE, /* (symbol + offset) or addr */
+ BPF_PERF_INFO_UPROBE, /* filename + offset */
+ BPF_PERF_INFO_URETPROBE, /* filename + offset */
+};
+
#endif /* _UAPI__LINUX_BPF_H__ */
diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index a3a8fb2..e0152aa 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -641,3 +641,26 @@ int bpf_load_btf(void *btf, __u32 btf_size, char *log_buf, __u32 log_buf_size,
return fd;
}
+
+int bpf_trace_event_query(int pid, int fd, char *buf, __u32 buf_len,
+ __u32 *prog_id, __u32 *prog_info,
+ __u64 *probe_offset, __u64 *probe_addr)
+{
+ union bpf_attr attr = {};
+ int err;
+
+ attr.perf_event_query.pid = pid;
+ attr.perf_event_query.fd = fd;
+ attr.perf_event_query.buf = ptr_to_u64(buf);
+ attr.perf_event_query.buf_len = buf_len;
+
+ err = sys_bpf(BPF_PERF_EVENT_QUERY, &attr, sizeof(attr));
+ if (!err) {
+ *prog_id = attr.perf_event_query.prog_id;
+ *prog_info = attr.perf_event_query.prog_info;
+ *probe_offset = attr.perf_event_query.probe_offset;
+ *probe_addr = attr.perf_event_query.probe_addr;
+ }
+
+ return err;
+}
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index fb3a146..53d05fc 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -105,4 +105,7 @@ int bpf_prog_query(int target_fd, enum bpf_attach_type type, __u32 query_flags,
int bpf_raw_tracepoint_open(const char *name, int prog_fd);
int bpf_load_btf(void *btf, __u32 btf_size, char *log_buf, __u32 log_buf_size,
bool do_log);
+int bpf_trace_event_query(int pid, int fd, char *buf, __u32 buf_len,
+ __u32 *prog_id, __u32 *prog_info,
+ __u64 *probe_offset, __u64 *probe_addr);
#endif
--
2.9.5
^ permalink raw reply related
* Re
From: ''Maria-Elisabeth Schaeffler'' @ 2018-05-15 21:56 UTC (permalink / raw)
To: Recipients
I am Maria-Elisabeth Schaeffler, a German citizen, wife of late George W.Schaeffler, 75 years old. You can see here:
en.wikipedia.org/wiki/Maria-Elisabeth_Schaeffler I intend to give to you a portion of my Wealth as a free-will financial donation to you.
Respond now to partake.
Regards
Maria-Elisabeth Schaeffler
^ permalink raw reply
* [PATCH net-next v2] net: ethernet: ti: cpsw-phy-sel: check bus_find_device() ret value
From: Grygorii Strashko @ 2018-05-15 23:37 UTC (permalink / raw)
To: David S. Miller, netdev
Cc: Sekhar Nori, linux-kernel, linux-omap, Grygorii Strashko
This fixes klockworks warnings: Pointer 'dev' returned from call to
function 'bus_find_device' at line 179 may be NULL and will be dereferenced
at line 181.
cpsw-phy-sel.c:179: 'dev' is assigned the return value from function 'bus_find_device'.
bus.c:342: 'bus_find_device' explicitly returns a NULL value.
cpsw-phy-sel.c:181: 'dev' is dereferenced by passing argument 1 to function 'dev_get_drvdata'.
device.h:1024: 'dev' is passed to function 'dev_get_drvdata'.
device.h:1026: 'dev' is explicitly dereferenced.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
[nsekhar@ti.com: add an error message, fix return path]
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
---
v2: use %pOF
drivers/net/ethernet/ti/cpsw-phy-sel.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/ti/cpsw-phy-sel.c b/drivers/net/ethernet/ti/cpsw-phy-sel.c
index 1801364..0c1adad 100644
--- a/drivers/net/ethernet/ti/cpsw-phy-sel.c
+++ b/drivers/net/ethernet/ti/cpsw-phy-sel.c
@@ -177,12 +177,18 @@ void cpsw_phy_sel(struct device *dev, phy_interface_t phy_mode, int slave)
}
dev = bus_find_device(&platform_bus_type, NULL, node, match);
- of_node_put(node);
+ if (!dev) {
+ dev_err(dev, "unable to find platform device for %pOF\n", node);
+ goto out;
+ }
+
priv = dev_get_drvdata(dev);
priv->cpsw_phy_sel(priv, phy_mode, slave);
put_device(dev);
+out:
+ of_node_put(node);
}
EXPORT_SYMBOL_GPL(cpsw_phy_sel);
--
2.10.5
^ permalink raw reply related
* [PATCH bpf-next] samples/bpf: Decrement ttl in fib forwarding example
From: David Ahern @ 2018-05-15 23:20 UTC (permalink / raw)
To: netdev, borkmann, ast; +Cc: David Ahern
Only consider forwarding packets if ttl in received packet is > 1 and
decrement ttl before handing off to bpf_redirect_map.
Signed-off-by: David Ahern <dsahern@gmail.com>
---
samples/bpf/xdp_fwd_kern.c | 39 +++++++++++++++++++++++++++++++--------
1 file changed, 31 insertions(+), 8 deletions(-)
diff --git a/samples/bpf/xdp_fwd_kern.c b/samples/bpf/xdp_fwd_kern.c
index cdf4fc383cc9..4a6be0f87505 100644
--- a/samples/bpf/xdp_fwd_kern.c
+++ b/samples/bpf/xdp_fwd_kern.c
@@ -30,12 +30,24 @@ struct bpf_map_def SEC("maps") tx_port = {
.max_entries = 64,
};
+/* from include/net/ip.h */
+static __always_inline int ip_decrease_ttl(struct iphdr *iph)
+{
+ u32 check = (__force u32)iph->check;
+
+ check += (__force u32)htons(0x0100);
+ iph->check = (__force __sum16)(check + (check >= 0xFFFF));
+ return --iph->ttl;
+}
+
static __always_inline int xdp_fwd_flags(struct xdp_md *ctx, u32 flags)
{
void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;
struct bpf_fib_lookup fib_params;
struct ethhdr *eth = data;
+ struct ipv6hdr *ip6h;
+ struct iphdr *iph;
int out_index;
u16 h_proto;
u64 nh_off;
@@ -48,11 +60,14 @@ static __always_inline int xdp_fwd_flags(struct xdp_md *ctx, u32 flags)
h_proto = eth->h_proto;
if (h_proto == htons(ETH_P_IP)) {
- struct iphdr *iph = data + nh_off;
+ iph = data + nh_off;
if (iph + 1 > data_end)
return XDP_DROP;
+ if (iph->ttl <= 1)
+ return XDP_PASS;
+
fib_params.family = AF_INET;
fib_params.tos = iph->tos;
fib_params.l4_protocol = iph->protocol;
@@ -64,19 +79,22 @@ static __always_inline int xdp_fwd_flags(struct xdp_md *ctx, u32 flags)
} else if (h_proto == htons(ETH_P_IPV6)) {
struct in6_addr *src = (struct in6_addr *) fib_params.ipv6_src;
struct in6_addr *dst = (struct in6_addr *) fib_params.ipv6_dst;
- struct ipv6hdr *iph = data + nh_off;
- if (iph + 1 > data_end)
+ ip6h = data + nh_off;
+ if (ip6h + 1 > data_end)
return XDP_DROP;
+ if (ip6h->hop_limit <= 1)
+ return XDP_PASS;
+
fib_params.family = AF_INET6;
- fib_params.flowlabel = *(__be32 *)iph & IPV6_FLOWINFO_MASK;
- fib_params.l4_protocol = iph->nexthdr;
+ fib_params.flowlabel = *(__be32 *)ip6h & IPV6_FLOWINFO_MASK;
+ fib_params.l4_protocol = ip6h->nexthdr;
fib_params.sport = 0;
fib_params.dport = 0;
- fib_params.tot_len = ntohs(iph->payload_len);
- *src = iph->saddr;
- *dst = iph->daddr;
+ fib_params.tot_len = ntohs(ip6h->payload_len);
+ *src = ip6h->saddr;
+ *dst = ip6h->daddr;
} else {
return XDP_PASS;
}
@@ -92,6 +110,11 @@ static __always_inline int xdp_fwd_flags(struct xdp_md *ctx, u32 flags)
* forwarding packets are dropped.
*/
if (out_index > 0) {
+ if (h_proto == htons(ETH_P_IP))
+ ip_decrease_ttl(iph);
+ else if (h_proto == htons(ETH_P_IPV6))
+ ip6h->hop_limit--;
+
memcpy(eth->h_dest, fib_params.dmac, ETH_ALEN);
memcpy(eth->h_source, fib_params.smac, ETH_ALEN);
return bpf_redirect_map(&tx_port, out_index, 0);
--
2.11.0
^ permalink raw reply related
* Re: [PATCH net-next 2/3] net: qualcomm: rmnet: Add support for ethtool private stats
From: kbuild test robot @ 2018-05-15 23:16 UTC (permalink / raw)
To: Subash Abhinov Kasiviswanathan
Cc: kbuild-all, davem, netdev, Subash Abhinov Kasiviswanathan
In-Reply-To: <1526328527-20026-3-git-send-email-subashab@codeaurora.org>
[-- Attachment #1: Type: text/plain, Size: 3343 bytes --]
Hi Subash,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on net-next/master]
url: https://github.com/0day-ci/linux/commits/Subash-Abhinov-Kasiviswanathan/net-qualcomm-rmnet-Updates-2018-05-14/20180515-115355
config: x86_64-randconfig-s4-05160610 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All error/warnings (new ones prefixed by >>):
In file included from include/linux/kernel.h:10:0,
from include/linux/list.h:9,
from include/linux/timer.h:5,
from include/linux/netdevice.h:28,
from drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c:16:
drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c: In function 'rmnet_map_checksum_downlink_packet':
include/linux/compiler.h:58:2: warning: this 'if' clause does not guard... [-Wmisleading-indentation]
if (__builtin_constant_p(!!(cond)) ? !!(cond) : \
^
include/linux/compiler.h:56:23: note: in expansion of macro '__trace_if'
#define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
^~~~~~~~~~
>> drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c:375:7: note: in expansion of macro 'if'
else if (skb->protocol == htons(ETH_P_IPV6))
^~
drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c:380:3: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'
return -EPROTONOSUPPORT;
^~~~~~
>> drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c:382:2: error: 'else' without a previous 'if'
else
^~~~
vim +382 drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
349
350 /* Validates packet checksums. Function takes a pointer to
351 * the beginning of a buffer which contains the IP payload +
352 * padding + checksum trailer.
353 * Only IPv4 and IPv6 are supported along with TCP & UDP.
354 * Fragmented or tunneled packets are not supported.
355 */
356 int rmnet_map_checksum_downlink_packet(struct sk_buff *skb, u16 len)
357 {
358 struct rmnet_priv *priv = netdev_priv(skb->dev);
359 struct rmnet_map_dl_csum_trailer *csum_trailer;
360
361 if (unlikely(!(skb->dev->features & NETIF_F_RXCSUM))) {
362 priv->stats.csum_sw++;
363 return -EOPNOTSUPP;
364 }
365
366 csum_trailer = (struct rmnet_map_dl_csum_trailer *)(skb->data + len);
367
368 if (!csum_trailer->valid) {
369 priv->stats.csum_valid_unset++;
370 return -EINVAL;
371 }
372
373 if (skb->protocol == htons(ETH_P_IP))
374 return rmnet_map_ipv4_dl_csum_trailer(skb, csum_trailer, priv);
> 375 else if (skb->protocol == htons(ETH_P_IPV6))
376 #if IS_ENABLED(CONFIG_IPV6)
377 return rmnet_map_ipv6_dl_csum_trailer(skb, csum_trailer, priv);
378 #else
379 priv->stats.csum_err_invalid_ip_version++;
380 return -EPROTONOSUPPORT;
381 #endif
> 382 else
383 priv->stats.csum_err_invalid_ip_version++;
384 return -EPROTONOSUPPORT;
385
386 return 0;
387 }
388
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 36599 bytes --]
^ permalink raw reply
* Re: [PATCH net-next] net: ethernet: ti: cpsw-phy-sel: check bus_find_device() ret value
From: Grygorii Strashko @ 2018-05-15 23:11 UTC (permalink / raw)
To: Andy Shevchenko
Cc: David S. Miller, netdev, Sekhar Nori, Linux Kernel Mailing List,
Linux OMAP Mailing List
In-Reply-To: <CAHp75VdXjiis9R6a1EZO9q3fawB_nSmJhqRSvv_7yggTr-EBOA@mail.gmail.com>
On 05/15/2018 06:07 PM, Andy Shevchenko wrote:
> On Wed, May 16, 2018 at 2:01 AM, Grygorii Strashko
> <grygorii.strashko@ti.com> wrote:
>> This fixes klockworks warnings: Pointer 'dev' returned from call to
>> function 'bus_find_device' at line 179 may be NULL and will be dereferenced
>> at line 181.
>
>> + dev_err(dev, "unable to find platform device for %s\n",
>> + of_node_full_name(node));
>
> Sorry, isn't %pOF works for this?
>
Thanks, will update.
--
regards,
-grygorii
^ permalink raw reply
* Re: [PATCH net-next] net: ethernet: ti: cpsw-phy-sel: check bus_find_device() ret value
From: Andy Shevchenko @ 2018-05-15 23:07 UTC (permalink / raw)
To: Grygorii Strashko
Cc: David S. Miller, netdev, Sekhar Nori, Linux Kernel Mailing List,
Linux OMAP Mailing List
In-Reply-To: <20180515230149.6547-1-grygorii.strashko@ti.com>
On Wed, May 16, 2018 at 2:01 AM, Grygorii Strashko
<grygorii.strashko@ti.com> wrote:
> This fixes klockworks warnings: Pointer 'dev' returned from call to
> function 'bus_find_device' at line 179 may be NULL and will be dereferenced
> at line 181.
> + dev_err(dev, "unable to find platform device for %s\n",
> + of_node_full_name(node));
Sorry, isn't %pOF works for this?
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox