* malloc() alignment on 32 bit
@ 2022-09-19 12:37 Enrico Scholz
2022-09-19 13:33 ` Ahmad Fatoum
2022-09-19 13:57 ` Sascha Hauer
0 siblings, 2 replies; 6+ messages in thread
From: Enrico Scholz @ 2022-09-19 12:37 UTC (permalink / raw)
To: barebox
Hello,
on an iMX6ull I stumpled across
| zstd_decomp_init:536 workspace=8ff1a004+161320
| ERROR: initcall ubifs_init+0x1/0xc4 failed: Invalid argument
which is caused by
| static int zstd_decomp_init(void)
| void *wksp = malloc(wksp_size);
| ...
| ZSTD_DCtx* ZSTD_initStaticDCtx(void *workspace, size_t workspaceSize)
| if ((size_t)workspace & 7) return NULL; /* 8-aligned */
Trivial fix would be 'memalign(8, wksp_size)', but is it really ok that
malloc() for 32 bit has only an alignment of 4?
Relevant code seems to be in common/tlsf.c
| enum tlsf_private
| {
| #if defined (TLSF_64BIT)
| /* All allocation sizes and addresses are aligned to 8 bytes. */
| ALIGN_SIZE_LOG2 = 3,
| #else
| /* All allocation sizes and addresses are aligned to 4 bytes. */
| ALIGN_SIZE_LOG2 = 2,
| #endif
'ldrd/strd' require 8 byte alignment which might break with such
alignment.
Enrico
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: malloc() alignment on 32 bit
2022-09-19 12:37 malloc() alignment on 32 bit Enrico Scholz
@ 2022-09-19 13:33 ` Ahmad Fatoum
2022-09-19 13:57 ` Sascha Hauer
1 sibling, 0 replies; 6+ messages in thread
From: Ahmad Fatoum @ 2022-09-19 13:33 UTC (permalink / raw)
To: Enrico Scholz, barebox
On 19.09.22 13:37, Enrico Scholz wrote:
> Hello,
>
> on an iMX6ull I stumpled across
>
> | zstd_decomp_init:536 workspace=8ff1a004+161320
> | ERROR: initcall ubifs_init+0x1/0xc4 failed: Invalid argument
>
> which is caused by
>
> | static int zstd_decomp_init(void)
> | void *wksp = malloc(wksp_size);
> | ...
> | ZSTD_DCtx* ZSTD_initStaticDCtx(void *workspace, size_t workspaceSize)
> | if ((size_t)workspace & 7) return NULL; /* 8-aligned */
>
>
> Trivial fix would be 'memalign(8, wksp_size)', but is it really ok that
> malloc() for 32 bit has only an alignment of 4?
>
> Relevant code seems to be in common/tlsf.c
>
> | enum tlsf_private
> | {
> | #if defined (TLSF_64BIT)
> | /* All allocation sizes and addresses are aligned to 8 bytes. */
> | ALIGN_SIZE_LOG2 = 3,
> | #else
> | /* All allocation sizes and addresses are aligned to 4 bytes. */
> | ALIGN_SIZE_LOG2 = 2,
> | #endif
>
> 'ldrd/strd' require 8 byte alignment which might break with such
> alignment.
I recently learnt too that on 32-bit TLSF only has 4 byte alignment.
I also think that this is too low. 8 byte alignment sounds good IMO.
Cheers,
Ahmad
>
>
> Enrico
>
>
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: malloc() alignment on 32 bit
2022-09-19 12:37 malloc() alignment on 32 bit Enrico Scholz
2022-09-19 13:33 ` Ahmad Fatoum
@ 2022-09-19 13:57 ` Sascha Hauer
2022-09-19 14:24 ` Enrico Scholz
1 sibling, 1 reply; 6+ messages in thread
From: Sascha Hauer @ 2022-09-19 13:57 UTC (permalink / raw)
To: Enrico Scholz; +Cc: barebox
Hi Enrico,
On Mon, Sep 19, 2022 at 02:37:59PM +0200, Enrico Scholz wrote:
> Hello,
>
> on an iMX6ull I stumpled across
>
> | zstd_decomp_init:536 workspace=8ff1a004+161320
> | ERROR: initcall ubifs_init+0x1/0xc4 failed: Invalid argument
>
> which is caused by
>
> | static int zstd_decomp_init(void)
> | void *wksp = malloc(wksp_size);
> | ...
> | ZSTD_DCtx* ZSTD_initStaticDCtx(void *workspace, size_t workspaceSize)
> | if ((size_t)workspace & 7) return NULL; /* 8-aligned */
>
>
> Trivial fix would be 'memalign(8, wksp_size)', but is it really ok that
> malloc() for 32 bit has only an alignment of 4?
>
> Relevant code seems to be in common/tlsf.c
>
> | enum tlsf_private
> | {
> | #if defined (TLSF_64BIT)
> | /* All allocation sizes and addresses are aligned to 8 bytes. */
> | ALIGN_SIZE_LOG2 = 3,
> | #else
> | /* All allocation sizes and addresses are aligned to 4 bytes. */
> | ALIGN_SIZE_LOG2 = 2,
> | #endif
>
> 'ldrd/strd' require 8 byte alignment which might break with such
> alignment.
If you had asked me which alignment we have then I would have said it's
bigger. OTOH I never received any reports about insufficient alignment
on ARM or any other 32bit architecture.
I suspect we could just drop the check without any harm, but that's just
a gut feeling because we never had any alignment issues.
BTW are you sure ldrd/strd need 8 byte alignment? I just tested it with
the following patch and this works without problems. I verified the
compiler indeed generates ldrd/strd for accessing the 64bit field.
Sascha
-------------------------8<----------------------------
diff --git a/common/startup.c b/common/startup.c
index f53b73f81a..f261b1bdac 100644
--- a/common/startup.c
+++ b/common/startup.c
@@ -334,10 +334,31 @@ static void do_ctors(void)
int (*barebox_main)(void);
+struct bar {
+ uint64_t foo;
+};
+
+struct bar *myfoo(void)
+{
+ struct bar *x;
+ void *ptr;
+
+ ptr = malloc(16);
+
+ ptr = (void *)((unsigned long)ptr | 4);
+
+ x = ptr;
+
+ x->foo = get_time_ns();
+
+ return x;
+}
+
void __noreturn start_barebox(void)
{
initcall_t *initcall;
int result;
+ struct bar *b;
if (!IS_ENABLED(CONFIG_SHELL_NONE) && IS_ENABLED(CONFIG_COMMAND_SUPPORT))
barebox_main = run_init;
@@ -355,6 +376,9 @@ void __noreturn start_barebox(void)
pr_debug("initcalls done\n");
+ b = myfoo();
+ printf("V: %lld\n", b->foo);
+
if (IS_ENABLED(CONFIG_SELFTEST_AUTORUN))
selftests_run();
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: malloc() alignment on 32 bit
2022-09-19 13:57 ` Sascha Hauer
@ 2022-09-19 14:24 ` Enrico Scholz
2022-09-20 7:36 ` Sascha Hauer
0 siblings, 1 reply; 6+ messages in thread
From: Enrico Scholz @ 2022-09-19 14:24 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
Sascha Hauer <sha@pengutronix.de> writes:
>> | zstd_decomp_init:536 workspace=8ff1a004+161320
>> | ERROR: initcall ubifs_init+0x1/0xc4 failed: Invalid argument
>>
> If you had asked me which alignment we have then I would have said it's
> bigger. OTOH I never received any reports about insufficient alignment
> on ARM or any other 32bit architecture.
The code which failed for me was added 3 months ago
| commit b4a9782d4f56333e897dccc35c2c27e2605f6b93
| Author: Ahmad Fatoum <a.fatoum@pengutronix.de>
| Date: Wed Jul 13 12:09:18 2022 +0200
|
| lib: zstd: sync with Linux
and the Kconfig options (FS_UBIFS_COMPRESSION_ZSTD) are set to "off"...
> I suspect we could just drop the check without any harm, but that's just
> a gut feeling because we never had any alignment issues.
>
> BTW are you sure ldrd/strd need 8 byte alignment?
Their EX variants (LDREXD + STREXD; see [1]). Unaligned access on
plain LDRD/STRD is allowed on ARMv7-A. But not on ARMv7-M or ARMv6 and
earlier.
Enrico
Footnotes:
[1] https://developer.arm.com/documentation/ddi0406/c/Application-Level-Architecture/Application-Level-Memory-Model/Alignment-support/Unaligned-data-access
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: malloc() alignment on 32 bit
2022-09-19 14:24 ` Enrico Scholz
@ 2022-09-20 7:36 ` Sascha Hauer
2022-09-28 10:24 ` Enrico Scholz
0 siblings, 1 reply; 6+ messages in thread
From: Sascha Hauer @ 2022-09-20 7:36 UTC (permalink / raw)
To: Enrico Scholz; +Cc: barebox
On Mon, Sep 19, 2022 at 04:24:19PM +0200, Enrico Scholz wrote:
> Sascha Hauer <sha@pengutronix.de> writes:
>
> >> | zstd_decomp_init:536 workspace=8ff1a004+161320
> >> | ERROR: initcall ubifs_init+0x1/0xc4 failed: Invalid argument
> >>
> > If you had asked me which alignment we have then I would have said it's
> > bigger. OTOH I never received any reports about insufficient alignment
> > on ARM or any other 32bit architecture.
>
> The code which failed for me was added 3 months ago
>
> | commit b4a9782d4f56333e897dccc35c2c27e2605f6b93
> | Author: Ahmad Fatoum <a.fatoum@pengutronix.de>
> | Date: Wed Jul 13 12:09:18 2022 +0200
> |
> | lib: zstd: sync with Linux
>
> and the Kconfig options (FS_UBIFS_COMPRESSION_ZSTD) are set to "off"...
When I said I received no reports about insufficient malloc alignment I
meant reports about erroneous accesses, like wrong data read/writes or data
aborts.
>
>
> > I suspect we could just drop the check without any harm, but that's just
> > a gut feeling because we never had any alignment issues.
> >
> > BTW are you sure ldrd/strd need 8 byte alignment?
>
> Their EX variants (LDREXD + STREXD; see [1]). Unaligned access on
> plain LDRD/STRD is allowed on ARMv7-A. But not on ARMv7-M or ARMv6 and
> earlier.
Ok, I found this for the LDRD instruction:
| Prior to ARMv6, if the memory address is not 64-bit aligned, the data read from memory is
| UNPREDICTABLE. Alignment checking (taking a data abort), and support for a big-endian
| (BE-32) data format are implementation options.
So it seems it's really a good idea to increase malloc alignment
accordingly.
Sascha
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: malloc() alignment on 32 bit
2022-09-20 7:36 ` Sascha Hauer
@ 2022-09-28 10:24 ` Enrico Scholz
0 siblings, 0 replies; 6+ messages in thread
From: Enrico Scholz @ 2022-09-28 10:24 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
Sascha Hauer <sha@pengutronix.de> writes:
> So it seems it's really a good idea to increase malloc alignment
> accordingly.
But this does not seem to be trivial :(
A naive
| - ALIGN_SIZE_LOG2 = 2,
| + ALIGN_SIZE_LOG2 = 3,
triggers a lot of warnings.
I think, ALIGN_SIZE in tlsf_add_pool() and in the higher level functions
(tlsf_malloc(), _memalign(), _realloc()) should be replaced by a new,
bigger constant.
But this appears invasive and I have no idea about tlsf and the sideeffects :(
There exists https://github.com/mattconte/tlsf/issues/16 which asks for
proper alignment; but project seems to be unmaintained.
Replacing 'malloc()' with 'memalign()' on problems, seems the best idea
for now.
Enrico
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2022-09-28 10:25 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-19 12:37 malloc() alignment on 32 bit Enrico Scholz
2022-09-19 13:33 ` Ahmad Fatoum
2022-09-19 13:57 ` Sascha Hauer
2022-09-19 14:24 ` Enrico Scholz
2022-09-20 7:36 ` Sascha Hauer
2022-09-28 10:24 ` Enrico Scholz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox