Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3d6357de authored by Arun KS's avatar Arun KS Committed by Linus Torvalds
Browse files

mm: reference totalram_pages and managed_pages once per function

Patch series "mm: convert totalram_pages, totalhigh_pages and managed
pages to atomic", v5.

This series converts totalram_pages, totalhigh_pages and
zone->managed_pages to atomic variables.

totalram_pages, zone->managed_pages and totalhigh_pages updates are
protected by managed_page_count_lock, but readers never care about it.
Convert these variables to atomic to avoid readers potentially seeing a
store tear.

Main motivation was that managed_page_count_lock handling was complicating
things.  It was discussed in length here,
https://lore.kernel.org/patchwork/patch/995739/#1181785 It seemes better
to remove the lock and convert variables to atomic.  With the change,
preventing poteintial store-to-read tearing comes as a bonus.

This patch (of 4):

This is in preparation to a later patch which converts totalram_pages and
zone->managed_pages to atomic variables.  Please note that re-reading the
value might lead to a different value and as such it could lead to
unexpected behavior.  There are no known bugs as a result of the current
code but it is better to prevent from them in principle.

Link: http://lkml.kernel.org/r/1542090790-21750-2-git-send-email-arunks@codeaurora.org


Signed-off-by: default avatarArun KS <arunks@codeaurora.org>
Reviewed-by: default avatarKonstantin Khlebnikov <khlebnikov@yandex-team.ru>
Reviewed-by: default avatarDavid Hildenbrand <david@redhat.com>
Acked-by: default avatarMichal Hocko <mhocko@suse.com>
Acked-by: default avatarVlastimil Babka <vbabka@suse.cz>
Reviewed-by: default avatarPavel Tatashin <pasha.tatashin@soleen.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent fecd4a50
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -52,7 +52,7 @@ void __init mem_init(void)
	/* this will put all low memory onto the freelists */
	memblock_free_all();
	max_low_pfn = totalram_pages;
	max_pfn = totalram_pages;
	max_pfn = max_low_pfn;
	mem_init_print_info(NULL);
	kmalloc_ok = 1;
}
+3 −2
Original line number Diff line number Diff line
@@ -434,9 +434,10 @@ static ssize_t microcode_write(struct file *file, const char __user *buf,
			       size_t len, loff_t *ppos)
{
	ssize_t ret = -EINVAL;
	unsigned long nr_pages = totalram_pages;

	if ((len >> PAGE_SHIFT) > totalram_pages) {
		pr_err("too much data (max %ld pages)\n", totalram_pages);
	if ((len >> PAGE_SHIFT) > nr_pages) {
		pr_err("too much data (max %ld pages)\n", nr_pages);
		return ret;
	}

+10 −9
Original line number Diff line number Diff line
@@ -1090,6 +1090,7 @@ static void process_info(struct hv_dynmem_device *dm, struct dm_info_msg *msg)
static unsigned long compute_balloon_floor(void)
{
	unsigned long min_pages;
	unsigned long nr_pages = totalram_pages;
#define MB2PAGES(mb) ((mb) << (20 - PAGE_SHIFT))
	/* Simple continuous piecewiese linear function:
	 *  max MiB -> min MiB  gradient
@@ -1102,16 +1103,16 @@ static unsigned long compute_balloon_floor(void)
	 *    8192       744    (1/16)
	 *   32768      1512	(1/32)
	 */
	if (totalram_pages < MB2PAGES(128))
		min_pages = MB2PAGES(8) + (totalram_pages >> 1);
	else if (totalram_pages < MB2PAGES(512))
		min_pages = MB2PAGES(40) + (totalram_pages >> 2);
	else if (totalram_pages < MB2PAGES(2048))
		min_pages = MB2PAGES(104) + (totalram_pages >> 3);
	else if (totalram_pages < MB2PAGES(8192))
		min_pages = MB2PAGES(232) + (totalram_pages >> 4);
	if (nr_pages < MB2PAGES(128))
		min_pages = MB2PAGES(8) + (nr_pages >> 1);
	else if (nr_pages < MB2PAGES(512))
		min_pages = MB2PAGES(40) + (nr_pages >> 2);
	else if (nr_pages < MB2PAGES(2048))
		min_pages = MB2PAGES(104) + (nr_pages >> 3);
	else if (nr_pages < MB2PAGES(8192))
		min_pages = MB2PAGES(232) + (nr_pages >> 4);
	else
		min_pages = MB2PAGES(488) + (totalram_pages >> 5);
		min_pages = MB2PAGES(488) + (nr_pages >> 5);
#undef MB2PAGES
	return min_pages;
}
+4 −3
Original line number Diff line number Diff line
@@ -380,10 +380,11 @@ void __init files_init(void)
void __init files_maxfiles_init(void)
{
	unsigned long n;
	unsigned long memreserve = (totalram_pages - nr_free_pages()) * 3/2;
	unsigned long nr_pages = totalram_pages;
	unsigned long memreserve = (nr_pages - nr_free_pages()) * 3/2;

	memreserve = min(memreserve, totalram_pages - 1);
	n = ((totalram_pages - memreserve) * (PAGE_SIZE / 1024)) / 10;
	memreserve = min(memreserve, nr_pages - 1);
	n = ((nr_pages - memreserve) * (PAGE_SIZE / 1024)) / 10;

	files_stat.max_files = max_t(unsigned long, n, NR_FILE);
}
+3 −2
Original line number Diff line number Diff line
@@ -744,15 +744,16 @@ void __init __weak arch_task_cache_init(void) { }
static void set_max_threads(unsigned int max_threads_suggested)
{
	u64 threads;
	unsigned long nr_pages = totalram_pages;

	/*
	 * The number of threads shall be limited such that the thread
	 * structures may only consume a small part of the available memory.
	 */
	if (fls64(totalram_pages) + fls64(PAGE_SIZE) > 64)
	if (fls64(nr_pages) + fls64(PAGE_SIZE) > 64)
		threads = MAX_THREADS;
	else
		threads = div64_u64((u64) totalram_pages * (u64) PAGE_SIZE,
		threads = div64_u64((u64) nr_pages * (u64) PAGE_SIZE,
				    (u64) THREAD_SIZE * 8UL);

	if (threads > max_threads_suggested)
Loading