* Re: [PATCH net-next 8/8] net: mscc: PTP Hardware Clock (PHC) support
From: Antoine Tenart @ 2019-07-05 17:16 UTC (permalink / raw)
To: Richard Cochran
Cc: Antoine Tenart, davem, alexandre.belloni, UNGLinuxDriver, ralf,
paul.burton, jhogan, netdev, linux-mips, thomas.petazzoni,
allan.nielsen
In-Reply-To: <20190705164736.x6dy2oc6jo5db65v@localhost>
Hello Richard,
On Fri, Jul 05, 2019 at 09:47:36AM -0700, Richard Cochran wrote:
> On Mon, Jul 01, 2019 at 12:03:27PM +0200, Antoine Tenart wrote:
>
> > +void ocelot_get_hwtimestamp(struct ocelot *ocelot, struct timespec64 *ts)
> > +{
> > + /* Read current PTP time to get seconds */
> > + u32 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
>
> This register is protected by ocelot->ptp_clock_lock from other code
> paths, but not in this one!
Oops. I'll fix it.
> > +static int ocelot_init_timestamp(struct ocelot *ocelot)
> > +{
> > + ocelot->ptp_info = ocelot_ptp_clock_info;
> > +
> > + ocelot->ptp_clock = ptp_clock_register(&ocelot->ptp_info, ocelot->dev);
> > + if (IS_ERR(ocelot->ptp_clock))
> > + return PTR_ERR(ocelot->ptp_clock);
>
> You need to handle the NULL case:
Will do.
> ptp_clock_register() - register a PTP hardware clock driver
>
> @info: Structure describing the new clock.
> @parent: Pointer to the parent device of the new clock.
>
> Returns a valid pointer on success or PTR_ERR on failure. If PHC
> support is missing at the configuration level, this function
> returns NULL, and drivers are expected to gracefully handle that
> case separately.
Thanks,
Antoine
--
Antoine Ténart, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* Re: [PATCH bpf-next] tools: bpftool: add "prog run" subcommand to test-run programs
From: Y Song @ 2019-07-05 17:08 UTC (permalink / raw)
To: Quentin Monnet
Cc: Alexei Starovoitov, Daniel Borkmann, bpf, netdev, oss-drivers
In-Reply-To: <4e7a66b8-8c4b-58cc-61a8-9ec6568d4df7@netronome.com>
On Fri, Jul 5, 2019 at 9:03 AM Quentin Monnet
<quentin.monnet@netronome.com> wrote:
>
> 2019-07-05 08:42 UTC-0700 ~ Y Song <ys114321@gmail.com>
> > On Fri, Jul 5, 2019 at 1:21 AM Quentin Monnet
> > <quentin.monnet@netronome.com> wrote:
> >>
> >> 2019-07-04 22:49 UTC-0700 ~ Y Song <ys114321@gmail.com>
> >>> On Thu, Jul 4, 2019 at 1:58 AM Quentin Monnet
> >>> <quentin.monnet@netronome.com> wrote:
> >>>>
> >>>> Add a new "bpftool prog run" subcommand to run a loaded program on input
> >>>> data (and possibly with input context) passed by the user.
> >>>>
> >>>> Print output data (and output context if relevant) into a file or into
> >>>> the console. Print return value and duration for the test run into the
> >>>> console.
> >>>>
> >>>> A "repeat" argument can be passed to run the program several times in a
> >>>> row.
> >>>>
> >>>> The command does not perform any kind of verification based on program
> >>>> type (Is this program type allowed to use an input context?) or on data
> >>>> consistency (Can I work with empty input data?), this is left to the
> >>>> kernel.
> >>>>
> >>>> Example invocation:
> >>>>
> >>>> # perl -e 'print "\x0" x 14' | ./bpftool prog run \
> >>>> pinned /sys/fs/bpf/sample_ret0 \
> >>>> data_in - data_out - repeat 5
> >>>> 0000000 0000 0000 0000 0000 0000 0000 0000 | ........ ......
> >>>> Return value: 0, duration (average): 260ns
> >>>>
> >>>> When one of data_in or ctx_in is "-", bpftool reads from standard input,
> >>>> in binary format. Other formats (JSON, hexdump) might be supported (via
> >>>> an optional command line keyword like "data_fmt_in") in the future if
> >>>> relevant, but this would require doing more parsing in bpftool.
> >>>>
> >>>> Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
> >>>> Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
> >>>> ---
> >>
> >> [...]
> >>
> >>>> diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
> >>>> index 9b0db5d14e31..8dcbaa0a8ab1 100644
> >>>> --- a/tools/bpf/bpftool/prog.c
> >>>> +++ b/tools/bpf/bpftool/prog.c
> >>>> @@ -15,6 +15,7 @@
> >>>> #include <sys/stat.h>
> >>>>
> >>>> #include <linux/err.h>
> >>>> +#include <linux/sizes.h>
> >>>>
> >>>> #include <bpf.h>
> >>>> #include <btf.h>
> >>>> @@ -748,6 +749,344 @@ static int do_detach(int argc, char **argv)
> >>>> return 0;
> >>>> }
> >>>>
> >>>> +static int check_single_stdin(char *file_in, char *other_file_in)
> >>>> +{
> >>>> + if (file_in && other_file_in &&
> >>>> + !strcmp(file_in, "-") && !strcmp(other_file_in, "-")) {
> >>>> + p_err("cannot use standard input for both data_in and ctx_in");
> >>>
> >>> The error message says data_in and ctx_in.
> >>> Maybe the input parameter should be file_data_in and file_ctx_in?
> >>
> >>
> >> Hi Yonghong,
> >>
> >> It's true those parameters should be file names. But having
> >> "file_data_in", "file_data_out", "file_ctx_in" and "file_ctx_out" on a
> >> command line seems a bit heavy to me? (And relying on keyword prefixing
> >> for typing the command won't help much.)
> >>
> >> My opinion is that it should be clear from the man page or the "help"
> >> command that the parameters are file names. What do you think? I can
> >> prefix all four arguments with "file_" if you believe this is better.
> >
> > I think you misunderstood my question above.
>
> Totally did, sorry :/.
>
> > The command line parameters are fine.
> > I am talking about the function parameter names. Since in the error message,
> > the input parameters are referred for data_in and ctx_in
> > p_err("cannot use standard input for both data_in and ctx_in")
> > maybe the function signature should be
> > static int check_single_stdin(char *file_data_in, char *file_ctx_in)
> >
> > If you are worried that later on the same function can be used in different
> > contexts, then alternatively, you can have signature like
> > static int check_single_stdin(char *file_in, char *other_file_in,
> > const char *file_in_arg, const char *other_file_in_arg)
> > where file_in_arg will be passed in as "data_in" and other_file_in_arg
> > as "ctx_in".
> > I think we could delay this until it is really needed.
>
> As a matter of fact, the opposite thing happened. I first used the
> function for data_in/ctx_in, and also for data_out/ctx_out. But I
> changed my mind eventually because there is no real reason not to print
> both data_out and ctx_out to stdout if we want to do so. So I updated
> the name of the parameters in the error messages, but forgot to change
> the arguments for the function. Silly me.
>
> So I totally agree, I'll respin and change the argument names for the
> function. And yes, we could also pass the names to print in the error
> message, but I agree that this is not needed, and not helpful at the moment.
>
> Thanks for catching this!
>
> >>
> >> [...]
> >>
> >>>> +static int do_run(int argc, char **argv)
> >>>> +{
> >>>> + char *data_fname_in = NULL, *data_fname_out = NULL;
> >>>> + char *ctx_fname_in = NULL, *ctx_fname_out = NULL;
> >>>> + struct bpf_prog_test_run_attr test_attr = {0};
> >>>> + const unsigned int default_size = SZ_32K;
> >>>> + void *data_in = NULL, *data_out = NULL;
> >>>> + void *ctx_in = NULL, *ctx_out = NULL;
> >>>> + unsigned int repeat = 1;
> >>>> + int fd, err;
> >>>> +
> >>>> + if (!REQ_ARGS(4))
> >>>> + return -1;
> >>>> +
> >>>> + fd = prog_parse_fd(&argc, &argv);
> >>>> + if (fd < 0)
> >>>> + return -1;
> >>>> +
> >>>> + while (argc) {
> >>>> + if (detect_common_prefix(*argv, "data_in", "data_out",
> >>>> + "data_size_out", NULL))
> >>>> + return -1;
> >>>> + if (detect_common_prefix(*argv, "ctx_in", "ctx_out",
> >>>> + "ctx_size_out", NULL))
> >>>> + return -1;
> >>>> +
> >>>> + if (is_prefix(*argv, "data_in")) {
> >>>> + NEXT_ARG();
> >>>> + if (!REQ_ARGS(1))
> >>>> + return -1;
> >>>> +
> >>>> + data_fname_in = GET_ARG();
> >>>> + if (check_single_stdin(data_fname_in, ctx_fname_in))
> >>>> + return -1;
> >>>> + } else if (is_prefix(*argv, "data_out")) {
> >>>
> >>> Here, we all use is_prefix() to match "data_in", "data_out",
> >>> "data_size_out" etc.
> >>> That means users can use "data_i" instead of "data_in" as below
> >>> ... | ./bpftool prog run id 283 data_i - data_out - repeat 5
> >>> is this expected?
> >> Yes, this is expected. We use prefix matching as we do pretty much
> >> everywhere else in bpftool. It's not as useful here because most of the
> >> strings for the names are similar. I agree that typing "data_i" instead
> >> of "data_in" brings little advantage, but I see no reason why we should
> >> reject prefixing for those keywords. And we accept "data_s" instead of
> >> "data_size_out", which is still shorter to type than the complete keyword.
> >
> > This makes sense. Thanks for explanation.
> >
> > Another question. Currently, you are proposing "./bpftool prog run ...",
> > but actually it is just a test_run. Do you think we should rename it
> > to "./bpftool prog test_run ..." to make it clear for its intention?
>
> Good question. Hmm. It would make it more explicit that we use the
> BPF_PROG_TEST_RUN command, but at the same time, from the point of view
> of the user, there is nothing in particular that makes it a test run, is
> it? I mean, you provide input data, you get output data and return
> value, that makes it a real BPF run somehow, except that it's not on a
> packet or anything. Do you think it is ambiguous and people may confuse
> it with something like "attach"?
I am more thinking about whether we could have a real "bpftool prog run ..."
in the future which could really run the program in some kind of production
environment...
But I could be wrong since after "bpf prog attach" it may already just start
to run in production, so "bpf prog run ..." not really needed for it.
So "bpf prog run ..." is probably fine.
>
> Thanks,
> Quentin
^ permalink raw reply
* Re: [PATCH v2 1/7] dt-bindings: net: Add bindings for Realtek PHYs
From: Rob Herring @ 2019-07-05 17:07 UTC (permalink / raw)
To: Andrew Lunn
Cc: Matthias Kaehlcke, David S . Miller, Mark Rutland,
Florian Fainelli, Heiner Kallweit, netdev, devicetree,
linux-kernel@vger.kernel.org, Douglas Anderson
In-Reply-To: <20190705162926.GM18473@lunn.ch>
On Fri, Jul 5, 2019 at 10:29 AM Andrew Lunn <andrew@lunn.ch> wrote:
>
> On Fri, Jul 05, 2019 at 10:17:16AM -0600, Rob Herring wrote:
> > On Wed, Jul 3, 2019 at 3:33 PM Andrew Lunn <andrew@lunn.ch> wrote:
> > >
> > > > I think if we're going to have custom properties for phys, we should
> > > > have a compatible string to at least validate whether the custom
> > > > properties are even valid for the node.
> > >
> > > Hi Rob
> > >
> > > What happens with other enumerable busses where a compatible string is
> > > not used?
> >
> > We usually have a compatible. USB and PCI both do. Sometimes it is a
> > defined format based on VID/PID.
>
> Hi Rob
>
> Is it defined what to do with this compatible? Just totally ignore it?
> Validate it against the hardware and warning if it is wrong? Force
> load the driver that implements the compatible, even thought bus
> enumeration says it is the wrong driver?
The short answer is either the problems get fixed or if DTs exist and
need to be supported which are wrong then the OS deals with the
problem to make things work as desired (see PowerMac code).
If the ethernet phy subsystem wants to ignore compatible, that is totally fine.
> > > The Ethernet PHY subsystem will ignore the compatible string and load
> > > the driver which fits the enumeration data. Using the compatible
> > > string only to get the right YAML validator seems wrong. I would
> > > prefer adding some other property with a clear name indicates its is
> > > selecting the validator, and has nothing to do with loading the
> > > correct driver. And it can then be used as well for USB and PCI
> > > devices etc.
> >
> > Just because Linux happens to not use compatible really has nothing to
> > do with whether or not the nodes should have a compatible. What does
> > FreeBSD want? U-boot?
> >
> > I don't follow how adding a validate property would help. It would
> > need to be 'validate-node-as-a-realtek-phy'.
>
> This makes it clear it is all about validating the DT, and nothing
> about the actual running hardware. What i don't really want to see is
> the poorly defined situation that DT contains a compatible string, but
> we have no idea what it is actually used for. See the question above.
What's poorly defined are the current bindings, type definitions of
properties, and what properties are valid or not in specific nodes. If
we only had to better define the rules around compatible use or
mismatches, we'd be a lot better off.
I'm not going to add properties solely for validation when we already
have a well defined, 15 year+ pattern for defining what a node
contains that practically every other subsystem and node uses. I guess
we just won't worry about validating ethernet phy nodes beyond some
basic checks.
Rob
^ permalink raw reply
* Re: [PATCH net-next 8/8] net: mscc: PTP Hardware Clock (PHC) support
From: Richard Cochran @ 2019-07-05 16:47 UTC (permalink / raw)
To: Antoine Tenart
Cc: davem, alexandre.belloni, UNGLinuxDriver, ralf, paul.burton,
jhogan, netdev, linux-mips, thomas.petazzoni, allan.nielsen
In-Reply-To: <20190701100327.6425-9-antoine.tenart@bootlin.com>
On Mon, Jul 01, 2019 at 12:03:27PM +0200, Antoine Tenart wrote:
> +void ocelot_get_hwtimestamp(struct ocelot *ocelot, struct timespec64 *ts)
> +{
> + /* Read current PTP time to get seconds */
> + u32 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
This register is protected by ocelot->ptp_clock_lock from other code
paths, but not in this one!
> + val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM);
> + val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_SAVE);
> + ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
> + ts->tv_sec = ocelot_read_rix(ocelot, PTP_PIN_TOD_SEC_LSB, TOD_ACC_PIN);
...
> +}
> +static int ocelot_init_timestamp(struct ocelot *ocelot)
> +{
> + ocelot->ptp_info = ocelot_ptp_clock_info;
> +
> + ocelot->ptp_clock = ptp_clock_register(&ocelot->ptp_info, ocelot->dev);
> + if (IS_ERR(ocelot->ptp_clock))
> + return PTR_ERR(ocelot->ptp_clock);
You need to handle the NULL case:
ptp_clock_register() - register a PTP hardware clock driver
@info: Structure describing the new clock.
@parent: Pointer to the parent device of the new clock.
Returns a valid pointer on success or PTR_ERR on failure. If PHC
support is missing at the configuration level, this function
returns NULL, and drivers are expected to gracefully handle that
case separately.
> +
> + ocelot_write(ocelot, SYS_PTP_CFG_PTP_STAMP_WID(30), SYS_PTP_CFG);
> + ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_LOW);
> + ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_HIGH);
> +
> + ocelot_write(ocelot, PTP_CFG_MISC_PTP_EN, PTP_CFG_MISC);
> +
> + return 0;
> +}
Thanks,
Richard
^ permalink raw reply
* RE: [rdma 14/16] RDMA/irdma: Add ABI definitions
From: Saleem, Shiraz @ 2019-07-05 16:42 UTC (permalink / raw)
To: Jason Gunthorpe, Leon Romanovsky
Cc: Kirsher, Jeffrey T, dledford@redhat.com, davem@davemloft.net,
Ismail, Mustafa, linux-rdma@vger.kernel.org,
netdev@vger.kernel.org, nhorman@redhat.com, sassmann@redhat.com,
poswald@suse.com, Ertman, David M
In-Reply-To: <20190704121933.GD3401@mellanox.com>
> Subject: Re: [rdma 14/16] RDMA/irdma: Add ABI definitions
>
> On Thu, Jul 04, 2019 at 10:40:21AM +0300, Leon Romanovsky wrote:
> > On Wed, Jul 03, 2019 at 07:12:57PM -0700, Jeff Kirsher wrote:
> > > From: Mustafa Ismail <mustafa.ismail@intel.com>
> > >
> > > Add ABI definitions for irdma.
> > >
> > > Signed-off-by: Mustafa Ismail <mustafa.ismail@intel.com>
> > > Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
> > > include/uapi/rdma/irdma-abi.h | 130
> > > ++++++++++++++++++++++++++++++++++
> > > 1 file changed, 130 insertions(+)
> > > create mode 100644 include/uapi/rdma/irdma-abi.h
> > >
> > > diff --git a/include/uapi/rdma/irdma-abi.h
> > > b/include/uapi/rdma/irdma-abi.h new file mode 100644 index
> > > 000000000000..bdfbda4c829e
> > > +++ b/include/uapi/rdma/irdma-abi.h
> > > @@ -0,0 +1,130 @@
> > > +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */
> > > +/* Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved.
> > > + * Copyright (c) 2005 Topspin Communications. All rights reserved.
> > > + * Copyright (c) 2005 Cisco Systems. All rights reserved.
> > > + * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
> > > + */
> > > +
> > > +#ifndef IRDMA_ABI_H
> > > +#define IRDMA_ABI_H
> > > +
> > > +#include <linux/types.h>
> > > +
> > > +/* irdma must support legacy GEN_1 i40iw kernel
> > > + * and user-space whose last ABI ver is 5 */ #define IRDMA_ABI_VER
> > > +6
> >
> > Can you please elaborate about it more?
> > There is no irdma code in RDMA yet, so it makes me wonder why new
> > define shouldn't start from 1.
>
> It is because they are ABI compatible with the current user space, which raises the
> question why we even have this confusing header file..
It is because we need to support current providers/i40iw user-space.
Our user-space patch series will introduce a new provider (irdma) whose ABI
ver. is also 6 (capable of supporting X722 and which will work with i40iw driver
on older kernels) and removes providers/i40iw from rdma-core.
^ permalink raw reply
* Re: [PATCH net-next 1/8] Documentation/bindings: net: ocelot: document the PTP bank
From: Antoine Tenart @ 2019-07-05 16:39 UTC (permalink / raw)
To: Andrew Lunn
Cc: Antoine Tenart, davem, richardcochran, alexandre.belloni,
UNGLinuxDriver, ralf, paul.burton, jhogan, netdev, linux-mips,
thomas.petazzoni, allan.nielsen
In-Reply-To: <20190705144517.GD4428@lunn.ch>
Hi Andrew,
On Fri, Jul 05, 2019 at 04:45:17PM +0200, Andrew Lunn wrote:
> On Fri, Jul 05, 2019 at 03:30:16PM +0200, Antoine Tenart wrote:
> >
> > I'm not sure about this: optional properties means some parts of the h/w
> > can be missing or not wired. It's not the case here, it's "optional" in
> > the driver only for dt compatibility (so that an older dt blob can work
> > with a newer kernel image), but it's now mandatory in the binding.
>
> If the driver can work without it, it is clearly optional. You just
> get reduced functionality. That is the thing with DT. You can never
> add more required properties after the first commit without breaking
> backwards compatibility. To make the documentation fit the driver,
> somewhere you need to state they are optional. Either by placing the
> new properties in the optional section of the binding, or add a
> comment.
The documentation is unrelated to the driver. It's the documentation of
the binding itself, which is only describing the h/w.
But I discussed this with a someone and I got to the same conclusion as
your statement, because there can be old dt blobs in the wild and the
binding documentation can be used to make new code. That code should be
aware of required/optional properties.
I'll fix this in v2.
Thanks!
Antoine
--
Antoine Ténart, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* RE: [net-next 1/3] ice: Initialize and register platform device to provide RDMA
From: Saleem, Shiraz @ 2019-07-05 16:33 UTC (permalink / raw)
To: Greg KH, Jason Gunthorpe
Cc: Kirsher, Jeffrey T, davem@davemloft.net, dledford@redhat.com,
Nguyen, Anthony L, netdev@vger.kernel.org,
linux-rdma@vger.kernel.org, nhorman@redhat.com,
sassmann@redhat.com, poswald@suse.com, Ismail, Mustafa,
Ertman, David M, Bowers, AndrewX
In-Reply-To: <20190704134612.GB10963@kroah.com>
> Subject: Re: [net-next 1/3] ice: Initialize and register platform device to provide
> RDMA
>
> On Thu, Jul 04, 2019 at 12:48:29PM +0000, Jason Gunthorpe wrote:
> > On Thu, Jul 04, 2019 at 02:42:47PM +0200, Greg KH wrote:
> > > On Thu, Jul 04, 2019 at 12:37:33PM +0000, Jason Gunthorpe wrote:
> > > > On Thu, Jul 04, 2019 at 02:29:50PM +0200, Greg KH wrote:
> > > > > On Thu, Jul 04, 2019 at 12:16:41PM +0000, Jason Gunthorpe wrote:
> > > > > > On Wed, Jul 03, 2019 at 07:12:50PM -0700, Jeff Kirsher wrote:
> > > > > > > From: Tony Nguyen <anthony.l.nguyen@intel.com>
> > > > > > >
> > > > > > > The RDMA block does not advertise on the PCI bus or any other bus.
> > > > > > > Thus the ice driver needs to provide access to the RDMA
> > > > > > > hardware block via a virtual bus; utilize the platform bus to provide this
> access.
> > > > > > >
> > > > > > > This patch initializes the driver to support RDMA as well as
> > > > > > > creates and registers a platform device for the RDMA driver
> > > > > > > to register to. At this point the driver is fully
> > > > > > > initialized to register a platform driver, however, can not
> > > > > > > yet register as the ops have not been implemented.
> > > > > >
> > > > > > I think you need Greg's ack on all this driver stuff -
> > > > > > particularly that a platform_device is OK.
> > > > >
> > > > > A platform_device is almost NEVER ok.
> > > > >
> > > > > Don't abuse it, make a real device on a real bus. If you don't
> > > > > have a real bus and just need to create a device to hang other
> > > > > things off of, then use the virtual one, that's what it is there for.
> > > >
> > > > Ideally I'd like to see all the RDMA drivers that connect to
> > > > ethernet drivers use some similar scheme.
> > >
> > > Why? They should be attached to a "real" device, why make any up?
> >
> > ? A "real" device, like struct pci_device, can only bind to one
> > driver. How can we bind it concurrently to net, rdma, scsi, etc?
>
> MFD was designed for this very problem.
>
> > > > This is for a PCI device that plugs into multiple subsystems in
> > > > the kernel, ie it has net driver functionality, rdma
> > > > functionality, some even have SCSI functionality
> > >
> > > Sounds like a MFD device, why aren't you using that functionality
> > > instead?
> >
> > This was also my advice, but in another email Jeff says:
> >
> > MFD architecture was also considered, and we selected the simpler
> > platform model. Supporting a MFD architecture would require an
> > additional MFD core driver, individual platform netdev, RDMA function
> > drivers, and stripping a large portion of the netdev drivers into
> > MFD core. The sub-devices registered by MFD core for function
> > drivers are indeed platform devices.
>
> So, "mfd is too hard, let's abuse a platform device" is ok?
>
> People have been wanting to do MFD drivers for PCI devices for a long time, it's
> about time someone actually did the work for it, I bet it will not be all that complex
> if tiny embedded drivers can do it :)
>
Hi Greg - Thanks for your feedback!
We currently have 2 PCI function netdev drivers in the kernel (i40e & ice) that support devices (x722 & e810)
which are RDMA capable. Our objective is to add a single unified RDMA driver
(as this a subsystem specific requirement) which needs to access HW resources from the
netdev PF drivers. Attaching platform devices from the netdev drivers to the platform bus
and having a single RDMA platform driver bind to them and access these resources seemed
like a simple approach to realize our objective. But seems like attaching platform devices is
wrong. I would like to understand why.
Are platform sub devices only to be added from an MFD core driver? I am also wondering if MFD arch.
would allow for realizing a single RDMA driver and whether we need an MFD core driver for
each device, x722 & e810 or whether it can be a single driver.
Shiraz
^ permalink raw reply
* Re: [PATCH v2 1/7] dt-bindings: net: Add bindings for Realtek PHYs
From: Andrew Lunn @ 2019-07-05 16:29 UTC (permalink / raw)
To: Rob Herring
Cc: Matthias Kaehlcke, David S . Miller, Mark Rutland,
Florian Fainelli, Heiner Kallweit, netdev, devicetree,
linux-kernel@vger.kernel.org, Douglas Anderson
In-Reply-To: <CAL_Jsq+dqz7n0_+Y5R4772-rh=9x=k20A69hnDwxH3OyZXQneQ@mail.gmail.com>
On Fri, Jul 05, 2019 at 10:17:16AM -0600, Rob Herring wrote:
> On Wed, Jul 3, 2019 at 3:33 PM Andrew Lunn <andrew@lunn.ch> wrote:
> >
> > > I think if we're going to have custom properties for phys, we should
> > > have a compatible string to at least validate whether the custom
> > > properties are even valid for the node.
> >
> > Hi Rob
> >
> > What happens with other enumerable busses where a compatible string is
> > not used?
>
> We usually have a compatible. USB and PCI both do. Sometimes it is a
> defined format based on VID/PID.
Hi Rob
Is it defined what to do with this compatible? Just totally ignore it?
Validate it against the hardware and warning if it is wrong? Force
load the driver that implements the compatible, even thought bus
enumeration says it is the wrong driver?
> > The Ethernet PHY subsystem will ignore the compatible string and load
> > the driver which fits the enumeration data. Using the compatible
> > string only to get the right YAML validator seems wrong. I would
> > prefer adding some other property with a clear name indicates its is
> > selecting the validator, and has nothing to do with loading the
> > correct driver. And it can then be used as well for USB and PCI
> > devices etc.
>
> Just because Linux happens to not use compatible really has nothing to
> do with whether or not the nodes should have a compatible. What does
> FreeBSD want? U-boot?
>
> I don't follow how adding a validate property would help. It would
> need to be 'validate-node-as-a-realtek-phy'.
This makes it clear it is all about validating the DT, and nothing
about the actual running hardware. What i don't really want to see is
the poorly defined situation that DT contains a compatible string, but
we have no idea what it is actually used for. See the question above.
Andrew
^ permalink raw reply
* Re: [PATCH bpf-next RFC v3 2/6] bpf: add BPF_MAP_DUMP command to dump more than one entry per call
From: Y Song @ 2019-07-05 16:22 UTC (permalink / raw)
To: Brian Vazquez
Cc: Brian Vazquez, Alexei Starovoitov, Daniel Borkmann,
David S . Miller, Stanislav Fomichev, Willem de Bruijn,
Petar Penkov, LKML, netdev, bpf
In-Reply-To: <20190703170118.196552-3-brianvv@google.com>
On Wed, Jul 3, 2019 at 10:03 AM Brian Vazquez <brianvv@google.com> wrote:
>
> This introduces a new command to retrieve a variable number of entries
> from a bpf map wrapping the existing bpf methods:
> map_get_next_key and map_lookup_elem
>
> To start dumping the map from the beginning you must specify NULL as
> the prev_key.
>
> The new API returns 0 when it successfully copied all the elements
> requested or it copied less because there weren't more elements to
> retrieved (err == -ENOENT). In last scenario err will be masked to 0.
>
> On a successful call buf and buf_len will contain correct data and in
> case prev_key was provided (not for the first walk, since prev_key is
> NULL) it will contain the last_key copied into the buf which will simplify
> next call.
>
> Only when it can't find a single element it will return -ENOENT meaning
> that the map has been entirely walked. When an error is return buf,
> buf_len and prev_key shouldn't be read nor used.
>
> Because maps can be called from userspace and kernel code, this function
> can have a scenario where the next_key was found but by the time we
> try to retrieve the value the element is not there, in this case the
> function continues and tries to get a new next_key value, skipping the
> deleted key. If at some point the function find itself trap in a loop,
> it will return -EINTR.
>
> The function will try to fit as much as possible in the buf provided and
> will return -EINVAL if buf_len is smaller than elem_size.
>
> QUEUE and STACK maps are not supported.
>
> Note that map_dump doesn't guarantee that reading the entire table is
> consistent since this function is always racing with kernel and user code
> but the same behaviour is found when the entire table is walked using
> the current interfaces: map_get_next_key + map_lookup_elem.
> It is also important to note that when a locked map the lock is grabbed for
> 1 entry at the time, meaning that the buf returned might or might not be
> consistent.
First, thanks for the RFC. I do think there are use cases where
batch dumping helps.
Some comments below.
>
> Suggested-by: Stanislav Fomichev <sdf@google.com>
> Signed-off-by: Brian Vazquez <brianvv@google.com>
> ---
> include/uapi/linux/bpf.h | 9 +++
> kernel/bpf/syscall.c | 118 +++++++++++++++++++++++++++++++++++++++
> 2 files changed, 127 insertions(+)
>
> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> index cffea1826a1f..cc589570a639 100644
> --- a/include/uapi/linux/bpf.h
> +++ b/include/uapi/linux/bpf.h
> @@ -106,6 +106,7 @@ enum bpf_cmd {
> BPF_TASK_FD_QUERY,
> BPF_MAP_LOOKUP_AND_DELETE_ELEM,
> BPF_MAP_FREEZE,
> + BPF_MAP_DUMP,
> };
>
> enum bpf_map_type {
> @@ -388,6 +389,14 @@ union bpf_attr {
> __u64 flags;
> };
>
> + struct { /* struct used by BPF_MAP_DUMP command */
> + __u32 map_fd;
> + __aligned_u64 prev_key;
> + __aligned_u64 buf;
> + __aligned_u64 buf_len; /* input/output: len of buf */
> + __u64 flags;
> + } dump;
Maybe you can swap map_fd and flags?
This way, you won't have hole right after map_fd?
> +
> struct { /* anonymous struct used by BPF_PROG_LOAD command */
> __u32 prog_type; /* one of enum bpf_prog_type */
> __u32 insn_cnt;
> diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
> index d200d2837ade..78d55463fc76 100644
> --- a/kernel/bpf/syscall.c
> +++ b/kernel/bpf/syscall.c
> @@ -1097,6 +1097,121 @@ static int map_get_next_key(union bpf_attr *attr)
> return err;
> }
>
> +/* last field in 'union bpf_attr' used by this command */
> +#define BPF_MAP_DUMP_LAST_FIELD dump.buf_len
> +
> +static int map_dump(union bpf_attr *attr)
> +{
> + void __user *ukey = u64_to_user_ptr(attr->dump.prev_key);
> + void __user *ubuf = u64_to_user_ptr(attr->dump.buf);
> + u32 __user *ubuf_len = u64_to_user_ptr(attr->dump.buf_len);
> + int ufd = attr->dump.map_fd;
> + struct bpf_map *map;
> + void *buf, *prev_key, *key, *value;
> + u32 value_size, elem_size, buf_len, cp_len;
> + struct fd f;
> + int err;
> + bool first_key = false;
> +
> + if (CHECK_ATTR(BPF_MAP_DUMP))
> + return -EINVAL;
> +
> + attr->flags = 0;
Why do you want attr->flags? This is to modify anonumous struct used by
BPF_MAP_*_ELEM commands.
> + if (attr->dump.flags & ~BPF_F_LOCK)
> + return -EINVAL;
> +
> + f = fdget(ufd);
> + map = __bpf_map_get(f);
> + if (IS_ERR(map))
> + return PTR_ERR(map);
> + if (!(map_get_sys_perms(map, f) & FMODE_CAN_READ)) {
> + err = -EPERM;
> + goto err_put;
> + }
> +
> + if ((attr->dump.flags & BPF_F_LOCK) &&
> + !map_value_has_spin_lock(map)) {
> + err = -EINVAL;
> + goto err_put;
> + }
> +
> + if (map->map_type == BPF_MAP_TYPE_QUEUE ||
> + map->map_type == BPF_MAP_TYPE_STACK) {
> + err = -ENOTSUPP;
> + goto err_put;
> + }
> +
> + value_size = bpf_map_value_size(map);
> +
> + err = get_user(buf_len, ubuf_len);
> + if (err)
> + goto err_put;
> +
> + elem_size = map->key_size + value_size;
> + if (buf_len < elem_size) {
> + err = -EINVAL;
> + goto err_put;
> + }
> +
> + if (ukey) {
> + prev_key = __bpf_copy_key(ukey, map->key_size);
> + if (IS_ERR(prev_key)) {
> + err = PTR_ERR(prev_key);
> + goto err_put;
> + }
> + } else {
> + prev_key = NULL;
> + first_key = true;
> + }
> +
> + err = -ENOMEM;
> + buf = kmalloc(elem_size, GFP_USER | __GFP_NOWARN);
> + if (!buf)
> + goto err_put;
> +
> + key = buf;
> + value = key + map->key_size;
> + for (cp_len = 0; cp_len + elem_size <= buf_len;) {
> + if (signal_pending(current)) {
> + err = -EINTR;
> + break;
> + }
> +
> + rcu_read_lock();
> + err = map->ops->map_get_next_key(map, prev_key, key);
> + rcu_read_unlock();
> +
> + if (err)
> + break;
> +
> + err = bpf_map_copy_value(map, key, value, attr->dump.flags);
> +
> + if (err == -ENOENT)
> + continue;
> + if (err)
> + goto free_buf;
> +
> + if (copy_to_user(ubuf + cp_len, buf, elem_size)) {
> + err = -EFAULT;
> + goto free_buf;
> + }
> +
> + prev_key = key;
> + cp_len += elem_size;
> + }
> +
> + if (err == -ENOENT && cp_len)
> + err = 0;
> + if (!err && (copy_to_user(ubuf_len, &cp_len, sizeof(cp_len)) ||
> + (!first_key && copy_to_user(ukey, key, map->key_size))))
> + err = -EFAULT;
> +free_buf:
> + kfree(buf);
> +err_put:
> + fdput(f);
> + return err;
> +}
> +
> #define BPF_MAP_LOOKUP_AND_DELETE_ELEM_LAST_FIELD value
>
> static int map_lookup_and_delete_elem(union bpf_attr *attr)
> @@ -2910,6 +3025,9 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, siz
> case BPF_MAP_LOOKUP_AND_DELETE_ELEM:
> err = map_lookup_and_delete_elem(&attr);
> break;
> + case BPF_MAP_DUMP:
> + err = map_dump(&attr);
> + break;
In bcc, we have use cases like this. At a certain time interval (e.g.,
every 2 seconds),
we get all key/value pairs for a map, we format and print out map
key/values on the screen,
and then delete all key/value pairs we retrieved earlier.
Currently, bpf_get_next_key() is used to get all key/value pairs, and
deletion also happened
at each key level.
Your batch dump command should help retrieving map key/value pairs.
What do you think deletions of those just retrieved map entries?
With an additional flag and fold into BPF_MAP_DUMP?
or implement a new BPF_MAP_DUMP_AND_DELETE?
I mentioned this so that we can start discussion now.
You do not need to implement batch deletion part, but let us
have a design extensible for that.
Thanks.
> default:
> err = -EINVAL;
> break;
> --
> 2.22.0.410.gd8fdbe21b5-goog
>
^ permalink raw reply
* Re: [PATCH net-next] nfp: tls: fix error return code in nfp_net_tls_add()
From: Jakub Kicinski @ 2019-07-05 16:21 UTC (permalink / raw)
To: Wei Yongjun; +Cc: Dirk van der Merwe, oss-drivers, netdev, kernel-janitors
In-Reply-To: <20190705082625.168515-1-weiyongjun1@huawei.com>
On Fri, 5 Jul 2019 08:26:25 +0000, Wei Yongjun wrote:
> Fix to return negative error code -EINVAL from the error handling
> case instead of 0, as done elsewhere in this function.
>
> Fixes: 1f35a56cf586 ("nfp: tls: add/delete TLS TX connections")
> Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
Acked-by: Jakub Kicinski <jakub.kicinski@netronome.com>
^ permalink raw reply
* Re: [PATCH v7 net-next 1/5] net: core: page_pool: add user refcnt and reintroduce page_pool_destroy
From: Saeed Mahameed @ 2019-07-05 16:19 UTC (permalink / raw)
To: Jesper Dangaard Brouer
Cc: Ivan Khoronzhuk, grygorii.strashko, David S. Miller,
Alexei Starovoitov, linux-kernel, linux-omap, ilias.apalodimas,
Linux Netdev List, Daniel Borkmann, Jakub Kicinski,
John Fastabend, Tariq Toukan, Saeed Mahameed
In-Reply-To: <20190705094346.13b06da6@carbon>
On Fri, Jul 5, 2019 at 3:45 AM Jesper Dangaard Brouer <brouer@redhat.com> wrote:
>
>
> CC: Tariq + Saeed, could you please review the mlx5 part.
>
> On Fri, 5 Jul 2019 02:14:02 +0300
> Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org> wrote:
>
> > Jesper recently removed page_pool_destroy() (from driver invocation)
> > and moved shutdown and free of page_pool into xdp_rxq_info_unreg(),
> > in-order to handle in-flight packets/pages. This created an asymmetry
> > in drivers create/destroy pairs.
> >
> > This patch reintroduce page_pool_destroy and add page_pool user
> > refcnt. This serves the purpose to simplify drivers error handling as
> > driver now drivers always calls page_pool_destroy() and don't need to
> > track if xdp_rxq_info_reg_mem_model() was unsuccessful.
> >
> > This could be used for a special cases where a single RX-queue (with a
> > single page_pool) provides packets for two net_device'es, and thus
> > needs to register the same page_pool twice with two xdp_rxq_info
> > structures.
> >
> > This patch is primarily to ease API usage for drivers. The recently
> > merged netsec driver, actually have a bug in this area, which is
> > solved by this API change.
> >
This patch and the mlx5 part looks good to me,
Reviewed-by: Saeed Mahameed <saeedm@mellanox.com>
> > This patch is a modified version of Ivan Khoronzhu's original patch.
> >
> > Link: https://lore.kernel.org/netdev/20190625175948.24771-2-ivan.khoronzhuk@linaro.org/
> > Fixes: 5c67bf0ec4d0 ("net: netsec: Use page_pool API")
> > Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
> > Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
> > Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
>
> Acked-by: Jesper Dangaard Brouer <brouer@redhat.com>
>
> Thank you Ivan for taking this more simple approach. If we later see
> more drivers wanting this feature of a single RX-queue providing
> packets to multiple net_device'es, then we can change into your
> more generic API at XDP-reg-layer approach later. For now, we keep
> code complexity as low as possible.
>
>
> > ---
> > .../net/ethernet/mellanox/mlx5/core/en_main.c | 4 +--
> > drivers/net/ethernet/socionext/netsec.c | 8 ++----
> > include/net/page_pool.h | 25 +++++++++++++++++++
> > net/core/page_pool.c | 8 ++++++
> > net/core/xdp.c | 3 +++
> > 5 files changed, 40 insertions(+), 8 deletions(-)
> >
> > diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
> > index 2f9093ba82aa..ac882b2341d0 100644
> > --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
> > +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
> > @@ -575,8 +575,6 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
> > }
> > err = xdp_rxq_info_reg_mem_model(&rq->xdp_rxq,
> > MEM_TYPE_PAGE_POOL, rq->page_pool);
> > - if (err)
> > - page_pool_free(rq->page_pool);
> > }
> > if (err)
> > goto err_free;
> > @@ -644,6 +642,7 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
> > if (rq->xdp_prog)
> > bpf_prog_put(rq->xdp_prog);
> > xdp_rxq_info_unreg(&rq->xdp_rxq);
> > + page_pool_destroy(rq->page_pool);
> > mlx5_wq_destroy(&rq->wq_ctrl);
> >
> > return err;
> > @@ -678,6 +677,7 @@ static void mlx5e_free_rq(struct mlx5e_rq *rq)
> > }
> >
> > xdp_rxq_info_unreg(&rq->xdp_rxq);
> > + page_pool_destroy(rq->page_pool);
> > mlx5_wq_destroy(&rq->wq_ctrl);
> > }
> >
> > diff --git a/drivers/net/ethernet/socionext/netsec.c b/drivers/net/ethernet/socionext/netsec.c
> > index 5544a722543f..43ab0ce90704 100644
> > --- a/drivers/net/ethernet/socionext/netsec.c
> > +++ b/drivers/net/ethernet/socionext/netsec.c
> > @@ -1210,15 +1210,11 @@ static void netsec_uninit_pkt_dring(struct netsec_priv *priv, int id)
> > }
> > }
> >
> > - /* Rx is currently using page_pool
> > - * since the pool is created during netsec_setup_rx_dring(), we need to
> > - * free the pool manually if the registration failed
> > - */
> > + /* Rx is currently using page_pool */
> > if (id == NETSEC_RING_RX) {
> > if (xdp_rxq_info_is_reg(&dring->xdp_rxq))
> > xdp_rxq_info_unreg(&dring->xdp_rxq);
> > - else
> > - page_pool_free(dring->page_pool);
> > + page_pool_destroy(dring->page_pool);
> > }
> >
> > memset(dring->desc, 0, sizeof(struct netsec_desc) * DESC_NUM);
> > diff --git a/include/net/page_pool.h b/include/net/page_pool.h
> > index ee9c871d2043..2cbcdbdec254 100644
> > --- a/include/net/page_pool.h
> > +++ b/include/net/page_pool.h
> > @@ -101,6 +101,12 @@ struct page_pool {
> > struct ptr_ring ring;
> >
> > atomic_t pages_state_release_cnt;
> > +
> > + /* A page_pool is strictly tied to a single RX-queue being
> > + * protected by NAPI, due to above pp_alloc_cache. This
> > + * refcnt serves purpose is to simplify drivers error handling.
> > + */
> > + refcount_t user_cnt;
> > };
> >
> > struct page *page_pool_alloc_pages(struct page_pool *pool, gfp_t gfp);
> > @@ -134,6 +140,15 @@ static inline void page_pool_free(struct page_pool *pool)
> > #endif
> > }
> >
> > +/* Drivers use this instead of page_pool_free */
> > +static inline void page_pool_destroy(struct page_pool *pool)
> > +{
> > + if (!pool)
> > + return;
> > +
> > + page_pool_free(pool);
> > +}
> > +
> > /* Never call this directly, use helpers below */
> > void __page_pool_put_page(struct page_pool *pool,
> > struct page *page, bool allow_direct);
> > @@ -201,4 +216,14 @@ static inline bool is_page_pool_compiled_in(void)
> > #endif
> > }
> >
> > +static inline void page_pool_get(struct page_pool *pool)
> > +{
> > + refcount_inc(&pool->user_cnt);
> > +}
> > +
> > +static inline bool page_pool_put(struct page_pool *pool)
> > +{
> > + return refcount_dec_and_test(&pool->user_cnt);
> > +}
> > +
> > #endif /* _NET_PAGE_POOL_H */
> > diff --git a/net/core/page_pool.c b/net/core/page_pool.c
> > index b366f59885c1..3272dc7a8c81 100644
> > --- a/net/core/page_pool.c
> > +++ b/net/core/page_pool.c
> > @@ -49,6 +49,9 @@ static int page_pool_init(struct page_pool *pool,
> >
> > atomic_set(&pool->pages_state_release_cnt, 0);
> >
> > + /* Driver calling page_pool_create() also call page_pool_destroy() */
> > + refcount_set(&pool->user_cnt, 1);
> > +
> > if (pool->p.flags & PP_FLAG_DMA_MAP)
> > get_device(pool->p.dev);
> >
> > @@ -70,6 +73,7 @@ struct page_pool *page_pool_create(const struct page_pool_params *params)
> > kfree(pool);
> > return ERR_PTR(err);
> > }
> > +
> > return pool;
> > }
> > EXPORT_SYMBOL(page_pool_create);
> > @@ -356,6 +360,10 @@ static void __warn_in_flight(struct page_pool *pool)
> >
> > void __page_pool_free(struct page_pool *pool)
> > {
> > + /* Only last user actually free/release resources */
> > + if (!page_pool_put(pool))
> > + return;
> > +
> > WARN(pool->alloc.count, "API usage violation");
> > WARN(!ptr_ring_empty(&pool->ring), "ptr_ring is not empty");
> >
> > diff --git a/net/core/xdp.c b/net/core/xdp.c
> > index 829377cc83db..d7bf62ffbb5e 100644
> > --- a/net/core/xdp.c
> > +++ b/net/core/xdp.c
> > @@ -370,6 +370,9 @@ int xdp_rxq_info_reg_mem_model(struct xdp_rxq_info *xdp_rxq,
> > goto err;
> > }
> >
> > + if (type == MEM_TYPE_PAGE_POOL)
> > + page_pool_get(xdp_alloc->page_pool);
> > +
> > mutex_unlock(&mem_id_lock);
> >
> > trace_mem_connect(xdp_alloc, xdp_rxq);
>
>
>
> --
> Best regards,
> Jesper Dangaard Brouer
> MSc.CS, Principal Kernel Engineer at Red Hat
> LinkedIn: http://www.linkedin.com/in/brouer
^ permalink raw reply
* Re: [PATCH v2 1/7] dt-bindings: net: Add bindings for Realtek PHYs
From: Rob Herring @ 2019-07-05 16:18 UTC (permalink / raw)
To: Matthias Kaehlcke
Cc: Andrew Lunn, David S . Miller, Mark Rutland, Florian Fainelli,
Heiner Kallweit, netdev, devicetree, linux-kernel@vger.kernel.org,
Douglas Anderson
In-Reply-To: <20190703220843.GJ250418@google.com>
On Wed, Jul 3, 2019 at 4:08 PM Matthias Kaehlcke <mka@chromium.org> wrote:
>
> On Wed, Jul 03, 2019 at 11:33:27PM +0200, Andrew Lunn wrote:
> > > I think if we're going to have custom properties for phys, we should
> > > have a compatible string to at least validate whether the custom
> > > properties are even valid for the node.
> >
> > Hi Rob
> >
> > What happens with other enumerable busses where a compatible string is
> > not used?
> >
> > The Ethernet PHY subsystem will ignore the compatible string and load
> > the driver which fits the enumeration data. Using the compatible
> > string only to get the right YAML validator seems wrong. I would
> > prefer adding some other property with a clear name indicates its is
> > selecting the validator, and has nothing to do with loading the
> > correct driver. And it can then be used as well for USB and PCI
> > devices etc.
>
> I also have doubts whether a compatible string is the right answer
> here. It's not needed/used by the subsystem, but would it be a
> required property because it's needed for validation?
It could be required only for phy's with vendor specific properties.
^ permalink raw reply
* Re: [PATCH v2 1/7] dt-bindings: net: Add bindings for Realtek PHYs
From: Rob Herring @ 2019-07-05 16:17 UTC (permalink / raw)
To: Andrew Lunn
Cc: Matthias Kaehlcke, David S . Miller, Mark Rutland,
Florian Fainelli, Heiner Kallweit, netdev, devicetree,
linux-kernel@vger.kernel.org, Douglas Anderson
In-Reply-To: <20190703213327.GH18473@lunn.ch>
On Wed, Jul 3, 2019 at 3:33 PM Andrew Lunn <andrew@lunn.ch> wrote:
>
> > I think if we're going to have custom properties for phys, we should
> > have a compatible string to at least validate whether the custom
> > properties are even valid for the node.
>
> Hi Rob
>
> What happens with other enumerable busses where a compatible string is
> not used?
We usually have a compatible. USB and PCI both do. Sometimes it is a
defined format based on VID/PID.
> The Ethernet PHY subsystem will ignore the compatible string and load
> the driver which fits the enumeration data. Using the compatible
> string only to get the right YAML validator seems wrong. I would
> prefer adding some other property with a clear name indicates its is
> selecting the validator, and has nothing to do with loading the
> correct driver. And it can then be used as well for USB and PCI
> devices etc.
Just because Linux happens to not use compatible really has nothing to
do with whether or not the nodes should have a compatible. What does
FreeBSD want? U-boot?
I don't follow how adding a validate property would help. It would
need to be 'validate-node-as-a-realtek-phy'. The schema selection is
done for each schema on a node by node basis and has to be based on
some data in the node (or always applied). Using compatible or node
name are just the default way.
Rob
^ permalink raw reply
* [PATCH net-next] net: openvswitch: do not update max_headroom if new headroom is equal to old headroom
From: Taehee Yoo @ 2019-07-05 16:08 UTC (permalink / raw)
To: davem, pshelar, netdev, dev; +Cc: ap420073
When a vport is deleted, the maximum headroom size would be changed.
If the vport which has the largest headroom is deleted,
the new max_headroom would be set.
But, if the new headroom size is equal to the old headroom size,
updating routine is unnecessary.
Signed-off-by: Taehee Yoo <ap420073@gmail.com>
---
net/openvswitch/datapath.c | 39 +++++++++++++++++++++++++++-----------
1 file changed, 28 insertions(+), 11 deletions(-)
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 33b388103741..892287d06c17 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -1958,10 +1958,9 @@ static struct vport *lookup_vport(struct net *net,
}
-/* Called with ovs_mutex */
-static void update_headroom(struct datapath *dp)
+static unsigned int ovs_get_max_headroom(struct datapath *dp)
{
- unsigned dev_headroom, max_headroom = 0;
+ unsigned int dev_headroom, max_headroom = 0;
struct net_device *dev;
struct vport *vport;
int i;
@@ -1975,10 +1974,19 @@ static void update_headroom(struct datapath *dp)
}
}
- dp->max_headroom = max_headroom;
+ return max_headroom;
+}
+
+/* Called with ovs_mutex */
+static void ovs_update_headroom(struct datapath *dp, unsigned int new_headroom)
+{
+ struct vport *vport;
+ int i;
+
+ dp->max_headroom = new_headroom;
for (i = 0; i < DP_VPORT_HASH_BUCKETS; i++)
hlist_for_each_entry_rcu(vport, &dp->ports[i], dp_hash_node)
- netdev_set_rx_headroom(vport->dev, max_headroom);
+ netdev_set_rx_headroom(vport->dev, new_headroom);
}
static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
@@ -1989,6 +1997,7 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
struct sk_buff *reply;
struct vport *vport;
struct datapath *dp;
+ unsigned int new_headroom;
u32 port_no;
int err;
@@ -2050,8 +2059,10 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
info->snd_portid, info->snd_seq, 0,
OVS_VPORT_CMD_NEW);
- if (netdev_get_fwd_headroom(vport->dev) > dp->max_headroom)
- update_headroom(dp);
+ new_headroom = netdev_get_fwd_headroom(vport->dev);
+
+ if (new_headroom > dp->max_headroom)
+ ovs_update_headroom(dp, new_headroom);
else
netdev_set_rx_headroom(vport->dev, dp->max_headroom);
@@ -2122,11 +2133,12 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info)
static int ovs_vport_cmd_del(struct sk_buff *skb, struct genl_info *info)
{
- bool must_update_headroom = false;
+ bool update_headroom = false;
struct nlattr **a = info->attrs;
struct sk_buff *reply;
struct datapath *dp;
struct vport *vport;
+ unsigned int new_headroom;
int err;
reply = ovs_vport_cmd_alloc_info();
@@ -2152,12 +2164,17 @@ static int ovs_vport_cmd_del(struct sk_buff *skb, struct genl_info *info)
/* the vport deletion may trigger dp headroom update */
dp = vport->dp;
if (netdev_get_fwd_headroom(vport->dev) == dp->max_headroom)
- must_update_headroom = true;
+ update_headroom = true;
+
netdev_reset_rx_headroom(vport->dev);
ovs_dp_detach_port(vport);
- if (must_update_headroom)
- update_headroom(dp);
+ if (update_headroom) {
+ new_headroom = ovs_get_max_headroom(dp);
+
+ if (new_headroom < dp->max_headroom)
+ ovs_update_headroom(dp, new_headroom);
+ }
ovs_unlock();
ovs_notify(&dp_vport_genl_family, reply, info);
--
2.17.1
^ permalink raw reply related
* [PATCH net-next] net: openvswitch: use netif_ovs_is_port() instead of opencode
From: Taehee Yoo @ 2019-07-05 16:05 UTC (permalink / raw)
To: davem, pshelar, netdev, dev; +Cc: ap420073
Use netif_ovs_is_port() function instead of open code.
This patch doesn't change logic.
Signed-off-by: Taehee Yoo <ap420073@gmail.com>
---
net/openvswitch/dp_notify.c | 2 +-
net/openvswitch/vport-netdev.c | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/openvswitch/dp_notify.c b/net/openvswitch/dp_notify.c
index 53cf07d141b4..7af0cde8b293 100644
--- a/net/openvswitch/dp_notify.c
+++ b/net/openvswitch/dp_notify.c
@@ -48,7 +48,7 @@ void ovs_dp_notify_wq(struct work_struct *work)
if (vport->ops->type == OVS_VPORT_TYPE_INTERNAL)
continue;
- if (!(vport->dev->priv_flags & IFF_OVS_DATAPATH))
+ if (!(netif_is_ovs_port(vport->dev)))
dp_detach_port_notify(vport);
}
}
diff --git a/net/openvswitch/vport-netdev.c b/net/openvswitch/vport-netdev.c
index 52a1ed9633ec..57d6436e6f6a 100644
--- a/net/openvswitch/vport-netdev.c
+++ b/net/openvswitch/vport-netdev.c
@@ -156,7 +156,7 @@ void ovs_netdev_detach_dev(struct vport *vport)
static void netdev_destroy(struct vport *vport)
{
rtnl_lock();
- if (vport->dev->priv_flags & IFF_OVS_DATAPATH)
+ if (netif_is_ovs_port(vport->dev))
ovs_netdev_detach_dev(vport);
rtnl_unlock();
@@ -166,7 +166,7 @@ static void netdev_destroy(struct vport *vport)
void ovs_netdev_tunnel_destroy(struct vport *vport)
{
rtnl_lock();
- if (vport->dev->priv_flags & IFF_OVS_DATAPATH)
+ if (netif_is_ovs_port(vport->dev))
ovs_netdev_detach_dev(vport);
/* We can be invoked by both explicit vport deletion and
@@ -186,7 +186,7 @@ EXPORT_SYMBOL_GPL(ovs_netdev_tunnel_destroy);
/* Returns null if this device is not attached to a datapath. */
struct vport *ovs_netdev_get_vport(struct net_device *dev)
{
- if (likely(dev->priv_flags & IFF_OVS_DATAPATH))
+ if (likely(netif_is_ovs_port(dev)))
return (struct vport *)
rcu_dereference_rtnl(dev->rx_handler_data);
else
--
2.17.1
^ permalink raw reply related
* Re: [PATCH bpf-next] tools: bpftool: add "prog run" subcommand to test-run programs
From: Quentin Monnet @ 2019-07-05 16:03 UTC (permalink / raw)
To: Y Song; +Cc: Alexei Starovoitov, Daniel Borkmann, bpf, netdev, oss-drivers
In-Reply-To: <CAH3MdRWcU9=YCO6WuLY2e2-kixE7E8yLBS+fJH4ASh94oHcK-A@mail.gmail.com>
2019-07-05 08:42 UTC-0700 ~ Y Song <ys114321@gmail.com>
> On Fri, Jul 5, 2019 at 1:21 AM Quentin Monnet
> <quentin.monnet@netronome.com> wrote:
>>
>> 2019-07-04 22:49 UTC-0700 ~ Y Song <ys114321@gmail.com>
>>> On Thu, Jul 4, 2019 at 1:58 AM Quentin Monnet
>>> <quentin.monnet@netronome.com> wrote:
>>>>
>>>> Add a new "bpftool prog run" subcommand to run a loaded program on input
>>>> data (and possibly with input context) passed by the user.
>>>>
>>>> Print output data (and output context if relevant) into a file or into
>>>> the console. Print return value and duration for the test run into the
>>>> console.
>>>>
>>>> A "repeat" argument can be passed to run the program several times in a
>>>> row.
>>>>
>>>> The command does not perform any kind of verification based on program
>>>> type (Is this program type allowed to use an input context?) or on data
>>>> consistency (Can I work with empty input data?), this is left to the
>>>> kernel.
>>>>
>>>> Example invocation:
>>>>
>>>> # perl -e 'print "\x0" x 14' | ./bpftool prog run \
>>>> pinned /sys/fs/bpf/sample_ret0 \
>>>> data_in - data_out - repeat 5
>>>> 0000000 0000 0000 0000 0000 0000 0000 0000 | ........ ......
>>>> Return value: 0, duration (average): 260ns
>>>>
>>>> When one of data_in or ctx_in is "-", bpftool reads from standard input,
>>>> in binary format. Other formats (JSON, hexdump) might be supported (via
>>>> an optional command line keyword like "data_fmt_in") in the future if
>>>> relevant, but this would require doing more parsing in bpftool.
>>>>
>>>> Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
>>>> Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
>>>> ---
>>
>> [...]
>>
>>>> diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
>>>> index 9b0db5d14e31..8dcbaa0a8ab1 100644
>>>> --- a/tools/bpf/bpftool/prog.c
>>>> +++ b/tools/bpf/bpftool/prog.c
>>>> @@ -15,6 +15,7 @@
>>>> #include <sys/stat.h>
>>>>
>>>> #include <linux/err.h>
>>>> +#include <linux/sizes.h>
>>>>
>>>> #include <bpf.h>
>>>> #include <btf.h>
>>>> @@ -748,6 +749,344 @@ static int do_detach(int argc, char **argv)
>>>> return 0;
>>>> }
>>>>
>>>> +static int check_single_stdin(char *file_in, char *other_file_in)
>>>> +{
>>>> + if (file_in && other_file_in &&
>>>> + !strcmp(file_in, "-") && !strcmp(other_file_in, "-")) {
>>>> + p_err("cannot use standard input for both data_in and ctx_in");
>>>
>>> The error message says data_in and ctx_in.
>>> Maybe the input parameter should be file_data_in and file_ctx_in?
>>
>>
>> Hi Yonghong,
>>
>> It's true those parameters should be file names. But having
>> "file_data_in", "file_data_out", "file_ctx_in" and "file_ctx_out" on a
>> command line seems a bit heavy to me? (And relying on keyword prefixing
>> for typing the command won't help much.)
>>
>> My opinion is that it should be clear from the man page or the "help"
>> command that the parameters are file names. What do you think? I can
>> prefix all four arguments with "file_" if you believe this is better.
>
> I think you misunderstood my question above.
Totally did, sorry :/.
> The command line parameters are fine.
> I am talking about the function parameter names. Since in the error message,
> the input parameters are referred for data_in and ctx_in
> p_err("cannot use standard input for both data_in and ctx_in")
> maybe the function signature should be
> static int check_single_stdin(char *file_data_in, char *file_ctx_in)
>
> If you are worried that later on the same function can be used in different
> contexts, then alternatively, you can have signature like
> static int check_single_stdin(char *file_in, char *other_file_in,
> const char *file_in_arg, const char *other_file_in_arg)
> where file_in_arg will be passed in as "data_in" and other_file_in_arg
> as "ctx_in".
> I think we could delay this until it is really needed.
As a matter of fact, the opposite thing happened. I first used the
function for data_in/ctx_in, and also for data_out/ctx_out. But I
changed my mind eventually because there is no real reason not to print
both data_out and ctx_out to stdout if we want to do so. So I updated
the name of the parameters in the error messages, but forgot to change
the arguments for the function. Silly me.
So I totally agree, I'll respin and change the argument names for the
function. And yes, we could also pass the names to print in the error
message, but I agree that this is not needed, and not helpful at the moment.
Thanks for catching this!
>>
>> [...]
>>
>>>> +static int do_run(int argc, char **argv)
>>>> +{
>>>> + char *data_fname_in = NULL, *data_fname_out = NULL;
>>>> + char *ctx_fname_in = NULL, *ctx_fname_out = NULL;
>>>> + struct bpf_prog_test_run_attr test_attr = {0};
>>>> + const unsigned int default_size = SZ_32K;
>>>> + void *data_in = NULL, *data_out = NULL;
>>>> + void *ctx_in = NULL, *ctx_out = NULL;
>>>> + unsigned int repeat = 1;
>>>> + int fd, err;
>>>> +
>>>> + if (!REQ_ARGS(4))
>>>> + return -1;
>>>> +
>>>> + fd = prog_parse_fd(&argc, &argv);
>>>> + if (fd < 0)
>>>> + return -1;
>>>> +
>>>> + while (argc) {
>>>> + if (detect_common_prefix(*argv, "data_in", "data_out",
>>>> + "data_size_out", NULL))
>>>> + return -1;
>>>> + if (detect_common_prefix(*argv, "ctx_in", "ctx_out",
>>>> + "ctx_size_out", NULL))
>>>> + return -1;
>>>> +
>>>> + if (is_prefix(*argv, "data_in")) {
>>>> + NEXT_ARG();
>>>> + if (!REQ_ARGS(1))
>>>> + return -1;
>>>> +
>>>> + data_fname_in = GET_ARG();
>>>> + if (check_single_stdin(data_fname_in, ctx_fname_in))
>>>> + return -1;
>>>> + } else if (is_prefix(*argv, "data_out")) {
>>>
>>> Here, we all use is_prefix() to match "data_in", "data_out",
>>> "data_size_out" etc.
>>> That means users can use "data_i" instead of "data_in" as below
>>> ... | ./bpftool prog run id 283 data_i - data_out - repeat 5
>>> is this expected?
>> Yes, this is expected. We use prefix matching as we do pretty much
>> everywhere else in bpftool. It's not as useful here because most of the
>> strings for the names are similar. I agree that typing "data_i" instead
>> of "data_in" brings little advantage, but I see no reason why we should
>> reject prefixing for those keywords. And we accept "data_s" instead of
>> "data_size_out", which is still shorter to type than the complete keyword.
>
> This makes sense. Thanks for explanation.
>
> Another question. Currently, you are proposing "./bpftool prog run ...",
> but actually it is just a test_run. Do you think we should rename it
> to "./bpftool prog test_run ..." to make it clear for its intention?
Good question. Hmm. It would make it more explicit that we use the
BPF_PROG_TEST_RUN command, but at the same time, from the point of view
of the user, there is nothing in particular that makes it a test run, is
it? I mean, you provide input data, you get output data and return
value, that makes it a real BPF run somehow, except that it's not on a
packet or anything. Do you think it is ambiguous and people may confuse
it with something like "attach"?
Thanks,
Quentin
^ permalink raw reply
* Re: [PATCH net-next 4/6] arm64: dts: fsl: ls1028a: Add Felix switch port DT node
From: Florian Fainelli @ 2019-07-05 16:03 UTC (permalink / raw)
To: Vladimir Oltean, Andrew Lunn
Cc: Alexandre Belloni, Allan W. Nielsen, Claudiu Manoil,
David S . Miller, devicetree@vger.kernel.org,
netdev@vger.kernel.org, Alexandru Marginean,
linux-kernel@vger.kernel.org, UNGLinuxDriver@microchip.com,
Allan Nielsen, Rob Herring, linux-arm-kernel@lists.infradead.org
In-Reply-To: <CA+h21hqU1H1PefBWKjnsmkMsLhx0p0HJTsp-UYrSgmVnsfqULA@mail.gmail.com>
On 7/5/2019 2:08 AM, Vladimir Oltean wrote:
> Hi Andrew,
>
> On Fri, 5 Jul 2019 at 07:49, Andrew Lunn <andrew@lunn.ch> wrote:
>>
>> Hi Vladimir
>>
>>> - DSA is typically used for discrete switches, switchdev is typically
>>> used for embedded ones.
>>
>> Typically DSA is for discrete switches, but not exclusively. The
>> b53/SF2 is embedded in a number of Broadcom SoCs. So this is no
>> different to Ocelot, except ARM vs MIPS. Also, i would disagree that
>> switchdev is used for embedded ones. Mellonex devices are discrete, on
>> a PCIe bus. I believe Netronome devices are also discrete PCIe
>> devices. In fact, i think ocelot is the only embedded switchdev
>> switch.
>>
>> So embedded vs discrete plays no role here at all.
>>
>
> drivers/staging/fsl-dpaa2/ethsw/ is another example of switchdev
> driver for an embedded switch.
> I would give it to you that the sample size is probably too small to
> say 'typically', but my point was that in order to support cascaded
> switches it makes more sense for those to be discrete.
>
>>> - The D in DSA is for cascaded switches. Apart from the absence of
>>> such a "Ocelot SoC" driver (which maybe can be written, I don't know),
>>> I think the switching core itself has some fundamental limitations
>>> that make a DSA implementation questionable:
>>
>> There is no requirement to implement D in DSA. In fact, only Marvell
>> does. None of the other switches do. And you will also find that most
>> boards with a Marvell switch use a single device. D in DSA is totally
>> optional. In fact, DSA is built from the ground up that nearly
>> everything is optional. Take a look at mv88e6060, as an example. It
>> implements nearly nothing. It cannot even offload a bridge to the
>> switch.
>>
>
> Let me see if I get your point.
> The D is optional, and the S is optional. So what's left? :)
> Also, there's a big difference between "the hardware can't do it" and
> "the driver doesn't implement it". If I follow your argument, would
> you write a DSA driver for a device that doesn't do L2 switching?
> Along that same line, what benefit does the DSA model bring to a
> switch that can't do cascading, compared to switchdev? I'm asking this
> as a user, not as a developer.
As an user, I don't think there are compelling arguments to either
switchdev or DSA because the end result is the same: network devices
that can offload "stuff". As a developer though, there is much less code
to write with DSA than with switchdev to get your HW live.
>
>>> So my conclusion is that DSA for Felix/Ocelot doesn't make a lot of
>>> sense if the whole purpose is to hide the CPU-facing netdev.
>>
>> You actually convinced me the exact opposite. You described the
>> headers which are needed to implement DSA. The switch sounds like it
>> can do what DSA requires. So DSA is the correct model.
>>
>> Andrew
>
> Somebody actually asked, with the intention of building a board, if
> it's possible to cascade the LS1028A embedded switch (Felix) with
> discrete SJA1105 devices - Felix being at the top of the switch tree.
> Does the DSA model support heterogeneous setups (parsing stacked
> headers)? I can't tell if that's how EDSA tags work. With switchdev
> for Felix there wouldn't be any problem - it just wouldn't be part of
> the DSA tree and its own driver would remove its tags before DSA would
> look at the rest.
DSA not does not make any particular assumptions about how the stacking
is done actually because each slave network device is expected to
provided standard Ethernet frames to the network stack. How you get to
that point is entirely specific to what the hardware can do.
You do what Andrew described about one of my setup (bcm_sf2 w/ tagging
enabled and b53 w/o tagging, see more below why [1]]) and both being
discrete switch trees, with the master netdev of the b53 being a slave
netdev provided by bcm_sf2. If your tagging protocol supports it you can
make them part of the same DSA switch tree and just have them have
different switch identifiers, that is what Marvell switches do and it
works just great. In your case, I suppose you could even use double VLAN
tagging to get such cascading to work, that would limit you to a two
level of cascading, unless you invent something custom.
[1]: The original Broadcom tag format introduced with BCM5325/5365 did
support cascading in the same way that Marvell did where a switch
identifier can be added in addition to a port number within the tag. The
newest Broadcom tag that was introduced with 5395 and newer dropped
support for the switch identifier and the switch will "terminate" the
first (from start of Ethernet frame) tag that it receives. This is the
reason why we need to disable tagging on the outermost B53 device that
we are connected to. This means those network devices are mainly
configuration endpoints and not passing data (DSA_TAG_PROTO_NONE),
though we could use DSA_TAG_PROTO_8021Q and resolve that now.
--
Florian
^ permalink raw reply
* Re: [RFC net-next] net: dsa: add support for MC_DISABLED attribute
From: Vivien Didelot @ 2019-07-05 16:01 UTC (permalink / raw)
To: Ido Schimmel
Cc: Florian Fainelli, netdev@vger.kernel.org, Jiri Pirko,
linux@armlinux.org.uk, andrew@lunn.ch, davem@davemloft.net
In-Reply-To: <20190623070949.GB13466@splinter>
Hi Ido,
On Sun, 23 Jun 2019 07:09:52 +0000, Ido Schimmel <idosch@mellanox.com> wrote:
> > Russell, Ido, Florian, so far I understand that a multicast-unaware
> > bridge must flood unknown traffic everywhere (CPU included);
> > and a multicast-aware bridge must only flood its ports if their
> > mcast_flood is on, and known traffic targeting the bridge must be
> > offloaded accordingly. Do you guys agree with this?
>
> When multicast snooping is enabled unregistered multicast traffic should
> only be flooded to mrouter ports.
I've figured out that this is what I need to prevent the flooding of undesired
multicast traffic to the CPU port of the switch. The bridge itself has a
multicast_router attribute which can be disabled, that is when I should drop
unknown multicast traffic.
However with SWITCHDEV_ATTR_ID_BRIDGE_MROUTER implemented, this
attribute is always called with .mrouter=0, regardless the value of
/sys/class/net/br0/bridge/multicast_router. Do I miss something here?
Thanks,
Vivien
^ permalink raw reply
* [PATCH v5 bpf-next 4/4] selftests/bpf: convert legacy BPF maps to BTF-defined ones
From: Andrii Nakryiko @ 2019-07-05 15:50 UTC (permalink / raw)
To: andrii.nakryiko, kernel-team, ast, daniel, netdev, bpf; +Cc: Andrii Nakryiko
In-Reply-To: <20190705155012.3539722-1-andriin@fb.com>
Convert selftests that were originally left out and new ones added
recently to consistently use BTF-defined maps.
Reported-by: kernel test robot <rong.a.chen@intel.com>
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Acked-by: Song Liu <songliubraving@fb.com>
Acked-by: Yonghong Song <yhs@fb.com>
---
.../selftests/bpf/progs/get_cgroup_id_kern.c | 26 ++---
tools/testing/selftests/bpf/progs/pyperf.h | 90 +++++++-------
.../bpf/progs/sockmap_verdict_prog.c | 48 ++++----
.../testing/selftests/bpf/progs/strobemeta.h | 68 +++++------
.../selftests/bpf/progs/test_map_in_map.c | 30 ++---
.../testing/selftests/bpf/progs/test_obj_id.c | 12 +-
.../selftests/bpf/progs/test_xdp_loop.c | 26 ++---
.../selftests/bpf/progs/xdp_redirect_map.c | 12 +-
.../testing/selftests/bpf/progs/xdping_kern.c | 12 +-
.../selftests/bpf/test_queue_stack_map.h | 30 ++---
.../testing/selftests/bpf/test_sockmap_kern.h | 110 +++++++++---------
11 files changed, 228 insertions(+), 236 deletions(-)
diff --git a/tools/testing/selftests/bpf/progs/get_cgroup_id_kern.c b/tools/testing/selftests/bpf/progs/get_cgroup_id_kern.c
index 014dba10b8a5..16c54ade6888 100644
--- a/tools/testing/selftests/bpf/progs/get_cgroup_id_kern.c
+++ b/tools/testing/selftests/bpf/progs/get_cgroup_id_kern.c
@@ -4,19 +4,19 @@
#include <linux/bpf.h>
#include "bpf_helpers.h"
-struct bpf_map_def SEC("maps") cg_ids = {
- .type = BPF_MAP_TYPE_ARRAY,
- .key_size = sizeof(__u32),
- .value_size = sizeof(__u64),
- .max_entries = 1,
-};
-
-struct bpf_map_def SEC("maps") pidmap = {
- .type = BPF_MAP_TYPE_ARRAY,
- .key_size = sizeof(__u32),
- .value_size = sizeof(__u32),
- .max_entries = 1,
-};
+struct {
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, __u32);
+ __type(value, __u64);
+} cg_ids SEC(".maps");
+
+struct {
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, __u32);
+ __type(value, __u32);
+} pidmap SEC(".maps");
SEC("tracepoint/syscalls/sys_enter_nanosleep")
int trace(void *ctx)
diff --git a/tools/testing/selftests/bpf/progs/pyperf.h b/tools/testing/selftests/bpf/progs/pyperf.h
index abf6224649be..003fe106fc70 100644
--- a/tools/testing/selftests/bpf/progs/pyperf.h
+++ b/tools/testing/selftests/bpf/progs/pyperf.h
@@ -58,14 +58,6 @@ typedef struct {
} Event;
-struct bpf_elf_map {
- __u32 type;
- __u32 size_key;
- __u32 size_value;
- __u32 max_elem;
- __u32 flags;
-};
-
typedef int pid_t;
typedef struct {
@@ -118,47 +110,47 @@ static __always_inline bool get_frame_data(void *frame_ptr, PidData *pidData,
return true;
}
-struct bpf_elf_map SEC("maps") pidmap = {
- .type = BPF_MAP_TYPE_HASH,
- .size_key = sizeof(int),
- .size_value = sizeof(PidData),
- .max_elem = 1,
-};
-
-struct bpf_elf_map SEC("maps") eventmap = {
- .type = BPF_MAP_TYPE_HASH,
- .size_key = sizeof(int),
- .size_value = sizeof(Event),
- .max_elem = 1,
-};
-
-struct bpf_elf_map SEC("maps") symbolmap = {
- .type = BPF_MAP_TYPE_HASH,
- .size_key = sizeof(Symbol),
- .size_value = sizeof(int),
- .max_elem = 1,
-};
-
-struct bpf_elf_map SEC("maps") statsmap = {
- .type = BPF_MAP_TYPE_ARRAY,
- .size_key = sizeof(Stats),
- .size_value = sizeof(int),
- .max_elem = 1,
-};
-
-struct bpf_elf_map SEC("maps") perfmap = {
- .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
- .size_key = sizeof(int),
- .size_value = sizeof(int),
- .max_elem = 32,
-};
-
-struct bpf_elf_map SEC("maps") stackmap = {
- .type = BPF_MAP_TYPE_STACK_TRACE,
- .size_key = sizeof(int),
- .size_value = sizeof(long long) * 127,
- .max_elem = 1000,
-};
+struct {
+ __uint(type, BPF_MAP_TYPE_HASH);
+ __uint(max_entries, 1);
+ __type(key, int);
+ __type(value, PidData);
+} pidmap SEC(".maps");
+
+struct {
+ __uint(type, BPF_MAP_TYPE_HASH);
+ __uint(max_entries, 1);
+ __type(key, int);
+ __type(value, Event);
+} eventmap SEC(".maps");
+
+struct {
+ __uint(type, BPF_MAP_TYPE_HASH);
+ __uint(max_entries, 1);
+ __type(key, Symbol);
+ __type(value, int);
+} symbolmap SEC(".maps");
+
+struct {
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, int);
+ __type(value, Stats);
+} statsmap SEC(".maps");
+
+struct {
+ __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
+ __uint(max_entries, 32);
+ __uint(key_size, sizeof(int));
+ __uint(value_size, sizeof(int));
+} perfmap SEC(".maps");
+
+struct {
+ __uint(type, BPF_MAP_TYPE_STACK_TRACE);
+ __uint(max_entries, 1000);
+ __uint(key_size, sizeof(int));
+ __uint(value_size, sizeof(long long) * 127);
+} stackmap SEC(".maps");
static __always_inline int __on_event(struct pt_regs *ctx)
{
diff --git a/tools/testing/selftests/bpf/progs/sockmap_verdict_prog.c b/tools/testing/selftests/bpf/progs/sockmap_verdict_prog.c
index d85c874ef25e..433e23918a62 100644
--- a/tools/testing/selftests/bpf/progs/sockmap_verdict_prog.c
+++ b/tools/testing/selftests/bpf/progs/sockmap_verdict_prog.c
@@ -4,33 +4,33 @@
int _version SEC("version") = 1;
-struct bpf_map_def SEC("maps") sock_map_rx = {
- .type = BPF_MAP_TYPE_SOCKMAP,
- .key_size = sizeof(int),
- .value_size = sizeof(int),
- .max_entries = 20,
-};
+struct {
+ __uint(type, BPF_MAP_TYPE_SOCKMAP);
+ __uint(max_entries, 20);
+ __uint(key_size, sizeof(int));
+ __uint(value_size, sizeof(int));
+} sock_map_rx SEC(".maps");
-struct bpf_map_def SEC("maps") sock_map_tx = {
- .type = BPF_MAP_TYPE_SOCKMAP,
- .key_size = sizeof(int),
- .value_size = sizeof(int),
- .max_entries = 20,
-};
+struct {
+ __uint(type, BPF_MAP_TYPE_SOCKMAP);
+ __uint(max_entries, 20);
+ __uint(key_size, sizeof(int));
+ __uint(value_size, sizeof(int));
+} sock_map_tx SEC(".maps");
-struct bpf_map_def SEC("maps") sock_map_msg = {
- .type = BPF_MAP_TYPE_SOCKMAP,
- .key_size = sizeof(int),
- .value_size = sizeof(int),
- .max_entries = 20,
-};
+struct {
+ __uint(type, BPF_MAP_TYPE_SOCKMAP);
+ __uint(max_entries, 20);
+ __uint(key_size, sizeof(int));
+ __uint(value_size, sizeof(int));
+} sock_map_msg SEC(".maps");
-struct bpf_map_def SEC("maps") sock_map_break = {
- .type = BPF_MAP_TYPE_ARRAY,
- .key_size = sizeof(int),
- .value_size = sizeof(int),
- .max_entries = 20,
-};
+struct {
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 20);
+ __type(key, int);
+ __type(value, int);
+} sock_map_break SEC(".maps");
SEC("sk_skb2")
int bpf_prog2(struct __sk_buff *skb)
diff --git a/tools/testing/selftests/bpf/progs/strobemeta.h b/tools/testing/selftests/bpf/progs/strobemeta.h
index 553bc3b62e89..8a399bdfd920 100644
--- a/tools/testing/selftests/bpf/progs/strobemeta.h
+++ b/tools/testing/selftests/bpf/progs/strobemeta.h
@@ -204,40 +204,40 @@ struct strobelight_bpf_sample {
char dummy_safeguard;
};
-struct bpf_map_def SEC("maps") samples = {
- .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
- .key_size = sizeof(int),
- .value_size = sizeof(int),
- .max_entries = 32,
-};
-
-struct bpf_map_def SEC("maps") stacks_0 = {
- .type = BPF_MAP_TYPE_STACK_TRACE,
- .key_size = sizeof(uint32_t),
- .value_size = sizeof(uint64_t) * PERF_MAX_STACK_DEPTH,
- .max_entries = 16,
-};
-
-struct bpf_map_def SEC("maps") stacks_1 = {
- .type = BPF_MAP_TYPE_STACK_TRACE,
- .key_size = sizeof(uint32_t),
- .value_size = sizeof(uint64_t) * PERF_MAX_STACK_DEPTH,
- .max_entries = 16,
-};
-
-struct bpf_map_def SEC("maps") sample_heap = {
- .type = BPF_MAP_TYPE_PERCPU_ARRAY,
- .key_size = sizeof(uint32_t),
- .value_size = sizeof(struct strobelight_bpf_sample),
- .max_entries = 1,
-};
-
-struct bpf_map_def SEC("maps") strobemeta_cfgs = {
- .type = BPF_MAP_TYPE_PERCPU_ARRAY,
- .key_size = sizeof(pid_t),
- .value_size = sizeof(struct strobemeta_cfg),
- .max_entries = STROBE_MAX_CFGS,
-};
+struct {
+ __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
+ __uint(max_entries, 32);
+ __uint(key_size, sizeof(int));
+ __uint(value_size, sizeof(int));
+} samples SEC(".maps");
+
+struct {
+ __uint(type, BPF_MAP_TYPE_STACK_TRACE);
+ __uint(max_entries, 16);
+ __uint(key_size, sizeof(uint32_t));
+ __uint(value_size, sizeof(uint64_t) * PERF_MAX_STACK_DEPTH);
+} stacks_0 SEC(".maps");
+
+struct {
+ __uint(type, BPF_MAP_TYPE_STACK_TRACE);
+ __uint(max_entries, 16);
+ __uint(key_size, sizeof(uint32_t));
+ __uint(value_size, sizeof(uint64_t) * PERF_MAX_STACK_DEPTH);
+} stacks_1 SEC(".maps");
+
+struct {
+ __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, uint32_t);
+ __type(value, struct strobelight_bpf_sample);
+} sample_heap SEC(".maps");
+
+struct {
+ __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
+ __uint(max_entries, STROBE_MAX_CFGS);
+ __type(key, pid_t);
+ __type(value, struct strobemeta_cfg);
+} strobemeta_cfgs SEC(".maps");
/* Type for the dtv. */
/* https://github.com/lattera/glibc/blob/master/nptl/sysdeps/x86_64/tls.h#L34 */
diff --git a/tools/testing/selftests/bpf/progs/test_map_in_map.c b/tools/testing/selftests/bpf/progs/test_map_in_map.c
index 2985f262846e..113226115365 100644
--- a/tools/testing/selftests/bpf/progs/test_map_in_map.c
+++ b/tools/testing/selftests/bpf/progs/test_map_in_map.c
@@ -5,23 +5,23 @@
#include <linux/types.h>
#include "bpf_helpers.h"
-struct bpf_map_def SEC("maps") mim_array = {
- .type = BPF_MAP_TYPE_ARRAY_OF_MAPS,
- .key_size = sizeof(int),
+struct {
+ __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
+ __uint(max_entries, 1);
+ __uint(map_flags, 0);
+ __uint(key_size, sizeof(__u32));
/* must be sizeof(__u32) for map in map */
- .value_size = sizeof(__u32),
- .max_entries = 1,
- .map_flags = 0,
-};
-
-struct bpf_map_def SEC("maps") mim_hash = {
- .type = BPF_MAP_TYPE_HASH_OF_MAPS,
- .key_size = sizeof(int),
+ __uint(value_size, sizeof(__u32));
+} mim_array SEC(".maps");
+
+struct {
+ __uint(type, BPF_MAP_TYPE_HASH_OF_MAPS);
+ __uint(max_entries, 1);
+ __uint(map_flags, 0);
+ __uint(key_size, sizeof(int));
/* must be sizeof(__u32) for map in map */
- .value_size = sizeof(__u32),
- .max_entries = 1,
- .map_flags = 0,
-};
+ __uint(value_size, sizeof(__u32));
+} mim_hash SEC(".maps");
SEC("xdp_mimtest")
int xdp_mimtest0(struct xdp_md *ctx)
diff --git a/tools/testing/selftests/bpf/progs/test_obj_id.c b/tools/testing/selftests/bpf/progs/test_obj_id.c
index 726340fa6fe0..3d30c02bdae9 100644
--- a/tools/testing/selftests/bpf/progs/test_obj_id.c
+++ b/tools/testing/selftests/bpf/progs/test_obj_id.c
@@ -13,12 +13,12 @@
int _version SEC("version") = 1;
-struct bpf_map_def SEC("maps") test_map_id = {
- .type = BPF_MAP_TYPE_ARRAY,
- .key_size = sizeof(__u32),
- .value_size = sizeof(__u64),
- .max_entries = 1,
-};
+struct {
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, __u32);
+ __type(value, __u64);
+} test_map_id SEC(".maps");
SEC("test_obj_id_dummy")
int test_obj_id(struct __sk_buff *skb)
diff --git a/tools/testing/selftests/bpf/progs/test_xdp_loop.c b/tools/testing/selftests/bpf/progs/test_xdp_loop.c
index 7fa4677df22e..97175f73c3fe 100644
--- a/tools/testing/selftests/bpf/progs/test_xdp_loop.c
+++ b/tools/testing/selftests/bpf/progs/test_xdp_loop.c
@@ -18,19 +18,19 @@
int _version SEC("version") = 1;
-struct bpf_map_def SEC("maps") rxcnt = {
- .type = BPF_MAP_TYPE_PERCPU_ARRAY,
- .key_size = sizeof(__u32),
- .value_size = sizeof(__u64),
- .max_entries = 256,
-};
-
-struct bpf_map_def SEC("maps") vip2tnl = {
- .type = BPF_MAP_TYPE_HASH,
- .key_size = sizeof(struct vip),
- .value_size = sizeof(struct iptnl_info),
- .max_entries = MAX_IPTNL_ENTRIES,
-};
+struct {
+ __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
+ __uint(max_entries, 256);
+ __type(key, __u32);
+ __type(value, __u64);
+} rxcnt SEC(".maps");
+
+struct {
+ __uint(type, BPF_MAP_TYPE_HASH);
+ __uint(max_entries, MAX_IPTNL_ENTRIES);
+ __type(key, struct vip);
+ __type(value, struct iptnl_info);
+} vip2tnl SEC(".maps");
static __always_inline void count_tx(__u32 protocol)
{
diff --git a/tools/testing/selftests/bpf/progs/xdp_redirect_map.c b/tools/testing/selftests/bpf/progs/xdp_redirect_map.c
index e87a985b9df9..1c5f298d7196 100644
--- a/tools/testing/selftests/bpf/progs/xdp_redirect_map.c
+++ b/tools/testing/selftests/bpf/progs/xdp_redirect_map.c
@@ -3,12 +3,12 @@
#include <linux/bpf.h>
#include "bpf_helpers.h"
-struct bpf_map_def SEC("maps") tx_port = {
- .type = BPF_MAP_TYPE_DEVMAP,
- .key_size = sizeof(int),
- .value_size = sizeof(int),
- .max_entries = 8,
-};
+struct {
+ __uint(type, BPF_MAP_TYPE_DEVMAP);
+ __uint(max_entries, 8);
+ __uint(key_size, sizeof(int));
+ __uint(value_size, sizeof(int));
+} tx_port SEC(".maps");
SEC("redirect_map_0")
int xdp_redirect_map_0(struct xdp_md *xdp)
diff --git a/tools/testing/selftests/bpf/progs/xdping_kern.c b/tools/testing/selftests/bpf/progs/xdping_kern.c
index 87393e7c667c..112a2857f4e2 100644
--- a/tools/testing/selftests/bpf/progs/xdping_kern.c
+++ b/tools/testing/selftests/bpf/progs/xdping_kern.c
@@ -17,12 +17,12 @@
#include "xdping.h"
-struct bpf_map_def SEC("maps") ping_map = {
- .type = BPF_MAP_TYPE_HASH,
- .key_size = sizeof(__u32),
- .value_size = sizeof(struct pinginfo),
- .max_entries = 256,
-};
+struct {
+ __uint(type, BPF_MAP_TYPE_HASH);
+ __uint(max_entries, 256);
+ __type(key, __u32);
+ __type(value, struct pinginfo);
+} ping_map SEC(".maps");
static __always_inline void swap_src_dst_mac(void *data)
{
diff --git a/tools/testing/selftests/bpf/test_queue_stack_map.h b/tools/testing/selftests/bpf/test_queue_stack_map.h
index 295b9b3bc5c7..0e014d3b2b36 100644
--- a/tools/testing/selftests/bpf/test_queue_stack_map.h
+++ b/tools/testing/selftests/bpf/test_queue_stack_map.h
@@ -10,21 +10,21 @@
int _version SEC("version") = 1;
-struct bpf_map_def __attribute__ ((section("maps"), used)) map_in = {
- .type = MAP_TYPE,
- .key_size = 0,
- .value_size = sizeof(__u32),
- .max_entries = 32,
- .map_flags = 0,
-};
-
-struct bpf_map_def __attribute__ ((section("maps"), used)) map_out = {
- .type = MAP_TYPE,
- .key_size = 0,
- .value_size = sizeof(__u32),
- .max_entries = 32,
- .map_flags = 0,
-};
+struct {
+ __uint(type, MAP_TYPE);
+ __uint(max_entries, 32);
+ __uint(map_flags, 0);
+ __uint(key_size, 0);
+ __uint(value_size, sizeof(__u32));
+} map_in SEC(".maps");
+
+struct {
+ __uint(type, MAP_TYPE);
+ __uint(max_entries, 32);
+ __uint(map_flags, 0);
+ __uint(key_size, 0);
+ __uint(value_size, sizeof(__u32));
+} map_out SEC(".maps");
SEC("test")
int _test(struct __sk_buff *skb)
diff --git a/tools/testing/selftests/bpf/test_sockmap_kern.h b/tools/testing/selftests/bpf/test_sockmap_kern.h
index 4e7d3da21357..d008b41b7d8d 100644
--- a/tools/testing/selftests/bpf/test_sockmap_kern.h
+++ b/tools/testing/selftests/bpf/test_sockmap_kern.h
@@ -28,61 +28,61 @@
* are established and verdicts are decided.
*/
-struct bpf_map_def SEC("maps") sock_map = {
- .type = TEST_MAP_TYPE,
- .key_size = sizeof(int),
- .value_size = sizeof(int),
- .max_entries = 20,
-};
-
-struct bpf_map_def SEC("maps") sock_map_txmsg = {
- .type = TEST_MAP_TYPE,
- .key_size = sizeof(int),
- .value_size = sizeof(int),
- .max_entries = 20,
-};
-
-struct bpf_map_def SEC("maps") sock_map_redir = {
- .type = TEST_MAP_TYPE,
- .key_size = sizeof(int),
- .value_size = sizeof(int),
- .max_entries = 20,
-};
-
-struct bpf_map_def SEC("maps") sock_apply_bytes = {
- .type = BPF_MAP_TYPE_ARRAY,
- .key_size = sizeof(int),
- .value_size = sizeof(int),
- .max_entries = 1
-};
-
-struct bpf_map_def SEC("maps") sock_cork_bytes = {
- .type = BPF_MAP_TYPE_ARRAY,
- .key_size = sizeof(int),
- .value_size = sizeof(int),
- .max_entries = 1
-};
-
-struct bpf_map_def SEC("maps") sock_bytes = {
- .type = BPF_MAP_TYPE_ARRAY,
- .key_size = sizeof(int),
- .value_size = sizeof(int),
- .max_entries = 6
-};
-
-struct bpf_map_def SEC("maps") sock_redir_flags = {
- .type = BPF_MAP_TYPE_ARRAY,
- .key_size = sizeof(int),
- .value_size = sizeof(int),
- .max_entries = 1
-};
-
-struct bpf_map_def SEC("maps") sock_skb_opts = {
- .type = BPF_MAP_TYPE_ARRAY,
- .key_size = sizeof(int),
- .value_size = sizeof(int),
- .max_entries = 1
-};
+struct {
+ __uint(type, TEST_MAP_TYPE);
+ __uint(max_entries, 20);
+ __uint(key_size, sizeof(int));
+ __uint(value_size, sizeof(int));
+} sock_map SEC(".maps");
+
+struct {
+ __uint(type, TEST_MAP_TYPE);
+ __uint(max_entries, 20);
+ __uint(key_size, sizeof(int));
+ __uint(value_size, sizeof(int));
+} sock_map_txmsg SEC(".maps");
+
+struct {
+ __uint(type, TEST_MAP_TYPE);
+ __uint(max_entries, 20);
+ __uint(key_size, sizeof(int));
+ __uint(value_size, sizeof(int));
+} sock_map_redir SEC(".maps");
+
+struct {
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, int);
+ __type(value, int);
+} sock_apply_bytes SEC(".maps");
+
+struct {
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, int);
+ __type(value, int);
+} sock_cork_bytes SEC(".maps");
+
+struct {
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 6);
+ __type(key, int);
+ __type(value, int);
+} sock_bytes SEC(".maps");
+
+struct {
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, int);
+ __type(value, int);
+} sock_redir_flags SEC(".maps");
+
+struct {
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, int);
+ __type(value, int);
+} sock_skb_opts SEC(".maps");
SEC("sk_skb1")
int bpf_prog1(struct __sk_buff *skb)
--
2.17.1
^ permalink raw reply related
* [PATCH v5 bpf-next 3/4] selftests/bpf: convert selftests using BTF-defined maps to new syntax
From: Andrii Nakryiko @ 2019-07-05 15:50 UTC (permalink / raw)
To: andrii.nakryiko, kernel-team, ast, daniel, netdev, bpf; +Cc: Andrii Nakryiko
In-Reply-To: <20190705155012.3539722-1-andriin@fb.com>
Convert all the existing selftests that are already using BTF-defined
maps to use new syntax (with no static data initialization).
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Acked-by: Song Liu <songliubraving@fb.com>
Acked-by: Yonghong Song <yhs@fb.com>
---
tools/testing/selftests/bpf/progs/bpf_flow.c | 28 +++----
.../testing/selftests/bpf/progs/netcnt_prog.c | 20 ++---
.../selftests/bpf/progs/socket_cookie_prog.c | 13 ++-
.../selftests/bpf/progs/test_btf_newkv.c | 13 ++-
.../bpf/progs/test_get_stack_rawtp.c | 39 ++++-----
.../selftests/bpf/progs/test_global_data.c | 37 ++++-----
tools/testing/selftests/bpf/progs/test_l4lb.c | 65 ++++++---------
.../selftests/bpf/progs/test_l4lb_noinline.c | 65 ++++++---------
.../selftests/bpf/progs/test_map_lock.c | 26 +++---
.../bpf/progs/test_select_reuseport_kern.c | 67 ++++++---------
.../bpf/progs/test_send_signal_kern.c | 26 +++---
.../bpf/progs/test_sock_fields_kern.c | 78 +++++++-----------
.../selftests/bpf/progs/test_spin_lock.c | 36 ++++-----
.../bpf/progs/test_stacktrace_build_id.c | 55 +++++--------
.../selftests/bpf/progs/test_stacktrace_map.c | 52 +++++-------
.../selftests/bpf/progs/test_tcp_estats.c | 13 ++-
.../selftests/bpf/progs/test_tcpbpf_kern.c | 26 +++---
.../selftests/bpf/progs/test_tcpnotify_kern.c | 28 +++----
tools/testing/selftests/bpf/progs/test_xdp.c | 26 +++---
.../selftests/bpf/progs/test_xdp_noinline.c | 81 +++++++------------
20 files changed, 300 insertions(+), 494 deletions(-)
diff --git a/tools/testing/selftests/bpf/progs/bpf_flow.c b/tools/testing/selftests/bpf/progs/bpf_flow.c
index 849f42e548b5..5ae485a6af3f 100644
--- a/tools/testing/selftests/bpf/progs/bpf_flow.c
+++ b/tools/testing/selftests/bpf/progs/bpf_flow.c
@@ -58,26 +58,18 @@ struct frag_hdr {
};
struct {
- __u32 type;
- __u32 max_entries;
- __u32 key_size;
- __u32 value_size;
-} jmp_table SEC(".maps") = {
- .type = BPF_MAP_TYPE_PROG_ARRAY,
- .max_entries = 8,
- .key_size = sizeof(__u32),
- .value_size = sizeof(__u32),
-};
+ __uint(type, BPF_MAP_TYPE_PROG_ARRAY);
+ __uint(max_entries, 8);
+ __uint(key_size, sizeof(__u32));
+ __uint(value_size, sizeof(__u32));
+} jmp_table SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- struct bpf_flow_keys *value;
-} last_dissection SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = 1,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, __u32);
+ __type(value, struct bpf_flow_keys);
+} last_dissection SEC(".maps");
static __always_inline int export_flow_keys(struct bpf_flow_keys *keys,
int ret)
diff --git a/tools/testing/selftests/bpf/progs/netcnt_prog.c b/tools/testing/selftests/bpf/progs/netcnt_prog.c
index a25c82a5b7c8..38a997852cad 100644
--- a/tools/testing/selftests/bpf/progs/netcnt_prog.c
+++ b/tools/testing/selftests/bpf/progs/netcnt_prog.c
@@ -11,20 +11,16 @@
#define NS_PER_SEC 1000000000
struct {
- __u32 type;
- struct bpf_cgroup_storage_key *key;
- struct percpu_net_cnt *value;
-} percpu_netcnt SEC(".maps") = {
- .type = BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE,
-};
+ __uint(type, BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE);
+ __type(key, struct bpf_cgroup_storage_key);
+ __type(value, struct percpu_net_cnt);
+} percpu_netcnt SEC(".maps");
struct {
- __u32 type;
- struct bpf_cgroup_storage_key *key;
- struct net_cnt *value;
-} netcnt SEC(".maps") = {
- .type = BPF_MAP_TYPE_CGROUP_STORAGE,
-};
+ __uint(type, BPF_MAP_TYPE_CGROUP_STORAGE);
+ __type(key, struct bpf_cgroup_storage_key);
+ __type(value, struct net_cnt);
+} netcnt SEC(".maps");
SEC("cgroup/skb")
int bpf_nextcnt(struct __sk_buff *skb)
diff --git a/tools/testing/selftests/bpf/progs/socket_cookie_prog.c b/tools/testing/selftests/bpf/progs/socket_cookie_prog.c
index 6aabb681fb9a..e4440fdd94cb 100644
--- a/tools/testing/selftests/bpf/progs/socket_cookie_prog.c
+++ b/tools/testing/selftests/bpf/progs/socket_cookie_prog.c
@@ -13,14 +13,11 @@ struct socket_cookie {
};
struct {
- __u32 type;
- __u32 map_flags;
- int *key;
- struct socket_cookie *value;
-} socket_cookies SEC(".maps") = {
- .type = BPF_MAP_TYPE_SK_STORAGE,
- .map_flags = BPF_F_NO_PREALLOC,
-};
+ __uint(type, BPF_MAP_TYPE_SK_STORAGE);
+ __uint(map_flags, BPF_F_NO_PREALLOC);
+ __type(key, int);
+ __type(value, struct socket_cookie);
+} socket_cookies SEC(".maps");
SEC("cgroup/connect6")
int set_cookie(struct bpf_sock_addr *ctx)
diff --git a/tools/testing/selftests/bpf/progs/test_btf_newkv.c b/tools/testing/selftests/bpf/progs/test_btf_newkv.c
index 28c16bb583b6..5ee3622ddebb 100644
--- a/tools/testing/selftests/bpf/progs/test_btf_newkv.c
+++ b/tools/testing/selftests/bpf/progs/test_btf_newkv.c
@@ -21,14 +21,11 @@ struct bpf_map_def SEC("maps") btf_map_legacy = {
BPF_ANNOTATE_KV_PAIR(btf_map_legacy, int, struct ipv_counts);
struct {
- int *key;
- struct ipv_counts *value;
- unsigned int type;
- unsigned int max_entries;
-} btf_map SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = 4,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 4);
+ __type(key, int);
+ __type(value, struct ipv_counts);
+} btf_map SEC(".maps");
struct dummy_tracepoint_args {
unsigned long long pad;
diff --git a/tools/testing/selftests/bpf/progs/test_get_stack_rawtp.c b/tools/testing/selftests/bpf/progs/test_get_stack_rawtp.c
index aaa6ec250e15..d06b47a09097 100644
--- a/tools/testing/selftests/bpf/progs/test_get_stack_rawtp.c
+++ b/tools/testing/selftests/bpf/progs/test_get_stack_rawtp.c
@@ -16,26 +16,18 @@ struct stack_trace_t {
};
struct {
- __u32 type;
- __u32 max_entries;
- __u32 key_size;
- __u32 value_size;
-} perfmap SEC(".maps") = {
- .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
- .max_entries = 2,
- .key_size = sizeof(int),
- .value_size = sizeof(__u32),
-};
+ __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
+ __uint(max_entries, 2);
+ __uint(key_size, sizeof(int));
+ __uint(value_size, sizeof(__u32));
+} perfmap SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- struct stack_trace_t *value;
-} stackdata_map SEC(".maps") = {
- .type = BPF_MAP_TYPE_PERCPU_ARRAY,
- .max_entries = 1,
-};
+ __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, __u32);
+ __type(value, struct stack_trace_t);
+} stackdata_map SEC(".maps");
/* Allocate per-cpu space twice the needed. For the code below
* usize = bpf_get_stack(ctx, raw_data, max_len, BPF_F_USER_STACK);
@@ -56,14 +48,11 @@ struct {
* This is an acceptable workaround since there is one entry here.
*/
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
+ __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, __u32);
__u64 (*value)[2 * MAX_STACK_RAWTP];
-} rawdata_map SEC(".maps") = {
- .type = BPF_MAP_TYPE_PERCPU_ARRAY,
- .max_entries = 1,
-};
+} rawdata_map SEC(".maps");
SEC("tracepoint/raw_syscalls/sys_enter")
int bpf_prog1(void *ctx)
diff --git a/tools/testing/selftests/bpf/progs/test_global_data.c b/tools/testing/selftests/bpf/progs/test_global_data.c
index 866cc7ddbe43..32a6073acb99 100644
--- a/tools/testing/selftests/bpf/progs/test_global_data.c
+++ b/tools/testing/selftests/bpf/progs/test_global_data.c
@@ -8,24 +8,18 @@
#include "bpf_helpers.h"
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- __u64 *value;
-} result_number SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = 11,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 11);
+ __type(key, __u32);
+ __type(value, __u64);
+} result_number SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 5);
+ __type(key, __u32);
const char (*value)[32];
-} result_string SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = 5,
-};
+} result_string SEC(".maps");
struct foo {
__u8 a;
@@ -34,14 +28,11 @@ struct foo {
};
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- struct foo *value;
-} result_struct SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = 5,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 5);
+ __type(key, __u32);
+ __type(value, struct foo);
+} result_struct SEC(".maps");
/* Relocation tests for __u64s. */
static __u64 num0;
diff --git a/tools/testing/selftests/bpf/progs/test_l4lb.c b/tools/testing/selftests/bpf/progs/test_l4lb.c
index 848cbb90f581..1d652ee8e73d 100644
--- a/tools/testing/selftests/bpf/progs/test_l4lb.c
+++ b/tools/testing/selftests/bpf/progs/test_l4lb.c
@@ -170,54 +170,39 @@ struct eth_hdr {
};
struct {
- __u32 type;
- __u32 max_entries;
- struct vip *key;
- struct vip_meta *value;
-} vip_map SEC(".maps") = {
- .type = BPF_MAP_TYPE_HASH,
- .max_entries = MAX_VIPS,
-};
+ __uint(type, BPF_MAP_TYPE_HASH);
+ __uint(max_entries, MAX_VIPS);
+ __type(key, struct vip);
+ __type(value, struct vip_meta);
+} vip_map SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- __u32 *value;
-} ch_rings SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = CH_RINGS_SIZE,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, CH_RINGS_SIZE);
+ __type(key, __u32);
+ __type(value, __u32);
+} ch_rings SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- struct real_definition *value;
-} reals SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = MAX_REALS,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, MAX_REALS);
+ __type(key, __u32);
+ __type(value, struct real_definition);
+} reals SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- struct vip_stats *value;
-} stats SEC(".maps") = {
- .type = BPF_MAP_TYPE_PERCPU_ARRAY,
- .max_entries = MAX_VIPS,
-};
+ __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
+ __uint(max_entries, MAX_VIPS);
+ __type(key, __u32);
+ __type(value, struct vip_stats);
+} stats SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- struct ctl_value *value;
-} ctl_array SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = CTL_MAP_SIZE,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, CTL_MAP_SIZE);
+ __type(key, __u32);
+ __type(value, struct ctl_value);
+} ctl_array SEC(".maps");
static __always_inline __u32 get_packet_hash(struct packet_description *pckt,
bool ipv6)
diff --git a/tools/testing/selftests/bpf/progs/test_l4lb_noinline.c b/tools/testing/selftests/bpf/progs/test_l4lb_noinline.c
index c63ecf3ca573..2e4efe70b1e5 100644
--- a/tools/testing/selftests/bpf/progs/test_l4lb_noinline.c
+++ b/tools/testing/selftests/bpf/progs/test_l4lb_noinline.c
@@ -166,54 +166,39 @@ struct eth_hdr {
};
struct {
- __u32 type;
- __u32 max_entries;
- struct vip *key;
- struct vip_meta *value;
-} vip_map SEC(".maps") = {
- .type = BPF_MAP_TYPE_HASH,
- .max_entries = MAX_VIPS,
-};
+ __uint(type, BPF_MAP_TYPE_HASH);
+ __uint(max_entries, MAX_VIPS);
+ __type(key, struct vip);
+ __type(value, struct vip_meta);
+} vip_map SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- __u32 *value;
-} ch_rings SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = CH_RINGS_SIZE,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, CH_RINGS_SIZE);
+ __type(key, __u32);
+ __type(value, __u32);
+} ch_rings SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- struct real_definition *value;
-} reals SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = MAX_REALS,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, MAX_REALS);
+ __type(key, __u32);
+ __type(value, struct real_definition);
+} reals SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- struct vip_stats *value;
-} stats SEC(".maps") = {
- .type = BPF_MAP_TYPE_PERCPU_ARRAY,
- .max_entries = MAX_VIPS,
-};
+ __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
+ __uint(max_entries, MAX_VIPS);
+ __type(key, __u32);
+ __type(value, struct vip_stats);
+} stats SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- struct ctl_value *value;
-} ctl_array SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = CTL_MAP_SIZE,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, CTL_MAP_SIZE);
+ __type(key, __u32);
+ __type(value, struct ctl_value);
+} ctl_array SEC(".maps");
static __u32 get_packet_hash(struct packet_description *pckt,
bool ipv6)
diff --git a/tools/testing/selftests/bpf/progs/test_map_lock.c b/tools/testing/selftests/bpf/progs/test_map_lock.c
index 40d9c2853393..bb7ce35f691b 100644
--- a/tools/testing/selftests/bpf/progs/test_map_lock.c
+++ b/tools/testing/selftests/bpf/progs/test_map_lock.c
@@ -12,14 +12,11 @@ struct hmap_elem {
};
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- struct hmap_elem *value;
-} hash_map SEC(".maps") = {
- .type = BPF_MAP_TYPE_HASH,
- .max_entries = 1,
-};
+ __uint(type, BPF_MAP_TYPE_HASH);
+ __uint(max_entries, 1);
+ __type(key, __u32);
+ __type(value, struct hmap_elem);
+} hash_map SEC(".maps");
struct array_elem {
struct bpf_spin_lock lock;
@@ -27,14 +24,11 @@ struct array_elem {
};
struct {
- __u32 type;
- __u32 max_entries;
- int *key;
- struct array_elem *value;
-} array_map SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = 1,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, int);
+ __type(value, struct array_elem);
+} array_map SEC(".maps");
SEC("map_lock_demo")
int bpf_map_lock_test(struct __sk_buff *skb)
diff --git a/tools/testing/selftests/bpf/progs/test_select_reuseport_kern.c b/tools/testing/selftests/bpf/progs/test_select_reuseport_kern.c
index 435a9527733e..ea7d84f01235 100644
--- a/tools/testing/selftests/bpf/progs/test_select_reuseport_kern.c
+++ b/tools/testing/selftests/bpf/progs/test_select_reuseport_kern.c
@@ -22,56 +22,39 @@ int _version SEC("version") = 1;
#endif
struct {
- __u32 type;
- __u32 max_entries;
- __u32 key_size;
- __u32 value_size;
-} outer_map SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY_OF_MAPS,
- .max_entries = 1,
- .key_size = sizeof(__u32),
- .value_size = sizeof(__u32),
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
+ __uint(max_entries, 1);
+ __uint(key_size, sizeof(__u32));
+ __uint(value_size, sizeof(__u32));
+} outer_map SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- __u32 *value;
-} result_map SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = NR_RESULTS,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, NR_RESULTS);
+ __type(key, __u32);
+ __type(value, __u32);
+} result_map SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- int *value;
-} tmp_index_ovr_map SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = 1,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, __u32);
+ __type(value, int);
+} tmp_index_ovr_map SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- __u32 *value;
-} linum_map SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = 1,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, __u32);
+ __type(value, __u32);
+} linum_map SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- struct data_check *value;
-} data_check_map SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = 1,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, __u32);
+ __type(value, struct data_check);
+} data_check_map SEC(".maps");
#define GOTO_DONE(_result) ({ \
result = (_result); \
diff --git a/tools/testing/selftests/bpf/progs/test_send_signal_kern.c b/tools/testing/selftests/bpf/progs/test_send_signal_kern.c
index 6ac68be5d68b..0e6be01157e6 100644
--- a/tools/testing/selftests/bpf/progs/test_send_signal_kern.c
+++ b/tools/testing/selftests/bpf/progs/test_send_signal_kern.c
@@ -5,24 +5,18 @@
#include "bpf_helpers.h"
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- __u64 *value;
-} info_map SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = 1,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, __u32);
+ __type(value, __u64);
+} info_map SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- __u64 *value;
-} status_map SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = 1,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, __u32);
+ __type(value, __u64);
+} status_map SEC(".maps");
SEC("send_signal_demo")
int bpf_send_signal_test(void *ctx)
diff --git a/tools/testing/selftests/bpf/progs/test_sock_fields_kern.c b/tools/testing/selftests/bpf/progs/test_sock_fields_kern.c
index c3d383d650cb..a47b003623ef 100644
--- a/tools/testing/selftests/bpf/progs/test_sock_fields_kern.c
+++ b/tools/testing/selftests/bpf/progs/test_sock_fields_kern.c
@@ -28,44 +28,32 @@ enum bpf_linum_array_idx {
};
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- struct sockaddr_in6 *value;
-} addr_map SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = __NR_BPF_ADDR_ARRAY_IDX,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, __NR_BPF_ADDR_ARRAY_IDX);
+ __type(key, __u32);
+ __type(value, struct sockaddr_in6);
+} addr_map SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- struct bpf_sock *value;
-} sock_result_map SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = __NR_BPF_RESULT_ARRAY_IDX,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, __NR_BPF_RESULT_ARRAY_IDX);
+ __type(key, __u32);
+ __type(value, struct bpf_sock);
+} sock_result_map SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- struct bpf_tcp_sock *value;
-} tcp_sock_result_map SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = __NR_BPF_RESULT_ARRAY_IDX,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, __NR_BPF_RESULT_ARRAY_IDX);
+ __type(key, __u32);
+ __type(value, struct bpf_tcp_sock);
+} tcp_sock_result_map SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- __u32 *value;
-} linum_map SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = __NR_BPF_LINUM_ARRAY_IDX,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, __NR_BPF_LINUM_ARRAY_IDX);
+ __type(key, __u32);
+ __type(value, __u32);
+} linum_map SEC(".maps");
struct bpf_spinlock_cnt {
struct bpf_spin_lock lock;
@@ -73,24 +61,18 @@ struct bpf_spinlock_cnt {
};
struct {
- __u32 type;
- __u32 map_flags;
- int *key;
- struct bpf_spinlock_cnt *value;
-} sk_pkt_out_cnt SEC(".maps") = {
- .type = BPF_MAP_TYPE_SK_STORAGE,
- .map_flags = BPF_F_NO_PREALLOC,
-};
+ __uint(type, BPF_MAP_TYPE_SK_STORAGE);
+ __uint(map_flags, BPF_F_NO_PREALLOC);
+ __type(key, int);
+ __type(value, struct bpf_spinlock_cnt);
+} sk_pkt_out_cnt SEC(".maps");
struct {
- __u32 type;
- __u32 map_flags;
- int *key;
- struct bpf_spinlock_cnt *value;
-} sk_pkt_out_cnt10 SEC(".maps") = {
- .type = BPF_MAP_TYPE_SK_STORAGE,
- .map_flags = BPF_F_NO_PREALLOC,
-};
+ __uint(type, BPF_MAP_TYPE_SK_STORAGE);
+ __uint(map_flags, BPF_F_NO_PREALLOC);
+ __type(key, int);
+ __type(value, struct bpf_spinlock_cnt);
+} sk_pkt_out_cnt10 SEC(".maps");
static bool is_loopback6(__u32 *a6)
{
diff --git a/tools/testing/selftests/bpf/progs/test_spin_lock.c b/tools/testing/selftests/bpf/progs/test_spin_lock.c
index 0a77ae36d981..a43b999c8da2 100644
--- a/tools/testing/selftests/bpf/progs/test_spin_lock.c
+++ b/tools/testing/selftests/bpf/progs/test_spin_lock.c
@@ -11,14 +11,11 @@ struct hmap_elem {
};
struct {
- __u32 type;
- __u32 max_entries;
- int *key;
- struct hmap_elem *value;
-} hmap SEC(".maps") = {
- .type = BPF_MAP_TYPE_HASH,
- .max_entries = 1,
-};
+ __uint(type, BPF_MAP_TYPE_HASH);
+ __uint(max_entries, 1);
+ __type(key, int);
+ __type(value, struct hmap_elem);
+} hmap SEC(".maps");
struct cls_elem {
struct bpf_spin_lock lock;
@@ -26,12 +23,10 @@ struct cls_elem {
};
struct {
- __u32 type;
- struct bpf_cgroup_storage_key *key;
- struct cls_elem *value;
-} cls_map SEC(".maps") = {
- .type = BPF_MAP_TYPE_CGROUP_STORAGE,
-};
+ __uint(type, BPF_MAP_TYPE_CGROUP_STORAGE);
+ __type(key, struct bpf_cgroup_storage_key);
+ __type(value, struct cls_elem);
+} cls_map SEC(".maps");
struct bpf_vqueue {
struct bpf_spin_lock lock;
@@ -42,14 +37,11 @@ struct bpf_vqueue {
};
struct {
- __u32 type;
- __u32 max_entries;
- int *key;
- struct bpf_vqueue *value;
-} vqueue SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = 1,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, int);
+ __type(value, struct bpf_vqueue);
+} vqueue SEC(".maps");
#define CREDIT_PER_NS(delta, rate) (((delta) * rate) >> 20)
diff --git a/tools/testing/selftests/bpf/progs/test_stacktrace_build_id.c b/tools/testing/selftests/bpf/progs/test_stacktrace_build_id.c
index fcf2280bb60c..bbfc8337b6f0 100644
--- a/tools/testing/selftests/bpf/progs/test_stacktrace_build_id.c
+++ b/tools/testing/selftests/bpf/progs/test_stacktrace_build_id.c
@@ -9,51 +9,36 @@
#endif
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- __u32 *value;
-} control_map SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = 1,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, __u32);
+ __type(value, __u32);
+} control_map SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- __u32 *value;
-} stackid_hmap SEC(".maps") = {
- .type = BPF_MAP_TYPE_HASH,
- .max_entries = 16384,
-};
+ __uint(type, BPF_MAP_TYPE_HASH);
+ __uint(max_entries, 16384);
+ __type(key, __u32);
+ __type(value, __u32);
+} stackid_hmap SEC(".maps");
typedef struct bpf_stack_build_id stack_trace_t[PERF_MAX_STACK_DEPTH];
struct {
- __u32 type;
- __u32 max_entries;
- __u32 map_flags;
- __u32 key_size;
- __u32 value_size;
-} stackmap SEC(".maps") = {
- .type = BPF_MAP_TYPE_STACK_TRACE,
- .max_entries = 128,
- .map_flags = BPF_F_STACK_BUILD_ID,
- .key_size = sizeof(__u32),
- .value_size = sizeof(stack_trace_t),
-};
+ __uint(type, BPF_MAP_TYPE_STACK_TRACE);
+ __uint(max_entries, 128);
+ __uint(map_flags, BPF_F_STACK_BUILD_ID);
+ __uint(key_size, sizeof(__u32));
+ __uint(value_size, sizeof(stack_trace_t));
+} stackmap SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 128);
+ __type(key, __u32);
/* there seems to be a bug in kernel not handling typedef properly */
struct bpf_stack_build_id (*value)[PERF_MAX_STACK_DEPTH];
-} stack_amap SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = 128,
-};
+} stack_amap SEC(".maps");
/* taken from /sys/kernel/debug/tracing/events/random/urandom_read/format */
struct random_urandom_args {
diff --git a/tools/testing/selftests/bpf/progs/test_stacktrace_map.c b/tools/testing/selftests/bpf/progs/test_stacktrace_map.c
index 7ad09adbf648..803c15dc109d 100644
--- a/tools/testing/selftests/bpf/progs/test_stacktrace_map.c
+++ b/tools/testing/selftests/bpf/progs/test_stacktrace_map.c
@@ -9,48 +9,34 @@
#endif
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- __u32 *value;
-} control_map SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = 1,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, __u32);
+ __type(value, __u32);
+} control_map SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- __u32 *value;
-} stackid_hmap SEC(".maps") = {
- .type = BPF_MAP_TYPE_HASH,
- .max_entries = 16384,
-};
+ __uint(type, BPF_MAP_TYPE_HASH);
+ __uint(max_entries, 16384);
+ __type(key, __u32);
+ __type(value, __u32);
+} stackid_hmap SEC(".maps");
typedef __u64 stack_trace_t[PERF_MAX_STACK_DEPTH];
struct {
- __u32 type;
- __u32 max_entries;
- __u32 key_size;
- __u32 value_size;
-} stackmap SEC(".maps") = {
- .type = BPF_MAP_TYPE_STACK_TRACE,
- .max_entries = 16384,
- .key_size = sizeof(__u32),
- .value_size = sizeof(stack_trace_t),
-};
+ __uint(type, BPF_MAP_TYPE_STACK_TRACE);
+ __uint(max_entries, 16384);
+ __uint(key_size, sizeof(__u32));
+ __uint(value_size, sizeof(stack_trace_t));
+} stackmap SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 16384);
+ __type(key, __u32);
__u64 (*value)[PERF_MAX_STACK_DEPTH];
-} stack_amap SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = 16384,
-};
+} stack_amap SEC(".maps");
/* taken from /sys/kernel/debug/tracing/events/sched/sched_switch/format */
struct sched_switch_args {
diff --git a/tools/testing/selftests/bpf/progs/test_tcp_estats.c b/tools/testing/selftests/bpf/progs/test_tcp_estats.c
index df98f7e32832..c8c595da38d4 100644
--- a/tools/testing/selftests/bpf/progs/test_tcp_estats.c
+++ b/tools/testing/selftests/bpf/progs/test_tcp_estats.c
@@ -149,14 +149,11 @@ struct tcp_estats_basic_event {
};
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- struct tcp_estats_basic_event *value;
-} ev_record_map SEC(".maps") = {
- .type = BPF_MAP_TYPE_HASH,
- .max_entries = 1024,
-};
+ __uint(type, BPF_MAP_TYPE_HASH);
+ __uint(max_entries, 1024);
+ __type(key, __u32);
+ __type(value, struct tcp_estats_basic_event);
+} ev_record_map SEC(".maps");
struct dummy_tracepoint_args {
unsigned long long pad;
diff --git a/tools/testing/selftests/bpf/progs/test_tcpbpf_kern.c b/tools/testing/selftests/bpf/progs/test_tcpbpf_kern.c
index 38e10c9fd996..2e233613d1fc 100644
--- a/tools/testing/selftests/bpf/progs/test_tcpbpf_kern.c
+++ b/tools/testing/selftests/bpf/progs/test_tcpbpf_kern.c
@@ -15,24 +15,18 @@
#include "test_tcpbpf.h"
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- struct tcpbpf_globals *value;
-} global_map SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = 4,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 4);
+ __type(key, __u32);
+ __type(value, struct tcpbpf_globals);
+} global_map SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- int *value;
-} sockopt_results SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = 2,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 2);
+ __type(key, __u32);
+ __type(value, int);
+} sockopt_results SEC(".maps");
static inline void update_event_map(int event)
{
diff --git a/tools/testing/selftests/bpf/progs/test_tcpnotify_kern.c b/tools/testing/selftests/bpf/progs/test_tcpnotify_kern.c
index d073d37d4e27..08346e7765d5 100644
--- a/tools/testing/selftests/bpf/progs/test_tcpnotify_kern.c
+++ b/tools/testing/selftests/bpf/progs/test_tcpnotify_kern.c
@@ -15,26 +15,18 @@
#include "test_tcpnotify.h"
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- struct tcpnotify_globals *value;
-} global_map SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = 4,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 4);
+ __type(key, __u32);
+ __type(value, struct tcpnotify_globals);
+} global_map SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 key_size;
- __u32 value_size;
-} perf_event_map SEC(".maps") = {
- .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
- .max_entries = 2,
- .key_size = sizeof(int),
- .value_size = sizeof(__u32),
-};
+ __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
+ __uint(max_entries, 2);
+ __uint(key_size, sizeof(int));
+ __uint(value_size, sizeof(__u32));
+} perf_event_map SEC(".maps");
int _version SEC("version") = 1;
diff --git a/tools/testing/selftests/bpf/progs/test_xdp.c b/tools/testing/selftests/bpf/progs/test_xdp.c
index ec3d2c1c8cf9..0941c655b07b 100644
--- a/tools/testing/selftests/bpf/progs/test_xdp.c
+++ b/tools/testing/selftests/bpf/progs/test_xdp.c
@@ -23,24 +23,18 @@
int _version SEC("version") = 1;
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- __u64 *value;
-} rxcnt SEC(".maps") = {
- .type = BPF_MAP_TYPE_PERCPU_ARRAY,
- .max_entries = 256,
-};
+ __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
+ __uint(max_entries, 256);
+ __type(key, __u32);
+ __type(value, __u64);
+} rxcnt SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- struct vip *key;
- struct iptnl_info *value;
-} vip2tnl SEC(".maps") = {
- .type = BPF_MAP_TYPE_HASH,
- .max_entries = MAX_IPTNL_ENTRIES,
-};
+ __uint(type, BPF_MAP_TYPE_HASH);
+ __uint(max_entries, MAX_IPTNL_ENTRIES);
+ __type(key, struct vip);
+ __type(value, struct iptnl_info);
+} vip2tnl SEC(".maps");
static __always_inline void count_tx(__u32 protocol)
{
diff --git a/tools/testing/selftests/bpf/progs/test_xdp_noinline.c b/tools/testing/selftests/bpf/progs/test_xdp_noinline.c
index d2eddb5553d1..dad8a7e33eaa 100644
--- a/tools/testing/selftests/bpf/progs/test_xdp_noinline.c
+++ b/tools/testing/selftests/bpf/progs/test_xdp_noinline.c
@@ -164,66 +164,47 @@ struct lb_stats {
};
struct {
- __u32 type;
- __u32 max_entries;
- struct vip_definition *key;
- struct vip_meta *value;
-} vip_map SEC(".maps") = {
- .type = BPF_MAP_TYPE_HASH,
- .max_entries = 512,
-};
+ __uint(type, BPF_MAP_TYPE_HASH);
+ __uint(max_entries, 512);
+ __type(key, struct vip_definition);
+ __type(value, struct vip_meta);
+} vip_map SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 map_flags;
- struct flow_key *key;
- struct real_pos_lru *value;
-} lru_cache SEC(".maps") = {
- .type = BPF_MAP_TYPE_LRU_HASH,
- .max_entries = 300,
- .map_flags = 1U << 1,
-};
+ __uint(type, BPF_MAP_TYPE_LRU_HASH);
+ __uint(max_entries, 300);
+ __uint(map_flags, 1U << 1);
+ __type(key, struct flow_key);
+ __type(value, struct real_pos_lru);
+} lru_cache SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- __u32 *value;
-} ch_rings SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = 12 * 655,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 12 * 655);
+ __type(key, __u32);
+ __type(value, __u32);
+} ch_rings SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- struct real_definition *value;
-} reals SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = 40,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 40);
+ __type(key, __u32);
+ __type(value, struct real_definition);
+} reals SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- struct lb_stats *value;
-} stats SEC(".maps") = {
- .type = BPF_MAP_TYPE_PERCPU_ARRAY,
- .max_entries = 515,
-};
+ __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
+ __uint(max_entries, 515);
+ __type(key, __u32);
+ __type(value, struct lb_stats);
+} stats SEC(".maps");
struct {
- __u32 type;
- __u32 max_entries;
- __u32 *key;
- struct ctl_value *value;
-} ctl_array SEC(".maps") = {
- .type = BPF_MAP_TYPE_ARRAY,
- .max_entries = 16,
-};
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 16);
+ __type(key, __u32);
+ __type(value, struct ctl_value);
+} ctl_array SEC(".maps");
struct eth_hdr {
unsigned char eth_dest[6];
--
2.17.1
^ permalink raw reply related
* [PATCH v5 bpf-next 2/4] selftests/bpf: add __uint and __type macro for BTF-defined maps
From: Andrii Nakryiko @ 2019-07-05 15:50 UTC (permalink / raw)
To: andrii.nakryiko, kernel-team, ast, daniel, netdev, bpf; +Cc: Andrii Nakryiko
In-Reply-To: <20190705155012.3539722-1-andriin@fb.com>
Add simple __uint and __type macro that hide details of how type and
integer values are captured in BTF-defined maps.
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Acked-by: Song Liu <songliubraving@fb.com>
Acked-by: Yonghong Song <yhs@fb.com>
---
tools/testing/selftests/bpf/bpf_helpers.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h
index 1a5b1accf091..5a3d92c8bec8 100644
--- a/tools/testing/selftests/bpf/bpf_helpers.h
+++ b/tools/testing/selftests/bpf/bpf_helpers.h
@@ -8,6 +8,9 @@
*/
#define SEC(NAME) __attribute__((section(NAME), used))
+#define __uint(name, val) int (*name)[val]
+#define __type(name, val) val *name
+
/* helper macro to print out debug messages */
#define bpf_printk(fmt, ...) \
({ \
--
2.17.1
^ permalink raw reply related
* [PATCH v5 bpf-next 1/4] libbpf: capture value in BTF type info for BTF-defined map defs
From: Andrii Nakryiko @ 2019-07-05 15:50 UTC (permalink / raw)
To: andrii.nakryiko, kernel-team, ast, daniel, netdev, bpf; +Cc: Andrii Nakryiko
In-Reply-To: <20190705155012.3539722-1-andriin@fb.com>
Change BTF-defined map definitions to capture compile-time integer
values as part of BTF type definition, to avoid split of key/value type
information and actual type/size/flags initialization for maps.
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Acked-by: Song Liu <songliubraving@fb.com>
Acked-by: Yonghong Song <yhs@fb.com>
---
tools/lib/bpf/libbpf.c | 58 ++++++++++++++++++++----------------------
1 file changed, 28 insertions(+), 30 deletions(-)
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 4907997289e9..fad8901ee774 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -1028,40 +1028,40 @@ static const struct btf_type *skip_mods_and_typedefs(const struct btf *btf,
}
}
-static bool get_map_field_int(const char *map_name,
- const struct btf *btf,
+/*
+ * Fetch integer attribute of BTF map definition. Such attributes are
+ * represented using a pointer to an array, in which dimensionality of array
+ * encodes specified integer value. E.g., int (*type)[BPF_MAP_TYPE_ARRAY];
+ * encodes `type => BPF_MAP_TYPE_ARRAY` key/value pair completely using BTF
+ * type definition, while using only sizeof(void *) space in ELF data section.
+ */
+static bool get_map_field_int(const char *map_name, const struct btf *btf,
const struct btf_type *def,
- const struct btf_member *m,
- const void *data, __u32 *res) {
+ const struct btf_member *m, __u32 *res) {
const struct btf_type *t = skip_mods_and_typedefs(btf, m->type);
const char *name = btf__name_by_offset(btf, m->name_off);
- __u32 int_info = *(const __u32 *)(const void *)(t + 1);
+ const struct btf_array *arr_info;
+ const struct btf_type *arr_t;
- if (BTF_INFO_KIND(t->info) != BTF_KIND_INT) {
- pr_warning("map '%s': attr '%s': expected INT, got %u.\n",
+ if (BTF_INFO_KIND(t->info) != BTF_KIND_PTR) {
+ pr_warning("map '%s': attr '%s': expected PTR, got %u.\n",
map_name, name, BTF_INFO_KIND(t->info));
return false;
}
- if (t->size != 4 || BTF_INT_BITS(int_info) != 32 ||
- BTF_INT_OFFSET(int_info)) {
- pr_warning("map '%s': attr '%s': expected 32-bit non-bitfield integer, "
- "got %u-byte (%d-bit) one with bit offset %d.\n",
- map_name, name, t->size, BTF_INT_BITS(int_info),
- BTF_INT_OFFSET(int_info));
- return false;
- }
- if (BTF_INFO_KFLAG(def->info) && BTF_MEMBER_BITFIELD_SIZE(m->offset)) {
- pr_warning("map '%s': attr '%s': bitfield is not supported.\n",
- map_name, name);
+
+ arr_t = btf__type_by_id(btf, t->type);
+ if (!arr_t) {
+ pr_warning("map '%s': attr '%s': type [%u] not found.\n",
+ map_name, name, t->type);
return false;
}
- if (m->offset % 32) {
- pr_warning("map '%s': attr '%s': unaligned fields are not supported.\n",
- map_name, name);
+ if (BTF_INFO_KIND(arr_t->info) != BTF_KIND_ARRAY) {
+ pr_warning("map '%s': attr '%s': expected ARRAY, got %u.\n",
+ map_name, name, BTF_INFO_KIND(arr_t->info));
return false;
}
-
- *res = *(const __u32 *)(data + m->offset / 8);
+ arr_info = (const void *)(arr_t + 1);
+ *res = arr_info->nelems;
return true;
}
@@ -1074,7 +1074,6 @@ static int bpf_object__init_user_btf_map(struct bpf_object *obj,
const struct btf_var_secinfo *vi;
const struct btf_var *var_extra;
const struct btf_member *m;
- const void *def_data;
const char *map_name;
struct bpf_map *map;
int vlen, i;
@@ -1131,7 +1130,6 @@ static int bpf_object__init_user_btf_map(struct bpf_object *obj,
pr_debug("map '%s': at sec_idx %d, offset %zu.\n",
map_name, map->sec_idx, map->sec_offset);
- def_data = data->d_buf + vi->offset;
vlen = BTF_INFO_VLEN(def->info);
m = (const void *)(def + 1);
for (i = 0; i < vlen; i++, m++) {
@@ -1144,19 +1142,19 @@ static int bpf_object__init_user_btf_map(struct bpf_object *obj,
}
if (strcmp(name, "type") == 0) {
if (!get_map_field_int(map_name, obj->btf, def, m,
- def_data, &map->def.type))
+ &map->def.type))
return -EINVAL;
pr_debug("map '%s': found type = %u.\n",
map_name, map->def.type);
} else if (strcmp(name, "max_entries") == 0) {
if (!get_map_field_int(map_name, obj->btf, def, m,
- def_data, &map->def.max_entries))
+ &map->def.max_entries))
return -EINVAL;
pr_debug("map '%s': found max_entries = %u.\n",
map_name, map->def.max_entries);
} else if (strcmp(name, "map_flags") == 0) {
if (!get_map_field_int(map_name, obj->btf, def, m,
- def_data, &map->def.map_flags))
+ &map->def.map_flags))
return -EINVAL;
pr_debug("map '%s': found map_flags = %u.\n",
map_name, map->def.map_flags);
@@ -1164,7 +1162,7 @@ static int bpf_object__init_user_btf_map(struct bpf_object *obj,
__u32 sz;
if (!get_map_field_int(map_name, obj->btf, def, m,
- def_data, &sz))
+ &sz))
return -EINVAL;
pr_debug("map '%s': found key_size = %u.\n",
map_name, sz);
@@ -1207,7 +1205,7 @@ static int bpf_object__init_user_btf_map(struct bpf_object *obj,
__u32 sz;
if (!get_map_field_int(map_name, obj->btf, def, m,
- def_data, &sz))
+ &sz))
return -EINVAL;
pr_debug("map '%s': found value_size = %u.\n",
map_name, sz);
--
2.17.1
^ permalink raw reply related
* [PATCH v5 bpf-next 0/4] capture integers in BTF type info for map defs
From: Andrii Nakryiko @ 2019-07-05 15:50 UTC (permalink / raw)
To: andrii.nakryiko, kernel-team, ast, daniel, netdev, bpf; +Cc: Andrii Nakryiko
This patch set implements an update to how BTF-defined maps are specified. The
change is in how integer attributes, e.g., type, max_entries, map_flags, are
specified: now they are captured as part of map definition struct's BTF type
information (using array dimension), eliminating the need for compile-time
data initialization and keeping all the metadata in one place.
All existing selftests that were using BTF-defined maps are updated, along
with some other selftests, that were switched to new syntax.
v4->v5:
- revert sample_map_ret0.c, which is loaded with iproute2 (kernel test robot);
v3->v4:
- add acks;
- fix int -> uint type in commit message;
v2->v3:
- rename __int into __uint (Yonghong);
v1->v2:
- split bpf_helpers.h change from libbpf change (Song).
Andrii Nakryiko (4):
libbpf: capture value in BTF type info for BTF-defined map defs
selftests/bpf: add __uint and __type macro for BTF-defined maps
selftests/bpf: convert selftests using BTF-defined maps to new syntax
selftests/bpf: convert legacy BPF maps to BTF-defined ones
tools/lib/bpf/libbpf.c | 58 +++++----
tools/testing/selftests/bpf/bpf_helpers.h | 3 +
tools/testing/selftests/bpf/progs/bpf_flow.c | 28 ++---
.../selftests/bpf/progs/get_cgroup_id_kern.c | 26 ++---
.../testing/selftests/bpf/progs/netcnt_prog.c | 20 ++--
tools/testing/selftests/bpf/progs/pyperf.h | 90 +++++++-------
.../selftests/bpf/progs/socket_cookie_prog.c | 13 +--
.../bpf/progs/sockmap_verdict_prog.c | 48 ++++----
.../testing/selftests/bpf/progs/strobemeta.h | 68 +++++------
.../selftests/bpf/progs/test_btf_newkv.c | 13 +--
.../bpf/progs/test_get_stack_rawtp.c | 39 +++----
.../selftests/bpf/progs/test_global_data.c | 37 +++---
tools/testing/selftests/bpf/progs/test_l4lb.c | 65 ++++-------
.../selftests/bpf/progs/test_l4lb_noinline.c | 65 ++++-------
.../selftests/bpf/progs/test_map_in_map.c | 30 ++---
.../selftests/bpf/progs/test_map_lock.c | 26 ++---
.../testing/selftests/bpf/progs/test_obj_id.c | 12 +-
.../bpf/progs/test_select_reuseport_kern.c | 67 ++++-------
.../bpf/progs/test_send_signal_kern.c | 26 ++---
.../bpf/progs/test_sock_fields_kern.c | 78 +++++--------
.../selftests/bpf/progs/test_spin_lock.c | 36 +++---
.../bpf/progs/test_stacktrace_build_id.c | 55 ++++-----
.../selftests/bpf/progs/test_stacktrace_map.c | 52 +++------
.../selftests/bpf/progs/test_tcp_estats.c | 13 +--
.../selftests/bpf/progs/test_tcpbpf_kern.c | 26 ++---
.../selftests/bpf/progs/test_tcpnotify_kern.c | 28 ++---
tools/testing/selftests/bpf/progs/test_xdp.c | 26 ++---
.../selftests/bpf/progs/test_xdp_loop.c | 26 ++---
.../selftests/bpf/progs/test_xdp_noinline.c | 81 +++++--------
.../selftests/bpf/progs/xdp_redirect_map.c | 12 +-
.../testing/selftests/bpf/progs/xdping_kern.c | 12 +-
.../selftests/bpf/test_queue_stack_map.h | 30 ++---
.../testing/selftests/bpf/test_sockmap_kern.h | 110 +++++++++---------
33 files changed, 559 insertions(+), 760 deletions(-)
--
2.17.1
^ permalink raw reply
* Re: [PATCH rdma-next v5 00/17] Statistics counter support
From: Jason Gunthorpe @ 2019-07-05 15:50 UTC (permalink / raw)
To: Leon Romanovsky
Cc: Doug Ledford, Leon Romanovsky, RDMA mailing list, Majd Dibbiny,
Mark Zhang, Saeed Mahameed, linux-netdev
In-Reply-To: <20190702100246.17382-1-leon@kernel.org>
On Tue, Jul 02, 2019 at 01:02:29PM +0300, Leon Romanovsky wrote:
> From: Leon Romanovsky <leonro@mellanox.com>
>
> Changelog:
> v4 -> v5:
> * Patch #6 and #14 - consolidated many counter release functions,
> removed mutex lock protection from dealloc_counter() call
> and simplified kref_put/kref_get operations.
> * Added Saeed's ACK tags.
> v3 -> v4:
> * Add counter_dealloc() callback function
> * Moved to kref implementation
> * Fixed lock during spinlock
> v2 -> v3:
> * We didn't change use of atomics over kref for management of unbind
> counter from QP. The reason to it that bind and unbind are non-symmetric
> in regards of put and get, so we need to count differently memory
> release flows of HW objects (restrack) and SW bind operations.
> * Everything else was addressed.
> v1 -> v2:
> * Rebased to latest rdma-next
> v0 -> v1:
> * Changed wording of counter comment
> * Removed unneeded assignments
> * Added extra patch to present global counters
>
>
> Hi,
>
> This series from Mark provides dynamic statistics infrastructure.
> He uses netlink interface to configure and retrieve those counters.
>
> This infrastructure allows to users monitor various objects by binding
> to them counters. As the beginning, we used QP object as target for
> those counters, but future patches will include ODP MR information too.
>
> Two binding modes are supported:
> - Auto: This allows a user to build automatic set of objects to a counter
> according to common criteria. For example in a per-type scheme, where in
> one process all QPs with same QP type are bound automatically to a single
> counter.
> - Manual: This allows a user to manually bind objects on a counter.
>
> Those two modes are mutual-exclusive with separation between processes,
> objects created by different processes cannot be bound to a same counter.
>
> For objects which don't support counter binding, we will return
> pre-allocated counters.
>
> $ rdma statistic qp set link mlx5_2/1 auto type on
> $ rdma statistic qp set link mlx5_2/1 auto off
> $ rdma statistic qp bind link mlx5_2/1 lqpn 178
> $ rdma statistic qp unbind link mlx5_2/1 cntn 4 lqpn 178
> $ rdma statistic show
> $ rdma statistic qp mode
>
> Thanks
>
>
> Mark Zhang (17):
> net/mlx5: Add rts2rts_qp_counters_set_id field in hca cap
> RDMA/restrack: Introduce statistic counter
> RDMA/restrack: Add an API to attach a task to a resource
> RDMA/restrack: Make is_visible_in_pid_ns() as an API
> RDMA/counter: Add set/clear per-port auto mode support
> RDMA/counter: Add "auto" configuration mode support
> IB/mlx5: Support set qp counter
> IB/mlx5: Add counter set id as a parameter for
> mlx5_ib_query_q_counters()
> IB/mlx5: Support statistic q counter configuration
> RDMA/nldev: Allow counter auto mode configration through RDMA netlink
> RDMA/netlink: Implement counter dumpit calback
> IB/mlx5: Add counter_alloc_stats() and counter_update_stats() support
> RDMA/core: Get sum value of all counters when perform a sysfs stat
> read
> RDMA/counter: Allow manual mode configuration support
> RDMA/nldev: Allow counter manual mode configration through RDMA
> netlink
> RDMA/nldev: Allow get counter mode through RDMA netlink
> RDMA/nldev: Allow get default counter statistics through RDMA netlink
Okay, applied to for-next
Thanks,
Jason
^ permalink raw reply
* Re: INFO: rcu detected stall in ext4_write_checks
From: Dmitry Vyukov @ 2019-07-05 15:48 UTC (permalink / raw)
To: Paul E. McKenney
Cc: Theodore Ts'o, syzbot, Andreas Dilger, David Miller, eladr,
Ido Schimmel, Jiri Pirko, John Stultz, linux-ext4, LKML, netdev,
syzkaller-bugs, Thomas Gleixner, Peter Zijlstra, Ingo Molnar
In-Reply-To: <20190705151658.GP26519@linux.ibm.com>
On Fri, Jul 5, 2019 at 5:17 PM Paul E. McKenney <paulmck@linux.ibm.com> wrote:
>
> On Fri, Jul 05, 2019 at 03:24:26PM +0200, Dmitry Vyukov wrote:
> > On Thu, Jun 27, 2019 at 12:47 AM Theodore Ts'o <tytso@mit.edu> wrote:
> > >
> > > More details about what is going on. First, it requires root, because
> > > one of that is required is using sched_setattr (which is enough to
> > > shoot yourself in the foot):
> > >
> > > sched_setattr(0, {size=0, sched_policy=0x6 /* SCHED_??? */, sched_flags=0, sched_nice=0, sched_priority=0, sched_runtime=2251799813724439, sched_deadline=4611686018427453437, sched_period=0}, 0) = 0
> > >
> > > This is setting the scheduler policy to be SCHED_DEADLINE, with a
> > > runtime parameter of 2251799.813724439 seconds (or 26 days) and a
> > > deadline of 4611686018.427453437 seconds (or 146 *years*). This means
> > > a particular kernel thread can run for up to 26 **days** before it is
> > > scheduled away, and if a kernel reads gets woken up or sent a signal,
> > > no worries, it will wake up roughly seven times the interval that Rip
> > > Van Winkle spent snoozing in a cave in the Catskill Mountains (in
> > > Washington Irving's short story).
> > >
> > > We then kick off a half-dozen threads all running:
> > >
> > > sendfile(fd, fd, &pos, 0x8080fffffffe);
> > >
> > > (and since count is a ridiculously large number, this gets cut down to):
> > >
> > > sendfile(fd, fd, &pos, 2147479552);
> > >
> > > Is it any wonder that we are seeing RCU stalls? :-)
> >
> > +Peter, Ingo for sched_setattr and +Paul for rcu
> >
> > First of all: is it a semi-intended result of a root (CAP_SYS_NICE)
> > doing local DoS abusing sched_setattr? It would perfectly reasonable
> > to starve other processes, but I am not sure about rcu. In the end the
> > high prio process can use rcu itself, and then it will simply blow
> > system memory by stalling rcu. So it seems that rcu stalls should not
> > happen as a result of weird sched_setattr values. If that is the case,
> > what needs to be fixed? sched_setattr? rcu? sendfile?
>
> Does the (untested, probably does not even build) patch shown below help?
> This patch assumes that the kernel was built with CONFIG_PREEMPT=n.
> And that I found all the tight loops on the do_sendfile() code path.
The config used when this happened is referenced from here:
https://syzkaller.appspot.com/bug?extid=4bfbbf28a2e50ab07368
and it contains:
CONFIG_PREEMPT=y
So... what does this mean? The loop should have been preempted without
the cond_resched() then, right?
> > If this is semi-intended, the only option I see is to disable
> > something in syzkaller: sched_setattr entirely, or drop CAP_SYS_NICE,
> > or ...? Any preference either way?
>
> Long-running tight loops in the kernel really should contain
> cond_resched() or better.
>
> Thanx, Paul
>
> ------------------------------------------------------------------------
>
> diff --git a/fs/splice.c b/fs/splice.c
> index 25212dcca2df..50aa3286764a 100644
> --- a/fs/splice.c
> +++ b/fs/splice.c
> @@ -985,6 +985,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
> sd->pos = prev_pos + ret;
> goto out_release;
> }
> + cond_resched();
> }
>
> done:
>
^ 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