Re: Oops with DCACHE_WORD_ACCESS and ocfs2, autofs4

From: Linus Torvalds
Date: Thu May 03 2012 - 15:07:20 EST


On Thu, May 3, 2012 at 11:28 AM, H. Peter Anvin <hpa@xxxxxxxxx> wrote:
> +               "lea" __WORDSUFFIX " %2,%1\n\t"
> +               "and" __WORDSUFFIX " %4,%1\n\t"
> +               "shl" __WORDSUFFIX " $3,%1\n\t"
> +               "shr" __WORDSUFFIX " %b1,%0\n\t"
>
> Also, for this sequence of instructions using %ecx unconditionally is
> actually better (avoids REX prefixes on 64 bits.)

Ok, agreed, except for the last shr, which does need to be done in the
full word width. But yes, we could do the calculations of "how many
bits do we need to shift" in just 32 bits.

And yes, it does look like we can just rely on the register names, so
we can avoid all the WORDSUFFIX games, and make it be


static inline unsigned long load_unaligned_zeropad(const void *addr)
{
unsigned long ret, dummy;

asm(
"1:\tmov %2,%0\n"
"2:\n"
".section .fixup,\"ax\"\n"
"3:\t"
"lea %2,%1\n\t"
"and %3,%1\n\t"
"mov (%1),%0\n\t"
"leal %2,%%ecx\n\t"
"andl %4,%%ecx\n\t"
"shll $3,%%ecx\n\t"
"shr %%cl,%0\n\t"
"jmp 2b\n"
".previous\n"
_ASM_EXTABLE(1b, 3b)
:"=&r" (ret),"=&c" (dummy)
:"m" (*(unsigned long *)addr),
"i" (-sizeof(unsigned long)),
"i" (sizeof(unsigned long)-1));
return ret;
}

instead.

And I'm running that with DEBUG_PAGEALLOC, and haven't seen anything
odd yet. Not that it's easy to trigger the page crosser, but I've
tried to do things like look up 4095-byte pathnames with the final
components being just one character each, so I've *tried*.

Linus
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/