From: NIIBE Y. <gn...@m1...> - 2002-05-23 01:46:18
|
Changes from mainline. We need to implement TLB handling, but it will be done with 2.5.17 (or forthcoming 2.5.18) together... 2002-05-23 NIIBE Yutaka <gn...@m1...> * include/asm-sh/pgalloc.h (pte_free_tlb, pmd_free_tlb): Added. * AGAINST-2.5.16: New file. * AGAINST-2.5.15: Removed. * Makefile: Version 2.5.16 * arch/sh/kernel/process.c, arch/sh/vmlinux.lds.S, drivers/net/8139too.c, include/asm-sh/ide.h, include/linux/input.h, mm/memory.c: Incorporate changes in 2.5.16. Index: Makefile =================================================================== RCS file: /cvsroot/linuxsh/linux/Makefile,v retrieving revision 1.22 diff -u -3 -p -r1.22 Makefile --- Makefile 23 May 2002 01:31:03 -0000 1.22 +++ Makefile 23 May 2002 01:43:24 -0000 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 5 -SUBLEVEL = 15 +SUBLEVEL = 16 EXTRAVERSION =-sh KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) Index: arch/sh/vmlinux.lds.S =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/vmlinux.lds.S,v retrieving revision 1.3 diff -u -3 -p -r1.3 vmlinux.lds.S --- arch/sh/vmlinux.lds.S 1 Mar 2002 01:55:10 -0000 1.3 +++ arch/sh/vmlinux.lds.S 23 May 2002 01:43:24 -0000 @@ -5,8 +5,10 @@ #include <linux/config.h> #ifdef CONFIG_CPU_LITTLE_ENDIAN OUTPUT_FORMAT("elf32-sh-linux", "elf32-sh-linux", "elf32-sh-linux") +jiffies = jiffies_64; #else OUTPUT_FORMAT("elf32-shbig-linux", "elf32-shbig-linux", "elf32-shbig-linux") +jiffies = jiffies_64 + 4; #endif OUTPUT_ARCH(sh) ENTRY(_start) Index: arch/sh/kernel/process.c =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/kernel/process.c,v retrieving revision 1.10 diff -u -3 -p -r1.10 process.c --- arch/sh/kernel/process.c 12 Apr 2002 04:26:28 -0000 1.10 +++ arch/sh/kernel/process.c 23 May 2002 01:43:24 -0000 @@ -259,16 +259,20 @@ asmlinkage int sys_fork(unsigned long r4 unsigned long r6, unsigned long r7, struct pt_regs regs) { - return do_fork(SIGCHLD, regs.regs[15], ®s, 0); + struct task_struct *p; + p = do_fork(SIGCHLD, regs.regs[15], ®s, 0); + return IS_ERR(p) ? PTR_ERR(p) : p->pid; } asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, unsigned long r6, unsigned long r7, struct pt_regs regs) { + struct task_struct *p; if (!newsp) newsp = regs.regs[15]; - return do_fork(clone_flags, newsp, ®s, 0); + p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, ®s, 0); + return IS_ERR(p) ? PTR_ERR(p) : p->pid; } /* @@ -285,7 +289,9 @@ asmlinkage int sys_vfork(unsigned long r unsigned long r6, unsigned long r7, struct pt_regs regs) { - return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.regs[15], ®s, 0); + struct task_struct *p; + p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.regs[15], ®s, 0); + return IS_ERR(p) ? PTR_ERR(p) : p->pid; } /* Index: drivers/net/8139too.c =================================================================== RCS file: /cvsroot/linuxsh/linux/drivers/net/8139too.c,v retrieving revision 1.11 diff -u -3 -p -r1.11 8139too.c --- drivers/net/8139too.c 5 Apr 2002 04:45:00 -0000 1.11 +++ drivers/net/8139too.c 23 May 2002 01:43:24 -0000 @@ -2351,7 +2351,7 @@ static int netdev_ioctl (struct net_devi if (cmd != SIOCETHTOOL) { /* With SIOCETHTOOL, this would corrupt the pointer. */ - data->phy_id &= 0x1f; + data->phy_id &= 0x3f; data->reg_num &= 0x1f; } Index: include/asm-sh/ide.h =================================================================== RCS file: /cvsroot/linuxsh/linux/include/asm-sh/ide.h,v retrieving revision 1.4 diff -u -3 -p -r1.4 ide.h --- include/asm-sh/ide.h 23 May 2002 01:31:04 -0000 1.4 +++ include/asm-sh/ide.h 23 May 2002 01:43:24 -0000 @@ -107,10 +107,6 @@ static __inline__ void ide_init_default_ #endif /* CONFIG_PCI */ } -#define ide_ack_intr(hwif) (1) -#define ide_release_lock(lock) do {} while (0) -#define ide_get_lock(lock, hdlr, data) do {} while (0) - #endif /* __KERNEL__ */ #endif /* __ASM_SH_IDE_H */ Index: include/asm-sh/pgalloc.h =================================================================== RCS file: /cvsroot/linuxsh/linux/include/asm-sh/pgalloc.h,v retrieving revision 1.8 diff -u -3 -p -r1.8 pgalloc.h --- include/asm-sh/pgalloc.h 22 May 2002 07:37:02 -0000 1.8 +++ include/asm-sh/pgalloc.h 23 May 2002 01:43:24 -0000 @@ -38,6 +38,8 @@ static inline void pte_free(struct page __free_page(pte); } +#define pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte)) + /* * allocating and freeing a pmd is trivial: the 1-entry pmd is * inside the pgd, so has no extra memory associated with it. @@ -45,6 +47,7 @@ static inline void pte_free(struct page #define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); }) #define pmd_free(x) do { } while (0) +#define pmd_free_tlb(x) do { } while (0) #define pgd_populate(mm, pmd, pte) BUG() #if defined(__SH4__) Index: include/linux/input.h =================================================================== RCS file: /cvsroot/linuxsh/linux/include/linux/input.h,v retrieving revision 1.2 diff -u -3 -p -r1.2 input.h --- include/linux/input.h 1 Mar 2002 01:55:10 -0000 1.2 +++ include/linux/input.h 23 May 2002 01:43:24 -0000 @@ -326,6 +326,9 @@ struct input_event { #define KEY_UNKNOWN 240 +#define KEY_BRIGHTNESSDOWN 224 +#define KEY_BRIGHTNESSUP 225 + #define BTN_MISC 0x100 #define BTN_0 0x100 #define BTN_1 0x101 Index: mm/memory.c =================================================================== RCS file: /cvsroot/linuxsh/linux/mm/memory.c,v retrieving revision 1.13 diff -u -3 -p -r1.13 memory.c --- mm/memory.c 22 May 2002 07:37:02 -0000 1.13 +++ mm/memory.c 23 May 2002 01:43:24 -0000 @@ -72,28 +72,10 @@ static inline void copy_cow_page(struct mem_map_t * mem_map; /* - * Called by TLB shootdown - */ -void __free_pte(pte_t pte) -{ - struct page *page; - unsigned long pfn = pte_pfn(pte); - if (!pfn_valid(pfn)) - return; - page = pfn_to_page(pfn); - if (PageReserved(page)) - return; - if (pte_dirty(pte)) - set_page_dirty(page); - free_page_and_swap_cache(page); -} - - -/* * Note: this doesn't free the actual pages themselves. That * has been handled earlier when unmapping all the memory regions. */ -static inline void free_one_pmd(pmd_t * dir) +static inline void free_one_pmd(mmu_gather_t *tlb, pmd_t * dir) { struct page *pte; @@ -106,10 +88,10 @@ static inline void free_one_pmd(pmd_t * } pte = pmd_page(*dir); pmd_clear(dir); - pte_free(pte); + pte_free_tlb(tlb, pte); } -static inline void free_one_pgd(pgd_t * dir) +static inline void free_one_pgd(mmu_gather_t *tlb, pgd_t * dir) { int j; pmd_t * pmd; @@ -125,26 +107,26 @@ static inline void free_one_pgd(pgd_t * pgd_clear(dir); for (j = 0; j < PTRS_PER_PMD ; j++) { prefetchw(pmd+j+(PREFETCH_STRIDE/16)); - free_one_pmd(pmd+j); + free_one_pmd(tlb, pmd+j); } - pmd_free(pmd); + pmd_free_tlb(tlb, pmd); } /* * This function clears all user-level page tables of a process - this * is needed by execve(), so that old pages aren't in the way. + * + * Must be called with pagetable lock held. */ -void clear_page_tables(struct mm_struct *mm, unsigned long first, int nr) +void clear_page_tables(mmu_gather_t *tlb, unsigned long first, int nr) { - pgd_t * page_dir = mm->pgd; + pgd_t * page_dir = tlb->mm->pgd; - spin_lock(&mm->page_table_lock); page_dir += first; do { - free_one_pgd(page_dir); + free_one_pgd(tlb, page_dir); page_dir++; } while (--nr); - spin_unlock(&mm->page_table_lock); /* keep the page table cache within bounds */ check_pgt_cache(); @@ -340,18 +322,17 @@ static inline void forget_pte(pte_t page } } -static inline int zap_pte_range(mmu_gather_t *tlb, pmd_t * pmd, unsigned long address, unsigned long size) +static void zap_pte_range(mmu_gather_t *tlb, pmd_t * pmd, unsigned long address, unsigned long size) { unsigned long offset; pte_t *ptep; - int freed = 0; if (pmd_none(*pmd)) - return 0; + return; if (pmd_bad(*pmd)) { pmd_ERROR(*pmd); pmd_clear(pmd); - return 0; + return; } ptep = pte_offset_map(pmd, address); offset = address & ~PMD_MASK; @@ -363,49 +344,63 @@ static inline int zap_pte_range(mmu_gath if (pte_none(pte)) continue; if (pte_present(pte)) { - struct page *page; unsigned long pfn = pte_pfn(pte); + + pte_clear(ptep); + pfn = pte_pfn(pte); if (pfn_valid(pfn)) { - page = pfn_to_page(pfn); - if (!PageReserved(page)) - freed++; + struct page *page = pfn_to_page(pfn); + if (!PageReserved(page)) { + if (pte_dirty(pte)) + set_page_dirty(page); + tlb_remove_page(tlb, page); + } } - /* This will eventually call __free_pte on the pte. */ - tlb_remove_page(tlb, ptep, address + offset); } else { free_swap_and_cache(pte_to_swp_entry(pte)); pte_clear(ptep); } } pte_unmap(ptep-1); - - return freed; } -static inline int zap_pmd_range(mmu_gather_t *tlb, pgd_t * dir, unsigned long address, unsigned long size) +static void zap_pmd_range(mmu_gather_t *tlb, pgd_t * dir, unsigned long address, unsigned long size) { pmd_t * pmd; unsigned long end; - int freed; if (pgd_none(*dir)) - return 0; + return; if (pgd_bad(*dir)) { pgd_ERROR(*dir); pgd_clear(dir); - return 0; + return; } pmd = pmd_offset(dir, address); end = address + size; if (end > ((address + PGDIR_SIZE) & PGDIR_MASK)) end = ((address + PGDIR_SIZE) & PGDIR_MASK); - freed = 0; do { - freed += zap_pte_range(tlb, pmd, address, end - address); + zap_pte_range(tlb, pmd, address, end - address); address = (address + PMD_SIZE) & PMD_MASK; pmd++; } while (address < end); - return freed; +} + +void unmap_page_range(mmu_gather_t *tlb, struct vm_area_struct *vma, unsigned long address, unsigned long end) +{ + pgd_t * dir; + + if (address >= end) + BUG(); + dir = pgd_offset(vma->vm_mm, address); + tlb_start_vma(tlb, vma); + do { + zap_pmd_range(tlb, dir, address, end - address); + address = (address + PGDIR_SIZE) & PGDIR_MASK; + dir++; + } while (address && (address < end)); + tlb_end_vma(tlb, vma); } /* @@ -417,7 +412,6 @@ void zap_page_range(struct vm_area_struc mmu_gather_t *tlb; pgd_t * dir; unsigned long start = address, end = address + size; - int freed = 0; dir = pgd_offset(mm, address); @@ -432,25 +426,10 @@ void zap_page_range(struct vm_area_struc BUG(); spin_lock(&mm->page_table_lock); flush_cache_range(vma, address, end); - tlb = tlb_gather_mmu(vma); - do { - freed += zap_pmd_range(tlb, dir, address, end - address); - address = (address + PGDIR_SIZE) & PGDIR_MASK; - dir++; - } while (address && (address < end)); - - /* this will flush any remaining tlb entries */ + tlb = tlb_gather_mmu(mm); + unmap_page_range(tlb, vma, address, end); tlb_finish_mmu(tlb, start, end); - - /* - * Update rss for the mm_struct (not necessarily current->mm) - * Notice that rss is an unsigned long. - */ - if (mm->rss > freed) - mm->rss -= freed; - else - mm->rss = 0; spin_unlock(&mm->page_table_lock); } |