All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jaegeuk Kim <jaegeuk@kernel.org>
To: David Laight <David.Laight@aculab.com>
Cc: Zhiguo Niu <zhiguo.niu@unisoc.com>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"linux-f2fs-devel@lists.sourceforge.net"
	<linux-f2fs-devel@lists.sourceforge.net>
Subject: Re: [f2fs-dev] [PATCH] f2fs: fix unaligned field offset in 32-bits platform
Date: Thu, 9 Mar 2023 15:54:51 -0800	[thread overview]
Message-ID: <ZApxy2u9j3yKFRyS@google.com> (raw)
In-Reply-To: <942fe8111fdb48e583b846f3e2902228@AcuMS.aculab.com>

On 03/08, David Laight wrote:
> From: Chao Yu <chao@kernel.org>
> > Sent: 07 March 2023 15:14
> > 
> > F2FS-fs (dm-x): inconsistent rbtree, cur(3470333575168) next(3320009719808)
> > ------------[ cut here ]------------
> > kernel BUG at fs/f2fs/gc.c:602!
> > Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM
> > PC is at get_victim_by_default+0x13c0/0x1498
> > LR is at f2fs_check_rb_tree_consistence+0xc4/0xd4
> > ....
> > [<c04d98b0>] (get_victim_by_default) from [<c04d4f44>] (f2fs_gc+0x220/0x6cc)
> > [<c04d4f44>] (f2fs_gc) from [<c04d4780>] (gc_thread_func+0x2ac/0x708)
> > [<c04d4780>] (gc_thread_func) from [<c015c774>] (kthread+0x1a8/0x1b4)
> > [<c015c774>] (kthread) from [<c01010b4>] (ret_from_fork+0x14/0x20)
> > 
> > The reason is there is __packed attribute in struct rb_entry, but there
> > is no __packed attribute in struct victim_entry, so wrong offset of key
> > field will be parsed in struct rb_entry in f2fs_check_rb_tree_consistence,
> > it describes memory layouts of struct rb_entry and struct victim_entry in
> > 32-bits platform as below:
> > 
> > struct rb_entry {
> >    [0] struct rb_node rb_node;
> >        union {
> >            struct {...};
> >   [12]     unsigned long long key;
> >        } __packed;
> 
> This __packed removes the 4-byte pad before the union.
> I bet it should be removed...

struct rb_node {
        unsigned long  __rb_parent_color;
        struct rb_node *rb_right;
        struct rb_node *rb_left;
} __attribute__((aligned(sizeof(long))));

Hmm, isn't this aligned to 32bits originally? Why does 32bits pad 4-bytes
if we remove __packed?

> 
> > }
> > size of struct rb_entry: 20
> > 
> > struct victim_entry {
> >    [0] struct rb_node rb_node;
> >        union {
> >            struct {...};
> >   [16]     struct victim_info vi;
> >        };
> >   [32] struct list_head list;
> > }
> > size of struct victim_entry: 40
> > 
> > This patch tries to add __packed attribute in below structure:
> > - discard_info, discard_cmd
> > - extent_info, extent_node
> > - victim_info, victim_entry
> > in order to fix this unaligned field offset issue in 32-bits platform.
> 
> Have you looked at the amount of extra code that gets generated
> on systems that fault misaligned accesses?
> 
> Plausibly adding __packed __aligned(4) will restrict the compiler
> to just aligning 64bit items on 32bit boundaries.
> But even then is you pass the address of a misaligned structure
> to another function it will fault later of.
> 
> You haven't actually said where the misalignment comes from.
> If the code is doing (foo *)(ptr + 1) then that is broken
> when the alignments of 'ptr' and 'foo' differ.

IIUC, the problem comes since we access the same object with two structures
to handle rb_tree.

E.g.,

[struct extent_node]                   [struct rb_entry]
struct rb_node rb_node;                struct rb_node rb_node;
                                       union {
struct extent_info ei;                   struct {
  unsigned int fofs;                       unsigned int ofs;
  unsigned int len;                        unsigned int len;
                                         };
                                         unsigned long long key;
                                       } __packed;

So, I think if we get a different offset of fofs or ofs between in
extent_node and rb_entry, further work'll access a wrong memory since
we simply cast the object pointer between two.

> 
> 	David
> 
> -
> Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
> Registration No: 1397386 (Wales)


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

WARNING: multiple messages have this Message-ID (diff)
From: Jaegeuk Kim <jaegeuk@kernel.org>
To: David Laight <David.Laight@aculab.com>
Cc: 'Chao Yu' <chao@kernel.org>,
	"linux-f2fs-devel@lists.sourceforge.net" 
	<linux-f2fs-devel@lists.sourceforge.net>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	Zhiguo Niu <zhiguo.niu@unisoc.com>
Subject: Re: [PATCH] f2fs: fix unaligned field offset in 32-bits platform
Date: Thu, 9 Mar 2023 15:54:51 -0800	[thread overview]
Message-ID: <ZApxy2u9j3yKFRyS@google.com> (raw)
In-Reply-To: <942fe8111fdb48e583b846f3e2902228@AcuMS.aculab.com>

On 03/08, David Laight wrote:
> From: Chao Yu <chao@kernel.org>
> > Sent: 07 March 2023 15:14
> > 
> > F2FS-fs (dm-x): inconsistent rbtree, cur(3470333575168) next(3320009719808)
> > ------------[ cut here ]------------
> > kernel BUG at fs/f2fs/gc.c:602!
> > Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM
> > PC is at get_victim_by_default+0x13c0/0x1498
> > LR is at f2fs_check_rb_tree_consistence+0xc4/0xd4
> > ....
> > [<c04d98b0>] (get_victim_by_default) from [<c04d4f44>] (f2fs_gc+0x220/0x6cc)
> > [<c04d4f44>] (f2fs_gc) from [<c04d4780>] (gc_thread_func+0x2ac/0x708)
> > [<c04d4780>] (gc_thread_func) from [<c015c774>] (kthread+0x1a8/0x1b4)
> > [<c015c774>] (kthread) from [<c01010b4>] (ret_from_fork+0x14/0x20)
> > 
> > The reason is there is __packed attribute in struct rb_entry, but there
> > is no __packed attribute in struct victim_entry, so wrong offset of key
> > field will be parsed in struct rb_entry in f2fs_check_rb_tree_consistence,
> > it describes memory layouts of struct rb_entry and struct victim_entry in
> > 32-bits platform as below:
> > 
> > struct rb_entry {
> >    [0] struct rb_node rb_node;
> >        union {
> >            struct {...};
> >   [12]     unsigned long long key;
> >        } __packed;
> 
> This __packed removes the 4-byte pad before the union.
> I bet it should be removed...

struct rb_node {
        unsigned long  __rb_parent_color;
        struct rb_node *rb_right;
        struct rb_node *rb_left;
} __attribute__((aligned(sizeof(long))));

Hmm, isn't this aligned to 32bits originally? Why does 32bits pad 4-bytes
if we remove __packed?

> 
> > }
> > size of struct rb_entry: 20
> > 
> > struct victim_entry {
> >    [0] struct rb_node rb_node;
> >        union {
> >            struct {...};
> >   [16]     struct victim_info vi;
> >        };
> >   [32] struct list_head list;
> > }
> > size of struct victim_entry: 40
> > 
> > This patch tries to add __packed attribute in below structure:
> > - discard_info, discard_cmd
> > - extent_info, extent_node
> > - victim_info, victim_entry
> > in order to fix this unaligned field offset issue in 32-bits platform.
> 
> Have you looked at the amount of extra code that gets generated
> on systems that fault misaligned accesses?
> 
> Plausibly adding __packed __aligned(4) will restrict the compiler
> to just aligning 64bit items on 32bit boundaries.
> But even then is you pass the address of a misaligned structure
> to another function it will fault later of.
> 
> You haven't actually said where the misalignment comes from.
> If the code is doing (foo *)(ptr + 1) then that is broken
> when the alignments of 'ptr' and 'foo' differ.

IIUC, the problem comes since we access the same object with two structures
to handle rb_tree.

E.g.,

[struct extent_node]                   [struct rb_entry]
struct rb_node rb_node;                struct rb_node rb_node;
                                       union {
struct extent_info ei;                   struct {
  unsigned int fofs;                       unsigned int ofs;
  unsigned int len;                        unsigned int len;
                                         };
                                         unsigned long long key;
                                       } __packed;

So, I think if we get a different offset of fofs or ofs between in
extent_node and rb_entry, further work'll access a wrong memory since
we simply cast the object pointer between two.

> 
> 	David
> 
> -
> Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
> Registration No: 1397386 (Wales)

  reply	other threads:[~2023-03-09 23:55 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-07 15:14 [f2fs-dev] [PATCH] f2fs: fix unaligned field offset in 32-bits platform Chao Yu
2023-03-07 15:14 ` Chao Yu
2023-03-07 17:26 ` [f2fs-dev] " Jaegeuk Kim
2023-03-07 17:26   ` Jaegeuk Kim
2023-03-08  1:31   ` [f2fs-dev] " Chao Yu
2023-03-08  1:31     ` Chao Yu
2023-03-07 17:40 ` [f2fs-dev] " patchwork-bot+f2fs
2023-03-07 17:40   ` patchwork-bot+f2fs
2023-03-08 10:16 ` David Laight
2023-03-08 10:16   ` David Laight
2023-03-09 23:54   ` Jaegeuk Kim [this message]
2023-03-09 23:54     ` Jaegeuk Kim
2023-03-10  9:28     ` [f2fs-dev] " David Laight
2023-03-10  9:28       ` David Laight
2023-03-10 21:08       ` [f2fs-dev] " Jaegeuk Kim
2023-03-10 21:08         ` Jaegeuk Kim
2023-03-09 23:25 ` [f2fs-dev] " Jaegeuk Kim
2023-03-09 23:25   ` Jaegeuk Kim

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=ZApxy2u9j3yKFRyS@google.com \
    --to=jaegeuk@kernel.org \
    --cc=David.Laight@aculab.com \
    --cc=linux-f2fs-devel@lists.sourceforge.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=zhiguo.niu@unisoc.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.