From patchwork Mon Jan 11 15:57:00 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming Lei X-Patchwork-Id: 566011 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3C4DD1402C4 for ; Tue, 12 Jan 2016 02:58:52 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=E0jnixqK; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933751AbcAKP6d (ORCPT ); Mon, 11 Jan 2016 10:58:33 -0500 Received: from mail-pa0-f68.google.com ([209.85.220.68]:34958 "EHLO mail-pa0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933686AbcAKP5k (ORCPT ); Mon, 11 Jan 2016 10:57:40 -0500 Received: by mail-pa0-f68.google.com with SMTP id gi1so32041374pac.2; Mon, 11 Jan 2016 07:57:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=2GeCB/HDZPIgYMAetoFxF4q1nkWLUCJSZZbxvxhAILA=; b=E0jnixqK8ek1EeP5NWqVZf82+m5LfxRYXo+wyj0STL3xrm/NeD9NGV2Uqaob3nfHQa dh2vSFcIM5Ztys+imTy5/Segu7U0RGIPycRhr3BlaKhT3Y8qDPTc6xAG8QGOYZGXxNsr iViL7iYeFJ2VKPsa5rq7kydPIcscUgfiAAtMrY9MiUBWf8Ur1tpLpqTdFb6f/quLzAXg TDrGqQT4tq5uf+y4HDrY598CiperOmHnMi8dhuG9YDiqRXdfshfwqaS1VGZMIXVUm6Cz gazA2EyPRB8s/1DlRqVAqMBiQvJ/y1Z9ioVWAgFX/uq7hkeLCR8rcCSf417mFTFKHOq7 BcZw== X-Received: by 10.66.102.97 with SMTP id fn1mr183652182pab.131.1452527860236; Mon, 11 Jan 2016 07:57:40 -0800 (PST) Received: from localhost ([103.192.227.7]) by smtp.gmail.com with ESMTPSA id xz6sm186830272pab.42.2016.01.11.07.57.39 (version=TLS1_2 cipher=AES128-SHA bits=128/128); Mon, 11 Jan 2016 07:57:39 -0800 (PST) From: Ming Lei To: linux-kernel@vger.kernel.org, Alexei Starovoitov Cc: "David S. Miller" , netdev@vger.kernel.org, Daniel Borkmann , Martin KaFai Lau , Ming Lei Subject: [PATCH 8/9] sample/bpf: sockex1: user percpu array map Date: Mon, 11 Jan 2016 23:57:00 +0800 Message-Id: <1452527821-12276-9-git-send-email-tom.leiming@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1452527821-12276-1-git-send-email-tom.leiming@gmail.com> References: <1452527821-12276-1-git-send-email-tom.leiming@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org It is demonstrated the expensive atomic operations can be removed in eBPF prog. Signed-off-by: Ming Lei --- samples/bpf/sockex1_kern.c | 7 ++++--- samples/bpf/sockex1_user.c | 20 ++++++++++++++++---- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/samples/bpf/sockex1_kern.c b/samples/bpf/sockex1_kern.c index ed18e9a..400518a 100644 --- a/samples/bpf/sockex1_kern.c +++ b/samples/bpf/sockex1_kern.c @@ -5,7 +5,7 @@ #include "bpf_helpers.h" struct bpf_map_def SEC("maps") my_map = { - .type = BPF_MAP_TYPE_ARRAY, + .type = BPF_MAP_TYPE_ARRAY_PERCPU, .key_size = sizeof(u32), .value_size = sizeof(long), .max_entries = 256, @@ -16,13 +16,14 @@ int bpf_prog1(struct __sk_buff *skb) { int index = load_byte(skb, ETH_HLEN + offsetof(struct iphdr, protocol)); long *value; + unsigned cpu = bpf_get_smp_processor_id(); if (skb->pkt_type != PACKET_OUTGOING) return 0; - value = bpf_map_lookup_elem(&my_map, &index); + value = bpf_map_lookup_elem_percpu(&my_map, &index, cpu); if (value) - __sync_fetch_and_add(value, skb->len); + *value += skb->len; return 0; } diff --git a/samples/bpf/sockex1_user.c b/samples/bpf/sockex1_user.c index 678ce46..8572e81 100644 --- a/samples/bpf/sockex1_user.c +++ b/samples/bpf/sockex1_user.c @@ -6,6 +6,14 @@ #include #include +static int handle_one_cpu(unsigned cpu, void *val_cpu, void *val) +{ + long long *cnt = val; + + *cnt += *(long *)val_cpu; + return 0; +} + int main(int ac, char **argv) { char filename[256]; @@ -28,17 +36,21 @@ int main(int ac, char **argv) (void) f; for (i = 0; i < 5; i++) { - long long tcp_cnt, udp_cnt, icmp_cnt; + long cnt_percpu; + long long tcp_cnt = 0, udp_cnt = 0, icmp_cnt = 0; int key; key = IPPROTO_TCP; - assert(bpf_lookup_elem(map_fd[0], &key, &tcp_cnt) == 0); + assert(bpf_lookup_elem_allcpu(map_fd[0], &key, + &cnt_percpu, &tcp_cnt, handle_one_cpu) == 0); key = IPPROTO_UDP; - assert(bpf_lookup_elem(map_fd[0], &key, &udp_cnt) == 0); + assert(bpf_lookup_elem_allcpu(map_fd[0], &key, + &cnt_percpu, &udp_cnt, handle_one_cpu) == 0); key = IPPROTO_ICMP; - assert(bpf_lookup_elem(map_fd[0], &key, &icmp_cnt) == 0); + assert(bpf_lookup_elem_allcpu(map_fd[0], &key, + &cnt_percpu, &icmp_cnt, handle_one_cpu) == 0); printf("TCP %lld UDP %lld ICMP %lld bytes\n", tcp_cnt, udp_cnt, icmp_cnt);