lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20211012180148.1669685-1-hannes@cmpxchg.org>
Date:   Tue, 12 Oct 2021 14:01:37 -0400
From:   Johannes Weiner <hannes@...xchg.org>
To:     linux-mm@...ck.org
Cc:     Matthew Wilcox <willy@...radead.org>,
        Kent Overstreet <kent.overstreet@...il.com>,
        "Kirill A. Shutemov" <kirill@...temov.name>,
        Vlastimil Babka <vbabka@...e.cz>,
        Michal Hocko <mhocko@...e.com>, Roman Gushchin <guro@...com>,
        linux-kernel@...r.kernel.org, kernel-team@...com
Subject: [PATCH 00/11] PageSlab: eliminate unnecessary compound_head() calls

PageSlab() currently imposes a compound_head() call on all callsites
even though only very few situations encounter tailpages. This short
series bubbles tailpage resolution up to the few sites that need it,
and eliminates it everywhere else.

This is a stand-alone improvement. However, it's inspired by Willy's
patches to split struct slab from struct page. Those patches currently
resolve a slab object pointer to its struct slab as follows:

	slab = virt_to_slab(p);		/* tailpage resolution */
	if (slab_test_cache(slab)) {	/* slab or page alloc bypass? */
		do_slab_stuff(slab);
	} else {
		page = (struct page *)slab;
		do_page_stuff(page);
	}

which makes struct slab an ambiguous type that needs to self-identify
with the slab_test_cache() test (which in turn relies on PG_slab in
the flags field shared between page and slab).

It would be preferable to do:

	page = virt_to_head_page(p);	/* tailpage resolution */
	if (PageSlab(page)) {		/* slab or page alloc bypass? */
		slab = page_slab(page);
		do_slab_stuff(slab);
	} else {
		do_page_stuff(page);
	}

and leave the ambiguity and the need to self-identify with struct
page, so that struct slab is a strong and unambiguous type, and a
non-NULL struct slab encountered in the wild is always a valid object
without the need to check another dedicated flag for validity first.

However, because PageSlab() currently implies tailpage resolution,
writing the virt->slab lookup in the preferred way would add yet more
unnecessary compound_head() call to the hottest MM paths.

The page flag helpers should eventually all be weaned off of those
compound_head() calls for their unnecessary overhead alone. But this
one in particular is now getting in the way of writing code in the
preferred manner, and bleeding page ambiguity into the new types that
are supposed to eliminate specifically that. It's ripe for a cleanup.

Based on v5.15-rc4.

 arch/ia64/kernel/mca_drv.c |  2 +-
 drivers/ata/libata-sff.c   |  2 +-
 fs/proc/page.c             | 12 +++++++-----
 include/linux/net.h        |  2 +-
 include/linux/page-flags.h | 10 +++++-----
 mm/kasan/generic.c         |  2 +-
 mm/kasan/kasan.h           |  2 +-
 mm/kasan/report.c          |  4 ++--
 mm/kasan/report_tags.c     |  2 +-
 mm/memory-failure.c        |  6 +++---
 mm/memory.c                |  3 ++-
 mm/slab.h                  |  2 +-
 mm/slob.c                  |  4 ++--
 mm/slub.c                  |  6 +++---
 mm/util.c                  |  2 +-
 15 files changed, 32 insertions(+), 29 deletions(-)


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ