From patchwork Wed Jul 3 17:01:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Vazquez X-Patchwork-Id: 1126986 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="bukW9Fgr"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45f6qM5dFXz9sBp for ; Thu, 4 Jul 2019 03:02:39 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727271AbfGCRCJ (ORCPT ); Wed, 3 Jul 2019 13:02:09 -0400 Received: from mail-ua1-f74.google.com ([209.85.222.74]:52221 "EHLO mail-ua1-f74.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727240AbfGCRCF (ORCPT ); Wed, 3 Jul 2019 13:02:05 -0400 Received: by mail-ua1-f74.google.com with SMTP id d5so162127uaj.18 for ; Wed, 03 Jul 2019 10:02:04 -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=a4B2pi3afPrfivcwvxY/0YFG7emhlAa6z/TIz7oLh4I=; b=bukW9FgrgpnaTfg+obcuWRTUvcBzM1ggSi0JTvkY2Ae5L6Evnn1MydKeWAdJr4jHpD K155rMxmXXFSDoq4Gb6xRF5gobEtv7Uo8uSmSZ14Anr3zhMh2ChciBLGQZGq6OekZKEe jRP1pbytIydxHfngZ0esiuBzO2S38JHCupNdqAzG3a1512b2/+dX0x06ht1OuIhnMZwO /9nO/fzdGARi9rMTIVYLWPZIdBTRyaktPnhp99sgEoQSR4Wu8SAzlVe31dFU/gEiQPhV 7AEr53drxmxgT0iNyHiR5JGfHl5U/KRFgOeuXxobQH3RkOQwsTNpuYtWiXrOvJcJ3v6L qx+Q== 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=a4B2pi3afPrfivcwvxY/0YFG7emhlAa6z/TIz7oLh4I=; b=eNVATReNy4cUsOHp0IWmWpM/5rTJ9i8UvIPJKouKPMUHfj5+P6QwuS9aNZEDbno/T3 yjqEXcXzBwV1o1x11EyiU3G+I6zpw++mcDPTVIs8uzba9P+Py4gXVvFg+91KClPYXULQ hnedAEXX7aHpSLozlehU+kfFFgy4QP1QilOAYB7VMxNO1LXCKhYDYUi1LTsudyAzMtbF E74NTKUiNqMsCelij/GYBaKxU54rQT1KdkvCy6mixinpw7UYV71uymk/GjSTOOjlTVBI nH5noDwoXcQ7L/YqINSz46KebcveYNkgmshIl2xjNB8ZENz1mUD8swvJ/qv1k9q69QEL JhGQ== X-Gm-Message-State: APjAAAV0XA95Kd5WZFTwKitzSUeJweSkOEE/H+Y6mSt9vLBv0Kq629BN MnTJykzDHIbWzxIWY1kYgb4dH+BQHSTU X-Google-Smtp-Source: APXvYqyRDVT/laYhNDbWB8Xb2kPsFbhawuoJWiOJduoc/afILyBFyisVqWPFHogEuIHJSxmJgFzVmkvnEmqF X-Received: by 2002:a1f:a887:: with SMTP id r129mr11227778vke.75.1562173324191; Wed, 03 Jul 2019 10:02:04 -0700 (PDT) Date: Wed, 3 Jul 2019 10:01:13 -0700 In-Reply-To: <20190703170118.196552-1-brianvv@google.com> Message-Id: <20190703170118.196552-2-brianvv@google.com> Mime-Version: 1.0 References: <20190703170118.196552-1-brianvv@google.com> X-Mailer: git-send-email 2.22.0.410.gd8fdbe21b5-goog Subject: [PATCH bpf-next RFC v3 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: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@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 --- 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 b0f545e07425..d200d2837ade 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 3 17:01:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Vazquez X-Patchwork-Id: 1126977 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="XPtWsayQ"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45f6pn3r05z9sLt for ; Thu, 4 Jul 2019 03:02:09 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727244AbfGCRCI (ORCPT ); Wed, 3 Jul 2019 13:02:08 -0400 Received: from mail-ua1-f74.google.com ([209.85.222.74]:38569 "EHLO mail-ua1-f74.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727110AbfGCRCH (ORCPT ); Wed, 3 Jul 2019 13:02:07 -0400 Received: by mail-ua1-f74.google.com with SMTP id j22so162422uaq.5 for ; Wed, 03 Jul 2019 10:02:07 -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=byxWQcFkOw0n1MZOPKiskDPHZeszueGC1zKGXJuqoj8=; b=XPtWsayQUbX4mzexabtf4MCueZpbuKGgpUxkbz0RIeVX152jBmljMsQCpFCWXPVERn VComJBDRppBiZzS7WAw5rn6MICG9eHFPF60oYbb5Obcy/NqkzdMkioxFbH1uXvD6PWG9 fxZuUqkn3yxGZZ4fRjSR5TgfbIPV/mIztSyKxnQgXDz0vxJ8p1RmU/2rTq4pAn5J/VCu DtsyZ9r1h4QFg543h0c5/P65mhk98en44Ois2NCf/xhbWYnvNJwjlXtVHR2RIAmAAILd 5xWIikqlbsUOf+u36fuy3f5sisf4C1GGaCDh4L4j7USHBoWlhFi2xcVgjooko2qmR1w2 386Q== 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=byxWQcFkOw0n1MZOPKiskDPHZeszueGC1zKGXJuqoj8=; b=ciPfVo99SNIFFyC4l3UNQxZb0nxS63vEBwVI/ZatlqnEEfFJSPE3IknJZdBG/Bz8iA 5z8QAsbvh6cvLliJIC3zdpX3lmwwRG9z5EBiODLtNY6tLjTS3lbmLwR1KxHPyOq39PNa E5wfMKDvot8fvU/4nWWEycMZLiwS+cXitjWdkgjm+trjZ0nSiSEWaLvPibu3JinztGqt zuK5/x4sJAP7ZxQfduxPwM1lKLVP/imHz/KF+wVeI9lSQAhXmGAt4LX/ZaUZz3V5InS1 1BKAm3XaqSPSdAb6Iz2WXxG0sOdvUyUSSISGsSeKo72Fv3hxZ/HTCapFvm9DIlmCG5nk NnSA== X-Gm-Message-State: APjAAAW+lekrZCKNgcI+vF7m/JKmoF9jBdWtcsSxDnLs5VRfgZMugyrF 7dH0hysG8linrFk5JMYCSs9NpyMR99tT X-Google-Smtp-Source: APXvYqwyscb1TaeUFUBGXJ73ubkLTKfe0z2l2Lro+IlYXlp12XiNJFnOngqs21OKnqFetDeE5nbVJNgE5v9e X-Received: by 2002:a1f:9456:: with SMTP id w83mr11552693vkd.67.1562173326650; Wed, 03 Jul 2019 10:02:06 -0700 (PDT) Date: Wed, 3 Jul 2019 10:01:14 -0700 In-Reply-To: <20190703170118.196552-1-brianvv@google.com> Message-Id: <20190703170118.196552-3-brianvv@google.com> Mime-Version: 1.0 References: <20190703170118.196552-1-brianvv@google.com> X-Mailer: git-send-email 2.22.0.410.gd8fdbe21b5-goog Subject: [PATCH bpf-next RFC v3 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: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org This introduces a new command to retrieve a variable 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 (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 buf 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 when a locked map the lock is grabbed for 1 entry at the time, meaning that the buf returned 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 | 118 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index cffea1826a1f..cc589570a639 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 */ + __u32 map_fd; + __aligned_u64 prev_key; + __aligned_u64 buf; + __aligned_u64 buf_len; /* input/output: len of buf */ + __u64 flags; + } 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 d200d2837ade..78d55463fc76 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -1097,6 +1097,121 @@ 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.buf_len + +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; + + attr->flags = 0; + 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 +3025,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 3 17:01:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Vazquez X-Patchwork-Id: 1126984 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="V8AEOwvA"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45f6qC217jz9sBp for ; Thu, 4 Jul 2019 03:02:31 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727310AbfGCRCN (ORCPT ); Wed, 3 Jul 2019 13:02:13 -0400 Received: from mail-pg1-f202.google.com ([209.85.215.202]:44567 "EHLO mail-pg1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727276AbfGCRCK (ORCPT ); Wed, 3 Jul 2019 13:02:10 -0400 Received: by mail-pg1-f202.google.com with SMTP id a21so1954049pgh.11 for ; Wed, 03 Jul 2019 10:02:09 -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=FObiLyW+7s29VatAFwxKLbXFDiZhgbEOFEz5IaW9X1w=; b=V8AEOwvALDT/8NX2//x05tIUvrGs+LLBWkkMt4Tq6pHW5f/PnuvfcIZjTjc2BO2qFL JzOszIwOXb2TEHCqDOZHt3yk7Sww+2v0Qg51V6t89xo8bESuZULcPxU+qWppWnpTXqmW t/VkkDo2pHH9td/cwUYFPhRGyO1M87HJwUi73lzhh5J5nmfwkk3BqUmFwBT+hSL913EE Z2vioVchf92XkkxlQeVoRdmTUlub1rbCM4uwTGWNDOa9/PDwhR+d1E/Cye6T0Vn9ROsd INc57Xeyj4ktrB6g6cVBCjCH84VKHEY5EPa2WP11gFKSLRL+KGGH2j3/rk4ddsgHyaD9 zDpQ== 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=FObiLyW+7s29VatAFwxKLbXFDiZhgbEOFEz5IaW9X1w=; b=Ki4wh2aZ1VIjGNBYTzZ8XOL1LYvYff6V/8rY94asyiAS3YAtWB29aOtQFSji1aznYi 7yjf8pRnGuoP/bub+VOx2aRqNsfu+uMGcsSu4fVDdcEtbyx4GDVITaCfbnVjxvcZOVX6 e+h0UIxEUd3EjpSQnaKlLxFNrBhbdgOD1mknzfa8JXSCWXAtfaqU+faqNm8XnjvSRpFr HRoMkUuPG7QDubdRtPrSAi6RpeIDVxTca9umPutMbLhrq8E3Kx9M+wi1mCTzcLnZOUOi VqEAGwEI5T29eQHU7qWsJLJbVEH+EPdYjK3QWiE8rCXTLpt5HIXvOOalRKBlVAd/mZe8 xcLQ== X-Gm-Message-State: APjAAAXJ5xhWg1wxPZZC2SSdhtYse2OmBHfJDGcG+g5o0xL8fBEcEqqW Kp17Zsr1yGooBCF0xXKIo7Fln2j0jk+B X-Google-Smtp-Source: APXvYqw7ANZEITdOhSvuXoIc8hQyumIQuEGkkEcpfrRV4llGdWK6mj1RIg3BGwZD1WSZTH+vcmEoW+Ex0+Er X-Received: by 2002:a65:420c:: with SMTP id c12mr18547310pgq.125.1562173328926; Wed, 03 Jul 2019 10:02:08 -0700 (PDT) Date: Wed, 3 Jul 2019 10:01:15 -0700 In-Reply-To: <20190703170118.196552-1-brianvv@google.com> Message-Id: <20190703170118.196552-4-brianvv@google.com> Mime-Version: 1.0 References: <20190703170118.196552-1-brianvv@google.com> X-Mailer: git-send-email 2.22.0.410.gd8fdbe21b5-goog Subject: [PATCH bpf-next RFC v3 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: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@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 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index a396b516a2b2..db6785a03538 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 */ + __u32 map_fd; + __aligned_u64 prev_key; + __aligned_u64 buf; + __aligned_u64 buf_len; /* input/output: len of buf */ + __u64 flags; + } dump; + struct { /* anonymous struct used by BPF_PROG_LOAD command */ __u32 prog_type; /* one of enum bpf_prog_type */ __u32 insn_cnt; From patchwork Wed Jul 3 17:01:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Vazquez X-Patchwork-Id: 1126978 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="SSaXIUdq"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45f6ps5p1wz9sBp for ; Thu, 4 Jul 2019 03:02:13 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727063AbfGCRCM (ORCPT ); Wed, 3 Jul 2019 13:02:12 -0400 Received: from mail-pf1-f201.google.com ([209.85.210.201]:35308 "EHLO mail-pf1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727305AbfGCRCM (ORCPT ); Wed, 3 Jul 2019 13:02:12 -0400 Received: by mail-pf1-f201.google.com with SMTP id r142so1859872pfc.2 for ; Wed, 03 Jul 2019 10:02:12 -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=SkPVxPTkLQnSJ+04pOruRJ+oHifbro+qasEP8Q6MwF4=; b=SSaXIUdqZIgZvFHvhwZvfBWgZIsMPL+K6OnKBFCRQjlPLpmeZzVc9rJIfRlNu+KnoX 4ZWEd5V9nO/Q714zf0mRBjIva4Sxy8h04AdI3omElqxwP+BTy58PYe7rLDOj7gs2f1vd 548JoeoIdOKvTeO46tkv7LBny1ufzCOq4q7nrnh7uttNUQVag3QljTBIofOwJfuHXIo6 0pMHl/SNcBCngGWHqT00tRid+cjvSgiPhUrXnn5Hwa8MAjjdXnAqdMGxJ5DpJIF2Ndn9 PWtH4zWlYaq8ICS1BUv6axZ3pkwVaSILw8SNHwsEddJzL/LRgfrLr3Plad7f1wUh9Bob KjiA== 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=SkPVxPTkLQnSJ+04pOruRJ+oHifbro+qasEP8Q6MwF4=; b=NIBdHjiypmr5I54jpHhy2se9a4gYAIBxTYW70Nq7is2pcPWg0Y1dhTm8OpWGUbg5fy Xccj5KdibPAzorns4UoNtwKKvE5Qcy/uotqGgln1l+mOGCJLuprjw4zW52wuV5i/DCf9 3XqnLM6t6/ZAlh3XKYEuvc6RM7UoGwue6b+FVS+mT3xtcTkIyAnj+0cgik/rzCK/9ri8 /yad4DZbuBggAIOLGm4yxXG6bUUPt7d0BaswIeS3AdKPmyClVGUHytxoMyuyWjIt23ms yJJGAJh4juBqjpuSJUQ8tdM8l7v4NM39vMtRVy8zEFZ20SeDsN0U619vqi61GVEN4+Eh muEw== X-Gm-Message-State: APjAAAX3CeDptiYYr4IzLdcFDpAwOCI9wHqIYt5McZ1lH2SJJE4CZaQN qbJOFC+3ZfcnVCKeYV5YDZUlWq2v9ycL X-Google-Smtp-Source: APXvYqzwZOQDxqTS/N9MpFJsKgq9Ee3V0ekH5sugwFoCEzm1svFIvb3/pv1IUUqPpPyaGYaH+UAcaXa52Jgy X-Received: by 2002:a63:a41:: with SMTP id z1mr37996608pgk.290.1562173331396; Wed, 03 Jul 2019 10:02:11 -0700 (PDT) Date: Wed, 3 Jul 2019 10:01:16 -0700 In-Reply-To: <20190703170118.196552-1-brianvv@google.com> Message-Id: <20190703170118.196552-5-brianvv@google.com> Mime-Version: 1.0 References: <20190703170118.196552-1-brianvv@google.com> X-Mailer: git-send-email 2.22.0.410.gd8fdbe21b5-goog Subject: [PATCH bpf-next RFC v3 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 ++++ tools/lib/bpf/libbpf.map | 2 ++ 3 files changed, 34 insertions(+) diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c index c7d7993c44bb..c1139b7db756 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 ff42ca043dc8..86496443440e 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); diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map index 2c6d835620d2..e7641773cfb0 100644 --- a/tools/lib/bpf/libbpf.map +++ b/tools/lib/bpf/libbpf.map @@ -173,4 +173,6 @@ LIBBPF_0.0.4 { btf__parse_elf; bpf_object__load_xattr; libbpf_num_possible_cpus; + bpf_map_dump; + bpf_map_dump_flags; } LIBBPF_0.0.3; From patchwork Wed Jul 3 17:01:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Vazquez X-Patchwork-Id: 1126981 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="nomp9tHg"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45f6q82dwHz9sN4 for ; Thu, 4 Jul 2019 03:02:28 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727346AbfGCRCS (ORCPT ); Wed, 3 Jul 2019 13:02:18 -0400 Received: from mail-qk1-f202.google.com ([209.85.222.202]:45511 "EHLO mail-qk1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727242AbfGCRCQ (ORCPT ); Wed, 3 Jul 2019 13:02:16 -0400 Received: by mail-qk1-f202.google.com with SMTP id k125so3729887qkc.12 for ; Wed, 03 Jul 2019 10:02:16 -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=7zXPbkaWJfiDYFqUaQDv1CcnFA8M8EK5B7uTwERQ454=; b=nomp9tHgj5x1czbVL2zJDJqXtjpKSKSPuyKFUjvAnaURASlRHYALaHhtn8TAxyG9JM tmJdn2pGDwGaYKQxll828yehZpKwqT8HfPtgvD+pebT4VXbM8ZPV82rjIewOGerCVgWq +eca2s280/NGFe80fGEGJCW4WQ9TjxJZ/kRj+OFHAprYBKLCdXygwT6zKRFgHDMNLKI8 fMeGZzL+fz3MGtfoiXlIt7aZJEqLs9r3kbmXEF6h6K2JEIqQmIrnFiGmybC/IlfPK4oG poBvAW0u77XLIpwoMDaU+TOvWnFixK2tm376kgKBDoVBX9CKnu+Lnv7zIeOpWodtnhNY t1PQ== 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=7zXPbkaWJfiDYFqUaQDv1CcnFA8M8EK5B7uTwERQ454=; b=VOMsPvGZ6jakFV8FiZ+nJyZtF0egEup5eab+lh5ll7jLGMmMJ8WIzyCEFw+xEr+QGF 9cY7uTJ6A2kp71x1PrqERyODI2dd6yrwLGpO4Hx0A0rndL7gFGMpLcJ6O6Mu0Dhv/jbN b32/CMKRRy7xoEsaloOgB0mQkr3vKr/QxHR4rGSRFJnKc4YI40+lh+cgsTDjZeFUYieU 4U00WLC60K+cHMfTYtKTk2z2HaDjrg29jcVJ0XjDMsvcxJVfzkCQHVMFAZ9F/+ZJ2GrM VaBCTJr7UCGQ2cgIHetz+e0TXmY1wzZb1vktYoDHs50ZuHV3jKVSZ4+idNx1S5IElXyq pi0Q== X-Gm-Message-State: APjAAAVptji2yf8KFa+7OuSAGd5dSFG5fbPZT2ehV+IO702oiZBl7Tlv lWGMgIUvOGNm6Z7BNvBHON6hKNJNmvIZ X-Google-Smtp-Source: APXvYqw2+o4+1Uveyzv9avWN5ZCckB/E4IsSuP8b1U0tKJD988+pjZxmb77+rL2WN8IbVBCDnR75BYEHcheH X-Received: by 2002:ac8:17ac:: with SMTP id o41mr31315016qtj.184.1562173334642; Wed, 03 Jul 2019 10:02:14 -0700 (PDT) Date: Wed, 3 Jul 2019 10:01:17 -0700 In-Reply-To: <20190703170118.196552-1-brianvv@google.com> Message-Id: <20190703170118.196552-6-brianvv@google.com> Mime-Version: 1.0 References: <20190703170118.196552-1-brianvv@google.com> X-Mailer: git-send-email 2.22.0.410.gd8fdbe21b5-goog Subject: [PATCH bpf-next RFC v3 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 | 82 ++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/bpf/test_maps.c b/tools/testing/selftests/bpf/test_maps.c index a3fbc571280a..b19ba6aa8e36 100644 --- a/tools/testing/selftests/bpf/test_maps.c +++ b/tools/testing/selftests/bpf/test_maps.c @@ -309,6 +309,85 @@ 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. + */ + 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]); + + 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; @@ -1668,6 +1747,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); @@ -1705,11 +1785,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 3 17:01:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Vazquez X-Patchwork-Id: 1126980 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="TZrCGi3j"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45f6q63dSyz9sBp for ; Thu, 4 Jul 2019 03:02:26 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727370AbfGCRCV (ORCPT ); Wed, 3 Jul 2019 13:02:21 -0400 Received: from mail-qk1-f201.google.com ([209.85.222.201]:35049 "EHLO mail-qk1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727353AbfGCRCT (ORCPT ); Wed, 3 Jul 2019 13:02:19 -0400 Received: by mail-qk1-f201.google.com with SMTP id 5so3789264qki.2 for ; Wed, 03 Jul 2019 10:02:18 -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=ld5qNoKshdyRmavLPGoPc6BR++OK/w6IRlR9/ebcOn4=; b=TZrCGi3jcqjHluRGRqVScSH3nnF0ngfzc7kFNydCQYZVuwuUp9YebJ1FMq1bxqWMB2 tHhtCnnfbK7nhfIkJVSbdsly1Sb2uJEw63ORMMbMjGr+rgwFeja8VYmU9bIvdijewmMB skRF5jPJjA2NhKt8fyeSp1jCTaAEYa1NkzzKxF1iRkEaRFI3/EQRfY+F+d+TlRIsPdAv IzoPvqZd+U6VyoEB4zaqJQ0v0zehg1PHAldRx3VPq/5pID7CAoImHt+9f8+LdaSB4iK/ jfZo3e5+EO4pm+3WJra8HHkX2pcDrI7PQWAwwDh+lDqqDiUn/6Y+hvW1lnoMzw3cM47K dJnw== 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=ld5qNoKshdyRmavLPGoPc6BR++OK/w6IRlR9/ebcOn4=; b=Xx92DqlaWzJjAdaWVp4u458vX+Rq27P4B+uQz39/h69HJQ6KoVK39+lMJG6ACpiJv1 /ymMYUF3nKlo11JKTle0AS66FcEMo0EU/3BLGml16SJInkkCld9VLZeqxmvDKSjtdPuP hHDRGkLSb7EbLXYNCaj44toU41joakAJyZGC0WtpHKHJyYzLctVDxscXV0WVIKmDJGIU AwjsKj2u3i8LeadyeQAIYNscKlyD79/rNMLwOQC8tNumLgGN83va5A5Od55MqdlBDunG Py0/oJO16R2CFYp0beJ5bamWgK8ObVy/mYw+kbziKGCBR5AVIfWgT2LzSHicHu7vnB2P JbAQ== X-Gm-Message-State: APjAAAUIDmwVBT5v50SI39RtTvY2KnDA7C07UptKiD2/v6Vt9LhIg1ns iV7GQQxSm4bkmHSTQaFldVi53IKTDA+6 X-Google-Smtp-Source: APXvYqzUJWgXSVAR31qVHYmLDhXP3MkV6i2uPSVDio5Wx5fkOVznYsw7k/Ij5SbCILaDCrihlPc/nePm9qGy X-Received: by 2002:ac8:6958:: with SMTP id n24mr32368355qtr.360.1562173338277; Wed, 03 Jul 2019 10:02:18 -0700 (PDT) Date: Wed, 3 Jul 2019 10:01:18 -0700 In-Reply-To: <20190703170118.196552-1-brianvv@google.com> Message-Id: <20190703170118.196552-7-brianvv@google.com> Mime-Version: 1.0 References: <20190703170118.196552-1-brianvv@google.com> X-Mailer: git-send-email 2.22.0.410.gd8fdbe21b5-goog Subject: [PATCH bpf-next RFC v3 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: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@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 b19ba6aa8e36..786d0e340aed 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 @@ -388,6 +389,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; @@ -1748,6 +1812,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);