From nobody Sat Sep 26 11:00:56 2026 Received: from mta1.migadu.com (out-208.mta1.migadu.com [95.215.58.208]) (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 674093328E6 for ; Wed, 2 Sep 2026 08:17:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.208 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788337059; cv=none; b=dTIisF41cz1cNP0hm/KVTD1i4bTnltaJnz5e8bzZ6vvK8J0zqosXcv/No5P/uO0F9dLvneP7kcchR7przp2XC0YieBxWO8dWTkvFm8JtP9e61Xkf2fjHQort51SdlQ5x+QLguntuTcZNrenOst/Paq/uZ7KK7SRbOKJlHuF2Law= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788337059; c=relaxed/simple; bh=V8xaXgzY9XllyFlk89eNgFUoQBothzQGCS5P6ix37Rs=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=qvccnXsqNpkeuu4491+VKP/YLORCXLwT9LHl9GIBy7M8oV+DyIpp/65wFAkp6FEtOn3P59e+4t+l+GXQEIPscLM7eJII/zek/DwrWa1rjgkztB2o+zBnNwqAhFp4rQrgMV9OA83LYEx8UpuVCaN0gHy9ZWJ6MNpjhC1BuYWTDGE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=HVZJzx/C; arc=none smtp.client-ip=95.215.58.208 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="HVZJzx/C" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=V8xaXgzY9XllyFlk89eNgFUoQBothzQGCS5P6ix37Rs=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1788337055; v=1; x=1788941855; b=HVZJzx/CZ0IeaxUaKOCfjyfHqKK/U+EqqslsgWhGtveuAOhmWX5TsNO+YJfY/DqTqv+B9LoJ qYSgeCcUN04+8+VBwMlasW4DDBLmauPcYdDKMjUdgXzAHcQx5MDo+Ry8ikiNoaNo+7mOSyg06/I IleTlruSJdDSV2TP70zY+pPg= X-Envelope-To: linux-kernel@vger.kernel.org Received: by smtp.migadu.com with ESMTPS id e763d1ffbd60e14f; Wed, 02 Sep 2026 08:17:35 +0000 X-Mizu-Trace-ID: e763d1ffbd60e14f X-Migadu-Flow: FLOW_OUT From: Hao Ge To: Luis Chamberlain , Petr Pavlu , Daniel Gomez , Sami Tolvanen , Aaron Tomlin , Suren Baghdasaryan , Hao Ge , Andrew Morton Cc: linux-modules@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, Sashiko , stable@vger.kernel.org Subject: [PATCH v7 1/4] alloc_tag: move release_module_tags() above reserve_module_tags() Date: Wed, 2 Sep 2026 16:17:59 +0800 Message-Id: <20260902081802.146145-2-hao.ge@linux.dev> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20260902081802.146145-1-hao.ge@linux.dev> References: <20260902081802.146145-1-hao.ge@linux.dev> 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" release_module_tags() is a cleanup helper. reserve_module_tags() can also fail after storing the reservation in the maple tree, in which case it should call release_module_tags() to undo it. Move the helper above reserve_module_tags() so no forward declaration is needed. No functional change. Fixes: 4835f747d3ed ("alloc_tag: support for page allocation tag compressio= n") Fixes: 0f9b685626da ("alloc_tag: populate memory for module tags as needed") Reported-by: Sashiko Cc: stable@vger.kernel.org Acked-by: Suren Baghdasaryan Signed-off-by: Hao Ge --- mm/alloc_tag.c | 92 +++++++++++++++++++++++++------------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/mm/alloc_tag.c b/mm/alloc_tag.c index b1d48532a25a..e7a79116ad81 100644 --- a/mm/alloc_tag.c +++ b/mm/alloc_tag.c @@ -843,6 +843,52 @@ static int vm_module_tags_populate(void) return 0; } =20 +static void release_module_tags(struct module *mod, bool used) +{ + MA_STATE(mas, &mod_area_mt, module_tags.size, module_tags.size); + struct alloc_tag *start_tag; + struct alloc_tag *end_tag; + struct module *val; + + mas_lock(&mas); + mas_for_each_rev(&mas, val, 0) + if (val =3D=3D mod) + break; + + if (!val) /* module not found */ + goto out; + + if (!used) + goto release_area; + + start_tag =3D (struct alloc_tag *)(module_tags.start_addr + mas.index); + end_tag =3D (struct alloc_tag *)(module_tags.start_addr + mas.last); + if (!clean_unused_counters(start_tag, end_tag)) { + struct alloc_tag *tag; + + for (tag =3D start_tag; tag <=3D end_tag; tag++) { + struct alloc_tag_counters counter; + + if (!tag->counters) + continue; + + counter =3D alloc_tag_read(tag); + pr_info("%s:%u module %s func:%s has %llu allocated at module unload\n", + tag->ct.filename, tag->ct.lineno, tag->ct.modname, + tag->ct.function, counter.bytes); + } + } else { + used =3D false; + } +release_area: + mas_store(&mas, used ? &unloaded_mod : NULL); + val =3D mas_prev_range(&mas, 0); + if (val =3D=3D &prepend_mod) + mas_store(&mas, NULL); +out: + mas_unlock(&mas); +} + static void *reserve_module_tags(struct module *mod, unsigned long size, unsigned int prepend, unsigned long align) { @@ -930,52 +976,6 @@ static void *reserve_module_tags(struct module *mod, u= nsigned long size, return (struct alloc_tag *)(module_tags.start_addr + offset); } =20 -static void release_module_tags(struct module *mod, bool used) -{ - MA_STATE(mas, &mod_area_mt, module_tags.size, module_tags.size); - struct alloc_tag *start_tag; - struct alloc_tag *end_tag; - struct module *val; - - mas_lock(&mas); - mas_for_each_rev(&mas, val, 0) - if (val =3D=3D mod) - break; - - if (!val) /* module not found */ - goto out; - - if (!used) - goto release_area; - - start_tag =3D (struct alloc_tag *)(module_tags.start_addr + mas.index); - end_tag =3D (struct alloc_tag *)(module_tags.start_addr + mas.last); - if (!clean_unused_counters(start_tag, end_tag)) { - struct alloc_tag *tag; - - for (tag =3D start_tag; tag <=3D end_tag; tag++) { - struct alloc_tag_counters counter; - - if (!tag->counters) - continue; - - counter =3D alloc_tag_read(tag); - pr_info("%s:%u module %s func:%s has %llu allocated at module unload\n", - tag->ct.filename, tag->ct.lineno, tag->ct.modname, - tag->ct.function, counter.bytes); - } - } else { - used =3D false; - } -release_area: - mas_store(&mas, used ? &unloaded_mod : NULL); - val =3D mas_prev_range(&mas, 0); - if (val =3D=3D &prepend_mod) - mas_store(&mas, NULL); -out: - mas_unlock(&mas); -} - static int load_module(struct module *mod, struct codetag *start, struct c= odetag *stop) { /* Allocate module alloc_tag percpu counters */ --=20 2.25.1 From nobody Sat Sep 26 11:00:56 2026 Received: from mta0.migadu.com (out-213.mta0.migadu.com [91.218.175.213]) (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 AB9053542F6 for ; Wed, 2 Sep 2026 08:17:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.213 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788337078; cv=none; b=fuyjRjOwBpgl3+XOIEZxlw9nBPEXUwQeFKJZwLm0p7d7/SMy+PzPu2WegydWB5f7/KZbIsr0Rk+8Gotvy6iB3aCPbQadzTlH8rIcPj0HFGWxkBK+FSj3ydgEuz9/X8Mu5JwSplRTG5CRuaQGEkpDwPQ6LbyNy6H/9pPlP//l9y0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788337078; c=relaxed/simple; bh=IWPG5U0baJXua7XoV+ocXpmKQBCi8RyT3W3FBxO4w10=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=qj5B8KUWlnZIzfE7B7R/b9CmGnw897MWkaeeXGtMf35AcoXX+Nh/js03vm+lshZCL40TQ6xk9DS8di5pr+QIEcmgFRr006y8sBeEFnSLbLHl5ct/zRQ23jLGIWKvGzXW9jFIlYe03MKCeShqcZ49DsG1IN8HwB0r8JK9r1Os/Xs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=kEL5I6c1; arc=none smtp.client-ip=91.218.175.213 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="kEL5I6c1" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=IWPG5U0baJXua7XoV+ocXpmKQBCi8RyT3W3FBxO4w10=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1788337074; v=1; x=1788941874; b=kEL5I6c1Ia4WOfsgHNpeCT6PwWSgRXLIQFYLuiyh7z8CfePItLqtDZAQNlyzcVknNVLSTimp HWXz+qZOLOzmAeQHqhVMmelNBLOVOSZXZdOm1eC0luxA4AOU4hlMVw7Ly/yw7mCUxvljYQxISbI JEJGpRZHpRNEj5vx+FQwZ7eI= X-Envelope-To: linux-kernel@vger.kernel.org Received: by smtp.migadu.com with ESMTPS id 949a1ac0fa66a2aa; Wed, 02 Sep 2026 08:17:44 +0000 X-Mizu-Trace-ID: 949a1ac0fa66a2aa X-Migadu-Flow: FLOW_OUT From: Hao Ge To: Luis Chamberlain , Petr Pavlu , Daniel Gomez , Sami Tolvanen , Aaron Tomlin , Suren Baghdasaryan , Hao Ge , Andrew Morton Cc: linux-modules@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, Sashiko , stable@vger.kernel.org Subject: [PATCH v7 2/4] module: introduce SH_ENTSIZE_STANDALONE for separately allocated sections Date: Wed, 2 Sep 2026 16:18:00 +0800 Message-Id: <20260902081802.146145-3-hao.ge@linux.dev> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20260902081802.146145-1-hao.ge@linux.dev> References: <20260902081802.146145-1-hao.ge@linux.dev> 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" SHF_ALLOC means, per the ELF spec, that a section occupies memory during process execution. Some module sections occupy memory outside the regular module layout, for example the percpu section with its per-CPU allocations. The loader currently excludes such a section from the layout by clearing its SHF_ALLOC, which overloads the flag with a loader-internal meaning. apply_relocations() needs a special case for the section, and find_sec(".data..percpu") returns different results before and after layout_and_allocate(). Introduce SH_ENTSIZE_STANDALONE to mark sections with a separate allocation. The percpu section is its first user. layout_sections() and move_module() skip marked sections, and apply_relocations() goes back to testing only SHF_ALLOC. No functional change intended. Fixes: 4835f747d3ed ("alloc_tag: support for page allocation tag compressio= n") Reported-by: Sashiko Based-on-a-patch-by: Petr Pavlu Link: https://lore.kernel.org/all/499bb60c-c6e3-43a3-bd92-95a0567ece5e@suse= .com/ Cc: stable@vger.kernel.org Signed-off-by: Hao Ge --- include/linux/module.h | 2 ++ kernel/module/internal.h | 8 ++++++++ kernel/module/main.c | 31 +++++++++++++------------------ 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/include/linux/module.h b/include/linux/module.h index 7566815fabbe..33548daa31a3 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -325,6 +325,8 @@ enum mod_mem_type { MOD_INIT_RODATA, =20 MOD_MEM_NUM_TYPES, + + MOD_STANDALONE =3D -2, MOD_INVALID =3D -1, }; =20 diff --git a/kernel/module/internal.h b/kernel/module/internal.h index 061161cc79d9..4c738074a27b 100644 --- a/kernel/module/internal.h +++ b/kernel/module/internal.h @@ -29,6 +29,14 @@ #define SH_ENTSIZE_TYPE_MASK ((1UL << SH_ENTSIZE_TYPE_BITS) - 1) #define SH_ENTSIZE_OFFSET_MASK ((1UL << (BITS_PER_LONG - SH_ENTSIZE_TYPE_B= ITS)) - 1) =20 +/* + * Marker for sections with a separate allocation, which are not placed + * into mod->mem[]. + */ +#define SH_ENTSIZE_STANDALONE \ + (((unsigned long)MOD_STANDALONE & SH_ENTSIZE_TYPE_MASK) \ + << SH_ENTSIZE_TYPE_SHIFT) + /* Maximum number of characters written by module_flags() */ #define MODULE_FLAGS_BUF_SIZE (TAINT_FLAGS_COUNT + 4) =20 diff --git a/kernel/module/main.c b/kernel/module/main.c index c32f1d370b73..078dae188aba 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -1618,14 +1618,8 @@ static int apply_relocations(struct module *mod, con= st struct load_info *info) if (infosec >=3D info->hdr->e_shnum) continue; =20 - /* - * Don't bother with non-allocated sections. - * An exception is the percpu section, which has separate allocations - * for individual CPUs. We relocate the percpu section in the initial - * ELF template and subsequently copy it to the per-CPU destinations. - */ - if (!(info->sechdrs[infosec].sh_flags & SHF_ALLOC) && - (!infosec || infosec !=3D info->index.pcpu)) + /* Don't bother with non-allocated sections. */ + if (!(info->sechdrs[infosec].sh_flags & SHF_ALLOC)) continue; =20 if (info->sechdrs[i].sh_flags & SHF_RELA_LIVEPATCH) @@ -1716,7 +1710,7 @@ static void __layout_sections(struct module *mod, str= uct load_info *info, bool i =20 if ((s->sh_flags & masks[m][0]) !=3D masks[m][0] || (s->sh_flags & masks[m][1]) - || s->sh_entsize !=3D ~0UL + || s->sh_entsize !=3D ~0UL /* offset or standalone */ || is_init !=3D module_init_layout_section(sname)) continue; =20 @@ -1746,16 +1740,10 @@ static void __layout_sections(struct module *mod, s= truct load_info *info, bool i /* * Lay out the SHF_ALLOC sections in a way not dissimilar to how ld * might -- code, read-only data, read-write data, small data. Tally - * sizes, and place the offsets into sh_entsize fields: high bit means it - * belongs in init. + * sizes, and place the offsets into sh_entsize fields. */ static void layout_sections(struct module *mod, struct load_info *info) { - unsigned int i; - - for (i =3D 0; i < info->hdr->e_shnum; i++) - info->sechdrs[i].sh_entsize =3D ~0UL; - pr_debug("Core section allocation order for %s:\n", mod->name); __layout_sections(mod, info, false); =20 @@ -2811,7 +2799,8 @@ static int move_module(struct module *mod, struct loa= d_info *info) Elf_Shdr *shdr =3D &info->sechdrs[i]; const char *sname; =20 - if (!(shdr->sh_flags & SHF_ALLOC)) + if (!(shdr->sh_flags & SHF_ALLOC) + || shdr->sh_entsize =3D=3D SH_ENTSIZE_STANDALONE) continue; =20 sname =3D info->secstrings + shdr->sh_name; @@ -2943,6 +2932,7 @@ core_param(module_blacklist, module_blacklist, charp,= 0400); static struct module *layout_and_allocate(struct load_info *info, int flag= s) { struct module *mod; + unsigned int i; int err; =20 /* Allow arches to frob section contents and sizes. */ @@ -2956,8 +2946,13 @@ static struct module *layout_and_allocate(struct loa= d_info *info, int flags) if (err < 0) return ERR_PTR(err); =20 + /* Repurpose sh_entsize to track where each section is allocated. */ + for (i =3D 0; i < info->hdr->e_shnum; i++) + info->sechdrs[i].sh_entsize =3D ~0UL; + /* We will do a special allocation for per-cpu sections later. */ - info->sechdrs[info->index.pcpu].sh_flags &=3D ~(unsigned long)SHF_ALLOC; + if (info->index.pcpu) + info->sechdrs[info->index.pcpu].sh_entsize =3D SH_ENTSIZE_STANDALONE; =20 /* * Mark relevant sections as SHF_RO_AFTER_INIT so layout_sections() can --=20 2.25.1 From nobody Sat Sep 26 11:00:56 2026 Received: from mta1.migadu.com (out-214.mta1.migadu.com [95.215.58.214]) (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 0F8AD37F8B1 for ; Wed, 2 Sep 2026 08:17:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.214 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788337079; cv=none; b=orlcGUhxu5nowwgBLfydG4ZF21q3gui1pSXhxOrmDk+ZYUX5ChCsIUbpyT9lbU3CLdpcXk+zvA1azf/UoZPNZoo1wKGY3vQXT/5ylU1sGZ5yP0rTLnvTOkAOHfstC7QW5/sE/3qKtAGOxLAtcOTt9ycL9A8ZHdf6sSL7sWY5a4U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788337079; c=relaxed/simple; bh=4nP8oY3FXaK6DMyt7vwB8mKX+49J/UMAOZEl2daUDMY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=AlM9cgbJ9gVhgf1v9Hqd2sPQn7zcWs6JIVLJFsO/Y8OJVyTB1Hxssg0iJLOE7VPlU5YxLbj0zH6RnoNKcCnxYcJ+j8jIUVxpnlN5pqJuziPd/IZ8/iCftUEgZxMW7tlqCujJneC3xEvDXSCkzK4ZQuedFTwze0iFN0jFih8WH68= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=HFLeu+hU; arc=none smtp.client-ip=95.215.58.214 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="HFLeu+hU" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=4nP8oY3FXaK6DMyt7vwB8mKX+49J/UMAOZEl2daUDMY=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1788337074; v=1; x=1788941874; b=HFLeu+hUwGbQPfLt6fKYDW0nrqYdd3+B5K+6NDeOmppIIn1RYDK3xhDzcw8zSaiFpe9d4T1H Ela2dV+PenVnlUEpM1RgsFOdQ+FHo1kgfF0voJ2fBJkdHex9hBR93V3GNBOmsIKHbB+d7CmkR4t B/MaZms9nvA5gtMYNYRHvF5o= X-Envelope-To: linux-kernel@vger.kernel.org Received: by smtp.migadu.com with ESMTPS id d040b23edc8a3246; Wed, 02 Sep 2026 08:17:54 +0000 X-Mizu-Trace-ID: d040b23edc8a3246 X-Migadu-Flow: FLOW_OUT From: Hao Ge To: Luis Chamberlain , Petr Pavlu , Daniel Gomez , Sami Tolvanen , Aaron Tomlin , Suren Baghdasaryan , Hao Ge , Andrew Morton Cc: linux-modules@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, Sashiko , stable@vger.kernel.org Subject: [PATCH v7 3/4] module: allocate codetag sections before the regular module layout Date: Wed, 2 Sep 2026 16:18:01 +0800 Message-Id: <20260902081802.146145-4-hao.ge@linux.dev> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20260902081802.146145-1-hao.ge@linux.dev> References: <20260902081802.146145-1-hao.ge@linux.dev> 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" Whether a codetag section goes to the codetag region is decided by layout_sections() and asked again in move_module(). A concurrent load can shut profiling down in between, and move_module() then copies the section to offset 0 of its regular destination, overwriting whatever is there. Decide and allocate in one pass, before the layout. Allocation errors fail the load. On a tag area overflow profiling is already disabled, so -EAGAIN makes the section fall back to regular module data and the module still loads. When profiling was toggled off the overflow check did not run, a module could load with more tags than the page flags can address, and re-enabling profiling then silently corrupted /proc/allocinfo. The check no longer depends on mem_alloc_profiling_enabled(). Fixes: 4835f747d3ed ("alloc_tag: support for page allocation tag compressio= n") Reported-by: Sashiko Based-on-a-patch-by: Petr Pavlu Link: https://lore.kernel.org/all/499bb60c-c6e3-43a3-bd92-95a0567ece5e@suse= .com/ Cc: stable@vger.kernel.org Signed-off-by: Hao Ge --- kernel/module/main.c | 99 +++++++++++++++++++++++--------------------- mm/alloc_tag.c | 8 ++-- 2 files changed, 57 insertions(+), 50 deletions(-) diff --git a/kernel/module/main.c b/kernel/module/main.c index 078dae188aba..d0a8ac9b3ee5 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -1717,20 +1717,6 @@ static void __layout_sections(struct module *mod, st= ruct load_info *info, bool i if (WARN_ON_ONCE(type =3D=3D MOD_INVALID)) continue; =20 - /* - * Do not allocate codetag memory as we load it into - * preallocated contiguous memory. - */ - if (codetag_needs_module_section(mod, sname, s->sh_size)) { - /* - * s->sh_entsize won't be used but populate the - * type field to avoid confusion. - */ - s->sh_entsize =3D ((unsigned long)(type) & SH_ENTSIZE_TYPE_MASK) - << SH_ENTSIZE_TYPE_SHIFT; - continue; - } - s->sh_entsize =3D module_get_offset_and_type(mod, type, s, i); pr_debug("\t%s\n", sname); } @@ -2777,7 +2763,6 @@ static int move_module(struct module *mod, struct loa= d_info *info) { int i, ret; enum mod_mem_type t =3D MOD_MEM_NUM_TYPES; - bool codetag_section_found =3D false; =20 for_each_mod_mem_type(type) { if (!mod->mem[type].size) { @@ -2797,35 +2782,13 @@ static int move_module(struct module *mod, struct l= oad_info *info) for (i =3D 0; i < info->hdr->e_shnum; i++) { void *dest; Elf_Shdr *shdr =3D &info->sechdrs[i]; - const char *sname; =20 if (!(shdr->sh_flags & SHF_ALLOC) || shdr->sh_entsize =3D=3D SH_ENTSIZE_STANDALONE) continue; =20 - sname =3D info->secstrings + shdr->sh_name; - /* - * Load codetag sections separately as they might still be used - * after module unload. - */ - if (codetag_needs_module_section(mod, sname, shdr->sh_size)) { - dest =3D codetag_alloc_module_section(mod, sname, shdr->sh_size, - arch_mod_section_prepend(mod, i), shdr->sh_addralign); - if (WARN_ON(!dest)) { - ret =3D -EINVAL; - goto out_err; - } - if (IS_ERR(dest)) { - ret =3D PTR_ERR(dest); - goto out_err; - } - codetag_section_found =3D true; - } else { - enum mod_mem_type type =3D shdr->sh_entsize >> SH_ENTSIZE_TYPE_SHIFT; - unsigned long offset =3D shdr->sh_entsize & SH_ENTSIZE_OFFSET_MASK; - - dest =3D mod->mem[type].base + offset; - } + dest =3D mod->mem[shdr->sh_entsize >> SH_ENTSIZE_TYPE_SHIFT].base + + (shdr->sh_entsize & SH_ENTSIZE_OFFSET_MASK); =20 if (shdr->sh_type !=3D SHT_NOBITS) { /* @@ -2857,8 +2820,6 @@ static int move_module(struct module *mod, struct loa= d_info *info) module_memory_restore_rox(mod); while (t--) module_memory_free(mod, t); - if (codetag_section_found) - codetag_free_module_sections(mod); =20 return ret; } @@ -2929,6 +2890,47 @@ static bool blacklisted(const char *module_name) } core_param(module_blacklist, module_blacklist, charp, 0400); =20 +/* + * Allocate codetag sections separately. They are loaded into preallocated + * contiguous memory because they may still be used after the module is + * unloaded. + * + * If the separate allocation overflows, allocate the section normally + * so that the module can still be loaded. + */ +static int allocate_codetag_sections(struct load_info *info) +{ + for (unsigned int i =3D 1; i < info->hdr->e_shnum; i++) { + Elf_Shdr *shdr =3D &info->sechdrs[i]; + const char *sname =3D info->secstrings + shdr->sh_name; + void *dest; + + if (!codetag_needs_module_section(info->mod, sname, shdr->sh_size)) + continue; + + dest =3D codetag_alloc_module_section(info->mod, sname, shdr->sh_size, + arch_mod_section_prepend(info->mod, i), shdr->sh_addralign); + if (WARN_ON(!dest)) { + codetag_free_module_sections(info->mod); + return -EINVAL; + } + if (dest =3D=3D ERR_PTR(-EAGAIN)) + /* Allocate the section as a regular section. */ + continue; + if (IS_ERR(dest)) { + codetag_free_module_sections(info->mod); + return PTR_ERR(dest); + } + + if (shdr->sh_type !=3D SHT_NOBITS) + memcpy(dest, (void *)shdr->sh_addr, shdr->sh_size); + shdr->sh_addr =3D (unsigned long)dest; + shdr->sh_entsize =3D SH_ENTSIZE_STANDALONE; + } + + return 0; +} + static struct module *layout_and_allocate(struct load_info *info, int flag= s) { struct module *mod; @@ -2961,18 +2963,21 @@ static struct module *layout_and_allocate(struct lo= ad_info *info, int flags) */ module_mark_ro_after_init(info->hdr, info->sechdrs, info->secstrings); =20 - /* - * Determine total sizes, and put offsets in sh_entsize. For now - * this is done generically; there doesn't appear to be any - * special cases for the architectures. - */ + /* Allow codetag sections to be allocated separately first. */ + err =3D allocate_codetag_sections(info); + if (err) + return ERR_PTR(err); + + /* Determine total sizes and put offsets in sh_entsize. */ layout_sections(info->mod, info); layout_symtab(info->mod, info); =20 /* Allocate and move to the final place */ err =3D move_module(info->mod, info); - if (err) + if (err) { + codetag_free_module_sections(info->mod); return ERR_PTR(err); + } =20 /* Module has been copied to its final place now: return it. */ mod =3D (void *)info->sechdrs[info->index.mod].sh_addr; diff --git a/mm/alloc_tag.c b/mm/alloc_tag.c index e7a79116ad81..248496470904 100644 --- a/mm/alloc_tag.c +++ b/mm/alloc_tag.c @@ -958,10 +958,12 @@ static void *reserve_module_tags(struct module *mod, = unsigned long size, int grow_res; =20 module_tags.size =3D offset + size; - if (mem_alloc_profiling_enabled() && !tags_addressable()) { + if (!tags_addressable()) { shutdown_mem_profiling(true); - pr_warn("With module %s there are too many tags to fit in %d page flag = bits. Memory allocation profiling is disabled!\n", - mod->name, NR_UNUSED_PAGEFLAG_BITS); + pr_warn_once("With module %s there are too many tags to fit in %d page = flag bits. Memory allocation profiling is disabled!\n", + mod->name, NR_UNUSED_PAGEFLAG_BITS); + release_module_tags(mod, false); + return ERR_PTR(-EAGAIN); } =20 grow_res =3D vm_module_tags_populate(); --=20 2.25.1 From nobody Sat Sep 26 11:00:56 2026 Received: from mta1.migadu.com (out-221.mta1.migadu.com [95.215.58.221]) (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 765C33859EF for ; Wed, 2 Sep 2026 08:18:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.221 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788337083; cv=none; b=Rbz49cVEwn0SE6iMm5Mm4BU6a06ibNaJ7nzOzpN01WzxyxMygfKOVAPlzAfHpsUl6ybG35OT2MhZRQbQRC0kMAVpkqY2WkM3pzTdBKjwlJgVyG5RhvDKPgp88fOvkFsWbjxG7MdIK7qfhneYqs9ViK+JawETWA3PQYX8VcZ2orw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788337083; c=relaxed/simple; bh=dWk9y7b0drDaUlfFd/9bCLMEQv7pdwsvhjNQU3mPn70=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=oqp5YPUi/vIJx9/iI4E4Hho8C++v3tMLdzFE4/kb35Luy/FWl5Y6CQR0d/Na+xlYMmBK4eUOWxhxhmAod4ocWpB58K21dWwNQyJHouSOvbJlIuAoU6j0h1RsexiyW/URMUjbzrjXP8v1gXM6GUqBMHxFELjQWvknypqtLm+OPqg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=or4Fd+fj; arc=none smtp.client-ip=95.215.58.221 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="or4Fd+fj" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=dWk9y7b0drDaUlfFd/9bCLMEQv7pdwsvhjNQU3mPn70=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1788337079; v=1; x=1788941879; b=or4Fd+fjoDT55iqG+B+WGSLMTkSlmM2k8Qs99PoVYTcNgrL8/zCL/7azvjiPygrMyNP+v1eN tjsUmoY+rFpBv0IjhNbAKdX2oLGpT8SU8WZ9/nEl/T38ACMIGrdGTfEog5CkVYMXkx1yoI0TRHo be6yuvAXOPdMXJti7fV2Ly4o= X-Envelope-To: linux-kernel@vger.kernel.org Received: by smtp.migadu.com with ESMTPS id eca1d97746dd0c27; Wed, 02 Sep 2026 08:17:59 +0000 X-Mizu-Trace-ID: eca1d97746dd0c27 X-Migadu-Flow: FLOW_OUT From: Hao Ge To: Luis Chamberlain , Petr Pavlu , Daniel Gomez , Sami Tolvanen , Aaron Tomlin , Suren Baghdasaryan , Hao Ge , Andrew Morton Cc: linux-modules@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, Sashiko , stable@vger.kernel.org Subject: [PATCH v7 4/4] alloc_tag: release the reservation when populate fails Date: Wed, 2 Sep 2026 16:18:02 +0800 Message-Id: <20260902081802.146145-5-hao.ge@linux.dev> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20260902081802.146145-1-hao.ge@linux.dev> References: <20260902081802.146145-1-hao.ge@linux.dev> 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" vm_module_tags_populate() can fail after the reservation was stored in the maple tree, and the error return leaks the entry, since a failed load never unloads the module. Release it. Fixes: 0f9b685626da ("alloc_tag: populate memory for module tags as needed") Reported-by: Sashiko Cc: stable@vger.kernel.org Signed-off-by: Hao Ge --- mm/alloc_tag.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mm/alloc_tag.c b/mm/alloc_tag.c index 248496470904..3c25475becbc 100644 --- a/mm/alloc_tag.c +++ b/mm/alloc_tag.c @@ -971,6 +971,7 @@ static void *reserve_module_tags(struct module *mod, un= signed long size, shutdown_mem_profiling(true); pr_err("Failed to allocate memory for allocation tags in the module %s.= Memory allocation profiling is disabled!\n", mod->name); + release_module_tags(mod, false); return ERR_PTR(grow_res); } } --=20 2.25.1