On Fri, Jul 5, 2019 at 11:14 AM Toke Høiland-Jørgensen <[email protected]> wrote:
>
> From: Toke Høiland-Jørgensen <[email protected]>
>
> A common pattern when using xdp_redirect_map() is to create a device map
> where the lookup key is simply ifindex. Because device maps are arrays,
> this leaves holes in the map, and the map has to be sized to fit the
> largest ifindex, regardless of how many devices actually are actually
> needed in the map.
>
> This patch adds a second type of device map where the key is looked up
> using a hashmap, instead of being used as an array index. This allows maps
> to be densely packed, so they can be smaller.
>
> Signed-off-by: Toke Høiland-Jørgensen <[email protected]>
> ---
> include/linux/bpf.h | 7 +
> include/linux/bpf_types.h | 1
> include/trace/events/xdp.h | 3
> include/uapi/linux/bpf.h | 7 +
> kernel/bpf/devmap.c | 192
> +++++++++++++++++++++++++++++++
> kernel/bpf/verifier.c | 2
> net/core/filter.c | 9 +
> tools/bpf/bpftool/map.c | 1
> tools/include/uapi/linux/bpf.h | 7 +
> tools/lib/bpf/libbpf_probes.c | 1
> tools/testing/selftests/bpf/test_maps.c | 16 +++
> 11 files changed, 237 insertions(+), 9 deletions(-)
Could you break this patch into multiple commits for easy backporting
and easy syncing to libbpf repo?
For example, you can break it into 4 patches:
. kernel patch
. sync uapi bpf.h
. tools/lib/bpf/libbpf_probes.c
. other tools changes.
>
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index bfdb54dd2ad1..f9a506147c8a 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -713,6 +713,7 @@ struct xdp_buff;
> struct sk_buff;
>
> struct bpf_dtab_netdev *__dev_map_lookup_elem(struct bpf_map *map, u32 key);
> +struct bpf_dtab_netdev *__dev_map_hash_lookup_elem(struct bpf_map *map, u32
> key);
> void __dev_map_flush(struct bpf_map *map);
> int dev_map_enqueue(struct bpf_dtab_netdev *dst, struct xdp_buff *xdp,
> struct net_device *dev_rx);
> @@ -799,6 +800,12 @@ static inline struct net_device
> *__dev_map_lookup_elem(struct bpf_map *map,
> return NULL;
> }
>
> +static inline struct net_device *__dev_map_hash_lookup_elem(struct bpf_map
> *map,
> + u32 key)
> +{
> + return NULL;
> +}
> +
> static inline void __dev_map_flush(struct bpf_map *map)
> {
> }
> diff --git a/include/linux/bpf_types.h b/include/linux/bpf_types.h
> index eec5aeeeaf92..36a9c2325176 100644
> --- a/include/linux/bpf_types.h
> +++ b/include/linux/bpf_types.h
> @@ -62,6 +62,7 @@ BPF_MAP_TYPE(BPF_MAP_TYPE_ARRAY_OF_MAPS,
> array_of_maps_map_ops)
> BPF_MAP_TYPE(BPF_MAP_TYPE_HASH_OF_MAPS, htab_of_maps_map_ops)
> #ifdef CONFIG_NET
> BPF_MAP_TYPE(BPF_MAP_TYPE_DEVMAP, dev_map_ops)
> +BPF_MAP_TYPE(BPF_MAP_TYPE_DEVMAP_HASH, dev_map_hash_ops)
> BPF_MAP_TYPE(BPF_MAP_TYPE_SK_STORAGE, sk_storage_map_ops)
> #if defined(CONFIG_BPF_STREAM_PARSER)
> BPF_MAP_TYPE(BPF_MAP_TYPE_SOCKMAP, sock_map_ops)
[...]