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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.