Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1946087AbbGQKqy (ORCPT ); Fri, 17 Jul 2015 06:46:54 -0400 Received: from szxga02-in.huawei.com ([119.145.14.65]:32601 "EHLO szxga02-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757746AbbGQKpW (ORCPT ); Fri, 17 Jul 2015 06:45:22 -0400 From: kaixu xia To: , , , , , , CC: , , , , Subject: [RFC PATCH 2/6] bpf: Add function map->ops->map_traverse_elem() to traverse map elems Date: Fri, 17 Jul 2015 18:43:32 +0800 Message-ID: <1437129816-13176-3-git-send-email-xiakaixu@huawei.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1437129816-13176-1-git-send-email-xiakaixu@huawei.com> References: <1437129816-13176-1-git-send-email-xiakaixu@huawei.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.110.52.33] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3635 Lines: 120 Sometimes we want to traverse the map elements and make use of the map value one by one. So add new function map->ops->map_traverse_elem() to traverse map elements. Signed-off-by: kaixu xia --- include/linux/bpf.h | 3 +++ kernel/bpf/arraymap.c | 17 +++++++++++++++++ kernel/bpf/hashtab.c | 27 +++++++++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 2634a25..f593199 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -13,6 +13,8 @@ struct bpf_map; +typedef int (*bpf_map_traverse_callback)(void *value); + /* map is generic key/value storage optionally accesible by eBPF programs */ struct bpf_map_ops { /* funcs callable from userspace (via syscall) */ @@ -24,6 +26,7 @@ struct bpf_map_ops { void *(*map_lookup_elem)(struct bpf_map *map, void *key); int (*map_update_elem)(struct bpf_map *map, void *key, void *value, u64 flags); int (*map_delete_elem)(struct bpf_map *map, void *key); + int (*map_traverse_elem)(bpf_map_traverse_callback func, struct bpf_map *map); }; struct bpf_map { diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c index cb31229..3306916 100644 --- a/kernel/bpf/arraymap.c +++ b/kernel/bpf/arraymap.c @@ -114,6 +114,22 @@ static int array_map_delete_elem(struct bpf_map *map, void *key) return -EINVAL; } +static int array_map_traverse_elem(bpf_map_traverse_callback func, struct bpf_map *map) +{ + struct bpf_array *array = container_of(map, struct bpf_array, map); + void *value; + int i; + + for(i = 0; i < array->map.max_entries; i++) { + value = array->value + array->elem_size * i; + + if (func(value) < 0) + return -EINVAL; + } + + return 0; +} + /* Called when map->refcnt goes to zero, either from workqueue or from syscall */ static void array_map_free(struct bpf_map *map) { @@ -136,6 +152,7 @@ static const struct bpf_map_ops array_ops = { .map_lookup_elem = array_map_lookup_elem, .map_update_elem = array_map_update_elem, .map_delete_elem = array_map_delete_elem, + .map_traverse_elem = array_map_traverse_elem, }; static struct bpf_map_type_list array_type __read_mostly = { diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c index 83c209d..fa7887e 100644 --- a/kernel/bpf/hashtab.c +++ b/kernel/bpf/hashtab.c @@ -325,6 +325,32 @@ static void delete_all_elements(struct bpf_htab *htab) } } +static int htab_map_traverse_elem(bpf_map_traverse_callback func, struct bpf_map *map) +{ + struct bpf_htab *htab = container_of(map, struct bpf_htab, map); + struct hlist_head *head; + struct htab_elem *l; + u32 key_size; + void *value; + int i; + + key_size = map->key_size; + + for (i = 0; i < htab->n_buckets; i++) { + head = select_bucket(htab, i); + + hlist_for_each_entry_rcu(l, head, hash_node) { + value = l->key + round_up(key_size, 8); + + if (func(value) < 0) + return -EINVAL; + } + + } + + return 0; +} + /* Called when map->refcnt goes to zero, either from workqueue or from syscall */ static void htab_map_free(struct bpf_map *map) { @@ -352,6 +378,7 @@ static const struct bpf_map_ops htab_ops = { .map_lookup_elem = htab_map_lookup_elem, .map_update_elem = htab_map_update_elem, .map_delete_elem = htab_map_delete_elem, + .map_traverse_elem = htab_map_traverse_elem, }; static struct bpf_map_type_list htab_type __read_mostly = { -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/