public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH][RFC] __init and friends support for loadable modules
@ 2002-05-08 10:29 Andrey Panin
  2002-05-08 14:02 ` Keith Owens
  0 siblings, 1 reply; 3+ messages in thread
From: Andrey Panin @ 2002-05-08 10:29 UTC (permalink / raw)
  To: linux-kernel


[-- 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 --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2002-05-09  7:43 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-05-08 10:29 [PATCH][RFC] __init and friends support for loadable modules Andrey Panin
2002-05-08 14:02 ` Keith Owens
2002-05-09  7:45   ` Rusty Russell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox