The pointer to struct perf_event will be stored in map. So
add new flag BPF_MAP_FLAG_PERF_EVENT that specify the value
type stored in map. The high 8-bit of attr->map_type is used
to contain the new flags.

Signed-off-by: kaixu xia <xiaka...@huawei.com>
---
 include/linux/bpf.h      |    1 +
 include/uapi/linux/bpf.h |   14 ++++++++++++++
 kernel/bpf/syscall.c     |   13 +++++++++++--
 3 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 4383476..2634a25 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -34,6 +34,7 @@ struct bpf_map {
        u32 max_entries;
        const struct bpf_map_ops *ops;
        struct work_struct work;
+       unsigned int flags;
 };
 
 struct bpf_map_type_list {
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 29ef6f9..47d8516 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -131,6 +131,20 @@ enum bpf_prog_type {
 #define BPF_NOEXIST    1 /* create new element if it didn't exist */
 #define BPF_EXIST      2 /* update existing element */
 
+/* flags for BPF_MAP_CREATE command */
+enum {
+       BPF_PERF_EVENT = 0,
+       __NR_FLAG_BITS,
+};
+
+#define MAP_FLAG_BITS  __NR_FLAG_BITS
+#define MAP_FLAG_SHIFT (32 - MAP_FLAG_BITS)
+#define MAP_FLAG_MASK  (~0U << MAP_FLAG_SHIFT)
+
+#define BPF_FLAG_PERF_EVENT_BIT        (32 - BPF_PERF_EVENT -1)
+
+#define BPF_MAP_FLAG_PERF_EVENT        (1 << BPF_FLAG_PERF_EVENT_BIT) /* 
create a specific map for perf_event */
+
 union bpf_attr {
        struct { /* anonymous struct used by BPF_MAP_CREATE command */
                __u32   map_type;       /* one of enum bpf_map_type */
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index a1b14d1..4c2d9e6 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -20,7 +20,7 @@
 
 static LIST_HEAD(bpf_map_types);
 
-static struct bpf_map *find_and_alloc_map(union bpf_attr *attr)
+static struct bpf_map *find_and_alloc_map(union bpf_attr *attr, unsigned int 
flags)
 {
        struct bpf_map_type_list *tl;
        struct bpf_map *map;
@@ -32,6 +32,7 @@ static struct bpf_map *find_and_alloc_map(union bpf_attr 
*attr)
                                return map;
                        map->ops = tl->ops;
                        map->map_type = attr->map_type;
+                       map->flags = flags;
                        return map;
                }
        }
@@ -95,14 +96,22 @@ static const struct file_operations bpf_map_fops = {
 static int map_create(union bpf_attr *attr)
 {
        struct bpf_map *map;
+       unsigned int flags;
        int err;
 
        err = CHECK_ATTR(BPF_MAP_CREATE);
        if (err)
                return -EINVAL;
 
+       flags = attr->map_type & MAP_FLAG_MASK;
+       attr->map_type &= ~MAP_FLAG_MASK;
+
+       /* check if the map->value_size is suitable when creating PMU map*/
+       if ((flags & BPF_MAP_FLAG_PERF_EVENT) && (attr->value_size != 
sizeof(void *)))
+               return -EINVAL;
+
        /* find map type and init map: hashtable vs rbtree vs bloom vs ... */
-       map = find_and_alloc_map(attr);
+       map = find_and_alloc_map(attr, flags);
        if (IS_ERR(map))
                return PTR_ERR(map);
 
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to