From: Donald Hunter <donald.hunter@gmail.com>
To: sdf@google.com
Cc: bpf@vger.kernel.org, linux-doc@vger.kernel.org,
Jonathan Corbet <corbet@lwn.net>
Subject: Re: [PATCH] bpf, docs: document BPF_MAP_TYPE_HASH and variants
Date: Thu, 14 Jul 2022 23:20:23 +0100 [thread overview]
Message-ID: <m2y1wv2v6g.fsf@gmail.com> (raw)
In-Reply-To: <Ys9VhwanEB/T8/Ue@google.com> (sdf@google.com's message of "Wed, 13 Jul 2022 16:30:15 -0700")
sdf@google.com writes:
>> +``BPF_MAP_TYPE_HASH`` and ``BPF_MAP_TYPE_PERCPU_HASH`` provide general
>> +purpose hash map storage. Both the key and the value can be structs,
>> +allowing for composite keys and values. The maximum number of entries is
>> +defined in max_entries and is limited to 2^32. The kernel is responsible
>
> Do we really need to mention 2^32 limit here? It really depends on
> the key/value sizes, right?
>
> Instead, might be worth talking about how/when this memory is allocated and
> mention BPF_F_NO_PREALLOC?
Good suggestion. I'll incorporate this into v2.
>> +.. c:function::
>> + long bpf_map_update_elem(struct bpf_map *map, const void *key, const void *value, u60
>> flags)
>
> s/u60/u64/
Good catch, thanks.
>> +Kernel
>> +------
>> +
>> +.. code-block:: c
>> +
>> + #include <linux/bpf.h>
>> + #include <bpf/bpf_helpers.h>
>> +
>> + struct key {
>> + __u32 srcip;
>> + };
>> +
>> + struct value {
>> + __u64 packets;
>> + __u64 bytes;
>> + };
>> +
>> + struct {
>> + __uint(type, BPF_MAP_TYPE_LRU_HASH);
>> + __uint(max_entries, 32);
>> + __type(key, struct key);
>> + __type(value, struct value);
>> + } packet_stats SEC(".maps");
>> +
>> + static inline void count_by_srcip(__u32 srcip, int bytes)
>> + {
>> + struct key key = {
>> + .srcip = srcip
>> + };
>> + struct value *value = bpf_map_lookup_elem(&packet_stats, &key);
>> + if (value) {
>> + __sync_fetch_and_add(&value->packets, 1);
>> + __sync_fetch_and_add(&value->bytes, bytes);
>> + } else {
>> + struct value newval = { 1, bytes };
>> + bpf_map_update_elem(&packet_stats, &key, &newval, BPF_NOEXIST);
>> + }
>> + }
>> +
>> +Userspace
>> +---------
>> +
>> +.. code-block:: c
>> +
>> + #include <bpf/libbpf.h>
>> + #include <bpf/bpf.h>
>> +
>> + static void print_values(int map_fd)
>> + {
>> + struct key *cur_key = NULL;
>> + struct key next_key;
>> + int next;
>> + do {
>> + next = bpf_map_get_next_key(stats_fd, cur_key, &next_key);
>> + if (next == -ENOENT)
>> + break;
>> + if (next < 0) {
>> + fprintf(stderr, "bpf_map_get_next_key %d returned %s\n",
>> stats_fd, strerror(-next));
>> + break;
>> + }
>> +
>> + struct in_addr src_addr = {
>> + .s_addr = next_key.srcip
>> + };
>> + char *src_ip = inet_ntoa(src_addr);
>> +
>> + struct value value;
>> + int ret = bpf_map_lookup_elem(stats_fd, &next_key, &value);
>> + if (ret < 0) {
>> + fprintf(stderr, "Failed to lookup elem with key %s: %s\n",
>> src_ip, strerror(-ret));
>> + break;
>> + }
>> + printf("%s: %lld packets, %lld bytes\n", src_ip, value.packets,
>> value.bytes);
>> + cur_key = &next_key;
>> + } while (next == 0);
>> + }
>
> Instead of adding c code, maybe add pointers to specific file within
> tools/testing/selftests/bpf/progs ? That's what we've done for
> prog_cgroup_sockopt; the actual tests are a bit more maintained than
> the doc :-)
I tried to cut the examples to the minimum that was still complete
enough to show use in context. Happy to try cutting the examples down to
a sequence of shorter snippets and and links to samples/bpf and
tools/testing/selftests/bpf/progs. I'll need to reference samples/bpf
because there are no bpf_map_get_next_key examples in
tools/testing/selftests/bpf/progs.
Donald.
next prev parent reply other threads:[~2022-07-14 22:26 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-07-13 21:16 [PATCH] bpf, docs: document BPF_MAP_TYPE_HASH and variants Donald Hunter
2022-07-13 23:30 ` sdf
2022-07-14 22:20 ` Donald Hunter [this message]
2022-07-14 1:12 ` Bagas Sanjaya
2022-07-14 5:51 ` Daniel Müller
2022-07-14 8:10 ` Bagas Sanjaya
2022-07-14 21:53 ` Donald Hunter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=m2y1wv2v6g.fsf@gmail.com \
--to=donald.hunter@gmail.com \
--cc=bpf@vger.kernel.org \
--cc=corbet@lwn.net \
--cc=linux-doc@vger.kernel.org \
--cc=sdf@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.