|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v3 16/34] xen/lib: introduce generic find next bit operations
On Tue, 2024-01-23 at 12:14 +0100, Jan Beulich wrote:
> On 22.12.2023 16:13, Oleksii Kurochko wrote:
> > --- a/xen/arch/riscv/include/asm/fence.h
> > +++ b/xen/arch/riscv/include/asm/fence.h
> > @@ -1,4 +1,4 @@
> > -/* SPDX-License-Identifier: GPL-2.0-or-later */
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > #ifndef _ASM_RISCV_FENCE_H
> > #define _ASM_RISCV_FENCE_H
> >
> > @@ -11,3 +11,12 @@
> > #endif
> >
> > #endif /* _ASM_RISCV_FENCE_H */
> > +
> > +/*
> > + * Local variables:
> > + * mode: C
> > + * c-file-style: "BSD"
> > + * c-basic-offset: 4
> > + * indent-tabs-mode: nil
> > + * End:
> > + */
>
> Surely all of this wants doing in the previous patch, where the
> header
> is introduced?
Yes, it should be in the previous patch. I'll do the proper rebase.
>
> > --- a/xen/common/Kconfig
> > +++ b/xen/common/Kconfig
> > @@ -47,6 +47,9 @@ config ARCH_MAP_DOMAIN_PAGE
> > config GENERIC_BUG_FRAME
> > bool
> >
> > +config GENERIC_FIND_NEXT_BIT
> > + bool
>
> There's no need for this, as ...
>
> > --- a/xen/lib/Makefile
> > +++ b/xen/lib/Makefile
> > @@ -3,6 +3,7 @@ obj-$(CONFIG_X86) += x86/
> > lib-y += bsearch.o
> > lib-y += ctors.o
> > lib-y += ctype.o
> > +lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find-next-bit.o
>
> ... you're moving this to lib/. Or have you encountered any issue
> with building this uniformly, and you forgot to mention this in
> the description?
I didn't check. My intention was to provide opportunity to check if an
architecture want to use generic version or not. Otherwise, I expected
that we will have multiple definiotion of the funcion.
But considering that they are all defined under #ifdef...#endif we can
remove the declaration of the config GENERIC_FIND_NEXT_BIT.
>
> > --- /dev/null
> > +++ b/xen/lib/find-next-bit.c
> > @@ -0,0 +1,281 @@
> > +/* find_next_bit.c: fallback find next bit implementation
> > + *
> > + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
> > + * Written by David Howells (dhowells@xxxxxxxxxx)
> > + *
> > + * This program is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU General Public License
> > + * as published by the Free Software Foundation; either version
> > + * 2 of the License, or (at your option) any later version.
> > + */
> > +#include <xen/bitops.h>
> > +
> > +#include <asm/byteorder.h>
> > +
> > +#ifndef find_next_bit
> > +/*
> > + * Find the next set bit in a memory region.
> > + */
> > +unsigned long find_next_bit(const unsigned long *addr, unsigned
> > long size,
> > + unsigned long offset)
> > +{
> > + const unsigned long *p = addr + BIT_WORD(offset);
> > + unsigned long result = offset & ~(BITS_PER_LONG-1);
> > + unsigned long tmp;
> > +
> > + if (offset >= size)
> > + return size;
> > + size -= result;
> > + offset %= BITS_PER_LONG;
> > + if (offset) {
> > + tmp = *(p++);
> > + tmp &= (~0UL << offset);
> > + if (size < BITS_PER_LONG)
> > + goto found_first;
> > + if (tmp)
> > + goto found_middle;
> > + size -= BITS_PER_LONG;
> > + result += BITS_PER_LONG;
> > + }
> > + while (size & ~(BITS_PER_LONG-1)) {
> > + if ((tmp = *(p++)))
> > + goto found_middle;
> > + result += BITS_PER_LONG;
> > + size -= BITS_PER_LONG;
> > + }
> > + if (!size)
> > + return result;
> > + tmp = *p;
> > +
> > +found_first:
> > + tmp &= (~0UL >> (BITS_PER_LONG - size));
> > + if (tmp == 0UL) /* Are any bits set? */
> > + return result + size; /* Nope. */
> > +found_middle:
> > + return result + __ffs(tmp);
> > +}
> > +EXPORT_SYMBOL(find_next_bit);
> > +#endif
> > +
> > +#ifndef find_next_zero_bit
> > +/*
> > + * This implementation of find_{first,next}_zero_bit was stolen
> > from
> > + * Linus' asm-alpha/bitops.h.
> > + */
> > +unsigned long find_next_zero_bit(const unsigned long *addr,
> > unsigned long size,
> > + unsigned long offset)
> > +{
> > + const unsigned long *p = addr + BIT_WORD(offset);
> > + unsigned long result = offset & ~(BITS_PER_LONG-1);
> > + unsigned long tmp;
> > +
> > + if (offset >= size)
> > + return size;
> > + size -= result;
> > + offset %= BITS_PER_LONG;
> > + if (offset) {
> > + tmp = *(p++);
> > + tmp |= ~0UL >> (BITS_PER_LONG - offset);
> > + if (size < BITS_PER_LONG)
> > + goto found_first;
> > + if (~tmp)
> > + goto found_middle;
> > + size -= BITS_PER_LONG;
> > + result += BITS_PER_LONG;
> > + }
> > + while (size & ~(BITS_PER_LONG-1)) {
> > + if (~(tmp = *(p++)))
> > + goto found_middle;
> > + result += BITS_PER_LONG;
> > + size -= BITS_PER_LONG;
> > + }
> > + if (!size)
> > + return result;
> > + tmp = *p;
> > +
> > +found_first:
> > + tmp |= ~0UL << size;
> > + if (tmp == ~0UL) /* Are any bits zero? */
> > + return result + size; /* Nope. */
> > +found_middle:
> > + return result + ffz(tmp);
> > +}
> > +EXPORT_SYMBOL(find_next_zero_bit);
> > +#endif
> > +
> > +#ifndef find_first_bit
> > +/*
> > + * Find the first set bit in a memory region.
> > + */
> > +unsigned long find_first_bit(const unsigned long *addr, unsigned
> > long size)
> > +{
> > + const unsigned long *p = addr;
> > + unsigned long result = 0;
> > + unsigned long tmp;
> > +
> > + while (size & ~(BITS_PER_LONG-1)) {
> > + if ((tmp = *(p++)))
> > + goto found;
> > + result += BITS_PER_LONG;
> > + size -= BITS_PER_LONG;
> > + }
> > + if (!size)
> > + return result;
> > +
> > + tmp = (*p) & (~0UL >> (BITS_PER_LONG - size));
> > + if (tmp == 0UL) /* Are any bits set? */
> > + return result + size; /* Nope. */
> > +found:
> > + return result + __ffs(tmp);
> > +}
> > +EXPORT_SYMBOL(find_first_bit);
> > +#endif
> > +
> > +#ifndef find_first_zero_bit
> > +/*
> > + * Find the first cleared bit in a memory region.
> > + */
> > +unsigned long find_first_zero_bit(const unsigned long *addr,
> > unsigned long size)
> > +{
> > + const unsigned long *p = addr;
> > + unsigned long result = 0;
> > + unsigned long tmp;
> > +
> > + while (size & ~(BITS_PER_LONG-1)) {
> > + if (~(tmp = *(p++)))
> > + goto found;
> > + result += BITS_PER_LONG;
> > + size -= BITS_PER_LONG;
> > + }
> > + if (!size)
> > + return result;
> > +
> > + tmp = (*p) | (~0UL << size);
> > + if (tmp == ~0UL) /* Are any bits zero? */
> > + return result + size; /* Nope. */
> > +found:
> > + return result + ffz(tmp);
> > +}
> > +EXPORT_SYMBOL(find_first_zero_bit);
> > +#endif
> > +
> > +#ifdef __BIG_ENDIAN
> > +
> > +/* include/linux/byteorder does not support "unsigned long" type
> > */
> > +static inline unsigned long ext2_swabp(const unsigned long * x)
> > +{
> > +#if BITS_PER_LONG == 64
> > + return (unsigned long) __swab64p((u64 *) x);
> > +#elif BITS_PER_LONG == 32
> > + return (unsigned long) __swab32p((u32 *) x);
> > +#else
> > +#error BITS_PER_LONG not defined
> > +#endif
> > +}
> > +
> > +/* include/linux/byteorder doesn't support "unsigned long" type */
> > +static inline unsigned long ext2_swab(const unsigned long y)
> > +{
> > +#if BITS_PER_LONG == 64
> > + return (unsigned long) __swab64((u64) y);
> > +#elif BITS_PER_LONG == 32
> > + return (unsigned long) __swab32((u32) y);
> > +#else
> > +#error BITS_PER_LONG not defined
> > +#endif
> > +}
> > +
> > +#ifndef find_next_zero_bit_le
> > +unsigned long find_next_zero_bit_le(const void *addr, unsigned
> > + long size, unsigned long offset)
> > +{
> > + const unsigned long *p = addr;
> > + unsigned long result = offset & ~(BITS_PER_LONG - 1);
> > + unsigned long tmp;
> > +
> > + if (offset >= size)
> > + return size;
> > + p += BIT_WORD(offset);
> > + size -= result;
> > + offset &= (BITS_PER_LONG - 1UL);
> > + if (offset) {
> > + tmp = ext2_swabp(p++);
> > + tmp |= (~0UL >> (BITS_PER_LONG - offset));
> > + if (size < BITS_PER_LONG)
> > + goto found_first;
> > + if (~tmp)
> > + goto found_middle;
> > + size -= BITS_PER_LONG;
> > + result += BITS_PER_LONG;
> > + }
> > +
> > + while (size & ~(BITS_PER_LONG - 1)) {
> > + if (~(tmp = *(p++)))
> > + goto found_middle_swap;
> > + result += BITS_PER_LONG;
> > + size -= BITS_PER_LONG;
> > + }
> > + if (!size)
> > + return result;
> > + tmp = ext2_swabp(p);
> > +found_first:
> > + tmp |= ~0UL << size;
> > + if (tmp == ~0UL) /* Are any bits zero? */
> > + return result + size; /* Nope. Skip ffz */
> > +found_middle:
> > + return result + ffz(tmp);
> > +
> > +found_middle_swap:
> > + return result + ffz(ext2_swab(tmp));
> > +}
> > +EXPORT_SYMBOL(find_next_zero_bit_le);
> > +#endif
> > +
> > +#ifndef find_next_bit_le
> > +unsigned long find_next_bit_le(const void *addr, unsigned
> > + long size, unsigned long offset)
> > +{
> > + const unsigned long *p = addr;
> > + unsigned long result = offset & ~(BITS_PER_LONG - 1);
> > + unsigned long tmp;
> > +
> > + if (offset >= size)
> > + return size;
> > + p += BIT_WORD(offset);
> > + size -= result;
> > + offset &= (BITS_PER_LONG - 1UL);
> > + if (offset) {
> > + tmp = ext2_swabp(p++);
> > + tmp &= (~0UL << offset);
> > + if (size < BITS_PER_LONG)
> > + goto found_first;
> > + if (tmp)
> > + goto found_middle;
> > + size -= BITS_PER_LONG;
> > + result += BITS_PER_LONG;
> > + }
> > +
> > + while (size & ~(BITS_PER_LONG - 1)) {
> > + tmp = *(p++);
> > + if (tmp)
> > + goto found_middle_swap;
> > + result += BITS_PER_LONG;
> > + size -= BITS_PER_LONG;
> > + }
> > + if (!size)
> > + return result;
> > + tmp = ext2_swabp(p);
> > +found_first:
> > + tmp &= (~0UL >> (BITS_PER_LONG - size));
> > + if (tmp == 0UL) /* Are any bits set? */
> > + return result + size; /* Nope. */
> > +found_middle:
> > + return result + __ffs(tmp);
> > +
> > +found_middle_swap:
> > + return result + __ffs(ext2_swab(tmp));
> > +}
> > +EXPORT_SYMBOL(find_next_bit_le);
> > +#endif
> > +
> > +#endif /* __BIG_ENDIAN */
>
> I was going to ask that you convince git to actually present a proper
> diff, to make visible what changes. But other than the description
> says
> you don't really move the file, you copy it. Judging from further
> titles
> there's also nowhere you'd make Arm actually use this now generic
> code.
I wanted to do it separately, outside this patch series to simplify
review and not have Arm specific changes in RISC-V patch series.
Regarding a proper diff, you would like me to make git shows that it
was copy from Arm and it is not newly created file. Am I understand you
correctly?
~ Oleksii
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |