FRV: Make the FRV arch work again
Subsystems (3)
PATCH 2/3 FRV: Clean up bootmem allocator's page freeing algorithm
In reply to David HowellsThe attached patch cleans up the way the bootmem allocator frees pages.
A new function, __free_pages_bootmem(), is provided in mm/page_alloc.c () that is called from mm/bootmem.c to turn pages over to the main allocator. All the bits of code to initialise pages (clearing PG_reserved and setting the page count) are moved to here. The checks on page validity are removed, on the assumption that the struct page arrays will have been prepared correctly.
---
warthog>diffstat -p1 frv-bootmem-2615rc2.diff
mm/bootmem.c | 20 +++------------- mm/internal.h | 2 - mm/page_alloc.c | 70 +++++++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 57 insertions(+), 35 deletions(-)
mm/bootmem.c renamed from warthog/kernels/linux-2.6.15-rc2/mm/bootmem.c +4 -16
@@ -294,20 +294,12 @@ static unsigned long __init free_all_boounsigned long v = ~map[i /BITS_PER_LONG ];if (gofast && v == ~0UL ) { -int j, order; +int order; page =pfn_to_page (pfn); count +=BITS_PER_LONG ; -__ClearPageReserved (page); order =ffs (BITS_PER_LONG ) -1 ; -set_page_refs (page, order); -for (j =1 ; j <BITS_PER_LONG ; j++) { -if (j +16 <BITS_PER_LONG ) -prefetchw (page + j +16 ); -__ClearPageReserved (page + j); -set_page_count (page + j,0 ); - } -__free_pages (page, order); +__free_pages_bootmem (page, order); i +=BITS_PER_LONG ; page +=BITS_PER_LONG ; }else if (v) {
@@ -317,9 +309,7 @@ static unsigned long __init free_all_boofor (m =1 ; m && i < idx; m<<=1 , page++, i++) {if (v & m) { count++; -__ClearPageReserved (page); -set_page_refs (page,0 ); -__free_page (page); +__free_pages_bootmem (page,0 ); } } }else {
@@ -337,9 +327,7 @@ static unsigned long __init free_all_boo count =0 ;for (i =0 ; i < ((bdata->node_low_pfn-(bdata->node_boot_start >>PAGE_SHIFT ))/8 +PAGE_SIZE -1 )/PAGE_SIZE ; i++,page++) { count++; -__ClearPageReserved (page); -set_page_count (page,1 ); -__free_page (page); +__free_pages_bootmem (page,0 ); } total += count; bdata->node_bootmem_map =NULL ;
mm/internal.h renamed from warthog/kernels/linux-2.6.15-rc2/mm/internal.h +1 -1
@@ -10,4 +10,4 @@*/ /* page_alloc.c */ -extern void set_page_refs (struct page *page,int order); +extern void fastcall __init __free_pages_bootmem(struct page *page, unsigned int order);
mm/page_alloc.c renamed from warthog/kernels/linux-2.6.15-rc2/mm/page_alloc.c +52 -18
100 lines not on this page · raw message
PATCH 1/3 FRV: Make the FRV arch work again
The attached patch implements a bunch of small changes to the FRV arch to make it work again.
It deals with the following problems:
(1) SEM_DEBUG should be SEMAPHORE_DEBUG.
(2) The argument list to pcibios_penalize_isa_irq() has changed.
(3) CONFIG_HIGHMEM can't be used directly in #if as it may not be defined.
(4) page->private is no longer directly accessible.
(5) linux/hardirq.h assumes asm/hardirq.h will include linux/irq.h
(6) The IDE MMIO access functions are given pointers, not integers, and so get type casting errors.
(7) __pa() is passed an explicit u64 type in drivers/char/mem.c, but that can't be cast directly to a pointer on a 32-bit platform.
(8) SEMAPHORE_DEBUG should not be contingent on WAITQUEUE_DEBUG as that no longer exists.
(9) PREEMPT_ACTIVE is too low a value.
---
warthog>diffstat -p1 frv-cleanup-2615rc2.diff
arch/frv/kernel/semaphore.c | 2 +- arch/frv/mb93090-mb00/pci-irq.c | 2 +- arch/frv/mm/init.c | 2 +- arch/frv/mm/pgalloc.c | 6 +++--- include/asm-frv/hardirq.h | 1 + include/asm-frv/ide.h | 8 ++++---- include/asm-frv/page.h | 4 ++-- include/asm-frv/semaphore.h | 2 +- include/asm-frv/thread_info.h | 2 +- 9 files changed, 15 insertions(+), 14 deletions(-)
arch/frv/kernel/semaphore.c renamed from warthog/kernels/linux-2.6.15-rc2/arch/frv/kernel/semaphore.c +1 -1
@@ -20,7 +20,7 @@ struct sem_waiter {struct task_struct *task; }; -#if SEM_DEBUG +#if SEMAPHORE_DEBUG void semtrace (struct semaphore *sem,const char *str) {if (sem->debug)
arch/frv/mb93090-mb00/pci-irq.c renamed from warthog/kernels/linux-2.6.15-rc2/arch/frv/mb93090-mb00/pci-irq.c +1 -1
@@ -60,7 +60,7 @@ void __init pcibios_fixup_irqs(void) } } -void __init pcibios_penalize_isa_irq (int irq,int active) +void __init pcibios_penalize_isa_irq (int irq) { }
arch/frv/mm/init.c renamed from warthog/kernels/linux-2.6.15-rc2/arch/frv/mm/init.c +1 -1
@@ -108,7 +108,7 @@ void __init paging_init(void)memset ((void *) empty_zero_page,0 ,PAGE_SIZE ); -#if CONFIG_HIGHMEM +#ifdef CONFIG_HIGHMEM if (num_physpages - num_mappedpages) {pgd_t *pge;pud_t *pue;
arch/frv/mm/pgalloc.c renamed from warthog/kernels/linux-2.6.15-rc2/arch/frv/mm/pgalloc.c +3 -3
@@ -85,7 +85,7 @@ static inline void pgd_list_add(pgd_t *pstruct page *page =virt_to_page (pgd); page->index = (unsigned long ) pgd_list;if (pgd_list) - pgd_list->private = (unsigned long ) &page->index; +set_page_private (pgd_list, (unsigned long ) &page->index); pgd_list = page;set_page_private (page, (unsigned long )&pgd_list); }
@@ -94,10 +94,10 @@ static inline void pgd_list_del(pgd_t *p {struct page *next, **pprev, *page =virt_to_page (pgd); next = (struct page *) page->index; - pprev = (struct page **)page_private (page); + pprev = (struct page **)page_private (page); *pprev = next;if (next) - next->private = (unsigned long ) pprev; +set_page_private (next, (unsigned long ) pprev); }void pgd_ctor (void *pgd,kmem_cache_t *cache,unsigned long unused)
include/asm-frv/hardirq.h renamed from warthog/kernels/linux-2.6.15-rc2/include/asm-frv/hardirq.h +1 -0
@@ -14,6 +14,7 @@#include <linux/config.h> #include <linux/threads.h> +#include <linux/irq.h> typedef struct { unsigned int __softirq_pending;
include/asm-frv/ide.h renamed from warthog/kernels/linux-2.6.15-rc2/include/asm-frv/ide.h +4 -4
@@ -33,10 +33,10 @@/* * some bits needed for parts of the IDE subsystem to compile */ -#define __ide_mm_insw (port, addr, n) insw(port, addr, n) -#define __ide_mm_insl (port, addr, n) insl(port, addr, n) -#define __ide_mm_outsw (port, addr, n) outsw(port, addr, n) -#define __ide_mm_outsl (port, addr, n) outsl(port, addr, n) +#define __ide_mm_insw (port, addr, n) insw((unsigned long) (port), addr, n) +#define __ide_mm_insl (port, addr, n) insl((unsigned long) (port), addr, n) +#define __ide_mm_outsw (port, addr, n) outsw((unsigned long) (port), addr, n) +#define __ide_mm_outsl (port, addr, n) outsl((unsigned long) (port), addr, n)#endif /* __KERNEL__ */
include/asm-frv/page.h renamed from warthog/kernels/linux-2.6.15-rc2/include/asm-frv/page.h +2 -2
@@ -47,8 +47,8 @@ typedef struct { unsigned long pgprot; }#define devmem_is_allowed (pfn) 1 -#define __pa (vaddr) virt_to_phys((void *) vaddr) -#define __va (paddr) phys_to_virt((unsigned long) paddr) +#define __pa (vaddr) virt_to_phys((void *) (unsigned long) (vaddr)) +#define __va (paddr) phys_to_virt((unsigned long) (paddr))#define pfn_to_kaddr (pfn) __va((pfn) << PAGE_SHIFT)
include/asm-frv/semaphore.h renamed from warthog/kernels/linux-2.6.15-rc2/include/asm-frv/semaphore.h +1 -1
@@ -20,7 +20,7 @@#include <linux/spinlock.h> #include <linux/rwsem.h> -#define SEMAPHORE_DEBUG WAITQUEUE_DEBUG +#define SEMAPHORE_DEBUG 0/* * the semaphore definition
include/asm-frv/thread_info.h renamed from warthog/kernels/linux-2.6.15-rc2/include/asm-frv/thread_info.h +1 -1
@@ -58,7 +58,7 @@ struct thread_info {#endif -#define PREEMPT_ACTIVE 0x4000000 +#define PREEMPT_ACTIVE 0x10000000/* * macros/functions for gaining access to the thread information structure
PATCH 3/3 FRV: Make futex code compilable on nommu
The attached patch makes the futex code compilable on nommu by making the attempt to handle page faults conditional on CONFIG_MMU. If this is not enabled, then we can assume that EFAULT returned from futex_atomic_op_inuser() is not recoverable, and that the address lies outside of valid memory.
---
warthog>diffstat -p1 frv-futex-2615rc2.diff
include/linux/mm.h | 3 +++ kernel/futex.c | 18 +++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-)
include/linux/mm.h renamed from warthog/kernels/linux-2.6.15-rc2/include/linux/mm.h +3 -0
@@ -708,12 +708,15 @@ static inline void unmap_shared_mapping_extern int vmtruncate (struct inode * inode,loff_t offset);extern int install_page (struct mm_struct *mm,struct vm_area_struct *vma,unsigned long addr,struct page *page,pgprot_t prot);extern int install_file_pte (struct mm_struct *mm,struct vm_area_struct *vma,unsigned long addr,unsigned long pgoff,pgprot_t prot); + +#ifdef CONFIG_MMU extern int __handle_mm_fault (struct mm_struct *mm,struct vm_area_struct *vma,unsigned long address,int write_access);static inline int handle_mm_fault (struct mm_struct *mm,struct vm_area_struct *vma,unsigned long address,int write_access) {return __handle_mm_fault (mm, vma, address, write_access) & (~VM_FAULT_WRITE ); } +#endif extern int make_pages_present (unsigned long addr,unsigned long end);extern int access_process_vm (struct task_struct *tsk,unsigned long addr,void *buf,int len,int write);
kernel/futex.c renamed from warthog/kernels/linux-2.6.15-rc2/kernel/futex.c +17 -1
@@ -335,9 +335,14 @@ static int futex_wake_op(unsigned long ustruct futex_hash_bucket *bh1, *bh2;struct list_head *head;struct futex_q *this, *next; -int ret, op_ret, attempt =0 ; +int ret, op_ret; +#ifdef CONFIG_MMU +int attempt =0 ; +#endif +#ifdef CONFIG_MMU retryfull: +#endif down_read (¤t->mm->mmap_sem); ret =get_futex_key (uaddr1, &key1);
@@ -350,7 +355,9 @@ retryfull: bh1 =hash_futex (&key1); bh2 =hash_futex (&key2); +#ifdef CONFIG_MMU retry: +#endif if (bh1 < bh2)spin_lock (&bh1->lock);spin_lock (&bh2->lock);
@@ -359,12 +366,15 @@ retry: op_ret =futex_atomic_op_inuser (op, (int __user *)uaddr2);if (unlikely (op_ret <0 )) { +#ifdef CONFIG_MMU int dummy; +#endif spin_unlock (&bh1->lock);if (bh1 != bh2)spin_unlock (&bh2->lock); +#ifdef CONFIG_MMU if (unlikely (op_ret != -EFAULT )) { ret = op_ret; goto out;
@@ -408,6 +418,12 @@ retry:return ret; goto retryfull; + +#else +/* we don't get EFAULT from MMU faults if we don't have an MMU, +* but we might get them from range checking */ + goto out; +#endif } head = &bh1->chain;
PATCH 3/3 FRV: Make futex code compilable on nommu [try #2]
The attached patch makes the futex code compilable and usable on NOMMU by making the attempt to handle page faults conditional on CONFIG_MMU. If this is not enabled, then we can assume that EFAULT returned from futex_atomic_op_inuser() is not recoverable, and that the address lies outside of valid memory.
handle_mm_fault() is made to BUG if called on NOMMU without attempting to invoke the actual handler (__handle_mm_fault).
---
warthog>diffstat -p1 frv-futex-2615rc2-2.diff
include/linux/mm.h | 10 ++++++++++ kernel/futex.c | 7 +++++++ 2 files changed, 17 insertions(+)
include/linux/mm.h renamed from warthog/kernels/linux-2.6.15-rc2/include/linux/mm.h +10 -0
@@ -708,12 +708,22 @@ static inline void unmap_shared_mapping_extern int vmtruncate (struct inode * inode,loff_t offset);extern int install_page (struct mm_struct *mm,struct vm_area_struct *vma,unsigned long addr,struct page *page,pgprot_t prot);extern int install_file_pte (struct mm_struct *mm,struct vm_area_struct *vma,unsigned long addr,unsigned long pgoff,pgprot_t prot); + +#ifdef CONFIG_MMU extern int __handle_mm_fault (struct mm_struct *mm,struct vm_area_struct *vma,unsigned long address,int write_access);static inline int handle_mm_fault (struct mm_struct *mm,struct vm_area_struct *vma,unsigned long address,int write_access) {return __handle_mm_fault (mm, vma, address, write_access) & (~VM_FAULT_WRITE ); } +#else +static inline int handle_mm_fault (struct mm_struct *mm,struct vm_area_struct *vma,unsigned long address,int write_access) +{ +/* should never happen if there's no MMU */ +BUG (); +return VM_FAULT_SIGBUS ; +} +#endif extern int make_pages_present (unsigned long addr,unsigned long end);extern int access_process_vm (struct task_struct *tsk,unsigned long addr,void *buf,int len,int write);
kernel/futex.c renamed from warthog/kernels/linux-2.6.15-rc2/kernel/futex.c +7 -0
@@ -365,6 +365,13 @@ retry:if (bh1 != bh2)spin_unlock (&bh2->lock); +#ifndef CONFIG_MMU +/* we don't get EFAULT from MMU faults if we don't have an MMU, +* but we might get them from range checking */ + ret = op_ret; + goto out; +#endif +if (unlikely (op_ret != -EFAULT )) { ret = op_ret; goto out;