From patchwork Mon Mar 21 13:22:47 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 8632701 Return-Path: X-Original-To: patchwork-linux-fsdevel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 7CC4B9F8A8 for ; Mon, 21 Mar 2016 13:22:36 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id CA88320320 for ; Mon, 21 Mar 2016 13:22:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id BFE37202F8 for ; Mon, 21 Mar 2016 13:22:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755118AbcCUNWc (ORCPT ); Mon, 21 Mar 2016 09:22:32 -0400 Received: from mx2.suse.de ([195.135.220.15]:51680 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754667AbcCUNWb (ORCPT ); Mon, 21 Mar 2016 09:22:31 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 913CEAB9D; Mon, 21 Mar 2016 13:22:29 +0000 (UTC) Received: by quack.suse.cz (Postfix, from userid 1000) id AB45D82520; Mon, 21 Mar 2016 14:22:58 +0100 (CET) From: Jan Kara To: linux-fsdevel@vger.kernel.org Cc: "Wilcox, Matthew R" , Ross Zwisler , Dan Williams , linux-nvdimm@lists.01.org, NeilBrown , Jan Kara Subject: [PATCH 02/10] radix-tree: make 'indirect' bit available to exception entries. Date: Mon, 21 Mar 2016 14:22:47 +0100 Message-Id: <1458566575-28063-3-git-send-email-jack@suse.cz> X-Mailer: git-send-email 2.6.2 In-Reply-To: <1458566575-28063-1-git-send-email-jack@suse.cz> References: <1458566575-28063-1-git-send-email-jack@suse.cz> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: NeilBrown A pointer to a radix_tree_node will always have the 'exception' bit cleared, so if the exception bit is set the value cannot be an indirect pointer. Thus it is safe to make the 'indirect bit' available to store extra information in exception entries. This patch adds a 'PTR_MASK' and a value is only treated as an indirect (pointer) entry the 2 ls-bits are '01'. The change in radix-tree.c ensures the stored value still looks like an indirect pointer, and saves a load as well. We could swap the two bits and so keep all the exectional bits contigious. But I have other plans for that bit.... Signed-off-by: NeilBrown Signed-off-by: Jan Kara --- include/linux/radix-tree.h | 11 +++++++++-- lib/radix-tree.c | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h index d08d6ec3bf53..2bc8c5829441 100644 --- a/include/linux/radix-tree.h +++ b/include/linux/radix-tree.h @@ -41,8 +41,13 @@ * Indirect pointer in fact is also used to tag the last pointer of a node * when it is shrunk, before we rcu free the node. See shrink code for * details. + * + * To allow an exception entry to only lose one bit, we ignore + * the INDIRECT bit when the exception bit is set. So an entry is + * indirect if the least significant 2 bits are 01. */ #define RADIX_TREE_INDIRECT_PTR 1 +#define RADIX_TREE_INDIRECT_MASK 3 /* * A common use of the radix tree is to store pointers to struct pages; * but shmem/tmpfs needs also to store swap entries in the same tree: @@ -54,7 +59,8 @@ static inline int radix_tree_is_indirect_ptr(void *ptr) { - return (int)((unsigned long)ptr & RADIX_TREE_INDIRECT_PTR); + return ((unsigned long)ptr & RADIX_TREE_INDIRECT_MASK) + == RADIX_TREE_INDIRECT_PTR; } /*** radix-tree API starts here ***/ @@ -222,7 +228,8 @@ static inline void *radix_tree_deref_slot_protected(void **pslot, */ static inline int radix_tree_deref_retry(void *arg) { - return unlikely((unsigned long)arg & RADIX_TREE_INDIRECT_PTR); + return unlikely(((unsigned long)arg & RADIX_TREE_INDIRECT_MASK) + == RADIX_TREE_INDIRECT_PTR); } /** diff --git a/lib/radix-tree.c b/lib/radix-tree.c index 1624c4117961..c6af1a445b67 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c @@ -1412,7 +1412,7 @@ static inline void radix_tree_shrink(struct radix_tree_root *root) * to force callers to retry. */ if (root->height == 0) - *((unsigned long *)&to_free->slots[0]) |= + *((unsigned long *)&to_free->slots[0]) = RADIX_TREE_INDIRECT_PTR; radix_tree_node_free(to_free);