bpf: offload: allow offloaded programs to use perf event arrays
authorJakub Kicinski <jakub.kicinski@netronome.com>
Fri, 4 May 2018 01:37:08 +0000 (18:37 -0700)
committerDaniel Borkmann <daniel@iogearbox.net>
Fri, 4 May 2018 21:41:03 +0000 (23:41 +0200)
BPF_MAP_TYPE_PERF_EVENT_ARRAY is special as far as offload goes.
The map only holds glue to perf ring, not actual data.  Allow
non-offloaded perf event arrays to be used in offloaded programs.
Offload driver can extract the events from HW and put them in
the map for user space to retrieve.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com>
Reviewed-by: Jiong Wang <jiong.wang@netronome.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
include/linux/bpf.h
kernel/bpf/offload.c

index 0e00a13ff01b09e771fe25456b0c1057290a1eab..321969da67b77776ed0d27027668b5baffebdb0c 100644 (file)
@@ -110,6 +110,11 @@ static inline struct bpf_offloaded_map *map_to_offmap(struct bpf_map *map)
        return container_of(map, struct bpf_offloaded_map, map);
 }
 
+static inline bool bpf_map_offload_neutral(const struct bpf_map *map)
+{
+       return map->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY;
+}
+
 static inline bool bpf_map_support_seq_show(const struct bpf_map *map)
 {
        return map->ops->map_seq_show_elem && map->ops->map_check_btf;
index c9401075b58c842d7a6e239d51a25283d1f53b3f..ac747d5cf7c68b196c3e37a1c58a9e23bc5fd786 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Netronome Systems, Inc.
+ * Copyright (C) 2017-2018 Netronome Systems, Inc.
  *
  * This software is licensed under the GNU General License Version 2,
  * June 1991 as shown in the file COPYING in the top-level directory of this
@@ -474,8 +474,10 @@ bool bpf_offload_dev_match(struct bpf_prog *prog, struct bpf_map *map)
        struct bpf_prog_offload *offload;
        bool ret;
 
-       if (!bpf_prog_is_dev_bound(prog->aux) || !bpf_map_is_dev_bound(map))
+       if (!bpf_prog_is_dev_bound(prog->aux))
                return false;
+       if (!bpf_map_is_dev_bound(map))
+               return bpf_map_offload_neutral(map);
 
        down_read(&bpf_devs_lock);
        offload = prog->aux->offload;