From nobody Sat Jun 13 02:58:37 2026 Received: from mail-pg1-f170.google.com (mail-pg1-f170.google.com [209.85.215.170]) (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 92A1D365A19 for ; Mon, 11 May 2026 11:18:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778498326; cv=none; b=tuuwCbYIE083XXxOoLNJhOo7keMyJgNGS4d8pfizWE+cc7BpKmB80zoIxsNqj0ObNCh1jn9b8b676YA4Few5K12YEFJohUt5dyfYTluKC3oYFH9uZoiK9ivJoEsPfamoQ+VuwGltjXVdR8Eve47e9dOQAVP40/Xez5pRZBClBzk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778498326; c=relaxed/simple; bh=8BBgxVCsv5YDCYQ2sR+dsQPRg5HbgVlv6JuCI3/17zM=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=MdN81eMmUxmXx0dDNqcPougPBp3x4lgKpcDEq4l2udyoZvDHZN87eji4HfXUWLEJwyOg3ibQ6Ckk8OrxmpfaJrhA+Wj8fWcGmrXQ4Dpbe2kQMqUls3tlSBiT9X9dQpJJDmoIxE1gUpghgEmYQNuEQBceugt2VCMz7x+FVhw2IEU= 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=LwfKph6e; arc=none smtp.client-ip=209.85.215.170 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="LwfKph6e" Received: by mail-pg1-f170.google.com with SMTP id 41be03b00d2f7-c7358a7a8d1so3079567a12.3 for ; Mon, 11 May 2026 04:18:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bytedance.com; s=google; t=1778498324; x=1779103124; 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=4nZ855QhOS6+DUu6cu1Pi5l2CbbOQ+24Qk9Hlm6rENI=; b=LwfKph6ehkA6MTh0xCqV1kpKfxYw2KiSo8spDbbl6JCKMgDsHDckl2EwRuaiKrLitn PE2d8ujqDBe0aWNSDwFsRKu7W+IF3kzCF9SaSI5MOTf82dlGaNPkdJX0NwwDLVkwJmPs kxevXzfvu4Id8kqAzIQFiJcLwzhyplp+C17Mzi91WBDOn6Jv09WpM+k/WH6OAgZ4eRDc 1sKMqelFVIP2xhm2bVTI7vJDvZBiFBt2VL2ssfYdfQ93t7TKKXnSNCcjLG1yTjdBFuBR WhJAy5s2ShENW3Qf7O97EG3hCobOMAFInMup1fSBXRs+gB9eSrh8jpkCeuwrkdakIUhe RsdQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778498324; x=1779103124; 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=4nZ855QhOS6+DUu6cu1Pi5l2CbbOQ+24Qk9Hlm6rENI=; b=HnKPAVd6IrqSZj23NRj0vE4B04YeMurlpnLQdCzF4NQwdoUbchm0CewgumU143GPl1 XdVWPngQbVFxXfHXmHkhpLStJRV9yZTkAI33CZ22iNDM3cXi2K1Kqn+4BrCnlyO38ZAM kwNXkR/iO/0w+33skFk7HXG6AhS8H0ReA77YRdqmmQYoKy7MOF3tUs9+HQZDI46aMBjM PqnF/Sk88NWRvYf/DnUeutQz8ilCXYkkSJGGblt1UbwmA/d/iQxHWjuFSS/rH7v/rQ/i rRjoEl9l9D6A5mZv3hpMRPXLus9tUv5vIW4T87XAW7Ke8E1AV/tsC8Nam1oL7VVKbKMm T9lw== X-Forwarded-Encrypted: i=1; AFNElJ/VGCIb2x0D74HL+WzkCcr4jAUZAsmQO4Jn3cV3cpwbsNOnqrX/Xx5hEEzO5EOKIzfUJAaNp0EhMv/ZKUk=@vger.kernel.org X-Gm-Message-State: AOJu0YxRXWcK3bK/l7+D63lNJCYgnF+Dpn9NutIyDkw9XegpjMLjp4D3 0E7aFy9tcHyWjCWjc+DxHF/QVBEFJ0jQ+hPSW2qX9cl55rTaOGzpAnd0+2AcKoHgwLM= X-Gm-Gg: Acq92OHFonv8QdK6XFzYK3AriCPFrzkYKNoHgwGcVaqab1Mj1VHxd31s5WfrC2pxywZ KkCG3qRBRXPJXzPdY8N/Q21ykkUVD27IlIQODYPlZHopZThUcVAd9IL89AdeBVEaLx6uuP+tsiD Q8zcDPL+KmVO08BmEei6TugpVY2eaUTBbbRswV71tKyi0ZR5NC2T7XxICw87u20O2FGpOAHairc 0zkjUAhw9vZBmuXob627Am3FTXtrmHsJq7nJcAAEt3zc83w+ChS+BfEZmFHDSINIMYfDakfpti0 sJ8R/4sp1267ohcPSoc0dn/sEqGotXEU3bcVjQ2vU260JUmc6bkSaRwTX/rOPsuvKjbirJqen7x fPXX5gafSuI7hf5xfbwpB4q8e6IDrEqR26kQvsRZd/+3ngNoXN0GIKl6gJSEcABtsJTRwLiP8pm 7krzx3fFD1o4wIT/ZV92ZENhysjL6zsjAH9zsjX/JWTyo9 X-Received: by 2002:a17:903:13cf:b0:2b2:501c:bc0 with SMTP id d9443c01a7336-2ba79290f29mr226590505ad.7.1778498323836; Mon, 11 May 2026 04:18:43 -0700 (PDT) Received: from n232-176-004.byted.org ([36.110.163.101]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2baf1e75fffsm96826495ad.59.2026.05.11.04.18.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 11 May 2026 04:18:43 -0700 (PDT) From: Muchun Song To: David Hildenbrand , Oscar Salvador , Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich Cc: Andrew Morton , Lorenzo Stoakes , "Liam R. Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Madhavan Srinivasan , Michael Ellerman , Nicholas Piggin , "Christophe Leroy (CS GROUP)" , Heiko Carstens , Vasily Gorbik , Alexander Gordeev , Christian Borntraeger , Sven Schnelle , linux-mm@kvack.org, driver-core@lists.linux.dev, linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-s390@vger.kernel.org, Muchun Song , muchun.song@linux.dev Subject: [PATCH] drivers/base/memory: make memory block get/put explicit Date: Mon, 11 May 2026 19:18:00 +0800 Message-ID: <20260511111800.2181785-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(), and collapse the redundant section-number wrapper into a 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: David Hildenbrand (Arm) Acked-by: Michal Hocko Acked-by: Oscar Salvador Reviewed-by: Lorenzo Stoakes Tested-by: Donet Tom --- .../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..29edef1f975c 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); +extern 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