From: "Huang, Ying" <ying.huang@intel.com>
To: Vlastimil Babka <vbabka@suse.cz>
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
Andrew Morton <akpm@linux-foundation.org>,
linux-mm@kvack.org, mm-commits@vger.kernel.org,
linux-kernel@vger.kernel.org,
Matthew Wilcox <willy@infradead.org>
Subject: Re: [GIT PULL] hotfixes for 6.3-rc1
Date: Thu, 09 Mar 2023 16:37:07 +0800 [thread overview]
Message-ID: <877cvq8gng.fsf@yhuang6-desk2.ccr.corp.intel.com> (raw)
In-Reply-To: <43f35191-9147-0aec-cb57-0bc14d041039@suse.cz> (Vlastimil Babka's message of "Wed, 8 Mar 2023 11:39:28 +0100")
Vlastimil Babka <vbabka@suse.cz> writes:
> On 3/6/23 02:25, Huang, Ying wrote:
>> Hi, Linus,
>>
>> Linus Torvalds <torvalds@linux-foundation.org> writes:
>>
>>> On Sat, Mar 4, 2023 at 3:21 PM Andrew Morton <akpm@linux-foundation.org> wrote:
>>>>
>>>> Ah. Ying did it this way:
>>>
>>> Yeah, I saw that patch flying past, but I actually think that it only
>>> silences the warning almost by mistake. There's nothing fundamental in
>>> there that a compiler wouldn't just follow across two assignments, and
>>> it just happens to now not trigger any more.
>>>
>>> Assigning to a union entry is a more fundamental operation in that
>>> respect. Not that the compiler still doesn't see that it's assigning a
>>> value that in the end is not really type compatible, so a different
>>> version of gcc could still warn, but at that point I feel like it's
>>> more of an actual compiler bug than just "oh, the compiler didn't
>>> happen to follow the cast through a temporary".
>>
>> Yes. Your fix is much better. This can be used for
>> __page_set_anon_rmap() family too to make the code look better?
>
> Those are trickier due to the PAGE_MAPPING_ANON tagging bit which your
> code doesn't need to handle because you can simply store an untagged
> anon_vma pointer. Otherwise we could have the union at the struct page
> level already (but probably not at this point as IIRC Matthew is
> planning to have completely separate types for anon and file folios).
>
> So right now we have e.g. folio_get_anon_vma() using unsigned long as
> the intermediate variable, page_move_anon_rmap() using a void *
> variable, __page_set_anon_rmap() casting through a (void *) ... Is there
> a single recommended way for "tagged pointers" that we could unify that to?
Ah, you are right. We need to deal with tagging bit and maybe struct
movable_operations *. I tried to write the below debug patch (only
build test it). The code adds 1 or 2 lines for each function. But to
be honest, the original force casting method appears more natural to me.
Best Regards,
Huang, Ying
---------------------------8<------------------------------------
From 68a0f54921beca8aeaa8fe78867e62b5a66658b8 Mon Sep 17 00:00:00 2001
From: Huang Ying <ying.huang@intel.com>
Date: Thu, 9 Mar 2023 15:29:58 +0800
Subject: [PATCH] dbg mapping_ptr
---
mm/rmap.c | 28 ++++++++++++++++++++--------
1 file changed, 20 insertions(+), 8 deletions(-)
diff --git a/mm/rmap.c b/mm/rmap.c
index 8632e02661ac..50ee208baff9 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -466,6 +466,13 @@ void __init anon_vma_init(void)
SLAB_PANIC|SLAB_ACCOUNT);
}
+union mapping_ptr {
+ struct address_space *mapping;
+ unsigned long tag;
+ struct anon_vma *anon_vma;
+ struct movable_operations *mops;
+};
+
/*
* Getting a lock on a stable anon_vma from a page off the LRU is tricky!
*
@@ -493,16 +500,17 @@ void __init anon_vma_init(void)
struct anon_vma *folio_get_anon_vma(struct folio *folio)
{
struct anon_vma *anon_vma = NULL;
- unsigned long anon_mapping;
+ union mapping_ptr mptr;
rcu_read_lock();
- anon_mapping = (unsigned long)READ_ONCE(folio->mapping);
- if ((anon_mapping & PAGE_MAPPING_FLAGS) != PAGE_MAPPING_ANON)
+ mptr.mapping = READ_ONCE(folio->mapping);
+ if ((mptr.tag & PAGE_MAPPING_FLAGS) != PAGE_MAPPING_ANON)
goto out;
if (!folio_mapped(folio))
goto out;
- anon_vma = (struct anon_vma *) (anon_mapping - PAGE_MAPPING_ANON);
+ mptr.tag &= ~PAGE_MAPPING_FLAGS;
+ anon_vma = mptr.anon_vma;
if (!atomic_inc_not_zero(&anon_vma->refcount)) {
anon_vma = NULL;
goto out;
@@ -1115,18 +1123,20 @@ int folio_total_mapcount(struct folio *folio)
void page_move_anon_rmap(struct page *page, struct vm_area_struct *vma)
{
void *anon_vma = vma->anon_vma;
+ union mapping_ptr mptr;
struct folio *folio = page_folio(page);
VM_BUG_ON_FOLIO(!folio_test_locked(folio), folio);
VM_BUG_ON_VMA(!anon_vma, vma);
- anon_vma += PAGE_MAPPING_ANON;
+ mptr.anon_vma = anon_vma;
+ mptr.tag |= PAGE_MAPPING_ANON;
/*
* Ensure that anon_vma and the PAGE_MAPPING_ANON bit are written
* simultaneously, so a concurrent reader (eg folio_referenced()'s
* folio_test_anon()) will not see one without the other.
*/
- WRITE_ONCE(folio->mapping, anon_vma);
+ WRITE_ONCE(folio->mapping, mptr.mapping);
SetPageAnonExclusive(page);
}
@@ -1142,6 +1152,7 @@ static void __page_set_anon_rmap(struct folio *folio, struct page *page,
struct vm_area_struct *vma, unsigned long address, int exclusive)
{
struct anon_vma *anon_vma = vma->anon_vma;
+ union mapping_ptr mptr;
BUG_ON(!anon_vma);
@@ -1162,8 +1173,9 @@ static void __page_set_anon_rmap(struct folio *folio, struct page *page,
* the PAGE_MAPPING_ANON type identifier, otherwise the rmap code
* could mistake the mapping for a struct address_space and crash.
*/
- anon_vma = (void *) anon_vma + PAGE_MAPPING_ANON;
- WRITE_ONCE(folio->mapping, (struct address_space *) anon_vma);
+ mptr.anon_vma = anon_vma;
+ mptr.tag |= PAGE_MAPPING_ANON;
+ WRITE_ONCE(folio->mapping, mptr.mapping);
folio->index = linear_page_index(vma, address);
out:
if (exclusive)
--
2.39.2
next prev parent reply other threads:[~2023-03-09 8:38 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-04 21:15 Andrew Morton
2023-03-04 22:26 ` pr-tracker-bot
2023-03-04 22:35 ` Linus Torvalds
2023-03-04 23:20 ` Andrew Morton
2023-03-04 23:37 ` Linus Torvalds
2023-03-06 1:25 ` Huang, Ying
2023-03-08 10:39 ` Vlastimil Babka
2023-03-09 8:37 ` Huang, Ying [this message]
2023-03-14 23:54 Andrew Morton
2023-03-15 2:41 ` pr-tracker-bot
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=877cvq8gng.fsf@yhuang6-desk2.ccr.corp.intel.com \
--to=ying.huang@intel.com \
--cc=akpm@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mm-commits@vger.kernel.org \
--cc=torvalds@linux-foundation.org \
--cc=vbabka@suse.cz \
--cc=willy@infradead.org \
/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