From: Jisheng Zhang <jszhang@kernel.org>
To: Nick Kossifidis <mick@ics.forth.gr>
Cc: Paul Walmsley <paul.walmsley@sifive.com>,
Palmer Dabbelt <palmer@dabbelt.com>,
Albert Ou <aou@eecs.berkeley.edu>,
linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org,
Matteo Croce <mcroce@microsoft.com>,
kernel test robot <lkp@intel.com>
Subject: Re: [PATCH 2/3] riscv: optimized memmove
Date: Tue, 30 Jan 2024 21:12:03 +0800 [thread overview]
Message-ID: <Zbj1o6VAsk8Tn2ab@xhacker> (raw)
In-Reply-To: <fa36b871-43d7-413c-82a2-0ecc0ebce9b4@ics.forth.gr>
On Tue, Jan 30, 2024 at 01:39:10PM +0200, Nick Kossifidis wrote:
> On 1/28/24 13:10, Jisheng Zhang wrote:
> > From: Matteo Croce <mcroce@microsoft.com>
> >
> > When the destination buffer is before the source one, or when the
> > buffers doesn't overlap, it's safe to use memcpy() instead, which is
> > optimized to use a bigger data size possible.
> >
> > Signed-off-by: Matteo Croce <mcroce@microsoft.com>
> > Reported-by: kernel test robot <lkp@intel.com>
> > Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
>
> I'd expect to have memmove handle both fw/bw copying and then memcpy being
> an alias to memmove, to also take care when regions overlap and avoid
> undefined behavior.
Hi Nick,
Here is somthing from man memcpy:
"void *memcpy(void dest[restrict .n], const void src[restrict .n],
size_t n);
The memcpy() function copies n bytes from memory area src to memory area dest.
The memory areas must not overlap. Use memmove(3) if the memory areas do over‐
lap."
IMHO, the "restrict" implies that there's no overlap. If overlap
happens, the manual doesn't say what will happen.
From another side, I have a concern: currently, other arch don't have
this alias behavior, IIUC(at least, per my understanding of arm and arm64
memcpy implementations)they just copy forward. I want to keep similar behavior
for riscv.
So I want to hear more before going towards alias-memcpy-to-memmove direction.
Thanks
>
>
> > --- a/arch/riscv/lib/string.c
> > +++ b/arch/riscv/lib/string.c
> > @@ -119,3 +119,28 @@ void *memcpy(void *dest, const void *src, size_t count) __weak __alias(__memcpy)
> > EXPORT_SYMBOL(memcpy);
> > void *__pi_memcpy(void *dest, const void *src, size_t count) __alias(__memcpy);
> > void *__pi___memcpy(void *dest, const void *src, size_t count) __alias(__memcpy);
> > +
> > +/*
> > + * Simply check if the buffer overlaps an call memcpy() in case,
> > + * otherwise do a simple one byte at time backward copy.
> > + */
> > +void *__memmove(void *dest, const void *src, size_t count)
> > +{
> > + if (dest < src || src + count <= dest)
> > + return __memcpy(dest, src, count);
> > +
> > + if (dest > src) {
> > + const char *s = src + count;
> > + char *tmp = dest + count;
> > +
> > + while (count--)
> > + *--tmp = *--s;
> > + }
> > + return dest;
> > +}
> > +EXPORT_SYMBOL(__memmove);
> > +
>
> Here is an approach for the backwards case to get things started...
>
> static void
> copy_bw(void *dst_ptr, const void *src_ptr, size_t len)
> {
> union const_data src = { .as_bytes = src_ptr + len };
> union data dst = { .as_bytes = dst_ptr + len };
> size_t remaining = len;
> size_t src_offt = 0;
>
> if (len < 2 * WORD_SIZE)
> goto trailing_bw;
>
> for(; dst.as_uptr & WORD_MASK; remaining--)
> *--dst.as_bytes = *--src.as_bytes;
>
> src_offt = src.as_uptr & WORD_MASK;
> if (!src_offt) {
> for (; remaining >= WORD_SIZE; remaining -= WORD_SIZE)
> *--dst.as_ulong = *--src.as_ulong;
> } else {
> unsigned long cur, prev;
> src.as_bytes -= src_offt;
> for (; remaining >= WORD_SIZE; remaining -= WORD_SIZE) {
> cur = *src.as_ulong;
> prev = *--src.as_ulong;
> *--dst.as_ulong = cur << ((WORD_SIZE - src_offt) * 8) |
> prev >> (src_offt * 8);
> }
> src.as_bytes += src_offt;
> }
>
> trailing_bw:
> while (remaining-- > 0)
> *--dst.as_bytes = *--src.as_bytes;
> }
>
> Regards,
> Nick
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
next prev parent reply other threads:[~2024-01-30 13:25 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-01-28 11:10 [PATCH 0/3] riscv: optimize memcpy/memmove/memset Jisheng Zhang
2024-01-28 11:10 ` [PATCH 1/3] riscv: optimized memcpy Jisheng Zhang
2024-01-28 12:35 ` David Laight
2024-01-30 12:11 ` Nick Kossifidis
2024-01-28 11:10 ` [PATCH 2/3] riscv: optimized memmove Jisheng Zhang
2024-01-28 12:47 ` David Laight
2024-01-30 11:30 ` Jisheng Zhang
2024-01-30 11:51 ` David Laight
2024-01-30 11:39 ` Nick Kossifidis
2024-01-30 13:12 ` Jisheng Zhang [this message]
2024-01-30 16:52 ` Nick Kossifidis
2024-01-31 5:25 ` Jisheng Zhang
2024-01-31 9:13 ` Nick Kossifidis
2024-01-28 11:10 ` [PATCH 3/3] riscv: optimized memset Jisheng Zhang
2024-01-30 12:07 ` Nick Kossifidis
2024-01-30 13:25 ` Jisheng Zhang
2024-02-01 23:04 ` David Laight
2024-01-29 18:16 ` [PATCH 0/3] riscv: optimize memcpy/memmove/memset Conor Dooley
2024-01-30 2:28 ` Jisheng Zhang
-- strict thread matches above, loose matches on Subject: below --
2021-06-15 2:38 [PATCH 0/3] riscv: optimized mem* functions Matteo Croce
2021-06-15 2:38 ` [PATCH 2/3] riscv: optimized memmove Matteo Croce
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Zbj1o6VAsk8Tn2ab@xhacker \
--to=jszhang@kernel.org \
--cc=aou@eecs.berkeley.edu \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=lkp@intel.com \
--cc=mcroce@microsoft.com \
--cc=mick@ics.forth.gr \
--cc=palmer@dabbelt.com \
--cc=paul.walmsley@sifive.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).