Message ID | CAA3XUr20eFyLshVM+7VBSMz4a4-cCA0PLrYGN5oyk-wOM2NLtg@mail.gmail.com |
---|---|
State | New |
Headers | show |
On 23 April 2014 05:38, Will Deacon <will.deacon@arm.com> wrote: > On Wed, Apr 23, 2014 at 07:37:11AM +0100, Victor Kamensky wrote: >> Hi Will, > > Hi Victor, > > Thanks for investigating this! > >> On 22 April 2014 02:46, Will Deacon <will.deacon@arm.com> wrote: >> > On Mon, Apr 21, 2014 at 11:36:10PM +0100, Victor Kamensky wrote: >> The issue turned out to be in another commit: "word-at-a-time: >> provide generic big-endian zero_bytemask implementation". Because >> of the issue in zero_bytemask function full_name_hash and >> hash_name were giving different hash results for the same path >> name (without slash). The issue is that (~0ul << 64) gives >> ~0ul not 0. I could not come up with more elegant solution other >> than use inline function that check shift value against type maximum >> width. Please take a look below. > > Ah yes, we're in UNDEFINED territory here and AArch64 differs from AArch32 > wrt LSL >= register width. Can you try the following instead of your patch > please? I think it should be more efficient. Yes, it works. Checked initramfs and nfs boot with FVP. I knew you could do it way more elegant :). How do we get it in? Do you want to commit/submit it yourself? Thanks, Victor > Cheers, > > Will > > --->8 > > diff --git a/include/asm-generic/word-at-a-time.h b/include/asm-generic/word-at-a-time.h > index d3909effd725..243ce8c84ee9 100644 > --- a/include/asm-generic/word-at-a-time.h > +++ b/include/asm-generic/word-at-a-time.h > @@ -50,11 +50,7 @@ static inline bool has_zero(unsigned long val, unsigned long *data, const struct > } > > #ifndef zero_bytemask > -#ifdef CONFIG_64BIT > -#define zero_bytemask(mask) (~0ul << fls64(mask)) > -#else > -#define zero_bytemask(mask) (~0ul << fls(mask)) > -#endif /* CONFIG_64BIT */ > +#define zero_bytemask(mask) (mask ? ~0ul << __fls(mask) << 1 : ~0ul) > #endif /* zero_bytemask */ > > #endif /* _ASM_WORD_AT_A_TIME_H */
On Wed, Apr 23, 2014 at 05:22:22PM +0100, Victor Kamensky wrote: > On 23 April 2014 05:38, Will Deacon <will.deacon@arm.com> wrote: > > On Wed, Apr 23, 2014 at 07:37:11AM +0100, Victor Kamensky wrote: > >> Hi Will, > > > > Hi Victor, > > > > Thanks for investigating this! > > > >> On 22 April 2014 02:46, Will Deacon <will.deacon@arm.com> wrote: > >> > On Mon, Apr 21, 2014 at 11:36:10PM +0100, Victor Kamensky wrote: > >> The issue turned out to be in another commit: "word-at-a-time: > >> provide generic big-endian zero_bytemask implementation". Because > >> of the issue in zero_bytemask function full_name_hash and > >> hash_name were giving different hash results for the same path > >> name (without slash). The issue is that (~0ul << 64) gives > >> ~0ul not 0. I could not come up with more elegant solution other > >> than use inline function that check shift value against type maximum > >> width. Please take a look below. > > > > Ah yes, we're in UNDEFINED territory here and AArch64 differs from AArch32 > > wrt LSL >= register width. Can you try the following instead of your patch > > please? I think it should be more efficient. > > Yes, it works. Checked initramfs and nfs boot with FVP. Hurrah! > I knew you could do it way more elegant :). > > How do we get it in? Do you want to commit/submit it yourself? I'll send a patch to LKML and see what Torvalds thinks. I've just come to the realisation that fs/namei.c will *never* call zero_bytemask with a mask == 0x0, so I'd like to remove the conditional altogether (which would be beneficial on AArch32). I'll keep you on CC. Cheers, Will
diff --git a/include/asm-generic/word-at-a-time.h b/include/asm-generic/word-at-a-time.h index d3909ef..6c80ead 100644 --- a/include/asm-generic/word-at-a-time.h +++ b/include/asm-generic/word-at-a-time.h @@ -50,10 +50,20 @@ static inline bool has_zero(unsigned long val, unsigned long *data, const struct } #ifndef zero_bytemask +static inline unsigned long __zero_bytemask(unsigned long shift) +{ + unsigned long ret; + if (shift != BITS_PER_LONG) + ret = (~0ul << shift); + else + ret = 0; + return ret; +} + #ifdef CONFIG_64BIT -#define zero_bytemask(mask) (~0ul << fls64(mask)) +#define zero_bytemask(mask) (__zero_bytemask(fls64(mask))) #else -#define zero_bytemask(mask) (~0ul << fls(mask)) +#define zero_bytemask(mask) (__zero_bytemask(fls(mask))) #endif /* CONFIG_64BIT */ #endif /* zero_bytemask */