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

ACPI: memhotplug: use a single static memory group for a single memory device

Let's group all memory we add for a single memory device - we want a
single node for that (which also seems to be the sane thing to do).

We won't care for now about memory that was already added to the system
(e.g., via e820) -- usually *all* memory of a memory device was already
added and we'll fail acpi_memory_enable_device().

Link: https://lkml.kernel.org/r/20210806124715.17090-6-david@redhat.com
Signed-off-by: David Hildenbrand <david@redhat.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Anshuman Khandual <anshuman.khandual@arm.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Hui Zhu <teawater@gmail.com>
Cc: Jason Wang <jasowang@redhat.com>
Cc: Len Brown <lenb@kernel.org>
Cc: Marek Kedzierski <mkedzier@redhat.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Pankaj Gupta <pankaj.gupta.linux@gmail.com>
Cc: Pavel Tatashin <pasha.tatashin@soleen.com>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Vitaly Kuznetsov <vkuznets@redhat.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Wei Yang <richard.weiyang@linux.alibaba.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

David Hildenbrand and committed by
Linus Torvalds
2a157839 836809ec

+30 -5
+30 -5
drivers/acpi/acpi_memhotplug.c
··· 54 54 struct acpi_memory_device { 55 55 struct acpi_device *device; 56 56 struct list_head res_list; 57 + int mgid; 57 58 }; 58 59 59 60 static acpi_status ··· 170 169 static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) 171 170 { 172 171 acpi_handle handle = mem_device->device->handle; 172 + mhp_t mhp_flags = MHP_NID_IS_MGID; 173 173 int result, num_enabled = 0; 174 174 struct acpi_memory_info *info; 175 - mhp_t mhp_flags = MHP_NONE; 176 - int node; 175 + u64 total_length = 0; 176 + int node, mgid; 177 177 178 178 node = acpi_get_node(handle); 179 + 180 + list_for_each_entry(info, &mem_device->res_list, list) { 181 + if (!info->length) 182 + continue; 183 + /* We want a single node for the whole memory group */ 184 + if (node < 0) 185 + node = memory_add_physaddr_to_nid(info->start_addr); 186 + total_length += info->length; 187 + } 188 + 189 + if (!total_length) { 190 + dev_err(&mem_device->device->dev, "device is empty\n"); 191 + return -EINVAL; 192 + } 193 + 194 + mgid = memory_group_register_static(node, PFN_UP(total_length)); 195 + if (mgid < 0) 196 + return mgid; 197 + mem_device->mgid = mgid; 198 + 179 199 /* 180 200 * Tell the VM there is more memory here... 181 201 * Note: Assume that this function returns zero on success ··· 210 188 */ 211 189 if (!info->length) 212 190 continue; 213 - if (node < 0) 214 - node = memory_add_physaddr_to_nid(info->start_addr); 215 191 216 192 if (mhp_supports_memmap_on_memory(info->length)) 217 193 mhp_flags |= MHP_MEMMAP_ON_MEMORY; 218 - result = __add_memory(node, info->start_addr, info->length, 194 + result = __add_memory(mgid, info->start_addr, info->length, 219 195 mhp_flags); 220 196 221 197 /* ··· 273 253 if (!mem_device) 274 254 return; 275 255 256 + /* In case we succeeded adding *some* memory, unregistering fails. */ 257 + if (mem_device->mgid >= 0) 258 + memory_group_unregister(mem_device->mgid); 259 + 276 260 acpi_memory_free_device_resources(mem_device); 277 261 mem_device->device->driver_data = NULL; 278 262 kfree(mem_device); ··· 297 273 298 274 INIT_LIST_HEAD(&mem_device->res_list); 299 275 mem_device->device = device; 276 + mem_device->mgid = -1; 300 277 sprintf(acpi_device_name(device), "%s", ACPI_MEMORY_DEVICE_NAME); 301 278 sprintf(acpi_device_class(device), "%s", ACPI_MEMORY_DEVICE_CLASS); 302 279 device->driver_data = mem_device;