ping? ... On 2019/3/4 13:13, Gao Xiang wrote: > ping? Is these two patches can be merged into linux-4.19? :'( > > Thanks, > Gao Xiang > > On 2019/2/26 20:43, Gao Xiang wrote: >> Hi Matthew, >> >> On 2019/2/26 13:14, Gao Xiang wrote: >>> From: Matthew Wilcox <willy@xxxxxxxxxxxxx> >>> >>> 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 <willy@xxxxxxxxxxxxx> >>> Reviewed-by: Josef Bacik <jbacik@xxxxxx> >>> [ take the minimum subset of tagged pointer support only. ] >>> Cc: Matthew Wilcox <willy@xxxxxxxxxxxxx> >>> Signed-off-by: Gao Xiang <gaoxiang25@xxxxxxxxxx> >>> --- >>> 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 <linux/spinlock.h> >>> >>> +/** >>> + * 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) >>>