From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965233AbcIVRDi (ORCPT ); Thu, 22 Sep 2016 13:03:38 -0400 Received: from p3plsmtps2ded04.prod.phx3.secureserver.net ([208.109.80.198]:59820 "EHLO p3plsmtps2ded04.prod.phx3.secureserver.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934155AbcIVRDe (ORCPT ); Thu, 22 Sep 2016 13:03:34 -0400 x-originating-ip: 72.167.245.219 From: Matthew Wilcox To: Linus Torvalds , "Kirill A. Shutemov" , Andrew Morton , Konstantin Khlebnikov , Ross Zwisler Cc: linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-fsdevel@vger.kernel.org, Matthew Wilcox Subject: [PATCH 2/2] radix-tree: Fix optimisation problem Date: Thu, 22 Sep 2016 11:53:35 -0700 Message-Id: <1474570415-14938-3-git-send-email-mawilcox@linuxonhyperv.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1474570415-14938-1-git-send-email-mawilcox@linuxonhyperv.com> References: <1474570415-14938-1-git-send-email-mawilcox@linuxonhyperv.com> X-CMAE-Envelope: MS4wfC7SWLc0vsQyfwywxYp7f9RS93djZSmv848UVssyEWnXuqvkt90eG/wsChlR9wHqR6LzNsAtFw8CppAV5dIgMvBP4y5gtJPE0hs/ibSAe0Ei5CaaNax8 kTkPqqj4C+1AVt873BJ+9rtwZg7Ae5Y734wgLB1bD1Blh2l5VpQ3E2vchiVcBZiYxXFw3nUGtUFH0r8pX50QVBjXh6ttR/ULuHIwxMVESSlE+G/LqOXrmKe8 TeZCfhsd79O7z+sPNOhjjEoJ95knXo/uSXTDyhrD9o3RU/I3pL7ZXrLMilptpolqGlsgFQ1R47zzM9HiWFaXfWTyZ5PHjOntESkJ/7tsso60HgN9HEfKDoCn cGyAUUKP/Wl0/QCkYC70Iezv1HwnsUVwWRqYVIXeVpYx5kcWdf4yRYnjFYsN1hQSWTHaHUL48KP+y1NOEF67jzUJiOcUtsLWKQItHQ6afVddIl1en1dBsMNl 42WAaQrYmyIMIZD95FBSqzTQHDnMEc0KEHs3vA== Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Matthew Wilcox When compiling the radix tree with -O2, GCC thinks it can optimise: void *entry = parent->slots[offset]; int siboff = entry - parent->slots; void *slot = parent->slots + siboff; into void *slot = entry; Unfortunately, 'entry' is a tagged pointer, so this optimisation leads to getting an unaligned pointer back from radix_tree_lookup_slot(). The test suite wasn't being compiled with optimisation, so we hadn't spotted it before now. Change the test suite to compile with -O2, and fix the optimisation problem by passing 'entry' through entry_to_node() so gcc knows this isn't a plain pointer. --- lib/radix-tree.c | 3 ++- tools/testing/radix-tree/Makefile | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/radix-tree.c b/lib/radix-tree.c index 1b7bf73..8bf1f32 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c @@ -105,7 +105,8 @@ static unsigned int radix_tree_descend(struct radix_tree_node *parent, #ifdef CONFIG_RADIX_TREE_MULTIORDER if (radix_tree_is_internal_node(entry)) { - unsigned long siboff = get_slot_offset(parent, entry); + unsigned long siboff = get_slot_offset(parent, + (void **)entry_to_node(entry)); if (siboff < RADIX_TREE_MAP_SIZE) { offset = siboff; entry = rcu_dereference_raw(parent->slots[offset]); diff --git a/tools/testing/radix-tree/Makefile b/tools/testing/radix-tree/Makefile index 3b53046..9d0919ed 100644 --- a/tools/testing/radix-tree/Makefile +++ b/tools/testing/radix-tree/Makefile @@ -1,5 +1,5 @@ -CFLAGS += -I. -g -Wall -D_LGPL_SOURCE +CFLAGS += -I. -g -O2 -Wall -D_LGPL_SOURCE LDFLAGS += -lpthread -lurcu TARGETS = main OFILES = main.o radix-tree.o linux.o test.o tag_check.o find_next_bit.o \ -- 2.9.3