Some recent commits incorrectly assumed the natural alignment of locks. That assumption fails on Linux/m68k (and, interestingly, would have failed on Linux/cris also). This leads to spurious warnings from the hang check code. Fix this bug by adding the necessary 'aligned' attribute.
Cc: Andrew Morton akpm@linux-foundation.org Cc: Geert Uytterhoeven geert@linux-m68k.org Cc: Lance Yang lance.yang@linux.dev Cc: Masami Hiramatsu mhiramat@kernel.org Cc: Eero Tamminen oak@helsinkinet.fi Cc: Peter Zijlstra peterz@infradead.org Cc: Will Deacon will@kernel.org Cc: stable@vger.kernel.org Reported-by: Eero Tamminen oak@helsinkinet.fi Closes: https://lore.kernel.org/lkml/CAMuHMdW7Ab13DdGs2acMQcix5ObJK0O2dG_Fxzr8_g58Rc... Fixes: e711faaafbe5 ("hung_task: replace blocker_mutex with encoded blocker") Signed-off-by: Finn Thain fthain@linux-m68k.org --- I tested this on m68k using GCC and it fixed the problem for me. AFAIK, the other architectures naturally align ints already so I'm expecting to see no effect there. --- include/linux/types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/types.h b/include/linux/types.h index 6dfdb8e8e4c3..cd5b2b0f4b02 100644 --- a/include/linux/types.h +++ b/include/linux/types.h @@ -179,7 +179,7 @@ typedef phys_addr_t resource_size_t; typedef unsigned long irq_hw_number_t;
typedef struct { - int counter; + int counter __aligned(sizeof(int)); } atomic_t;
#define ATOMIC_INIT(i) { (i) }
Hi Finn,
Nice work, thanks for your patch!
On 2025/8/25 10:03, Finn Thain wrote:
Some recent commits incorrectly assumed the natural alignment of locks. That assumption fails on Linux/m68k (and, interestingly, would have failed on Linux/cris also). This leads to spurious warnings from the hang check code. Fix this bug by adding the necessary 'aligned' attribute.
Cc: Andrew Morton akpm@linux-foundation.org Cc: Geert Uytterhoeven geert@linux-m68k.org Cc: Lance Yang lance.yang@linux.dev Cc: Masami Hiramatsu mhiramat@kernel.org Cc: Eero Tamminen oak@helsinkinet.fi Cc: Peter Zijlstra peterz@infradead.org Cc: Will Deacon will@kernel.org Cc: stable@vger.kernel.org Reported-by: Eero Tamminen oak@helsinkinet.fi Closes: https://lore.kernel.org/lkml/CAMuHMdW7Ab13DdGs2acMQcix5ObJK0O2dG_Fxzr8_g58Rc... Fixes: e711faaafbe5 ("hung_task: replace blocker_mutex with encoded blocker") Signed-off-by: Finn Thain fthain@linux-m68k.org
I tested this on m68k using GCC and it fixed the problem for me. AFAIK, the other architectures naturally align ints already so I'm expecting to see no effect there.
Yeah, it is the correct approach for the spurious warnings on architectures like m68k, where the natural alignment of types can be less than 4 bytes.
include/linux/types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/types.h b/include/linux/types.h index 6dfdb8e8e4c3..cd5b2b0f4b02 100644 --- a/include/linux/types.h +++ b/include/linux/types.h @@ -179,7 +179,7 @@ typedef phys_addr_t resource_size_t; typedef unsigned long irq_hw_number_t; typedef struct {
- int counter;
- int counter __aligned(sizeof(int)); } atomic_t;
#define ATOMIC_INIT(i) { (i) }
However, as we've seen from the kernel test robot's report on mt6660_chip, this won't solve the cases where a lock is forced to be unaligned by #pragma pack(1). That will still trigger warnings, IIUC.
Perhaps we should also apply the follwoing?
diff --git a/include/linux/hung_task.h b/include/linux/hung_task.h index 34e615c76ca5..940f8f3558f6 100644 --- a/include/linux/hung_task.h +++ b/include/linux/hung_task.h @@ -45,7 +45,7 @@ static inline void hung_task_set_blocker(void *lock, unsigned long type) * If the lock pointer matches the BLOCKER_TYPE_MASK, return * without writing anything. */ - if (WARN_ON_ONCE(lock_ptr & BLOCKER_TYPE_MASK)) + if (lock_ptr & BLOCKER_TYPE_MASK) return;
WRITE_ONCE(current->blocker, lock_ptr | type); @@ -53,8 +53,6 @@ static inline void hung_task_set_blocker(void *lock, unsigned long type)
static inline void hung_task_clear_blocker(void) { - WARN_ON_ONCE(!READ_ONCE(current->blocker)); - WRITE_ONCE(current->blocker, 0UL); }
Let the feature gracefully do nothing on that ;)
On Mon, 25 Aug 2025, Lance Yang wrote:
However, as we've seen from the kernel test robot's report on mt6660_chip, this won't solve the cases where a lock is forced to be unaligned by #pragma pack(1). That will still trigger warnings, IIUC.
I think you've misunderstood the warning that your patch produced. (BTW, I have not seen any warnings from my own patch, so far.)
The mistake you made in your patch was to add an alignment attribute to a member of a packed struct. That's why I suggested that you should align the lock instead.
Is there some problem with my approach?
On 2025/8/25 11:59, Finn Thain wrote:
On Mon, 25 Aug 2025, Lance Yang wrote:
However, as we've seen from the kernel test robot's report on mt6660_chip, this won't solve the cases where a lock is forced to be unaligned by #pragma pack(1). That will still trigger warnings, IIUC.
I think you've misunderstood the warning that your patch produced. (BTW, I have not seen any warnings from my own patch, so far.)
The mistake you made in your patch was to add an alignment attribute to a member of a packed struct. That's why I suggested that you should align the lock instead.
Apologies for the confusion. I was referring to the runtime warning from WARN_ON_ONCE, not a compile-time warning.
On Mon, 25 Aug 2025, Lance Yang wrote:
Perhaps we should also apply the follwoing?
diff --git a/include/linux/hung_task.h b/include/linux/hung_task.h index 34e615c76ca5..940f8f3558f6 100644 --- a/include/linux/hung_task.h +++ b/include/linux/hung_task.h @@ -45,7 +45,7 @@ static inline void hung_task_set_blocker(void *lock, unsigned long type) * If the lock pointer matches the BLOCKER_TYPE_MASK, return * without writing anything. */
- if (WARN_ON_ONCE(lock_ptr & BLOCKER_TYPE_MASK))
if (lock_ptr & BLOCKER_TYPE_MASK) return;
WRITE_ONCE(current->blocker, lock_ptr | type);
@@ -53,8 +53,6 @@ static inline void hung_task_set_blocker(void *lock, unsigned long type)
static inline void hung_task_clear_blocker(void) {
- WARN_ON_ONCE(!READ_ONCE(current->blocker));
- WRITE_ONCE(current->blocker, 0UL);
}
Let the feature gracefully do nothing on that ;)
This is poor style indeed.
The conditional you've added to the hung task code has no real relevance to hung tasks. It doesn't belong there.
Of course, nobody wants that sort of logic to get duplicated at each site affected by the architectural quirk in question. Try to imagine if the whole kernel followed your example, and such unrelated conditionals were scattered across code base for a few decades. Now imagine trying to work on that code.
You can see special cases for architectural quirks in drivers, but we do try to avoid them. And this is not a driver.
On 2025/8/25 12:07, Finn Thain wrote:
On Mon, 25 Aug 2025, Lance Yang wrote:
Perhaps we should also apply the follwoing?
diff --git a/include/linux/hung_task.h b/include/linux/hung_task.h index 34e615c76ca5..940f8f3558f6 100644 --- a/include/linux/hung_task.h +++ b/include/linux/hung_task.h @@ -45,7 +45,7 @@ static inline void hung_task_set_blocker(void *lock, unsigned long type) * If the lock pointer matches the BLOCKER_TYPE_MASK, return * without writing anything. */
- if (WARN_ON_ONCE(lock_ptr & BLOCKER_TYPE_MASK))
if (lock_ptr & BLOCKER_TYPE_MASK) return;
WRITE_ONCE(current->blocker, lock_ptr | type);
@@ -53,8 +53,6 @@ static inline void hung_task_set_blocker(void *lock, unsigned long type)
static inline void hung_task_clear_blocker(void) {
- WARN_ON_ONCE(!READ_ONCE(current->blocker));
- WRITE_ONCE(current->blocker, 0UL); }
Let the feature gracefully do nothing on that ;)
This is poor style indeed.
Thanks for the lesson!
The conditional you've added to the hung task code has no real relevance to hung tasks. It doesn't belong there.
You're right! The original pointer-encoding was a deliberate trade-off to save a field in task_struct, but as we're seeing now, that assumption is fragile and causing issues :(
Of course, nobody wants that sort of logic to get duplicated at each site affected by the architectural quirk in question. Try to imagine if the whole kernel followed your example, and such unrelated conditionals were scattered across code base for a few decades. Now imagine trying to work on that code.
I agree with you completely: scattering more alignment checks into core logic isn't the right long-term solution. It's not a clean design :(
You can see special cases for architectural quirks in drivers, but we do try to avoid them. And this is not a driver.
So, how about this?
What if we squash the runtime check fix into your patch? That would create a single, complete fix that can be cleanly backported to stop all the spurious warnings at once.
Then, as a follow-up, we can work on the proper long-term solution: changing the pointer-encoding and re-introducing a dedicated field for the blocker type.
On 2025/8/25 14:17, Finn Thain wrote:
On Mon, 25 Aug 2025, Lance Yang wrote:
What if we squash the runtime check fix into your patch?
Did my patch not solve the problem?
Hmm... it should solve the problem for natural alignment, which is a critical fix.
But it cannot solve the problem of forced misalignment from drivers using #pragma pack(1). The runtime warning will still trigger in those cases.
I built a simple test module on a kernel with your patch applied:
``` #include <linux/module.h> #include <linux/init.h>
struct __attribute__((packed)) test_container { char padding[49]; struct mutex io_lock; };
static int __init alignment_init(void) { struct test_container cont; pr_info("io_lock address offset mod 4: %lu\n", (unsigned long)&cont.io_lock % 4); return 0; }
static void __exit alignment_exit(void) { pr_info("Module unloaded\n"); }
module_init(alignment_init); module_exit(alignment_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("x"); MODULE_DESCRIPTION("x"); ```
Result from dmesg: [Mon Aug 25 15:44:50 2025] io_lock address offset mod 4: 1
As we can see, a packed struct can still force the entire mutex object to an unaligned address. With an address like this, the WARN_ON_ONCE can still be triggered.
That's why I proposed squashing the runtime check fix into your patch. Then it can be cleanly backported to stop all the spurious warnings at once.
I hope this clarifies things.
[Belated Cc linux-m68k...]
On Mon, 25 Aug 2025, Lance Yang wrote:
On 2025/8/25 14:17, Finn Thain wrote:
On Mon, 25 Aug 2025, Lance Yang wrote:
What if we squash the runtime check fix into your patch?
Did my patch not solve the problem?
Hmm... it should solve the problem for natural alignment, which is a critical fix.
But it cannot solve the problem of forced misalignment from drivers using #pragma pack(1). The runtime warning will still trigger in those cases.
I built a simple test module on a kernel with your patch applied:
#include <linux/module.h> #include <linux/init.h> struct __attribute__((packed)) test_container { char padding[49]; struct mutex io_lock; }; static int __init alignment_init(void) { struct test_container cont; pr_info("io_lock address offset mod 4: %lu\n", (unsigned long)&cont.io_lock % 4); return 0; } static void __exit alignment_exit(void) { pr_info("Module unloaded\n"); } module_init(alignment_init); module_exit(alignment_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("x"); MODULE_DESCRIPTION("x");
Result from dmesg: [Mon Aug 25 15:44:50 2025] io_lock address offset mod 4: 1
Thanks for sending code to illustrate your point. Unfortunately, I was not able to reproduce your results. Tested on x86, your test module shows no misalignment:
[131840.349042] io_lock address offset mod 4: 0
Tested on m68k I also get 0, given the patch at the top of this thread:
[ 0.400000] io_lock address offset mod 4: 0
As we can see, a packed struct can still force the entire mutex object to an unaligned address. With an address like this, the WARN_ON_ONCE can still be triggered.
I don't think so. But there is something unexpected going on here -- the output from pahole appears to say io_lock is at offset 49, which seems to contradict the printk() output above.
struct test_container { char padding[49]; /* 0 49 */ struct mutex io_lock __attribute__((__aligned__(1))); /* 49 12 */
/* size: 61, cachelines: 1, members: 2 */ /* forced alignments: 1 */ /* last cacheline: 61 bytes */ } __attribute__((__packed__));
Thanks for digging deeper!
On 2025/8/25 18:49, Finn Thain wrote:
[Belated Cc linux-m68k...]
On Mon, 25 Aug 2025, Lance Yang wrote:
On 2025/8/25 14:17, Finn Thain wrote:
On Mon, 25 Aug 2025, Lance Yang wrote:
What if we squash the runtime check fix into your patch?
Did my patch not solve the problem?
Hmm... it should solve the problem for natural alignment, which is a critical fix.
But it cannot solve the problem of forced misalignment from drivers using #pragma pack(1). The runtime warning will still trigger in those cases.
I built a simple test module on a kernel with your patch applied:
#include <linux/module.h> #include <linux/init.h> struct __attribute__((packed)) test_container { char padding[49]; struct mutex io_lock; }; static int __init alignment_init(void) { struct test_container cont; pr_info("io_lock address offset mod 4: %lu\n", (unsigned long)&cont.io_lock % 4); return 0; } static void __exit alignment_exit(void) { pr_info("Module unloaded\n"); } module_init(alignment_init); module_exit(alignment_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("x"); MODULE_DESCRIPTION("x");
Result from dmesg: [Mon Aug 25 15:44:50 2025] io_lock address offset mod 4: 1
Thanks for sending code to illustrate your point. Unfortunately, I was not able to reproduce your results. Tested on x86, your test module shows no misalignment:
[131840.349042] io_lock address offset mod 4: 0
Tested on m68k I also get 0, given the patch at the top of this thread:
[ 0.400000] io_lock address offset mod 4: 0
As we can see, a packed struct can still force the entire mutex object to an unaligned address. With an address like this, the WARN_ON_ONCE can still be triggered.
I don't think so. But there is something unexpected going on here -- the output from pahole appears to say io_lock is at offset 49, which seems to contradict the printk() output above.
Interesting! That contradiction is the key. It seems we're seeing different compiler behaviors.
I'm on GCC 14.2.0 (Debian 14.2.0-19), and it appears to be strictly respecting the packed attribute.
So let's print something more:
``` #include <linux/module.h> #include <linux/init.h>
struct __attribute__((packed)) test_container { char padding[49]; struct mutex io_lock; };
static int __init alignment_init(void) { struct test_container cont; pr_info("Container base address : %px\n", &cont); pr_info("io_lock member address : %px\n", &cont.io_lock); pr_info("io_lock address offset mod 4: %lu\n", (unsigned long)&cont.io_lock % 4); return 0; }
static void __exit alignment_exit(void) { pr_info("Module unloaded\n"); }
module_init(alignment_init); module_exit(alignment_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("x"); MODULE_DESCRIPTION("x"); ```
Result from dmesg:
``` [Mon Aug 25 19:15:33 2025] Container base address : ff1100063570f840 [Mon Aug 25 19:15:33 2025] io_lock member address : ff1100063570f871 [Mon Aug 25 19:15:33 2025] io_lock address offset mod 4: 1 ```
io_lock is exactly base + 49, resulting in misalignment.
Seems like your compiler is cleverly re-aligning the whole struct on the stack, but we can't rely on that behavior, as it's not guaranteed across all compilers or versions. wdyt?
On 2025/8/25 19:19, Lance Yang wrote:
Thanks for digging deeper!
On 2025/8/25 18:49, Finn Thain wrote:
[Belated Cc linux-m68k...]
On Mon, 25 Aug 2025, Lance Yang wrote:
On 2025/8/25 14:17, Finn Thain wrote:
On Mon, 25 Aug 2025, Lance Yang wrote:
What if we squash the runtime check fix into your patch?
Did my patch not solve the problem?
Hmm... it should solve the problem for natural alignment, which is a critical fix.
But it cannot solve the problem of forced misalignment from drivers using #pragma pack(1). The runtime warning will still trigger in those cases.
I built a simple test module on a kernel with your patch applied:
#include <linux/module.h> #include <linux/init.h> struct __attribute__((packed)) test_container { char padding[49]; struct mutex io_lock; }; static int __init alignment_init(void) { struct test_container cont; pr_info("io_lock address offset mod 4: %lu\n", (unsigned long)&cont.io_lock % 4); return 0; } static void __exit alignment_exit(void) { pr_info("Module unloaded\n"); } module_init(alignment_init); module_exit(alignment_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("x"); MODULE_DESCRIPTION("x");
Result from dmesg: [Mon Aug 25 15:44:50 2025] io_lock address offset mod 4: 1
Thanks for sending code to illustrate your point. Unfortunately, I was not able to reproduce your results. Tested on x86, your test module shows no misalignment:
[131840.349042] io_lock address offset mod 4: 0
Tested on m68k I also get 0, given the patch at the top of this thread:
[ 0.400000] io_lock address offset mod 4: 0
As we can see, a packed struct can still force the entire mutex object to an unaligned address. With an address like this, the WARN_ON_ONCE can still be triggered.
I don't think so. But there is something unexpected going on here -- the output from pahole appears to say io_lock is at offset 49, which seems to contradict the printk() output above.
Interesting! That contradiction is the key. It seems we're seeing different compiler behaviors.
I'm on GCC 14.2.0 (Debian 14.2.0-19), and it appears to be strictly respecting the packed attribute.
So let's print something more:
#include <linux/module.h> #include <linux/init.h> struct __attribute__((packed)) test_container { char padding[49]; struct mutex io_lock; }; static int __init alignment_init(void) { struct test_container cont; pr_info("Container base address : %px\n", &cont); pr_info("io_lock member address : %px\n", &cont.io_lock); pr_info("io_lock address offset mod 4: %lu\n", (unsigned long)&cont.io_lock % 4); return 0; } static void __exit alignment_exit(void) { pr_info("Module unloaded\n"); } module_init(alignment_init); module_exit(alignment_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("x"); MODULE_DESCRIPTION("x");
Result from dmesg:
[Mon Aug 25 19:15:33 2025] Container base address : ff1100063570f840 [Mon Aug 25 19:15:33 2025] io_lock member address : ff1100063570f871 [Mon Aug 25 19:15:33 2025] io_lock address offset mod 4: 1
io_lock is exactly base + 49, resulting in misalignment.
Seems like your compiler is cleverly re-aligning the whole struct on the stack, but we can't rely on that behavior, as it's not guaranteed across all compilers or versions. wdyt?
Same here, using a global static variable instead of a local one. The result is consistently misaligned.
``` #include <linux/module.h> #include <linux/init.h>
static struct __attribute__((packed)) test_container { char padding[49]; struct mutex io_lock; } cont;
static int __init alignment_init(void) { pr_info("Container base address : %px\n", &cont); pr_info("io_lock member address : %px\n", &cont.io_lock); pr_info("io_lock address offset mod 4: %lu\n", (unsigned long)&cont.io_lock % 4); return 0; }
static void __exit alignment_exit(void) { pr_info("Module unloaded\n"); }
module_init(alignment_init); module_exit(alignment_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("x"); MODULE_DESCRIPTION("x"); ```
Result from dmesg:
``` [Mon Aug 25 19:33:28 2025] Container base address : ffffffffc28f0940 [Mon Aug 25 19:33:28 2025] io_lock member address : ffffffffc28f0971 [Mon Aug 25 19:33:28 2025] io_lock address offset mod 4: 1 ```
On Mon, 25 Aug 2025 15:46:42 +0800 Lance Yang lance.yang@linux.dev wrote:
On 2025/8/25 14:17, Finn Thain wrote:
On Mon, 25 Aug 2025, Lance Yang wrote:
What if we squash the runtime check fix into your patch?
Did my patch not solve the problem?
Hmm... it should solve the problem for natural alignment, which is a critical fix.
But it cannot solve the problem of forced misalignment from drivers using #pragma pack(1). The runtime warning will still trigger in those cases.
I built a simple test module on a kernel with your patch applied:
#include <linux/module.h> #include <linux/init.h> struct __attribute__((packed)) test_container { char padding[49]; struct mutex io_lock; }; static int __init alignment_init(void) { struct test_container cont; pr_info("io_lock address offset mod 4: %lu\n", (unsigned long)&cont.io_lock % 4);
Doesn't that give a compilation warning from 'taking the address of a packed member'? Ignore that at your peril.
More problematic is that, IIRC, m68k kmalloc() allocates 16bit aligned memory. This has broken other things in the past. I doubt that increasing the alignment to 32bits would make much difference to the kernel memory footprint.
David
return 0;
}
static void __exit alignment_exit(void) { pr_info("Module unloaded\n"); }
module_init(alignment_init); module_exit(alignment_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("x"); MODULE_DESCRIPTION("x");
Result from dmesg: [Mon Aug 25 15:44:50 2025] io_lock address offset mod 4: 1 As we can see, a packed struct can still force the entire mutex object to an unaligned address. With an address like this, the WARN_ON_ONCE can still be triggered. That's why I proposed squashing the runtime check fix into your patch. Then it can be cleanly backported to stop all the spurious warnings at once. I hope this clarifies things.
On 2025/8/25 20:07, David Laight wrote:
On Mon, 25 Aug 2025 15:46:42 +0800 Lance Yang lance.yang@linux.dev wrote:
On 2025/8/25 14:17, Finn Thain wrote:
On Mon, 25 Aug 2025, Lance Yang wrote:
What if we squash the runtime check fix into your patch?
Did my patch not solve the problem?
Hmm... it should solve the problem for natural alignment, which is a critical fix.
But it cannot solve the problem of forced misalignment from drivers using #pragma pack(1). The runtime warning will still trigger in those cases.
I built a simple test module on a kernel with your patch applied:
#include <linux/module.h> #include <linux/init.h> struct __attribute__((packed)) test_container { char padding[49]; struct mutex io_lock; }; static int __init alignment_init(void) { struct test_container cont; pr_info("io_lock address offset mod 4: %lu\n", (unsigned long)&cont.io_lock % 4);
Doesn't that give a compilation warning from 'taking the address of a packed member'? Ignore that at your peril.
Hmm, I don't see that acctully ...
More problematic is that, IIRC, m68k kmalloc() allocates 16bit aligned memory. This has broken other things in the past. I doubt that increasing the alignment to 32bits would make much difference to the kernel memory footprint.
@Finn Given this new information, how about we just apply the runtime check fix for now?
Since we plan to remove the entire pointer-encoding scheme later anyway, a minimal and targeted change could be the logical choice. It's easy and safe to backport, and it cleanly stops the warnings from all sources without introducing new risks - exactly what we need for stable kernels.
Cheers, Lance
On Mon, Aug 25, 2025 at 12:03:05PM +1000, Finn Thain wrote:
Some recent commits incorrectly assumed the natural alignment of locks. That assumption fails on Linux/m68k (and, interestingly, would have failed on Linux/cris also). This leads to spurious warnings from the hang check code. Fix this bug by adding the necessary 'aligned' attribute.
Cc: Andrew Morton akpm@linux-foundation.org Cc: Geert Uytterhoeven geert@linux-m68k.org Cc: Lance Yang lance.yang@linux.dev Cc: Masami Hiramatsu mhiramat@kernel.org Cc: Eero Tamminen oak@helsinkinet.fi Cc: Peter Zijlstra peterz@infradead.org Cc: Will Deacon will@kernel.org Cc: stable@vger.kernel.org Reported-by: Eero Tamminen oak@helsinkinet.fi Closes: https://lore.kernel.org/lkml/CAMuHMdW7Ab13DdGs2acMQcix5ObJK0O2dG_Fxzr8_g58Rc... Fixes: e711faaafbe5 ("hung_task: replace blocker_mutex with encoded blocker")
I don't see how this patch it at all relevant. Let along how its fixed by the below.
Signed-off-by: Finn Thain fthain@linux-m68k.org
I tested this on m68k using GCC and it fixed the problem for me. AFAIK, the other architectures naturally align ints already so I'm expecting to see no effect there.
include/linux/types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/types.h b/include/linux/types.h index 6dfdb8e8e4c3..cd5b2b0f4b02 100644 --- a/include/linux/types.h +++ b/include/linux/types.h @@ -179,7 +179,7 @@ typedef phys_addr_t resource_size_t; typedef unsigned long irq_hw_number_t; typedef struct {
- int counter;
- int counter __aligned(sizeof(int));
} atomic_t; #define ATOMIC_INIT(i) { (i) }
And your architecture doesn't trap on unaligned atomic access ?!!?!
On Mon, Aug 25, 2025 at 06:03:23PM +1000, Finn Thain wrote:
On Mon, 25 Aug 2025, Peter Zijlstra wrote:
And your architecture doesn't trap on unaligned atomic access ?!!?!
Right. This port doesn't do SMP.
There is RMW_INSN which seems to imply a compare-and-swap instruction of sorts. That is happy to work on unaligned storage?
Anyway, it might make sense to add an alignment check to arch/m68k/include/asm/atomic.h somewhere, perhaps dependent on some DEBUG flag or other.
linux-stable-mirror@lists.linaro.org