From nobody Fri Jun 12 22:50:34 2026 Received: from mail-pl1-f177.google.com (mail-pl1-f177.google.com [209.85.214.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6FB3B32D0D8 for ; Tue, 12 May 2026 07:27:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778570825; cv=none; b=YtUP07VZMbHyjukGqccAjlePWb0pM4jM9uX7icDbCoFtGDbeZIs4fNhUm0juQDXX5HttFxy3RPAYBHSOSNvklcJONRDHIhhRAZefJjLVLUiad1u7ndB44av/hjE1GM6hPyhLL8xzmxfcUFIXMqhGOUc8rrjRdUJ9TlulY+KQepQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778570825; c=relaxed/simple; bh=uMIKuIDBKiM6AywTh8SPOlRTZMIQf529eDaNCHNLlNw=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=cTINAmnee+LG5VqofOZpg3qh7TaAkHBnXbuw8phc9oSZ98W9wQN6ftmHsfNO4/4iLqeTRw11TKyWbXw32a2ifw0vkTr/Mq2A5+e6zr3pM6e0sKX2yIkdkZBcA4E61tGbiZLULvdXtK7bu+aVBH5gXaug3mYpOeX9XF4f45K/caw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=bytedance.com; spf=pass smtp.mailfrom=bytedance.com; dkim=pass (2048-bit key) header.d=bytedance.com header.i=@bytedance.com header.b=eQDBEUmy; arc=none smtp.client-ip=209.85.214.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=bytedance.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bytedance.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bytedance.com header.i=@bytedance.com header.b="eQDBEUmy" Received: by mail-pl1-f177.google.com with SMTP id d9443c01a7336-2bc763e2ba8so14168535ad.3 for ; Tue, 12 May 2026 00:27:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bytedance.com; s=google; t=1778570823; x=1779175623; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=fx4e8OAen0NF75+J/YmhI593eekBwMCjX/uv6e51cmw=; b=eQDBEUmylSLkn8psS4Em2w1/9+UVxb3KK9BoccrY5ByMdxGMrFTEgskFBYJ5qju5Ld imV9Q7MnNG8q1fnc6nUsPdvYpJDskGMNBC3a4cGqPXiTYIPXVDNSMCWryfuz4l5ULPSA sRSAu6heGcn/AdBQnIaufqqprMd6TWHaYfDlWDB3jkPh8QdPdnx7PjD7aMAEeRkIfPkI V1Dnt7itoziyh11HxA7wwb8Ds+2yP+2BXXP4bhJ4kWh1i+sZGVhbFro/i0LcDIHZ8M9q gMNxrlNDxtuK/MyOywkNVkkZUG8H+tNYIGj3qhedTI073u+Ct5+kopMS0TzLtT2iSfir vH3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778570823; x=1779175623; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=fx4e8OAen0NF75+J/YmhI593eekBwMCjX/uv6e51cmw=; b=RAKrdWnBI6C0i9cU2XrDCOUJvisU4qm7C7YoSI6Nz7R14a8etWVTchLCTd674sY/n/ O9zNQv9tzuhs6bMNBIh5zK1jlsaHAVTkTEE8CmEOt581+8NGzvOZRTW+DD45dv/gcF+5 mP+is+Na5HaYl/IOv/xTm1dZrJjd1BwRBXG3iZ2JHQPsXxnGiJnK7aoNXmyHCAlmsRDD dlaO9lqBWi8NdjNURdMg/lJQdeRNM9x09NnAfechsPg5p1aq+QZ1X8taPSxWik+K/m+I B8cd4sVK+z3ENP4ptADMQzFCTvRZHhD8fxrQE5hJchlv+x1PWDSab7c8d/h1UyCSkfps 0DrA== X-Forwarded-Encrypted: i=1; AFNElJ8I1hW/8eiaL3OgP7n3JmIaBj2h7SeRGtL2ybmsnSS30MYgUUY78f/Oh8Y6qKS+moAXxa1g0qrHxqg03jA=@vger.kernel.org X-Gm-Message-State: AOJu0YwffsTh9CJFL1DPb7cNdYgaNImNhy1hbOlmLVSUoo+vtXoAgmEp smTApVG4zyt0E+GAfSX4VbexhWU0zGLgFGjnKNlwwWT9CXm0s64QHOORxMbb+AuRiZ4= X-Gm-Gg: Acq92OHlMtXltcX8xxxo2G7ChTbiZ9Kgk2Z85dxO2TLPCwc8KbnKC6PQRdTCSjfzLup zuEKGmFAYuYpyf23sUO4g3Rk7Sa1tdHOSP94G5zzvMpoRm5It/NoStGfkYeIT/vUuDvzj531X7i nMeTfEH176Z4o8jL2onn1/twgx2tSJd+JTd89elCIb/YEc9w4SfHa6YNwfLt8VqO2j/aEJ2TYb4 BmhIsg/DrHj8MpUaPkVrZmastjxHnR5ITyVYyv3xBtvyGfe2jB8UdvwNQtGEb5qX+vljz+CdFjI 5mVKN5s8lEuwZqM+WMGEvuW1ABxPIE+Y9clV4XThvK/OH54+IeuXLvGxL60CFPU1hQQpCOSejds huJLdrvslNF1MJ9NZl/tQoFqkKIxedG+InW5jeKZNA/hh6LzGD9FlXjkFvfT8lDRUrvRUqzQtUm Ea/IfpWY7CxEEu6an8Xg== X-Received: by 2002:a17:902:c401:b0:2bc:ebb1:e3a7 with SMTP id d9443c01a7336-2bd012b3330mr24218975ad.32.1778570822529; Tue, 12 May 2026 00:27:02 -0700 (PDT) Received: from n232-176-004.byted.org ([240e:83:200::343]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2baf1d2700dsm129200635ad.2.2026.05.12.00.26.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 May 2026 00:27:02 -0700 (PDT) From: Muchun Song To: Andrew Morton , David Hildenbrand , Greg Kroah-Hartman , linux-mm@kvack.org, driver-core@lists.linux.dev Cc: Oscar Salvador , Lorenzo Stoakes , "Liam R . Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Danilo Krummrich , "Rafael J . Wysocki" , linux-kernel@vger.kernel.org, linux-cxl@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-s390@vger.kernel.org, Madhavan Srinivasan , Michael Ellerman , Nicholas Piggin , Christophe Leroy , Heiko Carstens , Vasily Gorbik , Alexander Gordeev , Christian Borntraeger , Sven Schnelle , Sumanth Korikkar , Kees Cook , Douglas Anderson , Muchun Song , Donet Tom , muchun.song@linux.dev Subject: [PATCH v2] drivers/base/memory: make memory block get/put explicit Date: Tue, 12 May 2026 15:26:35 +0800 Message-ID: <20260512072635.3969576-1-songmuchun@bytedance.com> X-Mailer: git-send-email 2.54.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Rename the memory block lookup helper to make the acquired reference explicit, add memory_block_put() to wrap put_device(), remove find_memory_block(), and use memory_block_get() as the single block-id based lookup interface. This makes it clearer to callers that a successful lookup holds a reference that must be dropped, reducing the chance of forgetting the matching put and leaking the memory block device reference. Link: https://lore.kernel.org/linux-mm/7887915D-E598-42B3-9AFE-BFFBACE8DE2D= @linux.dev/#t Signed-off-by: Muchun Song Acked-by: Oscar Salvador Acked-by: David Hildenbrand (Arm) Acked-by: Michal Hocko Tested-by: Donet Tom Reviewed-by: Lorenzo Stoakes Acked-by: Mike Rapoport (Microsoft) Tested-by: Sumanth Korikkar #s390 --- Changes in v2: - mention the removal of find_memory_block() in the commit message - drop the redundant extern from the memory_block_get() declaration --- .../platforms/pseries/hotplug-memory.c | 14 ++----- drivers/base/memory.c | 38 +++++++------------ drivers/base/node.c | 4 +- drivers/s390/char/sclp_mem.c | 17 ++++----- include/linux/memory.h | 7 +++- mm/memory_hotplug.c | 5 +-- 6 files changed, 35 insertions(+), 50 deletions(-) diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc= /platforms/pseries/hotplug-memory.c index 75f85a5da981..94f3b57054b6 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c @@ -164,13 +164,7 @@ static int update_lmb_associativity_index(struct drmem= _lmb *lmb) =20 static struct memory_block *lmb_to_memblock(struct drmem_lmb *lmb) { - unsigned long section_nr; - struct memory_block *mem_block; - - section_nr =3D pfn_to_section_nr(PFN_DOWN(lmb->base_addr)); - - mem_block =3D find_memory_block(section_nr); - return mem_block; + return memory_block_get(phys_to_block_id(lmb->base_addr)); } =20 static int get_lmb_range(u32 drc_index, int n_lmbs, @@ -220,7 +214,7 @@ static int dlpar_change_lmb_state(struct drmem_lmb *lmb= , bool online) else rc =3D 0; =20 - put_device(&mem_block->dev); + memory_block_put(mem_block); =20 return rc; } @@ -319,12 +313,12 @@ static int dlpar_remove_lmb(struct drmem_lmb *lmb) =20 rc =3D dlpar_offline_lmb(lmb); if (rc) { - put_device(&mem_block->dev); + memory_block_put(mem_block); return rc; } =20 __remove_memory(lmb->base_addr, memory_block_size); - put_device(&mem_block->dev); + memory_block_put(mem_block); =20 /* Update memory regions for memory remove */ memblock_remove(lmb->base_addr, memory_block_size); diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 11d57cfa8d72..5b5d41089e81 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -649,7 +649,7 @@ int __weak arch_get_memory_phys_device(unsigned long st= art_pfn) * * Called under device_hotplug_lock. */ -struct memory_block *find_memory_block_by_id(unsigned long block_id) +struct memory_block *memory_block_get(unsigned long block_id) { struct memory_block *mem; =20 @@ -659,16 +659,6 @@ struct memory_block *find_memory_block_by_id(unsigned = long block_id) return mem; } =20 -/* - * Called under device_hotplug_lock. - */ -struct memory_block *find_memory_block(unsigned long section_nr) -{ - unsigned long block_id =3D memory_block_id(section_nr); - - return find_memory_block_by_id(block_id); -} - static struct attribute *memory_memblk_attrs[] =3D { &dev_attr_phys_index.attr, &dev_attr_state.attr, @@ -701,7 +691,7 @@ static int __add_memory_block(struct memory_block *memo= ry) =20 ret =3D device_register(&memory->dev); if (ret) { - put_device(&memory->dev); + memory_block_put(memory); return ret; } ret =3D xa_err(xa_store(&memory_blocks, memory->dev.id, memory, @@ -795,9 +785,9 @@ static int add_memory_block(unsigned long block_id, int= nid, unsigned long state struct memory_block *mem; int ret =3D 0; =20 - mem =3D find_memory_block_by_id(block_id); + mem =3D memory_block_get(block_id); if (mem) { - put_device(&mem->dev); + memory_block_put(mem); return -EEXIST; } mem =3D kzalloc_obj(*mem); @@ -845,8 +835,8 @@ static void remove_memory_block(struct memory_block *me= mory) memory->group =3D NULL; } =20 - /* drop the ref. we got via find_memory_block() */ - put_device(&memory->dev); + /* drop the ref. we got via memory_block_get() */ + memory_block_put(memory); device_unregister(&memory->dev); } =20 @@ -880,7 +870,7 @@ int create_memory_block_devices(unsigned long start, un= signed long size, end_block_id =3D block_id; for (block_id =3D start_block_id; block_id !=3D end_block_id; block_id++) { - mem =3D find_memory_block_by_id(block_id); + mem =3D memory_block_get(block_id); if (WARN_ON_ONCE(!mem)) continue; remove_memory_block(mem); @@ -908,7 +898,7 @@ void remove_memory_block_devices(unsigned long start, u= nsigned long size) return; =20 for (block_id =3D start_block_id; block_id !=3D end_block_id; block_id++)= { - mem =3D find_memory_block_by_id(block_id); + mem =3D memory_block_get(block_id); if (WARN_ON_ONCE(!mem)) continue; num_poisoned_pages_sub(-1UL, memblk_nr_poison(mem)); @@ -1015,12 +1005,12 @@ int walk_memory_blocks(unsigned long start, unsigne= d long size, return 0; =20 for (block_id =3D start_block_id; block_id <=3D end_block_id; block_id++)= { - mem =3D find_memory_block_by_id(block_id); + mem =3D memory_block_get(block_id); if (!mem) continue; =20 ret =3D func(mem, arg); - put_device(&mem->dev); + memory_block_put(mem); if (ret) break; } @@ -1228,22 +1218,22 @@ int walk_dynamic_memory_groups(int nid, walk_memory= _groups_func_t func, void memblk_nr_poison_inc(unsigned long pfn) { const unsigned long block_id =3D pfn_to_block_id(pfn); - struct memory_block *mem =3D find_memory_block_by_id(block_id); + struct memory_block *mem =3D memory_block_get(block_id); =20 if (mem) { atomic_long_inc(&mem->nr_hwpoison); - put_device(&mem->dev); + memory_block_put(mem); } } =20 void memblk_nr_poison_sub(unsigned long pfn, long i) { const unsigned long block_id =3D pfn_to_block_id(pfn); - struct memory_block *mem =3D find_memory_block_by_id(block_id); + struct memory_block *mem =3D memory_block_get(block_id); =20 if (mem) { atomic_long_sub(i, &mem->nr_hwpoison); - put_device(&mem->dev); + memory_block_put(mem); } } =20 diff --git a/drivers/base/node.c b/drivers/base/node.c index 126f66aa2c3e..b3333ca92090 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -847,13 +847,13 @@ static void register_memory_blocks_under_nodes(void) for (block_id =3D start_block_id; block_id <=3D end_block_id; block_id++= ) { struct memory_block *mem; =20 - mem =3D find_memory_block_by_id(block_id); + mem =3D memory_block_get(block_id); if (!mem) continue; =20 memory_block_add_nid_early(mem, nid); do_register_memory_block_under_node(nid, mem); - put_device(&mem->dev); + memory_block_put(mem); } =20 } diff --git a/drivers/s390/char/sclp_mem.c b/drivers/s390/char/sclp_mem.c index 78c054e26d17..6df1926d4c62 100644 --- a/drivers/s390/char/sclp_mem.c +++ b/drivers/s390/char/sclp_mem.c @@ -204,7 +204,7 @@ static ssize_t sclp_config_mem_store(struct kobject *ko= bj, struct kobj_attribute addr =3D sclp_mem->id * block_size; /* * Hold device_hotplug_lock when adding/removing memory blocks. - * Additionally, also protect calls to find_memory_block() and + * Additionally, also protect calls to memory_block_get() and * sclp_attach_storage(). */ rc =3D lock_device_hotplug_sysfs(); @@ -231,20 +231,19 @@ static ssize_t sclp_config_mem_store(struct kobject *= kobj, struct kobj_attribute sclp_mem_change_state(addr, block_size, 0); goto out_unlock; } - mem =3D find_memory_block(pfn_to_section_nr(PFN_DOWN(addr))); - put_device(&mem->dev); + mem =3D memory_block_get(phys_to_block_id(addr)); + memory_block_put(mem); WRITE_ONCE(sclp_mem->config, 1); } else { if (!sclp_mem->config) goto out_unlock; - mem =3D find_memory_block(pfn_to_section_nr(PFN_DOWN(addr))); + mem =3D memory_block_get(phys_to_block_id(addr)); if (mem->state !=3D MEM_OFFLINE) { - put_device(&mem->dev); + memory_block_put(mem); rc =3D -EBUSY; goto out_unlock; } - /* drop the ref just got via find_memory_block() */ - put_device(&mem->dev); + memory_block_put(mem); sclp_mem_change_state(addr, block_size, 0); __remove_memory(addr, block_size); #ifdef CONFIG_KASAN @@ -294,11 +293,11 @@ static ssize_t sclp_memmap_on_memory_store(struct kob= ject *kobj, struct kobj_att return rc; block_size =3D memory_block_size_bytes(); sclp_mem =3D container_of(kobj, struct sclp_mem, kobj); - mem =3D find_memory_block(pfn_to_section_nr(PFN_DOWN(sclp_mem->id * block= _size))); + mem =3D memory_block_get(phys_to_block_id(sclp_mem->id * block_size)); if (!mem) { WRITE_ONCE(sclp_mem->memmap_on_memory, value); } else { - put_device(&mem->dev); + memory_block_put(mem); rc =3D -EBUSY; } unlock_device_hotplug(); diff --git a/include/linux/memory.h b/include/linux/memory.h index 5bb5599c6b2b..463dc02f6cff 100644 --- a/include/linux/memory.h +++ b/include/linux/memory.h @@ -158,7 +158,11 @@ int create_memory_block_devices(unsigned long start, u= nsigned long size, void remove_memory_block_devices(unsigned long start, unsigned long size); extern void memory_dev_init(void); extern int memory_notify(enum memory_block_state state, void *v); -extern struct memory_block *find_memory_block(unsigned long section_nr); +struct memory_block *memory_block_get(unsigned long block_id); +static inline void memory_block_put(struct memory_block *mem) +{ + put_device(&mem->dev); +} typedef int (*walk_memory_blocks_func_t)(struct memory_block *, void *); extern int walk_memory_blocks(unsigned long start, unsigned long size, void *arg, walk_memory_blocks_func_t func); @@ -171,7 +175,6 @@ struct memory_group *memory_group_find_by_id(int mgid); typedef int (*walk_memory_groups_func_t)(struct memory_group *, void *); int walk_dynamic_memory_groups(int nid, walk_memory_groups_func_t func, struct memory_group *excluded, void *arg); -struct memory_block *find_memory_block_by_id(unsigned long block_id); #define hotplug_memory_notifier(fn, pri) ({ \ static __meminitdata struct notifier_block fn##_mem_nb =3D\ { .notifier_call =3D fn, .priority =3D pri };\ diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 462d8dcd636d..890c6453e887 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -1417,14 +1417,13 @@ static void remove_memory_blocks_and_altmaps(u64 st= art, u64 size) struct vmem_altmap *altmap =3D NULL; struct memory_block *mem; =20 - mem =3D find_memory_block(pfn_to_section_nr(PFN_DOWN(cur_start))); + mem =3D memory_block_get(phys_to_block_id(cur_start)); if (WARN_ON_ONCE(!mem)) continue; =20 altmap =3D mem->altmap; mem->altmap =3D NULL; - /* drop the ref. we got via find_memory_block() */ - put_device(&mem->dev); + memory_block_put(mem); =20 remove_memory_block_devices(cur_start, memblock_size); =20 base-commit: e98d21c170b01ddef366f023bbfcf6b31509fa83 --=20 2.54.0