From patchwork Wed Jul 24 16:57:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Vazquez X-Patchwork-Id: 1136419 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: incoming-bpf@patchwork.ozlabs.org Delivered-To: patchwork-incoming-bpf@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=bpf-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="kAKMDoDj"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45v1kv5crYz9sLt for ; Thu, 25 Jul 2019 02:58:31 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728376AbfGXQ6a (ORCPT ); Wed, 24 Jul 2019 12:58:30 -0400 Received: from mail-qt1-f202.google.com ([209.85.160.202]:42082 "EHLO mail-qt1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728360AbfGXQ6a (ORCPT ); Wed, 24 Jul 2019 12:58:30 -0400 Received: by mail-qt1-f202.google.com with SMTP id x1so42109005qts.9 for ; Wed, 24 Jul 2019 09:58:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=aJbPYrkSLi1J83pO68ABpJTFWg54SVdLxJdC1FsJCN0=; b=kAKMDoDjy/GQB+zG684OCW6wlWx3U7guijvEtLmQG1ZO+fg+9B4lwuuHZ1YCxFYbey aIILqCEbkhNMH/1BsaX8Cxra7NcE87v+SsbjD5OpcBIbmmWlRz3uXMB8+C45RrrUOw9h xvhQNp4wx4gnPQZooqPeuiaeCNaLX3GT0rnAX4NteS3vrzGcdqIfpUxooLnXV3Z9m9HE jIjNzyssLbdVIfwJJ/JdhgFI7pcegQgx94lyB5+p3zkgH3rbyskSznAv/K0kwwmiAYgW K4/jqLxEv81Y0oEZXKVf8AxZ+dEGvNEjviOpTqygmzBCY5wRY4ccqdr4SUdcY3UI0ork IcWg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=aJbPYrkSLi1J83pO68ABpJTFWg54SVdLxJdC1FsJCN0=; b=FseCBm5iuzILngL0CyH9vIAfJsI/LlXx+j0kEAaKQ9y+0M2K1PV9svrfeMroOA+igx qtSWuE+A9Bw221zu1tJfH4Hng2GORvoGit1Q5kNRj1ff3Ml4OHPyDt4NmEdPGUGIjUVP +RkJPOHjA/ElFFTYLNiwMMA03lM1bLVr4w5YUn08N9FNHO5pWZ7UkOYGfhb5FlJYmXLz 4SiWLCw5u+sAhRq9D5JSXwnnqTv8Rnnc3jzsrmbTBy5jg3T0EOwZcnicGgz/6gwwX5yO asVVBk/4RbU2MFp08dKEcauNJjX4L/LptDQU8faTkLLAib2ldtHLgydLvhcvQeQWNBIS IvCA== X-Gm-Message-State: APjAAAWxlpD5INGwfS0pPww/IseTHLdR+cdK4u1XTJCcYurv3je9PiF8 TdT6D3WhROuLQfyHcdcXbja0Atu5MzKp X-Google-Smtp-Source: APXvYqxgMXcuo8TFQqJKT944SW2wJ4aNvRsr895+1Vy1k+9oaPw7OAsiO1NiJ9psa1RBVkritBGPVRb87m7d X-Received: by 2002:a0c:afbd:: with SMTP id s58mr60379022qvc.217.1563987508719; Wed, 24 Jul 2019 09:58:28 -0700 (PDT) Date: Wed, 24 Jul 2019 09:57:58 -0700 In-Reply-To: <20190724165803.87470-1-brianvv@google.com> Message-Id: <20190724165803.87470-2-brianvv@google.com> Mime-Version: 1.0 References: <20190724165803.87470-1-brianvv@google.com> X-Mailer: git-send-email 2.22.0.657.g960e92d24f-goog Subject: [PATCH bpf-next 1/6] bpf: add bpf_map_value_size and bp_map_copy_value helper functions From: Brian Vazquez To: Brian Vazquez , Alexei Starovoitov , Daniel Borkmann , "David S . Miller" Cc: Stanislav Fomichev , Willem de Bruijn , Petar Penkov , linux-kernel@vger.kernel.org, netdev@vger.kernel.org, bpf@vger.kernel.org, Brian Vazquez Sender: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org Move reusable code from map_lookup_elem to helper functions to avoid code duplication in kernel/bpf/syscall.c Suggested-by: Stanislav Fomichev Signed-off-by: Brian Vazquez Acked-by: Song Liu --- kernel/bpf/syscall.c | 134 +++++++++++++++++++++++-------------------- 1 file changed, 73 insertions(+), 61 deletions(-) diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 5d141f16f6fa9..86cdc2f7bb56e 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -126,6 +126,76 @@ static struct bpf_map *find_and_alloc_map(union bpf_attr *attr) return map; } +static u32 bpf_map_value_size(struct bpf_map *map) +{ + if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH || + map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH || + map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY || + map->map_type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE) + return round_up(map->value_size, 8) * num_possible_cpus(); + else if (IS_FD_MAP(map)) + return sizeof(u32); + else + return map->value_size; +} + +static int bpf_map_copy_value(struct bpf_map *map, void *key, void *value, + __u64 flags) +{ + void *ptr; + int err; + + if (bpf_map_is_dev_bound(map)) + return bpf_map_offload_lookup_elem(map, key, value); + + preempt_disable(); + this_cpu_inc(bpf_prog_active); + if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH || + map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH) { + err = bpf_percpu_hash_copy(map, key, value); + } else if (map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY) { + err = bpf_percpu_array_copy(map, key, value); + } else if (map->map_type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE) { + err = bpf_percpu_cgroup_storage_copy(map, key, value); + } else if (map->map_type == BPF_MAP_TYPE_STACK_TRACE) { + err = bpf_stackmap_copy(map, key, value); + } else if (IS_FD_ARRAY(map)) { + err = bpf_fd_array_map_lookup_elem(map, key, value); + } else if (IS_FD_HASH(map)) { + err = bpf_fd_htab_map_lookup_elem(map, key, value); + } else if (map->map_type == BPF_MAP_TYPE_REUSEPORT_SOCKARRAY) { + err = bpf_fd_reuseport_array_lookup_elem(map, key, value); + } else if (map->map_type == BPF_MAP_TYPE_QUEUE || + map->map_type == BPF_MAP_TYPE_STACK) { + err = map->ops->map_peek_elem(map, value); + } else { + rcu_read_lock(); + if (map->ops->map_lookup_elem_sys_only) + ptr = map->ops->map_lookup_elem_sys_only(map, key); + else + ptr = map->ops->map_lookup_elem(map, key); + if (IS_ERR(ptr)) { + err = PTR_ERR(ptr); + } else if (!ptr) { + err = -ENOENT; + } else { + err = 0; + if (flags & BPF_F_LOCK) + /* lock 'ptr' and copy everything but lock */ + copy_map_value_locked(map, value, ptr, true); + else + copy_map_value(map, value, ptr); + /* mask lock, since value wasn't zero inited */ + check_and_init_map_lock(map, value); + } + rcu_read_unlock(); + } + this_cpu_dec(bpf_prog_active); + preempt_enable(); + + return err; +} + void *bpf_map_area_alloc(size_t size, int numa_node) { /* We really just want to fail instead of triggering OOM killer @@ -729,7 +799,7 @@ static int map_lookup_elem(union bpf_attr *attr) void __user *uvalue = u64_to_user_ptr(attr->value); int ufd = attr->map_fd; struct bpf_map *map; - void *key, *value, *ptr; + void *key, *value; u32 value_size; struct fd f; int err; @@ -761,72 +831,14 @@ static int map_lookup_elem(union bpf_attr *attr) goto err_put; } - if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH || - map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH || - map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY || - map->map_type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE) - value_size = round_up(map->value_size, 8) * num_possible_cpus(); - else if (IS_FD_MAP(map)) - value_size = sizeof(u32); - else - value_size = map->value_size; + value_size = bpf_map_value_size(map); err = -ENOMEM; value = kmalloc(value_size, GFP_USER | __GFP_NOWARN); if (!value) goto free_key; - if (bpf_map_is_dev_bound(map)) { - err = bpf_map_offload_lookup_elem(map, key, value); - goto done; - } - - preempt_disable(); - this_cpu_inc(bpf_prog_active); - if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH || - map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH) { - err = bpf_percpu_hash_copy(map, key, value); - } else if (map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY) { - err = bpf_percpu_array_copy(map, key, value); - } else if (map->map_type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE) { - err = bpf_percpu_cgroup_storage_copy(map, key, value); - } else if (map->map_type == BPF_MAP_TYPE_STACK_TRACE) { - err = bpf_stackmap_copy(map, key, value); - } else if (IS_FD_ARRAY(map)) { - err = bpf_fd_array_map_lookup_elem(map, key, value); - } else if (IS_FD_HASH(map)) { - err = bpf_fd_htab_map_lookup_elem(map, key, value); - } else if (map->map_type == BPF_MAP_TYPE_REUSEPORT_SOCKARRAY) { - err = bpf_fd_reuseport_array_lookup_elem(map, key, value); - } else if (map->map_type == BPF_MAP_TYPE_QUEUE || - map->map_type == BPF_MAP_TYPE_STACK) { - err = map->ops->map_peek_elem(map, value); - } else { - rcu_read_lock(); - if (map->ops->map_lookup_elem_sys_only) - ptr = map->ops->map_lookup_elem_sys_only(map, key); - else - ptr = map->ops->map_lookup_elem(map, key); - if (IS_ERR(ptr)) { - err = PTR_ERR(ptr); - } else if (!ptr) { - err = -ENOENT; - } else { - err = 0; - if (attr->flags & BPF_F_LOCK) - /* lock 'ptr' and copy everything but lock */ - copy_map_value_locked(map, value, ptr, true); - else - copy_map_value(map, value, ptr); - /* mask lock, since value wasn't zero inited */ - check_and_init_map_lock(map, value); - } - rcu_read_unlock(); - } - this_cpu_dec(bpf_prog_active); - preempt_enable(); - -done: + err = bpf_map_copy_value(map, key, value, attr->flags); if (err) goto free_value; From patchwork Wed Jul 24 16:57:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Vazquez X-Patchwork-Id: 1136420 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="X9Uxl1pQ"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45v1kx6kShz9sLt for ; Thu, 25 Jul 2019 02:58:33 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387616AbfGXQ6c (ORCPT ); Wed, 24 Jul 2019 12:58:32 -0400 Received: from mail-pg1-f202.google.com ([209.85.215.202]:35749 "EHLO mail-pg1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728414AbfGXQ6c (ORCPT ); Wed, 24 Jul 2019 12:58:32 -0400 Received: by mail-pg1-f202.google.com with SMTP id g2so7416403pgj.2 for ; Wed, 24 Jul 2019 09:58:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=JhiTFKPdgUPiq/3CLngeqY1pwECv2NMtE4FVnY5brWc=; b=X9Uxl1pQtqKu/ZuT+YDSx8UQSm3E8s/yC/XufSX18tbohg9rSekknJLAe9xHgjbbx7 D2FPWzlMHRyfhSABm7bsrH1CDV39nx5g/pZXfNSJDmv6KOKaV1ytCIuoTdonm84Xifu3 UmGhHpNPjWrLeSkfYgEksG+xolx7KSzitNaroJzNkljJjObyTRTnJh7FP9h1W6X4cLQD 6HNOMNCIQbMKTbsGenAS/UIDF2nr6dFP3BQumesprJGlCr7QRL4hHTOH/PLvi9b97IAE N22di3vtH1Es+HlUbMQnVhUY+utIpvPyX8xURkbBfAUs6OMTRGWhjEvDR0a2oXqSw+wx 7hkQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=JhiTFKPdgUPiq/3CLngeqY1pwECv2NMtE4FVnY5brWc=; b=RDZdyjGUJNFmaGGgtMmYifcAsouenlmE8b+pf0DHH1bId8vmCUokxZqVXL2X3UNFdi 71nS5PyO/wdAFWeW6tdOc/RUzpSjn50sGPqk1kQtdMUu//jVsj9dVpKpHeucaylTxdsB NEWByRIFDFcXHnYKSkTQaj86zzLV0FClUiKHm5OzbxsyB7HMPKlafBbaQCjnPPdAgFo/ xVQDV58eYJS3b/fPF3tvU6HQSSUcldnkCo6GRlv2nEuz0B0Oa7ditwuLwAlmk7fnuas/ rH86+1MPjqra7UycdbbHJOof91DV5bEZqi94rN6EuFSic6gb3yHXELfffz7v2tPg2CIh 5Wig== X-Gm-Message-State: APjAAAVZoL7AsgXwCFrUPHhqyD0hDku+3jqVxtn+UiiMlH+MhqHHdZoQ lur5NsvphexN2N3zTQkEybkRGgJHGqj1 X-Google-Smtp-Source: APXvYqw2VsB8QRHHZVMQ1VhvHU/nDMf5a8qvedfp46p5hb+FxJEbYpXEIh3n7OA6WwWDSR2D++aTvC0B3Fhm X-Received: by 2002:a63:dd16:: with SMTP id t22mr50863450pgg.140.1563987511332; Wed, 24 Jul 2019 09:58:31 -0700 (PDT) Date: Wed, 24 Jul 2019 09:57:59 -0700 In-Reply-To: <20190724165803.87470-1-brianvv@google.com> Message-Id: <20190724165803.87470-3-brianvv@google.com> Mime-Version: 1.0 References: <20190724165803.87470-1-brianvv@google.com> X-Mailer: git-send-email 2.22.0.657.g960e92d24f-goog Subject: [PATCH bpf-next 2/6] bpf: add BPF_MAP_DUMP command to dump more than one entry per call From: Brian Vazquez To: Brian Vazquez , Alexei Starovoitov , Daniel Borkmann , "David S . Miller" Cc: Stanislav Fomichev , Willem de Bruijn , Petar Penkov , linux-kernel@vger.kernel.org, netdev@vger.kernel.org, bpf@vger.kernel.org, Brian Vazquez Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This introduces a new command to retrieve multiple number of entries from a bpf map, wrapping the existing bpf methods: map_get_next_key and map_lookup_elem To start dumping the map from the beginning you must specify NULL as the prev_key. The new API returns 0 when it successfully copied all the elements requested or it copied less because there weren't more elements to retrieved (i.e err == -ENOENT). In last scenario err will be masked to 0. On a successful call buf and buf_len will contain correct data and in case prev_key was provided (not for the first walk, since prev_key is NULL) it will contain the last_key copied into the prev_key which will simplify next call. Only when it can't find a single element it will return -ENOENT meaning that the map has been entirely walked. When an error is return buf, buf_len and prev_key shouldn't be read nor used. Because maps can be called from userspace and kernel code, this function can have a scenario where the next_key was found but by the time we try to retrieve the value the element is not there, in this case the function continues and tries to get a new next_key value, skipping the deleted key. If at some point the function find itself trap in a loop, it will return -EINTR. The function will try to fit as much as possible in the buf provided and will return -EINVAL if buf_len is smaller than elem_size. QUEUE and STACK maps are not supported. Note that map_dump doesn't guarantee that reading the entire table is consistent since this function is always racing with kernel and user code but the same behaviour is found when the entire table is walked using the current interfaces: map_get_next_key + map_lookup_elem. It is also important to note that with a locked map, the lock is grabbed for 1 entry at the time, meaning that the returned buf might or might not be consistent. Suggested-by: Stanislav Fomichev Signed-off-by: Brian Vazquez --- include/uapi/linux/bpf.h | 9 +++ kernel/bpf/syscall.c | 117 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index fa1c753dcdbc7..66dab5385170d 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -106,6 +106,7 @@ enum bpf_cmd { BPF_TASK_FD_QUERY, BPF_MAP_LOOKUP_AND_DELETE_ELEM, BPF_MAP_FREEZE, + BPF_MAP_DUMP, }; enum bpf_map_type { @@ -388,6 +389,14 @@ union bpf_attr { __u64 flags; }; + struct { /* struct used by BPF_MAP_DUMP command */ + __aligned_u64 prev_key; + __aligned_u64 buf; + __aligned_u64 buf_len; /* input/output: len of buf */ + __u64 flags; + __u32 map_fd; + } dump; + struct { /* anonymous struct used by BPF_PROG_LOAD command */ __u32 prog_type; /* one of enum bpf_prog_type */ __u32 insn_cnt; diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 86cdc2f7bb56e..0c35505aa219f 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -1097,6 +1097,120 @@ static int map_get_next_key(union bpf_attr *attr) return err; } +/* last field in 'union bpf_attr' used by this command */ +#define BPF_MAP_DUMP_LAST_FIELD dump.map_fd + +static int map_dump(union bpf_attr *attr) +{ + void __user *ukey = u64_to_user_ptr(attr->dump.prev_key); + void __user *ubuf = u64_to_user_ptr(attr->dump.buf); + u32 __user *ubuf_len = u64_to_user_ptr(attr->dump.buf_len); + int ufd = attr->dump.map_fd; + struct bpf_map *map; + void *buf, *prev_key, *key, *value; + u32 value_size, elem_size, buf_len, cp_len; + struct fd f; + int err; + bool first_key = false; + + if (CHECK_ATTR(BPF_MAP_DUMP)) + return -EINVAL; + + if (attr->dump.flags & ~BPF_F_LOCK) + return -EINVAL; + + f = fdget(ufd); + map = __bpf_map_get(f); + if (IS_ERR(map)) + return PTR_ERR(map); + if (!(map_get_sys_perms(map, f) & FMODE_CAN_READ)) { + err = -EPERM; + goto err_put; + } + + if ((attr->dump.flags & BPF_F_LOCK) && + !map_value_has_spin_lock(map)) { + err = -EINVAL; + goto err_put; + } + + if (map->map_type == BPF_MAP_TYPE_QUEUE || + map->map_type == BPF_MAP_TYPE_STACK) { + err = -ENOTSUPP; + goto err_put; + } + + value_size = bpf_map_value_size(map); + + err = get_user(buf_len, ubuf_len); + if (err) + goto err_put; + + elem_size = map->key_size + value_size; + if (buf_len < elem_size) { + err = -EINVAL; + goto err_put; + } + + if (ukey) { + prev_key = __bpf_copy_key(ukey, map->key_size); + if (IS_ERR(prev_key)) { + err = PTR_ERR(prev_key); + goto err_put; + } + } else { + prev_key = NULL; + first_key = true; + } + + err = -ENOMEM; + buf = kmalloc(elem_size, GFP_USER | __GFP_NOWARN); + if (!buf) + goto err_put; + + key = buf; + value = key + map->key_size; + for (cp_len = 0; cp_len + elem_size <= buf_len;) { + if (signal_pending(current)) { + err = -EINTR; + break; + } + + rcu_read_lock(); + err = map->ops->map_get_next_key(map, prev_key, key); + rcu_read_unlock(); + + if (err) + break; + + err = bpf_map_copy_value(map, key, value, attr->dump.flags); + + if (err == -ENOENT) + continue; + if (err) + goto free_buf; + + if (copy_to_user(ubuf + cp_len, buf, elem_size)) { + err = -EFAULT; + goto free_buf; + } + + prev_key = key; + cp_len += elem_size; + } + + if (err == -ENOENT && cp_len) + err = 0; + if (!err && (copy_to_user(ubuf_len, &cp_len, sizeof(cp_len)) || + (!first_key && copy_to_user(ukey, key, map->key_size)))) + err = -EFAULT; +free_buf: + kfree(buf); +err_put: + fdput(f); + return err; +} + #define BPF_MAP_LOOKUP_AND_DELETE_ELEM_LAST_FIELD value static int map_lookup_and_delete_elem(union bpf_attr *attr) @@ -2910,6 +3024,9 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, siz case BPF_MAP_LOOKUP_AND_DELETE_ELEM: err = map_lookup_and_delete_elem(&attr); break; + case BPF_MAP_DUMP: + err = map_dump(&attr); + break; default: err = -EINVAL; break; From patchwork Wed Jul 24 16:58:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Vazquez X-Patchwork-Id: 1136427 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="Sqj8KFoP"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45v1lS0313z9sBZ for ; Thu, 25 Jul 2019 02:59:00 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728502AbfGXQ6h (ORCPT ); Wed, 24 Jul 2019 12:58:37 -0400 Received: from mail-pf1-f202.google.com ([209.85.210.202]:36094 "EHLO mail-pf1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387621AbfGXQ6e (ORCPT ); Wed, 24 Jul 2019 12:58:34 -0400 Received: by mail-pf1-f202.google.com with SMTP id e20so28952504pfd.3 for ; Wed, 24 Jul 2019 09:58:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=HR+i5k9D3xN0HWRoWeihUWIzPrhjF/a9nve8ODtPhD0=; b=Sqj8KFoPc7hD63y6Ke6KRZCuC892AJWxBiBjXl9lm7e3VHw7v9+2CPKEKkIIGVduBM +RBU0OzJVulCwCav3ICiM0TTFqCVjHo32X+Gfur0MmkdF5f2GDgfrmT1WIagFWh/eLk/ TfTRNQzkoI/Rmz8NQgzm6MtkfTWjehevn3uHkGkt71GlOorwiX63MNuUwmdGSK1TELYZ yZsjvh/nyXpdbATi79pq4jnwWfIB3+8JKgOd7lSJg16RSNjIDMyAHd2Wr/9b9d6aEVNe gVfwYSSWh8TBXcNRNU+IBM8ZgPWDd2ZdkP3MJYeVX+vkgj6Oq+OZ2br+9Ddj79zT7PRs HCuQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=HR+i5k9D3xN0HWRoWeihUWIzPrhjF/a9nve8ODtPhD0=; b=ikFTtID3OJbNGVoiXsBRC0sM3dlw3ySf73qj8HWuRBOPVLwgnTQtVGiAIN4kbKAnHt DGAKIyoIoV1k5cheQccPsQ6LqE2pF4bz84Mz3jRU3SkTnIpy3wLyyevi//UIa9dv+TzG IRdfvS4vV6RmL02j8IaxjBsZEHhwTh2Mmlllrd3LeHYHfady0PBIjS5snaHHqTy3wAt4 +gNe3BYIt1GSryxRkLjHVpdFxusANkRL3NwovKfXjAEo8uTFJ5trIw40vyD82fvvuvwx jp9XUmf6ePyFUxb1NqXxoSB0+kK19Pv3+ZoIZhR/y5q+lakdhjmq/10h6uqvXxHhnnQE 9SjA== X-Gm-Message-State: APjAAAXt2VQS7AsJaejovNIdytuaadSM/j5vWrZiW8aNfeDvY32lWFDp 3h5ZaOn1m+c4Lj/zI3gmVqYPJNVBS8uI X-Google-Smtp-Source: APXvYqzu5AQ+mRmZp518hex6IDEIzKbEvvBp9hLrjMi74On/5T8AvUdwkgxhlgx4t6PpiuEpqSWlNkQJPxJ2 X-Received: by 2002:a63:3009:: with SMTP id w9mr7663984pgw.260.1563987513746; Wed, 24 Jul 2019 09:58:33 -0700 (PDT) Date: Wed, 24 Jul 2019 09:58:00 -0700 In-Reply-To: <20190724165803.87470-1-brianvv@google.com> Message-Id: <20190724165803.87470-4-brianvv@google.com> Mime-Version: 1.0 References: <20190724165803.87470-1-brianvv@google.com> X-Mailer: git-send-email 2.22.0.657.g960e92d24f-goog Subject: [PATCH bpf-next 3/6] bpf: keep bpf.h in sync with tools/ From: Brian Vazquez To: Brian Vazquez , Alexei Starovoitov , Daniel Borkmann , "David S . Miller" Cc: Stanislav Fomichev , Willem de Bruijn , Petar Penkov , linux-kernel@vger.kernel.org, netdev@vger.kernel.org, bpf@vger.kernel.org, Brian Vazquez Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Adds bpf_attr.dump structure to libbpf. Suggested-by: Stanislav Fomichev Signed-off-by: Brian Vazquez --- tools/include/uapi/linux/bpf.h | 9 +++++++++ tools/lib/bpf/libbpf.map | 2 ++ 2 files changed, 11 insertions(+) diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 4e455018da65f..e127f16e4e932 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -106,6 +106,7 @@ enum bpf_cmd { BPF_TASK_FD_QUERY, BPF_MAP_LOOKUP_AND_DELETE_ELEM, BPF_MAP_FREEZE, + BPF_MAP_DUMP, }; enum bpf_map_type { @@ -388,6 +389,14 @@ union bpf_attr { __u64 flags; }; + struct { /* struct used by BPF_MAP_DUMP command */ + __aligned_u64 prev_key; + __aligned_u64 buf; + __aligned_u64 buf_len; /* input/output: len of buf */ + __u64 flags; + __u32 map_fd; + } dump; + struct { /* anonymous struct used by BPF_PROG_LOAD command */ __u32 prog_type; /* one of enum bpf_prog_type */ __u32 insn_cnt; diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map index f9d316e873d8d..cac3723d5c45c 100644 --- a/tools/lib/bpf/libbpf.map +++ b/tools/lib/bpf/libbpf.map @@ -183,4 +183,6 @@ LIBBPF_0.0.4 { perf_buffer__new; perf_buffer__new_raw; perf_buffer__poll; + bpf_map_dump; + bpf_map_dump_flags; } LIBBPF_0.0.3; From patchwork Wed Jul 24 16:58:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Vazquez X-Patchwork-Id: 1136421 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: incoming-bpf@patchwork.ozlabs.org Delivered-To: patchwork-incoming-bpf@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=bpf-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="rqq9g03P"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45v1l567XQz9sBF for ; Thu, 25 Jul 2019 02:58:41 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728537AbfGXQ6k (ORCPT ); Wed, 24 Jul 2019 12:58:40 -0400 Received: from mail-qk1-f202.google.com ([209.85.222.202]:42312 "EHLO mail-qk1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728496AbfGXQ6h (ORCPT ); Wed, 24 Jul 2019 12:58:37 -0400 Received: by mail-qk1-f202.google.com with SMTP id 199so39968150qkj.9 for ; Wed, 24 Jul 2019 09:58:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=glKaPZF0kuawPUQxXbpKIp+157oyf0yYPp3UELzJQsg=; b=rqq9g03PpRhF3ymvIyKsJZzyqpeGHYdT7zGj3bnG5I1MzwqawSR6jYQY47lcFaPh8u AC4HC3jBJ8Q6HPjbVfvzmz4thwjP+kPTjr2j5uQJzkIhru+IeBl/CNrBF8HUEJPBemGj YCZ8sgHUbNal4hCkX93eIDVTkVotYLPT72iFfHt7htZalJIeNAPgZOBv4v1Aggm/iBAF E4vT2Eug6Gz2suAsgF+EumINRAuFJHHIgZphdq8fz7jesmzD+kw6OvLpLQVJ3v4oNRKf 6h7BMZEYGDGnq0Cb8crL9rOnzJd0xO2wfJjOb3bwSjthqNd8+O6dl4tNFBv5bU8iEhTG 811w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=glKaPZF0kuawPUQxXbpKIp+157oyf0yYPp3UELzJQsg=; b=H3fA8hpU2p3AiPKrseoIyef/bKSAX1sC8xeEseg2XTJDqpLha8NzH1dloy02/ZIkgG 8Nyy4DCktZeHqtdcR+YryVwfRPJ5wKrq4htvhQXDUULj0Q02/Ugg68pAMjuTSAS0TxPo IuBHCNe4Sy67lwVkG5MANcXViQKJ4B8qMmdKvuThBTp8VCedC4G9F2w/V+gywbOUf90U StVbLF1u+RDYLghzTggdL6OG7z/XXNI171Sdm3YqrCfsMXKMbdqUxWZ2GyaRpNAOjTDS RDS+jjC2vgThprYiT9HqprPeU7sIVeplWL0oYylHkP6NU74Rpa4aNVm0mx3AWpCaiB2g kMLw== X-Gm-Message-State: APjAAAUHPvYxabHsPIwXY7ZbV+qK9TdGGSGWZ90FABUEK3TfhRpkxPi1 /1GfmeEP9WUBBwO3ZT5t6bsMYRMrvxjm X-Google-Smtp-Source: APXvYqwGhYKsmoggPNt4NsKlJiqWSzOCNjflzOiZPEzbK6MDkFFQIP6wyFXKUEoZQwNfArLV+zvI15TnxLV0 X-Received: by 2002:a0c:8a76:: with SMTP id 51mr60440819qvu.210.1563987516337; Wed, 24 Jul 2019 09:58:36 -0700 (PDT) Date: Wed, 24 Jul 2019 09:58:01 -0700 In-Reply-To: <20190724165803.87470-1-brianvv@google.com> Message-Id: <20190724165803.87470-5-brianvv@google.com> Mime-Version: 1.0 References: <20190724165803.87470-1-brianvv@google.com> X-Mailer: git-send-email 2.22.0.657.g960e92d24f-goog Subject: [PATCH bpf-next 4/6] libbpf: support BPF_MAP_DUMP command From: Brian Vazquez To: Brian Vazquez , Alexei Starovoitov , Daniel Borkmann , "David S . Miller" Cc: Stanislav Fomichev , Willem de Bruijn , Petar Penkov , linux-kernel@vger.kernel.org, netdev@vger.kernel.org, bpf@vger.kernel.org, Brian Vazquez Sender: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org Make libbpf aware of new BPF_MAP_DUMP command and add bpf_map_dump and bpf_map_dump_flags to use them from the library. Suggested-by: Stanislav Fomichev Signed-off-by: Brian Vazquez --- tools/lib/bpf/bpf.c | 28 ++++++++++++++++++++++++++++ tools/lib/bpf/bpf.h | 4 ++++ 2 files changed, 32 insertions(+) diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c index c7d7993c44bb0..c1139b7db756a 100644 --- a/tools/lib/bpf/bpf.c +++ b/tools/lib/bpf/bpf.c @@ -368,6 +368,34 @@ int bpf_map_update_elem(int fd, const void *key, const void *value, return sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr)); } +int bpf_map_dump(int fd, const void *prev_key, void *buf, void *buf_len) +{ + union bpf_attr attr; + + memset(&attr, 0, sizeof(attr)); + attr.dump.map_fd = fd; + attr.dump.prev_key = ptr_to_u64(prev_key); + attr.dump.buf = ptr_to_u64(buf); + attr.dump.buf_len = ptr_to_u64(buf_len); + + return sys_bpf(BPF_MAP_DUMP, &attr, sizeof(attr)); +} + +int bpf_map_dump_flags(int fd, const void *prev_key, void *buf, void *buf_len, + __u64 flags) +{ + union bpf_attr attr; + + memset(&attr, 0, sizeof(attr)); + attr.dump.map_fd = fd; + attr.dump.prev_key = ptr_to_u64(prev_key); + attr.dump.buf = ptr_to_u64(buf); + attr.dump.buf_len = ptr_to_u64(buf_len); + attr.dump.flags = flags; + + return sys_bpf(BPF_MAP_DUMP, &attr, sizeof(attr)); +} + int bpf_map_lookup_elem(int fd, const void *key, void *value) { union bpf_attr attr; diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h index ff42ca043dc8f..86496443440e9 100644 --- a/tools/lib/bpf/bpf.h +++ b/tools/lib/bpf/bpf.h @@ -112,6 +112,10 @@ LIBBPF_API int bpf_verify_program(enum bpf_prog_type type, LIBBPF_API int bpf_map_update_elem(int fd, const void *key, const void *value, __u64 flags); +LIBBPF_API int bpf_map_dump(int fd, const void *prev_key, void *buf, + void *buf_len); +LIBBPF_API int bpf_map_dump_flags(int fd, const void *prev_key, void *buf, + void *buf_len, __u64 flags); LIBBPF_API int bpf_map_lookup_elem(int fd, const void *key, void *value); LIBBPF_API int bpf_map_lookup_elem_flags(int fd, const void *key, void *value, __u64 flags); From patchwork Wed Jul 24 16:58:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Vazquez X-Patchwork-Id: 1136425 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="ttSizfIU"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45v1lL2Wqvz9s8m for ; Thu, 25 Jul 2019 02:58:54 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387667AbfGXQ6x (ORCPT ); Wed, 24 Jul 2019 12:58:53 -0400 Received: from mail-pg1-f201.google.com ([209.85.215.201]:43568 "EHLO mail-pg1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728533AbfGXQ6j (ORCPT ); Wed, 24 Jul 2019 12:58:39 -0400 Received: by mail-pg1-f201.google.com with SMTP id p29so20463782pgm.10 for ; Wed, 24 Jul 2019 09:58:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=1tJN/OG1NU+LcE8k1olHxJVBbmDDdzToejoDtp6IxoE=; b=ttSizfIUX852pbuQqkoRYrU31qBiP2arQzJJnPHCO8oLFLDMyA4R8eilHNC1gUbyMc LVaegQTPgggspcFsqbfxXy3tWH5yB8LBw5YDmMqXtTJBYMDZt1doXnY9KyoDv9kwJgcR DmLo4m72uamj1T7sqJxj7DrhkVqZWjAzDRcaexno9w6tfTbzxV2ZIAQZgbZC+SuzTALZ W6qPhnzQa67Xp87AeTIhvus9AQS1PrShJzeh6E7LPcn8yHJwKJ9v08ccpkRsS18zNxlD cmjASiRla7C+k6xKVn/HdqMICDTqqkgZGxY36QcePw9WbXmAom8WrhVD0whs6Y+WGmt3 nwRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=1tJN/OG1NU+LcE8k1olHxJVBbmDDdzToejoDtp6IxoE=; b=Rg46XzRfHgykCS3ITGht9g0vqcaf7L8Wh14/TOk1fRaOv+xHRv5i0PwUjczStw7MrJ RCYpgatSjsGHvmA94qKfaYwoPXcFj4O+wSPUq2bRbfvvqY0fBvpeTAacIsXTO8n1zGUb m5u0z9588guIDTqNmvZB6CDra6kB/Y/unakfMqVdi/3hZS5tnCvgeBVl5G0sz9wgC2GA zYZXqDKtPuOIGf1hKEqv15JToDIF2yN0etqpi4H5K4nkDxcoWG1GJ0uj1QbA9BaG/GWF ctIrxnzMD19IQh21ztS8xFUwB1vCJOTZxQKOgPMj9ASOkM0l4Gy8KfbbCyckbVpfWQuk HyXw== X-Gm-Message-State: APjAAAUVw/vhspJh3Af2D1gpoZxoqfX5H/FyPCgCzKI14xBxtiEHNB73 02HIxjqk49ESA83xFJJUxQhXxRmWmVRg X-Google-Smtp-Source: APXvYqyRPD/QPT5agrTZw3GtgEgVpkOaTvf+sUpcgn4birz1fO6FMoLqfdylzjJSnd352i20oIQQfL2Jns5c X-Received: by 2002:a63:7455:: with SMTP id e21mr77221768pgn.439.1563987518569; Wed, 24 Jul 2019 09:58:38 -0700 (PDT) Date: Wed, 24 Jul 2019 09:58:02 -0700 In-Reply-To: <20190724165803.87470-1-brianvv@google.com> Message-Id: <20190724165803.87470-6-brianvv@google.com> Mime-Version: 1.0 References: <20190724165803.87470-1-brianvv@google.com> X-Mailer: git-send-email 2.22.0.657.g960e92d24f-goog Subject: [PATCH bpf-next 5/6] selftests/bpf: test BPF_MAP_DUMP command on a bpf hashmap From: Brian Vazquez To: Brian Vazquez , Alexei Starovoitov , Daniel Borkmann , "David S . Miller" Cc: Stanislav Fomichev , Willem de Bruijn , Petar Penkov , linux-kernel@vger.kernel.org, netdev@vger.kernel.org, bpf@vger.kernel.org, Brian Vazquez Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This tests exercise the new command on a bpf hashmap and make sure it works as expected. Signed-off-by: Brian Vazquez --- tools/testing/selftests/bpf/test_maps.c | 83 ++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/bpf/test_maps.c b/tools/testing/selftests/bpf/test_maps.c index 5443b9bd75ed7..f7ab401399d40 100644 --- a/tools/testing/selftests/bpf/test_maps.c +++ b/tools/testing/selftests/bpf/test_maps.c @@ -309,6 +309,86 @@ static void test_hashmap_walk(unsigned int task, void *data) close(fd); } +static void test_hashmap_dump(void) +{ + int fd, i, max_entries = 5; + uint64_t keys[max_entries], values[max_entries]; + uint64_t key, value, next_key, prev_key; + bool next_key_valid = true; + void *buf, *elem; + u32 buf_len; + const int elem_size = sizeof(key) + sizeof(value); + + fd = helper_fill_hashmap(max_entries); + + // Get the elements in the hashmap, and store them in that order + assert(bpf_map_get_next_key(fd, NULL, &key) == 0); + i = 0; + keys[i] = key; + for (i = 1; next_key_valid; i++) { + next_key_valid = bpf_map_get_next_key(fd, &key, &next_key) == 0; + assert(bpf_map_lookup_elem(fd, &key, &values[i - 1]) == 0); + keys[i-1] = key; + key = next_key; + } + + // Alloc memory for the whole table + buf = malloc(elem_size * max_entries); + assert(buf != NULL); + + // Check that buf_len < elem_size returns EINVAL + buf_len = elem_size-1; + errno = 0; + assert(bpf_map_dump(fd, NULL, buf, &buf_len) == -1 && errno == EINVAL); + + // Check that it returns the first two elements + errno = 0; + buf_len = elem_size * 2; + i = 0; + assert(bpf_map_dump(fd, NULL, buf, &buf_len) == 0 && + buf_len == 2*elem_size); + elem = buf; + assert((*(uint64_t *)elem) == keys[i] && + (*(uint64_t *)(elem + sizeof(key))) == values[i]); + elem = buf + elem_size; + i++; + assert((*(uint64_t *)elem) == keys[i] && + (*(uint64_t *)(elem + sizeof(key))) == values[i]); + i++; + + /* Check that prev_key contains key from last_elem retrieved in previous + * call + */ + prev_key = *((uint64_t *)elem); + assert(bpf_map_dump(fd, &prev_key, buf, &buf_len) == 0 && + buf_len == elem_size*2); + elem = buf; + assert((*(uint64_t *)elem) == keys[i] && + (*(uint64_t *)(elem + sizeof(key))) == values[i]); + elem = buf + elem_size; + i++; + assert((*(uint64_t *)elem) == keys[i] && + (*(uint64_t *)(elem + sizeof(key))) == values[i]); + i++; + assert(prev_key == (*(uint64_t *)elem)); + + /* Continue reading from map and verify buf_len only contains 1 element + * even though buf_len is 2 elem_size and it returns err = 0. + */ + assert(bpf_map_dump(fd, &prev_key, buf, &buf_len) == 0 && + buf_len == elem_size); + elem = buf; + assert((*(uint64_t *)elem) == keys[i] && + (*(uint64_t *)(elem + sizeof(key))) == values[i]); + + // Verify there's no more entries and err = ENOENT + assert(bpf_map_dump(fd, &prev_key, buf, &buf_len) == -1 && + errno == ENOENT); + + free(buf); + close(fd); +} + static void test_hashmap_zero_seed(void) { int i, first, second, old_flags; @@ -1677,6 +1757,7 @@ static void run_all_tests(void) test_hashmap_percpu(0, NULL); test_hashmap_walk(0, NULL); test_hashmap_zero_seed(); + test_hashmap_dump(); test_arraymap(0, NULL); test_arraymap_percpu(0, NULL); @@ -1714,11 +1795,9 @@ int main(void) map_flags = BPF_F_NO_PREALLOC; run_all_tests(); - #define CALL #include #undef CALL - printf("test_maps: OK, %d SKIPPED\n", skips); return 0; } From patchwork Wed Jul 24 16:58:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Vazquez X-Patchwork-Id: 1136422 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: incoming-bpf@patchwork.ozlabs.org Delivered-To: patchwork-incoming-bpf@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=bpf-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="oUJf1bx4"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45v1lB6WHFz9sBF for ; Thu, 25 Jul 2019 02:58:46 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387645AbfGXQ6p (ORCPT ); Wed, 24 Jul 2019 12:58:45 -0400 Received: from mail-pg1-f201.google.com ([209.85.215.201]:33919 "EHLO mail-pg1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387628AbfGXQ6l (ORCPT ); Wed, 24 Jul 2019 12:58:41 -0400 Received: by mail-pg1-f201.google.com with SMTP id x19so28694831pgx.1 for ; Wed, 24 Jul 2019 09:58:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=IGj/M+6U995Y52IjNEaLV6LDl7AzZ6dG3QadQeE37S0=; b=oUJf1bx45jmFQxsX5BUA7N5crPP1ky/I4ydMP3+NZjrKcZ4IYQv4NSrYFZBPh3ba0O KUW1JA/XDot9TQDgD/EvsU9/6KMH52NYJD8iaa4EOdbMpnGsL6uni6HvqR4DMzOwNwio N8yHR4BK5WrbGWJK9M4mePqRz7Wm3KIjGMGXT/W9N81Sxaa5dfxA8oNe7rhc79J2bIPh wGFiZme9haD7UKM+LZj8frc9mP3ygbLlM4Fo9CjVF+6ZEbYfWG3sLl8oOqUnaYmLHL5D xo5t97SRL2RDscENQ7xblfMyvHnihOW0px4qIhxJVR+kZby+J9MPvDefXh/0ONgDkIn6 3wKg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=IGj/M+6U995Y52IjNEaLV6LDl7AzZ6dG3QadQeE37S0=; b=IoHbjnwv7ixUKlPrSk0YYl+hmTYAKzPFF7Wo/YdsP4AuNsMcI+GEQbfqhCD4JKACIm RTh5Z2SbXBV/LvLgugStDvpMrUTSjqsNYFR7OtPzZAHNrR4XINCTH6JeWt0CPLm4SrNG 7dR2aIlNtNZjhfnb0+bn2u1ylBAkQaa1KU+U5qnCwyXLXyE81fImpQqyXHHcup8mLizp X0oyRKv1Pw0HgUMFIeDOer1S8XzbTy8HvO9WMsMVpfFbONQ52L/+tAOINIb4Co1zgajN N3SbhSrJMciyrYTACObtMRsjdy37XDiqmKDnt9us4U78pKpj4g3AmnkNOgEPz6eieQb4 sdkw== X-Gm-Message-State: APjAAAVjbhiMI6+PiQu7KAh+mOc2oYm/WycRn9bPCBgRA4YrYAsePp3I 6XjEufu0gqIV0AxfKODb9RBBmasDXX5w X-Google-Smtp-Source: APXvYqxbKxLxrhzXjYCucyVFxZ24iwUfubUGnAiPkh3hmQBII0u/pLXrbRWzMfSy+YCD5R9UAeHnyTFZA0Z4 X-Received: by 2002:a63:1455:: with SMTP id 21mr38502725pgu.116.1563987520966; Wed, 24 Jul 2019 09:58:40 -0700 (PDT) Date: Wed, 24 Jul 2019 09:58:03 -0700 In-Reply-To: <20190724165803.87470-1-brianvv@google.com> Message-Id: <20190724165803.87470-7-brianvv@google.com> Mime-Version: 1.0 References: <20190724165803.87470-1-brianvv@google.com> X-Mailer: git-send-email 2.22.0.657.g960e92d24f-goog Subject: [PATCH bpf-next 6/6] selftests/bpf: add test to measure performance of BPF_MAP_DUMP From: Brian Vazquez To: Brian Vazquez , Alexei Starovoitov , Daniel Borkmann , "David S . Miller" Cc: Stanislav Fomichev , Willem de Bruijn , Petar Penkov , linux-kernel@vger.kernel.org, netdev@vger.kernel.org, bpf@vger.kernel.org, Brian Vazquez Sender: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org This tests compares the amount of time that takes to read an entire table of 100K elements on a bpf hashmap using both BPF_MAP_DUMP and BPF_MAP_GET_NEXT_KEY + BPF_MAP_LOOKUP_ELEM. Signed-off-by: Brian Vazquez --- tools/testing/selftests/bpf/test_maps.c | 65 +++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/tools/testing/selftests/bpf/test_maps.c b/tools/testing/selftests/bpf/test_maps.c index f7ab401399d40..c4593a8904ca6 100644 --- a/tools/testing/selftests/bpf/test_maps.c +++ b/tools/testing/selftests/bpf/test_maps.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -389,6 +390,69 @@ static void test_hashmap_dump(void) close(fd); } +static void test_hashmap_dump_perf(void) +{ + int fd, i, max_entries = 100000; + uint64_t key, value, next_key; + bool next_key_valid = true; + void *buf; + u32 buf_len, entries; + int j = 0; + int clk_id = CLOCK_MONOTONIC; + struct timespec begin, end; + long long time_spent, dump_time_spent; + double res; + int tests[] = {1, 2, 230, 5000, 73000, 100000, 234567}; + int test_len = ARRAY_SIZE(tests); + const int elem_size = sizeof(key) + sizeof(value); + + fd = helper_fill_hashmap(max_entries); + // Alloc memory considering the largest buffer + buf = malloc(elem_size * tests[test_len-1]); + assert(buf != NULL); + +test: + entries = tests[j]; + buf_len = elem_size*tests[j]; + j++; + clock_gettime(clk_id, &begin); + errno = 0; + i = 0; + while (errno == 0) { + bpf_map_dump(fd, !i ? NULL : &key, + buf, &buf_len); + if (errno) + break; + if (!i) + key = *((uint64_t *)(buf + buf_len - elem_size)); + i += buf_len / elem_size; + } + clock_gettime(clk_id, &end); + assert(i == max_entries); + dump_time_spent = NSEC_PER_SEC * (end.tv_sec - begin.tv_sec) + + end.tv_nsec - begin.tv_nsec; + next_key_valid = true; + clock_gettime(clk_id, &begin); + assert(bpf_map_get_next_key(fd, NULL, &key) == 0); + for (i = 0; next_key_valid; i++) { + next_key_valid = bpf_map_get_next_key(fd, &key, &next_key) == 0; + assert(bpf_map_lookup_elem(fd, &key, &value) == 0); + key = next_key; + } + clock_gettime(clk_id, &end); + time_spent = NSEC_PER_SEC * (end.tv_sec - begin.tv_sec) + + end.tv_nsec - begin.tv_nsec; + res = (1-((double)dump_time_spent/time_spent))*100; + printf("buf_len_%u:\t %llu entry-by-entry: %llu improvement %lf\n", + entries, dump_time_spent, time_spent, res); + assert(i == max_entries); + + if (j < test_len) + goto test; + free(buf); + close(fd); +} + static void test_hashmap_zero_seed(void) { int i, first, second, old_flags; @@ -1758,6 +1822,7 @@ static void run_all_tests(void) test_hashmap_walk(0, NULL); test_hashmap_zero_seed(); test_hashmap_dump(); + test_hashmap_dump_perf(); test_arraymap(0, NULL); test_arraymap_percpu(0, NULL);