[RFC PATCH 1/6] bpf: Add new flags that specify the value type stored in map

kaixu xia
2015-07-17T10:45:22Z

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 <xiakaixu@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