Skip to contentSkip to conversation

FRV: Make the FRV arch work again

PATCH New David Howells 1 participant 4 messages Nov 23, 2005 – Nov 29, 2005

Subsystems (3)
lore
Share & tools
lore
#1 lore raw

PATCH 2/3 FRV: Clean up bootmem allocator's page freeing algorithm

In reply to David Howells

The 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
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/mm/bootmem.c linux-2.6.15-rc2-frv/mm/bootmem.c
@@ -294,20 +294,12 @@ static unsigned long __init free_all_boo
 		unsigned 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_boo
 			for (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
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/mm/internal.h linux-2.6.15-rc2-frv/mm/internal.h
@@ -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

#0 lore raw

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
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/arch/frv/kernel/semaphore.c linux-2.6.15-rc2-frv/arch/frv/kernel/semaphore.c
@@ -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
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/arch/frv/mb93090-mb00/pci-irq.c linux-2.6.15-rc2-frv/arch/frv/mb93090-mb00/pci-irq.c
@@ -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
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/arch/frv/mm/init.c linux-2.6.15-rc2-frv/arch/frv/mm/init.c
@@ -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
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/arch/frv/mm/pgalloc.c linux-2.6.15-rc2-frv/arch/frv/mm/pgalloc.c
@@ -85,7 +85,7 @@ static inline void pgd_list_add(pgd_t *p
 	struct 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
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/include/asm-frv/hardirq.h linux-2.6.15-rc2-frv/include/asm-frv/hardirq.h
@@ -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
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/include/asm-frv/ide.h linux-2.6.15-rc2-frv/include/asm-frv/ide.h
@@ -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
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/include/asm-frv/page.h linux-2.6.15-rc2-frv/include/asm-frv/page.h
@@ -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
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/include/asm-frv/semaphore.h linux-2.6.15-rc2-frv/include/asm-frv/semaphore.h
@@ -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
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/include/asm-frv/thread_info.h linux-2.6.15-rc2-frv/include/asm-frv/thread_info.h
@@ -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
#2 lore raw

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
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/include/linux/mm.h linux-2.6.15-rc2-frv/include/linux/mm.h
@@ -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
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/kernel/futex.c linux-2.6.15-rc2-frv/kernel/futex.c
@@ -335,9 +335,14 @@ static int futex_wake_op(unsigned long u
 	struct 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(&current->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;
#3 lore raw

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
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/include/linux/mm.h linux-2.6.15-rc2-frv/include/linux/mm.h
@@ -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
diff -uNrp /warthog/kernels/linux-2.6.15-rc2/kernel/futex.c linux-2.6.15-rc2-frv/kernel/futex.c
@@ -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;