From patchwork Mon Jan 23 01:11:22 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joe Stringer X-Patchwork-Id: 718322 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 3v6CxR64D0z9sCg for ; Mon, 23 Jan 2017 12:13:31 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750841AbdAWBLq (ORCPT ); Sun, 22 Jan 2017 20:11:46 -0500 Received: from relay6-d.mail.gandi.net ([217.70.183.198]:43364 "EHLO relay6-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750705AbdAWBLn (ORCPT ); Sun, 22 Jan 2017 20:11:43 -0500 Received: from mfilter17-d.gandi.net (mfilter17-d.gandi.net [217.70.178.145]) by relay6-d.mail.gandi.net (Postfix) with ESMTP id 40377FB87D; Mon, 23 Jan 2017 02:11:42 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at mfilter17-d.gandi.net Received: from relay6-d.mail.gandi.net ([IPv6:::ffff:217.70.183.198]) by mfilter17-d.gandi.net (mfilter17-d.gandi.net [::ffff:10.0.15.180]) (amavisd-new, port 10024) with ESMTP id SsFlKG5gyYyj; Mon, 23 Jan 2017 02:11:40 +0100 (CET) X-Originating-IP: 208.91.1.34 Received: from carno.eng.vmware.com (unknown [208.91.1.34]) (Authenticated sender: joe@ovn.org) by relay6-d.mail.gandi.net (Postfix) with ESMTPSA id 89A4FFB877; Mon, 23 Jan 2017 02:11:38 +0100 (CET) From: Joe Stringer To: acme@kernel.org Cc: wangnan0@huawei.com, ast@fb.com, daniel@iogearbox.net, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, Arnaldo Carvalho de Melo Subject: [PATCHv2 perf/core 1/7] tools lib bpf: Fix map offsets in relocation Date: Sun, 22 Jan 2017 17:11:22 -0800 Message-Id: <20170123011128.26534-2-joe@ovn.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170123011128.26534-1-joe@ovn.org> References: <20170123011128.26534-1-joe@ovn.org> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Commit 4708bbda5cb2 ("tools lib bpf: Fix maps resolution") attempted to fix map resolution by identifying the number of symbols that point to maps, and using this number to resolve each of the maps. However, during relocation the original definition of the map size was still in use. For up to two maps, the calculation was correct if there was a small difference in size between the map definition in libbpf and the one that the client library uses. However if the difference was large, particularly if more than two maps were used in the BPF program, the relocation would fail. For example, when using a map definition with size 28, with three maps, map relocation would count (sym_offset / sizeof(struct bpf_map_def) => map_idx) (0 / 16 => 0), ie map_idx = 0 (28 / 16 => 1), ie map_idx = 1 (56 / 16 => 3), ie map_idx = 3 So, libbpf reports: libbpf: bpf relocation: map_idx 3 large than 2 Fix map relocation by checking the exact offset of maps when doing relocation. Fixes: 4708bbda5cb2 ("tools lib bpf: Fix maps resolution") Signed-off-by: Joe Stringer Signed-off-by: Wang Nan [Allow different map size in an object] Cc: Alexei Starovoitov Cc: Daniel Borkmann Cc: Arnaldo Carvalho de Melo --- v2: Use cached offsets of maps for relocation (Wang Nan) This is a repost of the version Wang Nan posted on Jan 19. --- tools/lib/bpf/libbpf.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 84e6b35da4bd..671d5ad07cf1 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -779,7 +779,7 @@ static int bpf_program__collect_reloc(struct bpf_program *prog, size_t nr_maps, GElf_Shdr *shdr, Elf_Data *data, Elf_Data *symbols, - int maps_shndx) + int maps_shndx, struct bpf_map *maps) { int i, nrels; @@ -829,7 +829,15 @@ bpf_program__collect_reloc(struct bpf_program *prog, return -LIBBPF_ERRNO__RELOC; } - map_idx = sym.st_value / sizeof(struct bpf_map_def); + /* TODO: 'maps' is sorted. We can use bsearch to make it faster. */ + for (map_idx = 0; map_idx < nr_maps; map_idx++) { + if (maps[map_idx].offset == sym.st_value) { + pr_debug("relocation: find map %zd (%s) for insn %u\n", + map_idx, maps[map_idx].name, insn_idx); + break; + } + } + if (map_idx >= nr_maps) { pr_warning("bpf relocation: map_idx %d large than %d\n", (int)map_idx, (int)nr_maps - 1); @@ -953,7 +961,8 @@ static int bpf_object__collect_reloc(struct bpf_object *obj) err = bpf_program__collect_reloc(prog, nr_maps, shdr, data, obj->efile.symbols, - obj->efile.maps_shndx); + obj->efile.maps_shndx, + obj->maps); if (err) return err; }