Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

s390/mm: implement MEM_PREPARE_ONLINE/MEM_FINISH_OFFLINE notifiers

MEM_PREPARE_ONLINE memory notifier makes memory block physical
accessible via sclp assign command. The notifier ensures self-contained
memory maps are accessible and hence enabling the "memmap on memory" on
s390.

MEM_FINISH_OFFLINE memory notifier shifts the memory block to an
inaccessible state via sclp unassign command.

Implementation considerations:
* When MHP_MEMMAP_ON_MEMORY is disabled, the system retains the old
behavior. This means the memory map is allocated from default memory.
* If MACHINE_HAS_EDAT1 is unavailable, MHP_MEMMAP_ON_MEMORY is
automatically disabled. This ensures that vmemmap pagetables do not
consume additional memory from the default memory allocator.
* The MEM_GOING_ONLINE notifier has been modified to perform no
operation, as MEM_PREPARE_ONLINE already executes the sclp assign
command.
* The MEM_CANCEL_ONLINE/MEM_OFFLINE notifier now performs no operation, as
MEM_FINISH_OFFLINE already executes the sclp unassign command.

Link: https://lkml.kernel.org/r/20240108132747.3238763-5-sumanthk@linux.ibm.com
Reviewed-by: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Cc: Anshuman Khandual <anshuman.khandual@arm.com>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Sumanth Korikkar and committed by
Andrew Morton
890a4212 fb6d5eb9

+35 -6
+35 -6
drivers/s390/char/sclp_cmd.c
··· 18 18 #include <linux/mm.h> 19 19 #include <linux/mmzone.h> 20 20 #include <linux/memory.h> 21 + #include <linux/memory_hotplug.h> 21 22 #include <linux/module.h> 22 23 #include <asm/ctlreg.h> 23 24 #include <asm/chpid.h> ··· 27 26 #include <asm/sclp.h> 28 27 #include <asm/numa.h> 29 28 #include <asm/facility.h> 29 + #include <asm/page-states.h> 30 30 31 31 #include "sclp.h" 32 32 ··· 342 340 if (contains_standby_increment(start, start + size)) 343 341 rc = -EPERM; 344 342 break; 345 - case MEM_GOING_ONLINE: 343 + case MEM_PREPARE_ONLINE: 344 + /* 345 + * Access the altmap_start_pfn and altmap_nr_pages fields 346 + * within the struct memory_notify specifically when dealing 347 + * with only MEM_PREPARE_ONLINE/MEM_FINISH_OFFLINE notifiers. 348 + * 349 + * When altmap is in use, take the specified memory range 350 + * online, which includes the altmap. 351 + */ 352 + if (arg->altmap_nr_pages) { 353 + start = PFN_PHYS(arg->altmap_start_pfn); 354 + size += PFN_PHYS(arg->altmap_nr_pages); 355 + } 346 356 rc = sclp_mem_change_state(start, size, 1); 357 + if (rc || !arg->altmap_nr_pages) 358 + break; 359 + /* 360 + * Set CMMA state to nodat here, since the struct page memory 361 + * at the beginning of the memory block will not go through the 362 + * buddy allocator later. 363 + */ 364 + __arch_set_page_nodat((void *)__va(start), arg->altmap_nr_pages); 347 365 break; 348 - case MEM_CANCEL_ONLINE: 349 - sclp_mem_change_state(start, size, 0); 350 - break; 351 - case MEM_OFFLINE: 366 + case MEM_FINISH_OFFLINE: 367 + /* 368 + * When altmap is in use, take the specified memory range 369 + * offline, which includes the altmap. 370 + */ 371 + if (arg->altmap_nr_pages) { 372 + start = PFN_PHYS(arg->altmap_start_pfn); 373 + size += PFN_PHYS(arg->altmap_nr_pages); 374 + } 352 375 sclp_mem_change_state(start, size, 0); 353 376 break; 354 377 default: ··· 424 397 if (!size) 425 398 goto skip_add; 426 399 for (addr = start; addr < start + size; addr += block_size) 427 - add_memory(0, addr, block_size, MHP_NONE); 400 + add_memory(0, addr, block_size, 401 + MACHINE_HAS_EDAT1 ? 402 + MHP_MEMMAP_ON_MEMORY | MHP_OFFLINE_INACCESSIBLE : MHP_NONE); 428 403 skip_add: 429 404 first_rn = rn; 430 405 num = 1;