All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH bpf-next 0/2] bpf, docs: Document BPF_MAP_TYPE_ARRAY
@ 2021-11-22 17:19 Dave Tucker
  2021-11-22 17:19 ` [PATCH bpf-next 1/2] bpf, docs: add kernel version to map_cgroup_storage Dave Tucker
  2021-11-22 17:19 ` [PATCH bpf-next 2/2] bpf, docs: document BPF_MAP_TYPE_ARRAY Dave Tucker
  0 siblings, 2 replies; 7+ messages in thread
From: Dave Tucker @ 2021-11-22 17:19 UTC (permalink / raw)
  To: bpf
  Cc: corbet, ast, daniel, andrii, kafai, songliubraving,
	john.fastabend, kpsingh, linux-doc, Dave Tucker

This series is the beginning of my attempt to improve the BPF map and
program type documentation. It expands the template from
map_cgroup_storage to include the kernel version it was introduced.
I then used this template to document BPF_MAP_TYPE_ARRAY and 
BPF_MAP_TYPE_PERCPU_ARRAY

Dave Tucker (2):
  bpf, docs: add kernel version to map_cgroup_storage
  bpf, docs: document BPF_MAP_TYPE_ARRAY

 Documentation/bpf/map_array.rst          | 150 +++++++++++++++++++++++
 Documentation/bpf/map_cgroup_storage.rst |   2 +
 2 files changed, 152 insertions(+)
 create mode 100644 Documentation/bpf/map_array.rst

-- 
2.33.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH bpf-next 1/2] bpf, docs: add kernel version to map_cgroup_storage
  2021-11-22 17:19 [PATCH bpf-next 0/2] bpf, docs: Document BPF_MAP_TYPE_ARRAY Dave Tucker
@ 2021-11-22 17:19 ` Dave Tucker
  2021-11-22 17:19 ` [PATCH bpf-next 2/2] bpf, docs: document BPF_MAP_TYPE_ARRAY Dave Tucker
  1 sibling, 0 replies; 7+ messages in thread
From: Dave Tucker @ 2021-11-22 17:19 UTC (permalink / raw)
  To: bpf
  Cc: corbet, ast, daniel, andrii, kafai, songliubraving,
	john.fastabend, kpsingh, linux-doc, Dave Tucker

This adds the version at which this map became available to use in the
documentation

Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
---
 Documentation/bpf/map_cgroup_storage.rst | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/bpf/map_cgroup_storage.rst b/Documentation/bpf/map_cgroup_storage.rst
index cab9543017bf..b626cb068846 100644
--- a/Documentation/bpf/map_cgroup_storage.rst
+++ b/Documentation/bpf/map_cgroup_storage.rst
@@ -5,6 +5,8 @@
 BPF_MAP_TYPE_CGROUP_STORAGE
 ===========================
 
+.. note:: Introduced in Kernel version 4.19
+
 The ``BPF_MAP_TYPE_CGROUP_STORAGE`` map type represents a local fix-sized
 storage. It is only available with ``CONFIG_CGROUP_BPF``, and to programs that
 attach to cgroups; the programs are made available by the same Kconfig. The
-- 
2.33.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH bpf-next 2/2] bpf, docs: document BPF_MAP_TYPE_ARRAY
  2021-11-22 17:19 [PATCH bpf-next 0/2] bpf, docs: Document BPF_MAP_TYPE_ARRAY Dave Tucker
  2021-11-22 17:19 ` [PATCH bpf-next 1/2] bpf, docs: add kernel version to map_cgroup_storage Dave Tucker
@ 2021-11-22 17:19 ` Dave Tucker
  2021-11-22 19:15   ` Jonathan Corbet
  2021-11-23  3:53   ` Andrii Nakryiko
  1 sibling, 2 replies; 7+ messages in thread
From: Dave Tucker @ 2021-11-22 17:19 UTC (permalink / raw)
  To: bpf
  Cc: corbet, ast, daniel, andrii, kafai, songliubraving,
	john.fastabend, kpsingh, linux-doc, Dave Tucker

This commit adds documentation for the BPF_MAP_TYPE_ARRAY including
kernel version introduced, usage and examples.
It also documents BPF_MAP_TYPE_PERCPU_ARRAY since this is similar.

Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
---
 Documentation/bpf/map_array.rst | 150 ++++++++++++++++++++++++++++++++
 1 file changed, 150 insertions(+)
 create mode 100644 Documentation/bpf/map_array.rst

diff --git a/Documentation/bpf/map_array.rst b/Documentation/bpf/map_array.rst
new file mode 100644
index 000000000000..f9eb5473a240
--- /dev/null
+++ b/Documentation/bpf/map_array.rst
@@ -0,0 +1,150 @@
+.. SPDX-License-Identifier: GPL-2.0-only
+.. Copyright (C) 2021 Red Hat, Inc.
+
+================================================
+BPF_MAP_TYPE_ARRAY and BPF_MAP_TYPE_PERCPU_ARRAY
+================================================
+
+.. note:: ``BPF_MAP_TYPE_ARRAY`` was introduced in Kernel version 3.19 and ``BPF_MAP_TYPE_PERCPU_ARRAY`` in version 4.6
+
+``BPF_MAP_TYPE_ARRAY`` and ``BPF_MAP_TYPE_PERCPU_ARRAY`` provide generic array storage.
+The key type is an unsigned 32-bit integer (4 bytes) and the map is of constant size.
+All array elements are pre-allocated and zero initialized when created.
+``BPF_MAP_TYPE_PERCPU_ARRAY`` uses a different memory region for each CPU whereas
+``BPF_MAP_TYPE_ARRAY`` uses the same memory region.
+The maximum size of an array, defined in max_entries, is limited to 2^32.
+The value stored can be of any size, however, small values will be rounded up to 8 bytes.
+
+Usage
+=====
+
+Array elements can be retrieved using the ``bpf_map_lookup_elem()`` helper.
+This helper returns a pointer into the array element, so to avoid data races with userspace reading the value,
+the user must use primitives like ``__sync_fetch_and_add()`` when updating the value in-place.
+Access from userspace uses the libbpf API of the same name.
+
+Array elements can also be added using the ``bpf_map_update_elem()`` helper or libbpf API.
+
+Since the array is of constant size, ``bpf_map_delete_elem()`` is not supported.
+To clear an array element, you may use ``bpf_map_update_eleme()`` to insert a zero value to that index.
+
+Values stored in ``BPF_MAP_TYPE_ARRAY`` can be accessed by multiple programs across different CPUs.
+To restrict storage to a single CPU, you may use a ``BPF_MAP_TYPE_PERCPU_ARRAY``.
+Since Kernel version 5.1, the BPF infrastructure provides ``struct bpf_spin_lock`` to synchronize access.
+
+```bpf_map_get_next_key()`` can be used to iterate over array values.
+
+Examples
+========
+
+Please see the `bpf/samples`_ directory for functional examples.
+This sample code simply demonstrates the API.
+
+.. section links
+.. _bpf/samples:
+    https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/samples/bpf/
+
+Kernel
+------
+
+.. code-block:: c
+
+    struct {
+        __uint(type, BPF_MAP_TYPE_ARRAY);
+        __type(key, u32);
+        __type(value, long);
+        __uint(max_entries, 256);
+    } my_map SEC(".maps");
+
+    int bpf_prog(struct __sk_buff *skb)
+    {
+        int index = load_byte(skb, ETH_HLEN + offsetof(struct iphdr, protocol));
+        long *value;
+
+        if (skb->pkt_type != PACKET_OUTGOING)
+            return 0;
+
+        value = bpf_map_lookup_elem(&my_map, &index);
+        if (value)
+            __sync_fetch_and_add(value, skb->len);
+
+        return 0;
+    }
+
+Userspace
+---------
+
+BPF_MAP_TYPE_ARRAY
+~~~~~~~~~~~~~~~~~~
+
+.. code-block:: c
+
+    #include <assert.h>
+    #include <bpf/libbpf.h>
+    #include <bpf/bpf.h>
+
+    int main(int argc, char **argv)
+        {
+
+            int fd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(__u32), sizeof(long), 256, 0);
+            if (fd < 0)
+            return -1;
+
+            // fill the map with values from 0-255
+            for(__u32 i=0; i < 256 ; i++) {
+                long v = i;
+                bpf_map_update_elem(fd, &i, &v, BPF_ANY);
+            }
+
+            __u32 index = 42;
+            long value;
+            bpf_map_lookup_elem(fd, &index, &value);
+            assert(value == 42);
+            return 0;
+    }
+
+
+BPF_MAP_TYPE_PERCPU_ARRAY
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: c
+
+    #include <assert.h>
+    #include <bpf/libbpf.h>
+    #include <bpf/bpf.h>
+
+    int main(int argc, char **argv)
+        {
+            int ncpus = libbpf_num_possible_cpus();
+
+            int fd = bpf_create_map(BPF_MAP_TYPE_PERCPU_ARRAY, sizeof(__u32), sizeof(long), 256, 0);
+            if (fd < 0)
+            return -1;
+
+            // fill the map with values from 0-255 for each cpu
+            for(__u32 i=0; i < 256 ; i++) {
+                long v[ncpus];
+                for (int j=0; j < ncpus; j++ ) {
+                    v[j] = i;
+                }
+                bpf_map_update_elem(fd, &i, &v, BPF_ANY);
+            }
+
+            sleep(60);
+
+            __u32 index = 42;
+            long value[ncpus];
+            bpf_map_lookup_elem(fd, &index, &value);
+            for (int j=0; j < ncpus; j++ ) {
+                assert(value[j] == 42);
+            }
+            return 0;
+    }
+
+Semantics
+=========
+
+As illustrated in the example above, when using a ``BPF_MAP_TYPE_PERCPU_ARRAY`` in userspace, the
+values are an array with ``ncpus`` elements.
+
+When calling ``bpf_map_update_elem()`` the flags `BPF_NOEXIST` can not be used for these maps.
\ No newline at end of file
-- 
2.33.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH bpf-next 2/2] bpf, docs: document BPF_MAP_TYPE_ARRAY
  2021-11-22 17:19 ` [PATCH bpf-next 2/2] bpf, docs: document BPF_MAP_TYPE_ARRAY Dave Tucker
@ 2021-11-22 19:15   ` Jonathan Corbet
  2021-11-22 19:33     ` Dave Tucker
  2021-11-23  3:53   ` Andrii Nakryiko
  1 sibling, 1 reply; 7+ messages in thread
From: Jonathan Corbet @ 2021-11-22 19:15 UTC (permalink / raw)
  To: Dave Tucker, bpf
  Cc: ast, daniel, andrii, kafai, songliubraving, john.fastabend,
	kpsingh, linux-doc, Dave Tucker

Dave Tucker <dave@dtucker.co.uk> writes:

> This commit adds documentation for the BPF_MAP_TYPE_ARRAY including
> kernel version introduced, usage and examples.
> It also documents BPF_MAP_TYPE_PERCPU_ARRAY since this is similar.
>
> Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
> ---
>  Documentation/bpf/map_array.rst | 150 ++++++++++++++++++++++++++++++++
>  1 file changed, 150 insertions(+)
>  create mode 100644 Documentation/bpf/map_array.rst

When you add a new BPF file, you need to add it to the corresponding
index.rst file as well.  Otherwise it won't be part of the docs build
and will, instead, generate the warning you surely saw when you tested
the build...:)

Thanks,

jon

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH bpf-next 2/2] bpf, docs: document BPF_MAP_TYPE_ARRAY
  2021-11-22 19:15   ` Jonathan Corbet
@ 2021-11-22 19:33     ` Dave Tucker
  2021-11-22 20:33       ` Jonathan Corbet
  0 siblings, 1 reply; 7+ messages in thread
From: Dave Tucker @ 2021-11-22 19:33 UTC (permalink / raw)
  To: Jonathan Corbet, bpf
  Cc: ast, daniel, andrii, kafai, songliubraving, john.fastabend,
	kpsingh, linux-doc

On Mon, 22 Nov 2021, at 19:15, Jonathan Corbet wrote:
> Dave Tucker <dave@dtucker.co.uk> writes:
>
> When you add a new BPF file, you need to add it to the corresponding
> index.rst file as well.  Otherwise it won't be part of the docs build
> and will, instead, generate the warning you surely saw when you tested
> the build...:)

I did test the build and I don't think I introduced any new warnings :)

This file is included in the docs build via the glob pattern that I added to 
the toctree in Documentation/bpf/maps.rst, which was recently applied to
bpf-next [1].

- Dave

[1]: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/commit/?id=5931d9a3d0529dc803c792a10e52f0de1d0b9991

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH bpf-next 2/2] bpf, docs: document BPF_MAP_TYPE_ARRAY
  2021-11-22 19:33     ` Dave Tucker
@ 2021-11-22 20:33       ` Jonathan Corbet
  0 siblings, 0 replies; 7+ messages in thread
From: Jonathan Corbet @ 2021-11-22 20:33 UTC (permalink / raw)
  To: Dave Tucker, bpf
  Cc: ast, daniel, andrii, kafai, songliubraving, john.fastabend,
	kpsingh, linux-doc

"Dave Tucker" <dave@dtucker.co.uk> writes:

> On Mon, 22 Nov 2021, at 19:15, Jonathan Corbet wrote:
>> Dave Tucker <dave@dtucker.co.uk> writes:
>>
>> When you add a new BPF file, you need to add it to the corresponding
>> index.rst file as well.  Otherwise it won't be part of the docs build
>> and will, instead, generate the warning you surely saw when you tested
>> the build...:)
>
> I did test the build and I don't think I introduced any new warnings :)
>
> This file is included in the docs build via the glob pattern that I added to 
> the toctree in Documentation/bpf/maps.rst, which was recently applied to
> bpf-next [1].

Interesting, I didn't know about :glob: - thanks for teaching me
something and apologies for the noise :)

Thanks,

jon

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH bpf-next 2/2] bpf, docs: document BPF_MAP_TYPE_ARRAY
  2021-11-22 17:19 ` [PATCH bpf-next 2/2] bpf, docs: document BPF_MAP_TYPE_ARRAY Dave Tucker
  2021-11-22 19:15   ` Jonathan Corbet
@ 2021-11-23  3:53   ` Andrii Nakryiko
  1 sibling, 0 replies; 7+ messages in thread
From: Andrii Nakryiko @ 2021-11-23  3:53 UTC (permalink / raw)
  To: Dave Tucker
  Cc: bpf, Jonathan Corbet, Alexei Starovoitov, Daniel Borkmann,
	Andrii Nakryiko, Martin Lau, Song Liu, john fastabend, KP Singh,
	Linux Doc Mailing List

On Mon, Nov 22, 2021 at 9:19 AM Dave Tucker <dave@dtucker.co.uk> wrote:
>
> This commit adds documentation for the BPF_MAP_TYPE_ARRAY including
> kernel version introduced, usage and examples.
> It also documents BPF_MAP_TYPE_PERCPU_ARRAY since this is similar.
>
> Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
> ---
>  Documentation/bpf/map_array.rst | 150 ++++++++++++++++++++++++++++++++
>  1 file changed, 150 insertions(+)
>  create mode 100644 Documentation/bpf/map_array.rst
>
> diff --git a/Documentation/bpf/map_array.rst b/Documentation/bpf/map_array.rst
> new file mode 100644
> index 000000000000..f9eb5473a240
> --- /dev/null
> +++ b/Documentation/bpf/map_array.rst
> @@ -0,0 +1,150 @@
> +.. SPDX-License-Identifier: GPL-2.0-only
> +.. Copyright (C) 2021 Red Hat, Inc.
> +
> +================================================
> +BPF_MAP_TYPE_ARRAY and BPF_MAP_TYPE_PERCPU_ARRAY
> +================================================
> +
> +.. note:: ``BPF_MAP_TYPE_ARRAY`` was introduced in Kernel version 3.19 and ``BPF_MAP_TYPE_PERCPU_ARRAY`` in version 4.6
> +
> +``BPF_MAP_TYPE_ARRAY`` and ``BPF_MAP_TYPE_PERCPU_ARRAY`` provide generic array storage.
> +The key type is an unsigned 32-bit integer (4 bytes) and the map is of constant size.
> +All array elements are pre-allocated and zero initialized when created.
> +``BPF_MAP_TYPE_PERCPU_ARRAY`` uses a different memory region for each CPU whereas
> +``BPF_MAP_TYPE_ARRAY`` uses the same memory region.
> +The maximum size of an array, defined in max_entries, is limited to 2^32.
> +The value stored can be of any size, however, small values will be rounded up to 8 bytes.
> +
> +Usage
> +=====
> +
> +Array elements can be retrieved using the ``bpf_map_lookup_elem()`` helper.
> +This helper returns a pointer into the array element, so to avoid data races with userspace reading the value,
> +the user must use primitives like ``__sync_fetch_and_add()`` when updating the value in-place.
> +Access from userspace uses the libbpf API of the same name.
> +
> +Array elements can also be added using the ``bpf_map_update_elem()`` helper or libbpf API.
> +
> +Since the array is of constant size, ``bpf_map_delete_elem()`` is not supported.
> +To clear an array element, you may use ``bpf_map_update_eleme()`` to insert a zero value to that index.
> +
> +Values stored in ``BPF_MAP_TYPE_ARRAY`` can be accessed by multiple programs across different CPUs.
> +To restrict storage to a single CPU, you may use a ``BPF_MAP_TYPE_PERCPU_ARRAY``.
> +Since Kernel version 5.1, the BPF infrastructure provides ``struct bpf_spin_lock`` to synchronize access.
> +

It would be good to also mention BPF_F_MMAPABLE flag and ability to
mmap() contents of BPF_MAP_TYPE_ARRAY created with such a flag. We
need to double-check, but there might be also a restriction to have
value_size be a multiple of page size in such case, we need to consult
the code.


> +```bpf_map_get_next_key()`` can be used to iterate over array values.
> +
> +Examples
> +========
> +
> +Please see the `bpf/samples`_ directory for functional examples.

Let's point to tools/testing/selftests/bpf for functional examples.
It's much more complete and more actively maintained and tested.

> +This sample code simply demonstrates the API.
> +
> +.. section links
> +.. _bpf/samples:
> +    https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/samples/bpf/
> +
> +Kernel
> +------
> +
> +.. code-block:: c
> +
> +    struct {
> +        __uint(type, BPF_MAP_TYPE_ARRAY);
> +        __type(key, u32);
> +        __type(value, long);
> +        __uint(max_entries, 256);
> +    } my_map SEC(".maps");
> +
> +    int bpf_prog(struct __sk_buff *skb)
> +    {
> +        int index = load_byte(skb, ETH_HLEN + offsetof(struct iphdr, protocol));
> +        long *value;
> +
> +        if (skb->pkt_type != PACKET_OUTGOING)
> +            return 0;
> +
> +        value = bpf_map_lookup_elem(&my_map, &index);
> +        if (value)
> +            __sync_fetch_and_add(value, skb->len);
> +
> +        return 0;
> +    }
> +
> +Userspace
> +---------
> +
> +BPF_MAP_TYPE_ARRAY
> +~~~~~~~~~~~~~~~~~~
> +
> +.. code-block:: c
> +
> +    #include <assert.h>
> +    #include <bpf/libbpf.h>
> +    #include <bpf/bpf.h>
> +
> +    int main(int argc, char **argv)
> +        {

something is off with this curly brace

> +
> +            int fd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(__u32), sizeof(long), 256, 0);
> +            if (fd < 0)
> +            return -1;

return not indented

and the example itself doesn't follow kernel style guide with
C89-style variable block separate from the rest of the code. Would be
good to stick to that in kernel documentation.

> +
> +            // fill the map with values from 0-255
> +            for(__u32 i=0; i < 256 ; i++) {

__u32 inside the for isn't C89-compatible either. Also C++-style
comment above isn't allowed.

> +                long v = i;
> +                bpf_map_update_elem(fd, &i, &v, BPF_ANY);

makes sense to do error checking for update and lookup

> +            }
> +
> +            __u32 index = 42;
> +            long value;
> +            bpf_map_lookup_elem(fd, &index, &value);
> +            assert(value == 42);
> +            return 0;
> +    }
> +
> +

[...]

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2021-11-23  3:54 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-22 17:19 [PATCH bpf-next 0/2] bpf, docs: Document BPF_MAP_TYPE_ARRAY Dave Tucker
2021-11-22 17:19 ` [PATCH bpf-next 1/2] bpf, docs: add kernel version to map_cgroup_storage Dave Tucker
2021-11-22 17:19 ` [PATCH bpf-next 2/2] bpf, docs: document BPF_MAP_TYPE_ARRAY Dave Tucker
2021-11-22 19:15   ` Jonathan Corbet
2021-11-22 19:33     ` Dave Tucker
2021-11-22 20:33       ` Jonathan Corbet
2021-11-23  3:53   ` Andrii Nakryiko

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