Re: [PATCH -mm 1/2 -v2] kexec/i386: kexec page table code clean up - add arch_kimage
On Tue, Jan 15, 2008 at 02:05:46PM +0800, Huang, Ying wrote: > This patch add an architecture specific struct arch_kimage into struct > kimage. Three pointers to page table pages used by kexec are added to > struct arch_kimage. The page tables pages are dynamically allocated in > machine_kexec_prepare instead of statically from BSS segment. This > will save up to 20k memory when kexec image is not loaded. I like this idea a lot. Acked-by: Simon Horman <[EMAIL PROTECTED]> > Signed-off-by: Huang Ying <[EMAIL PROTECTED]> -- Horms -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH -mm 1/2 -v2] kexec/i386: kexec page table code clean up - add arch_kimage
On Tue, Jan 15, 2008 at 02:05:46PM +0800, Huang, Ying wrote: This patch add an architecture specific struct arch_kimage into struct kimage. Three pointers to page table pages used by kexec are added to struct arch_kimage. The page tables pages are dynamically allocated in machine_kexec_prepare instead of statically from BSS segment. This will save up to 20k memory when kexec image is not loaded. I like this idea a lot. Acked-by: Simon Horman [EMAIL PROTECTED] Signed-off-by: Huang Ying [EMAIL PROTECTED] -- Horms -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH -mm 1/2 -v2] kexec/i386: kexec page table code clean up - add arch_kimage
On Tue, Jan 15, 2008 at 02:05:46PM +0800, Huang, Ying wrote: > This patch add an architecture specific struct arch_kimage into struct > kimage. Three pointers to page table pages used by kexec are added to > struct arch_kimage. The page tables pages are dynamically allocated in > machine_kexec_prepare instead of statically from BSS segment. This > will save up to 20k memory when kexec image is not loaded. > > Signed-off-by: Huang Ying <[EMAIL PROTECTED]> > Looks good to me. Thanks Vivek -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH -mm 1/2 -v2] kexec/i386: kexec page table code clean up - add arch_kimage
On Tue, Jan 15, 2008 at 02:05:46PM +0800, Huang, Ying wrote: This patch add an architecture specific struct arch_kimage into struct kimage. Three pointers to page table pages used by kexec are added to struct arch_kimage. The page tables pages are dynamically allocated in machine_kexec_prepare instead of statically from BSS segment. This will save up to 20k memory when kexec image is not loaded. Signed-off-by: Huang Ying [EMAIL PROTECTED] Looks good to me. Thanks Vivek -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH -mm 1/2 -v2] kexec/i386: kexec page table code clean up - add arch_kimage
This patch add an architecture specific struct arch_kimage into struct kimage. Three pointers to page table pages used by kexec are added to struct arch_kimage. The page tables pages are dynamically allocated in machine_kexec_prepare instead of statically from BSS segment. This will save up to 20k memory when kexec image is not loaded. Signed-off-by: Huang Ying <[EMAIL PROTECTED]> --- arch/x86/kernel/machine_kexec_32.c | 70 + include/asm-x86/kexec_32.h | 12 ++ include/linux/kexec.h |4 ++ 3 files changed, 64 insertions(+), 22 deletions(-) --- a/arch/x86/kernel/machine_kexec_32.c +++ b/arch/x86/kernel/machine_kexec_32.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -21,15 +22,6 @@ #include #include -#define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE))) -static u32 kexec_pgd[1024] PAGE_ALIGNED; -#ifdef CONFIG_X86_PAE -static u32 kexec_pmd0[1024] PAGE_ALIGNED; -static u32 kexec_pmd1[1024] PAGE_ALIGNED; -#endif -static u32 kexec_pte0[1024] PAGE_ALIGNED; -static u32 kexec_pte1[1024] PAGE_ALIGNED; - static void set_idt(void *newidt, __u16 limit) { struct Xgt_desc_struct curidt; @@ -72,6 +64,39 @@ static void load_segments(void) #undef __STR } +static void machine_kexec_free_page_tables(struct kimage *image) +{ + free_page((unsigned long)image->arch_kimage.pgd); +#ifdef CONFIG_X86_PAE + free_page((unsigned long)image->arch_kimage.pmd0); + free_page((unsigned long)image->arch_kimage.pmd1); +#endif + free_page((unsigned long)image->arch_kimage.pte0); + free_page((unsigned long)image->arch_kimage.pte1); +} + +static int machine_kexec_alloc_page_tables(struct kimage *image) +{ + image->arch_kimage.pgd = (pgd_t *)get_zeroed_page(GFP_KERNEL); +#ifdef CONFIG_X86_PAE + image->arch_kimage.pmd0 = (pmd_t *)get_zeroed_page(GFP_KERNEL); + image->arch_kimage.pmd1 = (pmd_t *)get_zeroed_page(GFP_KERNEL); +#endif + image->arch_kimage.pte0 = (pte_t *)get_zeroed_page(GFP_KERNEL); + image->arch_kimage.pte1 = (pte_t *)get_zeroed_page(GFP_KERNEL); + if (!image->arch_kimage.pgd || +#ifdef CONFIG_X86_PAE + !image->arch_kimage.pmd0 || + !image->arch_kimage.pmd1 || +#endif + !image->arch_kimage.pte0 || + !image->arch_kimage.pte1) { + machine_kexec_free_page_tables(image); + return -ENOMEM; + } + return 0; +} + /* * A architecture hook called to validate the * proposed image and prepare the control pages @@ -83,11 +108,11 @@ static void load_segments(void) * reboot code buffer to allow us to avoid allocations * later. * - * Currently nothing. + * - Allocate page tables */ int machine_kexec_prepare(struct kimage *image) { - return 0; + return machine_kexec_alloc_page_tables(image); } /* @@ -96,6 +121,7 @@ int machine_kexec_prepare(struct kimage */ void machine_kexec_cleanup(struct kimage *image) { + machine_kexec_free_page_tables(image); } /* @@ -115,18 +141,18 @@ NORET_TYPE void machine_kexec(struct kim page_list[PA_CONTROL_PAGE] = __pa(control_page); page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel; - page_list[PA_PGD] = __pa(kexec_pgd); - page_list[VA_PGD] = (unsigned long)kexec_pgd; + page_list[PA_PGD] = __pa(image->arch_kimage.pgd); + page_list[VA_PGD] = (unsigned long)image->arch_kimage.pgd; #ifdef CONFIG_X86_PAE - page_list[PA_PMD_0] = __pa(kexec_pmd0); - page_list[VA_PMD_0] = (unsigned long)kexec_pmd0; - page_list[PA_PMD_1] = __pa(kexec_pmd1); - page_list[VA_PMD_1] = (unsigned long)kexec_pmd1; -#endif - page_list[PA_PTE_0] = __pa(kexec_pte0); - page_list[VA_PTE_0] = (unsigned long)kexec_pte0; - page_list[PA_PTE_1] = __pa(kexec_pte1); - page_list[VA_PTE_1] = (unsigned long)kexec_pte1; + page_list[PA_PMD_0] = __pa(image->arch_kimage.pmd0); + page_list[VA_PMD_0] = (unsigned long)image->arch_kimage.pmd0; + page_list[PA_PMD_1] = __pa(image->arch_kimage.pmd1); + page_list[VA_PMD_1] = (unsigned long)image->arch_kimage.pmd1; +#endif + page_list[PA_PTE_0] = __pa(image->arch_kimage.pte0); + page_list[VA_PTE_0] = (unsigned long)image->arch_kimage.pte0; + page_list[PA_PTE_1] = __pa(image->arch_kimage.pte1); + page_list[VA_PTE_1] = (unsigned long)image->arch_kimage.pte1; /* The segment registers are funny things, they have both a * visible and an invisible part. Whenever the visible part is --- a/include/asm-x86/kexec_32.h +++ b/include/asm-x86/kexec_32.h @@ -94,6 +94,18 @@ relocate_kernel(unsigned long indirectio unsigned long start_address, unsigned int has_pae) ATTRIB_NORET; +#define ARCH_HAS_ARCH_KIMAGE + +struct arch_kimage { + pgd_t *pgd; +#ifdef CONFIG_X86_PAE + pmd_t *pmd0; +
[PATCH -mm 1/2 -v2] kexec/i386: kexec page table code clean up - add arch_kimage
This patch add an architecture specific struct arch_kimage into struct kimage. Three pointers to page table pages used by kexec are added to struct arch_kimage. The page tables pages are dynamically allocated in machine_kexec_prepare instead of statically from BSS segment. This will save up to 20k memory when kexec image is not loaded. Signed-off-by: Huang Ying [EMAIL PROTECTED] --- arch/x86/kernel/machine_kexec_32.c | 70 + include/asm-x86/kexec_32.h | 12 ++ include/linux/kexec.h |4 ++ 3 files changed, 64 insertions(+), 22 deletions(-) --- a/arch/x86/kernel/machine_kexec_32.c +++ b/arch/x86/kernel/machine_kexec_32.c @@ -11,6 +11,7 @@ #include linux/delay.h #include linux/init.h #include linux/numa.h +#include linux/gfp.h #include asm/pgtable.h #include asm/pgalloc.h #include asm/tlbflush.h @@ -21,15 +22,6 @@ #include asm/desc.h #include asm/system.h -#define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE))) -static u32 kexec_pgd[1024] PAGE_ALIGNED; -#ifdef CONFIG_X86_PAE -static u32 kexec_pmd0[1024] PAGE_ALIGNED; -static u32 kexec_pmd1[1024] PAGE_ALIGNED; -#endif -static u32 kexec_pte0[1024] PAGE_ALIGNED; -static u32 kexec_pte1[1024] PAGE_ALIGNED; - static void set_idt(void *newidt, __u16 limit) { struct Xgt_desc_struct curidt; @@ -72,6 +64,39 @@ static void load_segments(void) #undef __STR } +static void machine_kexec_free_page_tables(struct kimage *image) +{ + free_page((unsigned long)image-arch_kimage.pgd); +#ifdef CONFIG_X86_PAE + free_page((unsigned long)image-arch_kimage.pmd0); + free_page((unsigned long)image-arch_kimage.pmd1); +#endif + free_page((unsigned long)image-arch_kimage.pte0); + free_page((unsigned long)image-arch_kimage.pte1); +} + +static int machine_kexec_alloc_page_tables(struct kimage *image) +{ + image-arch_kimage.pgd = (pgd_t *)get_zeroed_page(GFP_KERNEL); +#ifdef CONFIG_X86_PAE + image-arch_kimage.pmd0 = (pmd_t *)get_zeroed_page(GFP_KERNEL); + image-arch_kimage.pmd1 = (pmd_t *)get_zeroed_page(GFP_KERNEL); +#endif + image-arch_kimage.pte0 = (pte_t *)get_zeroed_page(GFP_KERNEL); + image-arch_kimage.pte1 = (pte_t *)get_zeroed_page(GFP_KERNEL); + if (!image-arch_kimage.pgd || +#ifdef CONFIG_X86_PAE + !image-arch_kimage.pmd0 || + !image-arch_kimage.pmd1 || +#endif + !image-arch_kimage.pte0 || + !image-arch_kimage.pte1) { + machine_kexec_free_page_tables(image); + return -ENOMEM; + } + return 0; +} + /* * A architecture hook called to validate the * proposed image and prepare the control pages @@ -83,11 +108,11 @@ static void load_segments(void) * reboot code buffer to allow us to avoid allocations * later. * - * Currently nothing. + * - Allocate page tables */ int machine_kexec_prepare(struct kimage *image) { - return 0; + return machine_kexec_alloc_page_tables(image); } /* @@ -96,6 +121,7 @@ int machine_kexec_prepare(struct kimage */ void machine_kexec_cleanup(struct kimage *image) { + machine_kexec_free_page_tables(image); } /* @@ -115,18 +141,18 @@ NORET_TYPE void machine_kexec(struct kim page_list[PA_CONTROL_PAGE] = __pa(control_page); page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel; - page_list[PA_PGD] = __pa(kexec_pgd); - page_list[VA_PGD] = (unsigned long)kexec_pgd; + page_list[PA_PGD] = __pa(image-arch_kimage.pgd); + page_list[VA_PGD] = (unsigned long)image-arch_kimage.pgd; #ifdef CONFIG_X86_PAE - page_list[PA_PMD_0] = __pa(kexec_pmd0); - page_list[VA_PMD_0] = (unsigned long)kexec_pmd0; - page_list[PA_PMD_1] = __pa(kexec_pmd1); - page_list[VA_PMD_1] = (unsigned long)kexec_pmd1; -#endif - page_list[PA_PTE_0] = __pa(kexec_pte0); - page_list[VA_PTE_0] = (unsigned long)kexec_pte0; - page_list[PA_PTE_1] = __pa(kexec_pte1); - page_list[VA_PTE_1] = (unsigned long)kexec_pte1; + page_list[PA_PMD_0] = __pa(image-arch_kimage.pmd0); + page_list[VA_PMD_0] = (unsigned long)image-arch_kimage.pmd0; + page_list[PA_PMD_1] = __pa(image-arch_kimage.pmd1); + page_list[VA_PMD_1] = (unsigned long)image-arch_kimage.pmd1; +#endif + page_list[PA_PTE_0] = __pa(image-arch_kimage.pte0); + page_list[VA_PTE_0] = (unsigned long)image-arch_kimage.pte0; + page_list[PA_PTE_1] = __pa(image-arch_kimage.pte1); + page_list[VA_PTE_1] = (unsigned long)image-arch_kimage.pte1; /* The segment registers are funny things, they have both a * visible and an invisible part. Whenever the visible part is --- a/include/asm-x86/kexec_32.h +++ b/include/asm-x86/kexec_32.h @@ -94,6 +94,18 @@ relocate_kernel(unsigned long indirectio unsigned long start_address, unsigned int has_pae) ATTRIB_NORET; +#define ARCH_HAS_ARCH_KIMAGE + +struct