linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* rmap for ARMV.
@ 2002-02-19 16:01 David Woodhouse
  2002-02-19 16:14 ` Russell King - ARM Linux
  2002-02-19 16:42 ` David Woodhouse
  0 siblings, 2 replies; 3+ messages in thread
From: David Woodhouse @ 2002-02-19 16:01 UTC (permalink / raw)
  To: riel, linux-mm; +Cc: linux-arm-kernel

ARM was fun because it has a slab cache with 2KiB objects for page tables, 
rather than allocating them a page at a time - so we couldn't just use
page->{mapping,index} for each page as we do on other architectures.

I solve this by allocating a 16-byte structure to go with each page in the 
pte_cache slab, which holds {mm,index} for each of the two page tables in 
that page.

This means a second kmem_cache_alloc in the constructor for the pte_cache
slab, which I'm a bit dubious about. The only alternative I could see was to
allocate/free them individually for each page table in pte_alloc_one() and
pte_free_slow(). The only way I'd be able to keep track of them then,
though, would be to use page->mapping for the first and page->index as a
pointer to the second, and I was even less happy with that than this
version.

--- linux-clean/arch/arm/mm/mm-armv.c	Wed Jun 27 22:12:04 2001
+++ linux/arch/arm/mm/mm-armv.c	Tue Feb 19 11:37:31 2002
@@ -19,6 +19,7 @@
 #include <asm/page.h>
 #include <asm/io.h>
 #include <asm/setup.h>
+#include <asm/rmap.h>
 
 #include <asm/mach/map.h>
 
@@ -457,6 +458,7 @@
  * cache implementation.
  */
 kmem_cache_t *pte_cache;
+kmem_cache_t *pte_rmap_cache;
 
 /*
  * The constructor gets called for each object within the cache when the
@@ -467,6 +471,22 @@
 {
 	unsigned long block = (unsigned long)pte;
 
+	if (!(block & 2048)) {
+		/* First object of two in a page - allocate the 
+		   pte_rmap_info to go with them */
+
+		struct page * page = virt_to_page(pte);
+
+		if (flags & SLAB_CTOR_ATOMIC)
+			BUG();
+
+		page->mapping = kmem_cache_alloc(pte_rmap_cache, GFP_KERNEL);
+		if (!page->mapping) {
+			printk(KERN_CRIT "pte_rmap_cache alloc failed. Oops. Slab constructors need to be allowed to fail\n");
+			/* return -ENOMEM; */
+			BUG();
+		}
+	}
 	if (block & 2047)
 		BUG();
 
@@ -475,11 +495,31 @@
 			PTRS_PER_PTE * sizeof(pte_t), 0);
 }
 
+static void pte_cache_dtor(void *pte, kmem_cache_t *cache, unsigned long flags)
+{
+	unsigned long block = (unsigned long)pte;
+
+	if (!(block & 2048)) {
+		/* First object of two in a page - free the 
+		   pte_rmap_info that was associated with them */
+
+		struct page * page = virt_to_page(pte);
+
+		kmem_cache_free(pte_rmap_cache, page->mapping);
+	}
+}
+
 void __init pgtable_cache_init(void)
 {
+	pte_rmap_cache = kmem_cache_create("pte-rmap-cache",
+				2 * sizeof(struct arm_rmap_info), 0, 0,
+				NULL, NULL);
+	if (!pte_rmap_cache)
+		BUG();
+
 	pte_cache = kmem_cache_create("pte-cache",
 				2 * PTRS_PER_PTE * sizeof(pte_t), 0, 0,
-				pte_cache_ctor, NULL);
+				pte_cache_ctor, pte_cache_dtor);
 	if (!pte_cache)
 		BUG();
 }
diff -uNr --exclude *.o --exclude *.o.flags --exclude *.a --exclude *.a.flags --exclude *~ --exclude .version --exclude compile.h linux-clean/include/asm-arm/proc-armv/rmap.h linux/include/asm-arm/proc-armv/rmap.h
--- linux-clean/include/asm-arm/proc-armv/rmap.h	Thu Jan  1 01:00:00 1970
+++ linux/include/asm-arm/proc-armv/rmap.h	Tue Feb 19 11:38:42 2002
@@ -0,0 +1,72 @@
+#ifndef _ARMV_RMAP_H
+#define _ARMV_RMAP_H
+/*
+ * linux/include/asm-arm/proc-armv/rmap.h
+ *
+ * Architecture dependant parts of the reverse mapping code,
+ *
+ * We use the struct page of the page table page to find a pointer
+ * to an array of two 'struct arm_rmap_info's, one for each of the
+ * two page tables in each page.
+ * 
+ * - rmi->mm points to the process' mm_struct
+ * - rmi->index has the high bits of the address
+ * - the lower bits of the address are calculated from the
+ *   offset of the page table entry within the page table page
+ */
+#include <linux/mm.h>
+
+struct arm_rmap_info {
+	struct mm_struct *mm;
+	unsigned long index;
+};
+
+static inline void pgtable_add_rmap(pte_t * ptep, struct mm_struct * mm, unsigned long address)
+{
+	struct page * page = virt_to_page(ptep);
+	struct arm_rmap_info *rmi = (void *)page->mapping;
+
+	if (((unsigned long)ptep)&2048)
+		rmi++;
+
+	rmi->mm = mm;
+	rmi->index = address & ~((PTRS_PER_PTE * PAGE_SIZE) - 1);
+}
+
+static inline void pgtable_remove_rmap(pte_t * ptep)
+{
+	struct page * page = virt_to_page(ptep);
+	struct arm_rmap_info *rmi = (void *)page->mapping;
+
+	if (((unsigned long)ptep)&2048)
+		rmi++;
+
+	rmi->mm = NULL;
+	rmi->index = 0;
+}
+
+static inline struct mm_struct * ptep_to_mm(pte_t * ptep)
+{
+	struct page * page = virt_to_page(ptep);
+	struct arm_rmap_info *rmi = (void *)page->mapping;
+
+	if (((unsigned long)ptep)&2048)
+		rmi++;
+
+	return rmi->mm;
+}
+
+static inline unsigned long ptep_to_address(pte_t * ptep)
+{
+	struct page * page = virt_to_page(ptep);
+	struct arm_rmap_info *rmi = (void *)page->mapping;
+	unsigned long low_bits;
+
+	if (((unsigned long)ptep)&2048)
+		rmi++;
+
+	low_bits = ((unsigned long)ptep & ~PAGE_MASK) * PTRS_PER_PTE;
+	return rmi->index + low_bits;
+}
+
+#endif /* _ARMV_RMAP_H */
diff -uNr --exclude *.o --exclude *.o.flags --exclude *.a --exclude *.a.flags --exclude *~ --exclude .version --exclude compile.h linux-clean/include/asm-arm/rmap.h linux/include/asm-arm/rmap.h
--- linux-clean/include/asm-arm/rmap.h	Thu Jan  1 01:00:00 1970
+++ linux/include/asm-arm/rmap.h	Tue Feb 19 11:29:45 2002
@@ -0,0 +1,6 @@
+#ifndef _ARM_RMAP_H
+#define _ARM_RMAP_H
+
+#include <asm/proc/rmap.h>
+
+#endif /* _ARM_RMAP_H */

--
dwmw2


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/

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

* Re: rmap for ARMV.
  2002-02-19 16:01 rmap for ARMV David Woodhouse
@ 2002-02-19 16:14 ` Russell King - ARM Linux
  2002-02-19 16:42 ` David Woodhouse
  1 sibling, 0 replies; 3+ messages in thread
From: Russell King - ARM Linux @ 2002-02-19 16:14 UTC (permalink / raw)
  To: David Woodhouse; +Cc: riel, linux-mm, linux-arm-kernel

On Tue, Feb 19, 2002 at 04:01:34PM +0000, David Woodhouse wrote:
> ARM was fun because it has a slab cache with 2KiB objects for page tables, 
> rather than allocating them a page at a time - so we couldn't just use
> page->{mapping,index} for each page as we do on other architectures.

When rmap gets merged into the 2.5 kernel series, I'll look at what
can be done to sort out the pte situation - we could re-jig the page
tables so a 'pgd' is 8 bytes per entry (made up of two hardware PTE
pointers), the second level page tables end up being 2K hardware + 2K
for Linux, which nicely maps to a page per PTE as viewed by Linux.

This should simplify this patch, as well as getting rid of the pte
slab.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/

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

* Re: rmap for ARMV.
  2002-02-19 16:01 rmap for ARMV David Woodhouse
  2002-02-19 16:14 ` Russell King - ARM Linux
@ 2002-02-19 16:42 ` David Woodhouse
  1 sibling, 0 replies; 3+ messages in thread
From: David Woodhouse @ 2002-02-19 16:42 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: riel, linux-mm, linux-arm-kernel

linux@arm.linux.org.uk said:
>  When rmap gets merged into the 2.5 kernel series, I'll look at what
> can be done to sort out the pte situation - we could re-jig the page
> tables so a 'pgd' is 8 bytes per entry (made up of two hardware PTE
> pointers), the second level page tables end up being 2K hardware + 2K
> for Linux, which nicely maps to a page per PTE as viewed by Linux.

That would probably make sense - I didn't really want to do something that 
intrusive myself. In the meantime, this is also required:

--- linux-2.4.17-arm-rmap.patch	19 Feb 2002 15:59:41 -0000	1.1
+++ linux-2.4.17-arm-rmap.patch	19 Feb 2002 16:24:11 -0000
@@ -39,7 +39,7 @@
  	if (block & 2047)
  		BUG();
  
-@@ -475,11 +495,31 @@
+@@ -475,11 +495,32 @@
  			PTRS_PER_PTE * sizeof(pte_t), 0);
  }
  
@@ -54,6 +54,7 @@
 +		struct page * page = virt_to_page(pte);
 +
 +		kmem_cache_free(pte_rmap_cache, page->mapping);
++		page->mapping = NULL;
 +	}
 +}
 +


--
dwmw2


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/

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

end of thread, other threads:[~2002-02-19 16:42 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-02-19 16:01 rmap for ARMV David Woodhouse
2002-02-19 16:14 ` Russell King - ARM Linux
2002-02-19 16:42 ` David Woodhouse

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