| From 9ad840a2740055993150336155de08876759546f Mon Sep 17 00:00:00 2001 |
| From: Paolo Abeni <pabeni@redhat.com> |
| Date: Mon, 21 Jan 2019 12:36:12 +0100 |
| Subject: bpftool: fix percpu maps updating |
| |
| [ Upstream commit b0ca5ecb8e2279d706261f525f1bd0ba9e3fe800 ] |
| |
| When updating a percpu map, bpftool currently copies the provided |
| value only into the first per CPU copy of the specified value, |
| all others instances are left zeroed. |
| |
| This change explicitly copies the user-provided bytes to all the |
| per CPU instances, keeping the sub-command syntax unchanged. |
| |
| v2 -> v3: |
| - drop unused argument, as per Quentin's suggestion |
| v1 -> v2: |
| - rename the helper as per Quentin's suggestion |
| |
| Fixes: 71bb428fe2c1 ("tools: bpf: add bpftool") |
| Signed-off-by: Paolo Abeni <pabeni@redhat.com> |
| Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com> |
| Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| tools/bpf/bpftool/map.c | 16 ++++++++++++++++ |
| 1 file changed, 16 insertions(+) |
| |
| diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c |
| index b455930a3eaf..ec73d83d0d31 100644 |
| --- a/tools/bpf/bpftool/map.c |
| +++ b/tools/bpf/bpftool/map.c |
| @@ -370,6 +370,20 @@ static char **parse_bytes(char **argv, const char *name, unsigned char *val, |
| return argv + i; |
| } |
| |
| +/* on per cpu maps we must copy the provided value on all value instances */ |
| +static void fill_per_cpu_value(struct bpf_map_info *info, void *value) |
| +{ |
| + unsigned int i, n, step; |
| + |
| + if (!map_is_per_cpu(info->type)) |
| + return; |
| + |
| + n = get_possible_cpus(); |
| + step = round_up(info->value_size, 8); |
| + for (i = 1; i < n; i++) |
| + memcpy(value + i * step, value, info->value_size); |
| +} |
| + |
| static int parse_elem(char **argv, struct bpf_map_info *info, |
| void *key, void *value, __u32 key_size, __u32 value_size, |
| __u32 *flags, __u32 **value_fd) |
| @@ -449,6 +463,8 @@ static int parse_elem(char **argv, struct bpf_map_info *info, |
| argv = parse_bytes(argv, "value", value, value_size); |
| if (!argv) |
| return -1; |
| + |
| + fill_per_cpu_value(info, value); |
| } |
| |
| return parse_elem(argv, info, key, NULL, key_size, value_size, |
| -- |
| 2.19.1 |
| |