From: Andrey Panin <pazke@orbita1.ru>
To: linux-kernel@vger.kernel.org
Subject: [PATCH][RFC] __init and friends support for loadable modules
Date: Wed, 8 May 2002 14:29:33 +0400 [thread overview]
Message-ID: <20020508102933.GA574@pazke.ipt> (raw)
[-- Attachment #1.1: Type: text/plain, Size: 637 bytes --]
Hi all,
attached patch adds support for freeing .init sections of loadable modules
after init_module() function exits. Modutils have support for this since 1998,
but kernel support didn't exist.
All architectures that use vmalloc/vfree for module_map/unmap should work.
Patch contains three major part:
- shrink_vm_area() function for reducing size of vmalloc'ed area;
- init.h changes to allow .init sections in modules;
- change in kernel/module.c.
Comments, suggestions ?
Best regards.
--
Andrey Panin | Embedded systems software engineer
pazke@orbita1.ru | PGP key: wwwkeys.eu.pgp.net
[-- Attachment #1.2: patch-module-init --]
[-- Type: text/plain, Size: 12461 bytes --]
diff -urN -X /usr/share/dontdiff linux.vanilla/include/asm-alpha/module.h linux/include/asm-alpha/module.h
--- linux.vanilla/include/asm-alpha/module.h Wed May 8 10:01:53 2002
+++ linux/include/asm-alpha/module.h Wed May 8 10:06:36 2002
@@ -6,6 +6,7 @@
#define module_map(x) vmalloc(x)
#define module_unmap(x) vfree(x)
+#define module_remap(ptr, size) shrink_vm_area(ptr, size)
#define module_arch_init(x) alpha_module_init(x)
#define arch_init_modules(x) alpha_init_modules(x)
diff -urN -X /usr/share/dontdiff linux.vanilla/include/asm-arm/module.h linux/include/asm-arm/module.h
--- linux.vanilla/include/asm-arm/module.h Wed May 8 10:01:57 2002
+++ linux/include/asm-arm/module.h Wed May 8 10:06:36 2002
@@ -6,6 +6,7 @@
#define module_map(x) vmalloc(x)
#define module_unmap(x) vfree(x)
+#define module_remap(ptr, size) shrink_vm_area(ptr, size)
#define module_arch_init(x) (0)
#define arch_init_modules(x) do { } while (0)
diff -urN -X /usr/share/dontdiff linux.vanilla/include/asm-cris/module.h linux/include/asm-cris/module.h
--- linux.vanilla/include/asm-cris/module.h Wed May 8 10:02:01 2002
+++ linux/include/asm-cris/module.h Wed May 8 10:06:36 2002
@@ -6,6 +6,7 @@
#define module_map(x) vmalloc(x)
#define module_unmap(x) vfree(x)
+#define module_remap(ptr, size) shrink_vm_area(ptr, size)
#define module_arch_init(x) (0)
#define arch_init_modules(x) do { } while (0)
diff -urN -X /usr/share/dontdiff linux.vanilla/include/asm-i386/module.h linux/include/asm-i386/module.h
--- linux.vanilla/include/asm-i386/module.h Wed May 8 10:01:52 2002
+++ linux/include/asm-i386/module.h Wed May 8 10:06:36 2002
@@ -6,6 +6,7 @@
#define module_map(x) vmalloc(x)
#define module_unmap(x) vfree(x)
+#define module_remap(ptr, size) shrink_vm_area(ptr, size)
#define module_arch_init(x) (0)
#define arch_init_modules(x) do { } while (0)
diff -urN -X /usr/share/dontdiff linux.vanilla/include/asm-ia64/module.h linux/include/asm-ia64/module.h
--- linux.vanilla/include/asm-ia64/module.h Wed May 8 10:01:58 2002
+++ linux/include/asm-ia64/module.h Wed May 8 10:06:36 2002
@@ -13,6 +13,7 @@
#define module_map(x) vmalloc(x)
#define module_unmap(x) ia64_module_unmap(x)
+#define module_remap(ptr, size) (-ENOSYS)
#define module_arch_init(x) ia64_module_init(x)
/*
diff -urN -X /usr/share/dontdiff linux.vanilla/include/asm-m68k/module.h linux/include/asm-m68k/module.h
--- linux.vanilla/include/asm-m68k/module.h Wed May 8 10:01:53 2002
+++ linux/include/asm-m68k/module.h Wed May 8 10:06:36 2002
@@ -6,6 +6,7 @@
#define module_map(x) vmalloc(x)
#define module_unmap(x) vfree(x)
+#define module_remap(ptr, size) shrink_vm_area(ptr, size)
#define module_arch_init(x) (0)
#define arch_init_modules(x) do { } while (0)
diff -urN -X /usr/share/dontdiff linux.vanilla/include/asm-mips/module.h linux/include/asm-mips/module.h
--- linux.vanilla/include/asm-mips/module.h Wed May 8 10:01:52 2002
+++ linux/include/asm-mips/module.h Wed May 8 10:06:36 2002
@@ -9,6 +9,7 @@
#define module_map(x) vmalloc(x)
#define module_unmap(x) vfree(x)
+#define module_remap(ptr, size) shrink_vm_area(ptr, size)
#define module_arch_init(x) mips_module_init(x)
#define arch_init_modules(x) mips_init_modules(x)
diff -urN -X /usr/share/dontdiff linux.vanilla/include/asm-mips64/module.h linux/include/asm-mips64/module.h
--- linux.vanilla/include/asm-mips64/module.h Wed May 8 10:02:01 2002
+++ linux/include/asm-mips64/module.h Wed May 8 10:06:36 2002
@@ -9,6 +9,7 @@
#define module_map(x) vmalloc(x)
#define module_unmap(x) vfree(x)
+#define module_remap(ptr, size) shrink_vm_area(ptr, size)
#define module_arch_init(x) mips64_module_init(x)
#define arch_init_modules(x) mips64_init_modules(x)
diff -urN -X /usr/share/dontdiff linux.vanilla/include/asm-ppc/module.h linux/include/asm-ppc/module.h
--- linux.vanilla/include/asm-ppc/module.h Wed May 8 10:01:55 2002
+++ linux/include/asm-ppc/module.h Wed May 8 10:06:36 2002
@@ -9,6 +9,7 @@
#define module_map(x) vmalloc(x)
#define module_unmap(x) vfree(x)
+#define module_remap(ptr, size) shrink_vm_area(ptr, size)
#define module_arch_init(x) (0)
#define arch_init_modules(x) do { } while (0)
diff -urN -X /usr/share/dontdiff linux.vanilla/include/asm-ppc64/module.h linux/include/asm-ppc64/module.h
--- linux.vanilla/include/asm-ppc64/module.h Wed May 8 10:02:04 2002
+++ linux/include/asm-ppc64/module.h Wed May 8 10:06:36 2002
@@ -13,6 +13,7 @@
#define module_map(x) vmalloc(x)
#define module_unmap(x) vfree(x)
+#define module_remap(ptr, size) shrink_vm_area(ptr, size)
#define arch_init_modules(x) do { } while (0)
#define module_arch_init(x) (0)
#endif /* _ASM_PPC64_MODULE_H */
diff -urN -X /usr/share/dontdiff linux.vanilla/include/asm-s390/module.h linux/include/asm-s390/module.h
--- linux.vanilla/include/asm-s390/module.h Wed May 8 10:02:01 2002
+++ linux/include/asm-s390/module.h Wed May 8 10:06:36 2002
@@ -6,6 +6,7 @@
#define module_map(x) vmalloc(x)
#define module_unmap(x) vfree(x)
+#define module_remap(ptr, size) shrink_vm_area(ptr, size)
#define module_arch_init(x) (0)
#define arch_init_modules(x) do { } while (0)
diff -urN -X /usr/share/dontdiff linux.vanilla/include/asm-s390x/module.h linux/include/asm-s390x/module.h
--- linux.vanilla/include/asm-s390x/module.h Wed May 8 10:02:03 2002
+++ linux/include/asm-s390x/module.h Wed May 8 10:06:36 2002
@@ -6,6 +6,7 @@
#define module_map(x) vmalloc(x)
#define module_unmap(x) vfree(x)
+#define module_remap(ptr, size) shrink_vm_area(ptr, size)
#define module_arch_init(x) (0)
#define arch_init_modules(x) do { } while (0)
diff -urN -X /usr/share/dontdiff linux.vanilla/include/asm-sh/module.h linux/include/asm-sh/module.h
--- linux.vanilla/include/asm-sh/module.h Wed May 8 10:01:58 2002
+++ linux/include/asm-sh/module.h Wed May 8 10:06:36 2002
@@ -6,6 +6,7 @@
#define module_map(x) vmalloc(x)
#define module_unmap(x) vfree(x)
+#define module_remap(ptr, size) shrink_vm_area(ptr, size)
#define module_arch_init(x) (0)
#define arch_init_modules(x) do { } while (0)
diff -urN -X /usr/share/dontdiff linux.vanilla/include/asm-sparc/module.h linux/include/asm-sparc/module.h
--- linux.vanilla/include/asm-sparc/module.h Wed May 8 10:01:54 2002
+++ linux/include/asm-sparc/module.h Wed May 8 10:06:36 2002
@@ -6,6 +6,7 @@
#define module_map(x) vmalloc(x)
#define module_unmap(x) vfree(x)
+#define module_remap(ptr, size) shrink_vm_area(ptr, size)
#define module_arch_init(x) (0)
#define arch_init_modules(x) do { } while (0)
diff -urN -X /usr/share/dontdiff linux.vanilla/include/asm-sparc64/module.h linux/include/asm-sparc64/module.h
--- linux.vanilla/include/asm-sparc64/module.h Wed May 8 10:01:56 2002
+++ linux/include/asm-sparc64/module.h Wed May 8 10:06:36 2002
@@ -6,6 +6,7 @@
extern void * module_map (unsigned long size);
extern void module_unmap (void *addr);
+#define module_remap(ptr, size) (-ENOSYS)
#define module_arch_init(x) (0)
#define arch_init_modules(x) do { } while (0)
diff -urN -X /usr/share/dontdiff linux.vanilla/include/asm-x86_64/module.h linux/include/asm-x86_64/module.h
--- linux.vanilla/include/asm-x86_64/module.h Wed May 8 10:02:05 2002
+++ linux/include/asm-x86_64/module.h Wed May 8 10:06:36 2002
@@ -9,6 +9,8 @@
extern void *module_map(unsigned long);
extern void module_unmap(void *);
+#define module_remap(ptr, size) (-ENOSYS)
+
#define module_arch_init(x) (0)
#define arch_init_modules(x) do { } while (0)
diff -urN -X /usr/share/dontdiff linux.vanilla/include/linux/init.h linux/include/linux/init.h
--- linux.vanilla/include/linux/init.h Wed May 8 10:01:47 2002
+++ linux/include/linux/init.h Wed May 8 10:06:36 2002
@@ -38,6 +38,18 @@
* Also note, that this data cannot be "const".
*/
+/*
+ * Mark functions and data as being only used at initialization
+ * or exit time.
+ */
+#define __init __attribute__ ((__section__ (".text.init")))
+#define __initdata __attribute__ ((__section__ (".data.init")))
+
+/* For assembly routines */
+#define __INIT .section ".text.init","ax"
+#define __FINIT .previous
+#define __INITDATA .section ".data.init","aw"
+
#ifndef MODULE
#ifndef __ASSEMBLY__
@@ -89,23 +101,12 @@
#endif /* __ASSEMBLY__ */
-/*
- * Mark functions and data as being only used at initialization
- * or exit time.
- */
-#define __init __attribute__ ((__section__ (".text.init")))
-#define __exit __attribute__ ((unused, __section__(".text.exit")))
-#define __initdata __attribute__ ((__section__ (".data.init")))
-#define __exitdata __attribute__ ((unused, __section__ (".data.exit")))
#define __initsetup __attribute__ ((unused,__section__ (".setup.init")))
#define __init_call(level) __attribute__ ((unused,__section__ (".initcall" level ".init")))
+#define __exit __attribute__ ((unused, __section__(".text.exit")))
+#define __exitdata __attribute__ ((unused, __section__ (".data.exit")))
#define __exit_call __attribute__ ((unused,__section__ (".exitcall.exit")))
-/* For assembly routines */
-#define __INIT .section ".text.init","ax"
-#define __FINIT .previous
-#define __INITDATA .section ".data.init","aw"
-
/**
* module_init() - driver initialization entry point
* @x: function to be run at kernel boot time or module insertion
@@ -131,15 +132,9 @@
#else
-#define __init
#define __exit
-#define __initdata
#define __exitdata
#define __initcall(fn)
-/* For assembly routines */
-#define __INIT
-#define __FINIT
-#define __INITDATA
/* These macros create a dummy inline: gcc 2.9x does not count alias
as usage, hence the `unused function' warning when __init functions
diff -urN -X /usr/share/dontdiff linux.vanilla/include/linux/vmalloc.h linux/include/linux/vmalloc.h
--- linux.vanilla/include/linux/vmalloc.h Wed May 8 10:01:48 2002
+++ linux/include/linux/vmalloc.h Wed May 8 10:34:16 2002
@@ -24,6 +24,7 @@
extern void vmfree_area_pages(unsigned long address, unsigned long size);
extern int vmalloc_area_pages(unsigned long address, unsigned long size,
int gfp_mask, pgprot_t prot);
+extern int shrink_vm_area(void * addr, unsigned long size);
/*
* Allocate any pages
diff -urN -X /usr/share/dontdiff linux.vanilla/kernel/ksyms.c linux/kernel/ksyms.c
--- linux.vanilla/kernel/ksyms.c Wed May 8 10:01:45 2002
+++ linux/kernel/ksyms.c Wed May 8 10:06:36 2002
@@ -108,6 +108,7 @@
EXPORT_SYMBOL(vfree);
EXPORT_SYMBOL(__vmalloc);
EXPORT_SYMBOL(vmalloc_to_page);
+EXPORT_SYMBOL(shrink_vm_area);
EXPORT_SYMBOL(mem_map);
EXPORT_SYMBOL(remap_page_range);
EXPORT_SYMBOL(max_mapnr);
diff -urN -X /usr/share/dontdiff linux.vanilla/kernel/module.c linux/kernel/module.c
--- linux.vanilla/kernel/module.c Wed May 8 10:01:45 2002
+++ linux/kernel/module.c Wed May 8 10:06:36 2002
@@ -558,6 +558,13 @@
error = -EBUSY;
goto err0;
}
+
+ /* It's time to throw away .init sections */
+ if (mod->runsize) {
+ if (!module_remap(mod, mod->runsize))
+ mod->size = mod->runsize;
+ }
+
atomic_dec(&mod->uc.usecount);
/* And set it running. */
diff -urN -X /usr/share/dontdiff linux.vanilla/mm/vmalloc.c linux/mm/vmalloc.c
--- linux.vanilla/mm/vmalloc.c Wed May 8 10:01:46 2002
+++ linux/mm/vmalloc.c Wed May 8 10:06:36 2002
@@ -174,6 +174,44 @@
return ret;
}
+int shrink_vm_area(void * addr, unsigned long size)
+{
+ int ret;
+ struct vm_struct **p, *tmp;
+
+ if (!addr || !(unsigned long)addr & (PAGE_SIZE - 1) || !size)
+ return -EINVAL;
+
+ size = PAGE_ALIGN(size) + PAGE_SIZE;
+
+ ret = 0;
+ write_lock(&vmlist_lock);
+ for (p = &vmlist; (tmp = *p) ; p = &tmp->next) {
+ if (tmp->addr == addr) {
+ int delta;
+ unsigned long end;
+
+ if (size > tmp->size) {
+ ret = -EINVAL;
+ break;
+ }
+ if (size == tmp->size)
+ break;
+
+ delta = tmp->size - size;
+ end = (unsigned long) tmp->addr + size - PAGE_SIZE;
+
+ tmp->size = size + PAGE_SIZE;
+ vmfree_area_pages(VMALLOC_VMADDR(end), delta);
+
+ break;
+ }
+ }
+
+ write_unlock(&vmlist_lock);
+ return ret;
+}
+
struct vm_struct * get_vm_area(unsigned long size, unsigned long flags)
{
unsigned long addr;
[-- Attachment #2: Type: application/pgp-signature, Size: 232 bytes --]
next reply other threads:[~2002-05-08 10:24 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-05-08 10:29 Andrey Panin [this message]
2002-05-08 14:02 ` [PATCH][RFC] __init and friends support for loadable modules Keith Owens
2002-05-09 7:45 ` Rusty Russell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20020508102933.GA574@pazke.ipt \
--to=pazke@orbita1.ru \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox