From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.0 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 526EAC43381 for ; Tue, 26 Feb 2019 12:44:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1AC3A2173C for ; Tue, 26 Feb 2019 12:44:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726084AbfBZMoV (ORCPT ); Tue, 26 Feb 2019 07:44:21 -0500 Received: from szxga07-in.huawei.com ([45.249.212.35]:55278 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1725954AbfBZMoV (ORCPT ); Tue, 26 Feb 2019 07:44:21 -0500 Received: from DGGEMS402-HUB.china.huawei.com (unknown [172.30.72.59]) by Forcepoint Email with ESMTP id B9B16590824229084C22; Tue, 26 Feb 2019 20:44:17 +0800 (CST) Received: from [10.151.23.176] (10.151.23.176) by smtp.huawei.com (10.3.19.202) with Microsoft SMTP Server (TLS) id 14.3.408.0; Tue, 26 Feb 2019 20:44:08 +0800 Subject: Re: [PATCH v2 for-4.19 1/2] xarray: Replace exceptional entries To: Matthew Wilcox CC: , Greg Kroah-Hartman , , Chao Yu , Miao Xie References: <20190225182754.GF2496@bombadil.infradead.org> <20190226051449.1968-1-gaoxiang25@huawei.com> From: Gao Xiang Message-ID: Date: Tue, 26 Feb 2019 20:43:43 +0800 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.3.0 MIME-Version: 1.0 In-Reply-To: <20190226051449.1968-1-gaoxiang25@huawei.com> Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Originating-IP: [10.151.23.176] X-CFilter-Loop: Reflected Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org Hi Matthew, On 2019/2/26 13:14, Gao Xiang wrote: > From: Matthew Wilcox > > commit 3159f943aafdbacb2f94c38fdaadabf2bbde2a14 upstream. > > Introduce xarray value entries and tagged pointers to replace radix > tree exceptional entries. This is a slight change in encoding to allow > the use of an extra bit (we can now store BITS_PER_LONG - 1 bits in a > value entry). It is also a change in emphasis; exceptional entries are > intimidating and different. As the comment explains, you can choose > to store values or pointers in the xarray and they are both first-class > citizens. > > Signed-off-by: Matthew Wilcox > Reviewed-by: Josef Bacik > [ take the minimum subset of tagged pointer support only. ] > Cc: Matthew Wilcox > Signed-off-by: Gao Xiang > --- > change log v2: > - fix tagged pointer apis to make it work properly pointed out by Matthew; Is this version ok? Could you kindly give an "Acked-by" tag for this patch? The following patch is important for erofs, I'd like to backport it ASAP... staging: erofs: fix race when the managed cache is enabled It will be of great help. Thanks in advance! Thanks, Gao Xiang > > drivers/staging/erofs/utils.c | 18 +++++---------- > include/linux/xarray.h | 52 +++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 58 insertions(+), 12 deletions(-) > > diff --git a/drivers/staging/erofs/utils.c b/drivers/staging/erofs/utils.c > index 595cf90af9bb..bdee9bd09f11 100644 > --- a/drivers/staging/erofs/utils.c > +++ b/drivers/staging/erofs/utils.c > @@ -35,7 +35,6 @@ static atomic_long_t erofs_global_shrink_cnt; > > #ifdef CONFIG_EROFS_FS_ZIP > > -/* radix_tree and the future XArray both don't use tagptr_t yet */ > struct erofs_workgroup *erofs_find_workgroup( > struct super_block *sb, pgoff_t index, bool *tag) > { > @@ -47,9 +46,8 @@ struct erofs_workgroup *erofs_find_workgroup( > rcu_read_lock(); > grp = radix_tree_lookup(&sbi->workstn_tree, index); > if (grp != NULL) { > - *tag = radix_tree_exceptional_entry(grp); > - grp = (void *)((unsigned long)grp & > - ~RADIX_TREE_EXCEPTIONAL_ENTRY); > + *tag = xa_pointer_tag(grp); > + grp = xa_untag_pointer(grp); > > if (erofs_workgroup_get(grp, &oldcount)) { > /* prefer to relax rcu read side */ > @@ -83,9 +81,7 @@ int erofs_register_workgroup(struct super_block *sb, > sbi = EROFS_SB(sb); > erofs_workstn_lock(sbi); > > - if (tag) > - grp = (void *)((unsigned long)grp | > - 1UL << RADIX_TREE_EXCEPTIONAL_SHIFT); > + grp = xa_tag_pointer(grp, tag); > > err = radix_tree_insert(&sbi->workstn_tree, > grp->index, grp); > @@ -131,9 +127,7 @@ unsigned long erofs_shrink_workstation(struct erofs_sb_info *sbi, > > for (i = 0; i < found; ++i) { > int cnt; > - struct erofs_workgroup *grp = (void *) > - ((unsigned long)batch[i] & > - ~RADIX_TREE_EXCEPTIONAL_ENTRY); > + struct erofs_workgroup *grp = xa_untag_pointer(batch[i]); > > first_index = grp->index + 1; > > @@ -150,8 +144,8 @@ unsigned long erofs_shrink_workstation(struct erofs_sb_info *sbi, > #endif > continue; > > - if (radix_tree_delete(&sbi->workstn_tree, > - grp->index) != grp) { > + if (xa_untag_pointer(radix_tree_delete(&sbi->workstn_tree, > + grp->index)) != grp) { > #ifdef EROFS_FS_HAS_MANAGED_CACHE > skip: > erofs_workgroup_unfreeze(grp, 1); > diff --git a/include/linux/xarray.h b/include/linux/xarray.h > index 2dfc8006fe64..51ae9779d08b 100644 > --- a/include/linux/xarray.h > +++ b/include/linux/xarray.h > @@ -9,6 +9,58 @@ > > #include > > +/** > + * xa_tag_pointer() - Create an XArray entry for a tagged pointer. > + * @p: Plain pointer. > + * @tag: Tag value (0 or 1). > + * > + * If the user of the XArray prefers, they can tag their pointers instead > + * of storing value entries. Two tags are available (0 and 1). > + * These are distinct from the xa_mark_t as they are not replicated up > + * through the array and cannot be searched for. > + * > + * Context: Any context. > + * Return: An XArray entry. > + */ > +static inline void *xa_tag_pointer(void *p, unsigned long tag) > +{ > + if (__builtin_constant_p(tag)) > + BUILD_BUG_ON(tag > 1); > + else > + BUG_ON(tag > 1); > + return (void *)((unsigned long)p | (tag << 1)); > +} > + > +/** > + * xa_untag_pointer() - Turn an XArray entry into a plain pointer. > + * @entry: XArray entry. > + * > + * If you have stored a tagged pointer in the XArray, call this function > + * to get the untagged version of the pointer. > + * > + * Context: Any context. > + * Return: A pointer. > + */ > +static inline void *xa_untag_pointer(void *entry) > +{ > + return (void *)((unsigned long)entry & ~3UL); > +} > + > +/** > + * xa_pointer_tag() - Get the tag stored in an XArray entry. > + * @entry: XArray entry. > + * > + * If you have stored a tagged pointer in the XArray, call this function > + * to get the tag of that pointer. > + * > + * Context: Any context. > + * Return: A tag. > + */ > +static inline unsigned int xa_pointer_tag(void *entry) > +{ > + return ((unsigned long)entry & 3UL) >> 1; > +} > + > #define xa_trylock(xa) spin_trylock(&(xa)->xa_lock) > #define xa_lock(xa) spin_lock(&(xa)->xa_lock) > #define xa_unlock(xa) spin_unlock(&(xa)->xa_lock) > From mboxrd@z Thu Jan 1 00:00:00 1970 From: gaoxiang25@huawei.com (Gao Xiang) Date: Tue, 26 Feb 2019 20:43:43 +0800 Subject: [PATCH v2 for-4.19 1/2] xarray: Replace exceptional entries In-Reply-To: <20190226051449.1968-1-gaoxiang25@huawei.com> References: <20190225182754.GF2496@bombadil.infradead.org> <20190226051449.1968-1-gaoxiang25@huawei.com> Message-ID: Hi Matthew, On 2019/2/26 13:14, Gao Xiang wrote: > From: Matthew Wilcox > > commit 3159f943aafdbacb2f94c38fdaadabf2bbde2a14 upstream. > > Introduce xarray value entries and tagged pointers to replace radix > tree exceptional entries. This is a slight change in encoding to allow > the use of an extra bit (we can now store BITS_PER_LONG - 1 bits in a > value entry). It is also a change in emphasis; exceptional entries are > intimidating and different. As the comment explains, you can choose > to store values or pointers in the xarray and they are both first-class > citizens. > > Signed-off-by: Matthew Wilcox > Reviewed-by: Josef Bacik > [ take the minimum subset of tagged pointer support only. ] > Cc: Matthew Wilcox > Signed-off-by: Gao Xiang > --- > change log v2: > - fix tagged pointer apis to make it work properly pointed out by Matthew; Is this version ok? Could you kindly give an "Acked-by" tag for this patch? The following patch is important for erofs, I'd like to backport it ASAP... staging: erofs: fix race when the managed cache is enabled It will be of great help. Thanks in advance! Thanks, Gao Xiang > > drivers/staging/erofs/utils.c | 18 +++++---------- > include/linux/xarray.h | 52 +++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 58 insertions(+), 12 deletions(-) > > diff --git a/drivers/staging/erofs/utils.c b/drivers/staging/erofs/utils.c > index 595cf90af9bb..bdee9bd09f11 100644 > --- a/drivers/staging/erofs/utils.c > +++ b/drivers/staging/erofs/utils.c > @@ -35,7 +35,6 @@ static atomic_long_t erofs_global_shrink_cnt; > > #ifdef CONFIG_EROFS_FS_ZIP > > -/* radix_tree and the future XArray both don't use tagptr_t yet */ > struct erofs_workgroup *erofs_find_workgroup( > struct super_block *sb, pgoff_t index, bool *tag) > { > @@ -47,9 +46,8 @@ struct erofs_workgroup *erofs_find_workgroup( > rcu_read_lock(); > grp = radix_tree_lookup(&sbi->workstn_tree, index); > if (grp != NULL) { > - *tag = radix_tree_exceptional_entry(grp); > - grp = (void *)((unsigned long)grp & > - ~RADIX_TREE_EXCEPTIONAL_ENTRY); > + *tag = xa_pointer_tag(grp); > + grp = xa_untag_pointer(grp); > > if (erofs_workgroup_get(grp, &oldcount)) { > /* prefer to relax rcu read side */ > @@ -83,9 +81,7 @@ int erofs_register_workgroup(struct super_block *sb, > sbi = EROFS_SB(sb); > erofs_workstn_lock(sbi); > > - if (tag) > - grp = (void *)((unsigned long)grp | > - 1UL << RADIX_TREE_EXCEPTIONAL_SHIFT); > + grp = xa_tag_pointer(grp, tag); > > err = radix_tree_insert(&sbi->workstn_tree, > grp->index, grp); > @@ -131,9 +127,7 @@ unsigned long erofs_shrink_workstation(struct erofs_sb_info *sbi, > > for (i = 0; i < found; ++i) { > int cnt; > - struct erofs_workgroup *grp = (void *) > - ((unsigned long)batch[i] & > - ~RADIX_TREE_EXCEPTIONAL_ENTRY); > + struct erofs_workgroup *grp = xa_untag_pointer(batch[i]); > > first_index = grp->index + 1; > > @@ -150,8 +144,8 @@ unsigned long erofs_shrink_workstation(struct erofs_sb_info *sbi, > #endif > continue; > > - if (radix_tree_delete(&sbi->workstn_tree, > - grp->index) != grp) { > + if (xa_untag_pointer(radix_tree_delete(&sbi->workstn_tree, > + grp->index)) != grp) { > #ifdef EROFS_FS_HAS_MANAGED_CACHE > skip: > erofs_workgroup_unfreeze(grp, 1); > diff --git a/include/linux/xarray.h b/include/linux/xarray.h > index 2dfc8006fe64..51ae9779d08b 100644 > --- a/include/linux/xarray.h > +++ b/include/linux/xarray.h > @@ -9,6 +9,58 @@ > > #include > > +/** > + * xa_tag_pointer() - Create an XArray entry for a tagged pointer. > + * @p: Plain pointer. > + * @tag: Tag value (0 or 1). > + * > + * If the user of the XArray prefers, they can tag their pointers instead > + * of storing value entries. Two tags are available (0 and 1). > + * These are distinct from the xa_mark_t as they are not replicated up > + * through the array and cannot be searched for. > + * > + * Context: Any context. > + * Return: An XArray entry. > + */ > +static inline void *xa_tag_pointer(void *p, unsigned long tag) > +{ > + if (__builtin_constant_p(tag)) > + BUILD_BUG_ON(tag > 1); > + else > + BUG_ON(tag > 1); > + return (void *)((unsigned long)p | (tag << 1)); > +} > + > +/** > + * xa_untag_pointer() - Turn an XArray entry into a plain pointer. > + * @entry: XArray entry. > + * > + * If you have stored a tagged pointer in the XArray, call this function > + * to get the untagged version of the pointer. > + * > + * Context: Any context. > + * Return: A pointer. > + */ > +static inline void *xa_untag_pointer(void *entry) > +{ > + return (void *)((unsigned long)entry & ~3UL); > +} > + > +/** > + * xa_pointer_tag() - Get the tag stored in an XArray entry. > + * @entry: XArray entry. > + * > + * If you have stored a tagged pointer in the XArray, call this function > + * to get the tag of that pointer. > + * > + * Context: Any context. > + * Return: A tag. > + */ > +static inline unsigned int xa_pointer_tag(void *entry) > +{ > + return ((unsigned long)entry & 3UL) >> 1; > +} > + > #define xa_trylock(xa) spin_trylock(&(xa)->xa_lock) > #define xa_lock(xa) spin_lock(&(xa)->xa_lock) > #define xa_unlock(xa) spin_unlock(&(xa)->xa_lock) >