* [RFC:PATCH 001/008] Changes to common header files
2006-07-18 4:08 [RFC:PATCH 000/008] Tail Packing in the the Page Cache Dave Kleikamp
@ 2006-07-18 4:08 ` Dave Kleikamp
2006-07-18 4:08 ` [RFC:PATCH 002/008] Base file tail function Dave Kleikamp
` (6 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Dave Kleikamp @ 2006-07-18 4:08 UTC (permalink / raw)
To: linux-mm; +Cc: Dave Kleikamp, Dave McCracken, Badari Pulavarty
Changes to common header files
Add tail to address space and define PG_tail page flag
Signed-off-by: Dave Kleikamp <shaggy@austin.ibm.com>
---
diff -Nurp linux000/arch/powerpc/Kconfig linux001/arch/powerpc/Kconfig
--- linux000/arch/powerpc/Kconfig 2006-06-17 20:49:35.000000000 -0500
+++ linux001/arch/powerpc/Kconfig 2006-07-17 23:04:37.000000000 -0500
@@ -696,6 +696,15 @@ config PPC_64K_PAGES
while on hardware with such support, it will be used to map
normal application pages.
+config FILE_TAILS
+ bool "Store file tails in slab cache"
+ depends on PPC_64K_PAGES
+ help
+ If the data at the end of a file, or the entire file, is small,
+ the kernel will attempt to store that data in the slab cache,
+ rather than allocate an entire page in the page cache.
+ If unsure, say N here.
+
config SCHED_SMT
bool "SMT (Hyperthreading) scheduler support"
depends on PPC64 && SMP
diff -Nurp linux000/include/linux/fs.h linux001/include/linux/fs.h
--- linux000/include/linux/fs.h 2006-06-17 20:49:35.000000000 -0500
+++ linux001/include/linux/fs.h 2006-07-17 23:04:37.000000000 -0500
@@ -398,6 +398,9 @@ struct address_space {
spinlock_t private_lock; /* for use by the address_space */
struct list_head private_list; /* ditto */
struct address_space *assoc_mapping; /* ditto */
+#ifdef CONFIG_FILE_TAILS
+ void *tail; /* efficiently stored tail */
+#endif
} __attribute__((aligned(sizeof(long))));
/*
* On most architectures that alignment is already the case; but
diff -Nurp linux000/include/linux/page-flags.h linux001/include/linux/page-flags.h
--- linux000/include/linux/page-flags.h 2006-06-17 20:49:35.000000000 -0500
+++ linux001/include/linux/page-flags.h 2006-07-17 23:04:37.000000000 -0500
@@ -89,6 +89,7 @@
#define PG_buddy 19 /* Page is free, on buddy lists */
#define PG_uncached 20 /* Page has been mapped as uncached */
+#define PG_tail 21 /* Pseudo-page representing tail */
/*
* Global page accounting. One instance per CPU. Only unsigned longs are
@@ -360,6 +361,10 @@ extern void __mod_page_state_offset(unsi
#define SetPageUncached(page) set_bit(PG_uncached, &(page)->flags)
#define ClearPageUncached(page) clear_bit(PG_uncached, &(page)->flags)
+#define PageTail(page) test_bit(PG_tail, &(page)->flags)
+#define SetPageTail(page) set_bit(PG_tail, &(page)->flags)
+#define ClearPageTail(page) clear_bit(PG_tail, &(page)->flags)
+
struct page; /* forward declaration */
int test_clear_page_dirty(struct page *page);
--
David Kleikamp
IBM Linux Technology Center
--
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/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 9+ messages in thread* [RFC:PATCH 002/008] Base file tail function
2006-07-18 4:08 [RFC:PATCH 000/008] Tail Packing in the the Page Cache Dave Kleikamp
2006-07-18 4:08 ` [RFC:PATCH 001/008] Changes to common header files Dave Kleikamp
@ 2006-07-18 4:08 ` Dave Kleikamp
2006-07-18 4:08 ` [RFC:PATCH 003/008] Handle tail pages in kmap & kmap_atomic Dave Kleikamp
` (5 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Dave Kleikamp @ 2006-07-18 4:08 UTC (permalink / raw)
To: linux-mm; +Cc: Dave Kleikamp, Dave McCracken, Badari Pulavarty
Base file tail function
Signed-off-by: Dave Kleikamp <shaggy@austin.ibm.com>
---
diff -Nurp linux001/include/linux/file_tail.h linux002/include/linux/file_tail.h
--- linux001/include/linux/file_tail.h 1969-12-31 18:00:00.000000000 -0600
+++ linux002/include/linux/file_tail.h 2006-07-17 23:04:37.000000000 -0500
@@ -0,0 +1,48 @@
+#ifndef FILE_TAIL_H
+#define FILE_TAIL_H
+
+#include <linux/fs.h>
+#include <linux/pagemap.h>
+
+/*
+ * This file deals with storing tails of files in buffers smaller than a page
+ */
+
+#ifdef CONFIG_FILE_TAILS
+
+#define FILE_TAIL_INDEX(mapping) \
+ (i_size_read((mapping)->host) >> PAGE_CACHE_SHIFT)
+#define FILE_TAIL_LENGTH(mapping) \
+ (i_size_read((mapping)->host) & (PAGE_CACHE_SIZE - 1))
+
+static inline int page_data_size(struct page *page)
+{
+ if (PageTail(page))
+ return FILE_TAIL_LENGTH(page->mapping);
+ else
+ return PAGE_CACHE_SIZE;
+}
+
+extern struct page *page_cache_alloc_tail(struct address_space *);
+void page_cache_free_tail(struct page *);
+void pack_file_tail(struct page *);
+/*
+ * Called holding write_lock_irq(&mapping->tree_lock)
+ */
+extern void __unpack_file_tail(struct address_space *);
+
+static inline void unpack_file_tail(struct address_space *mapping)
+{
+ write_lock_irq(&mapping->tree_lock);
+ __unpack_file_tail(mapping);
+ write_unlock_irq(&mapping->tree_lock);
+}
+
+#else /* !CONFIG_FILE_TAILS */
+
+#define page_data_size(page) PAGE_CACHE_SIZE
+#define unpack_file_tail(mapping) do {} while (0)
+
+#endif /* CONFIG_FILE_TAILS */
+
+#endif /* FILE_TAIL_H */
diff -Nurp linux001/mm/Makefile linux002/mm/Makefile
--- linux001/mm/Makefile 2006-06-17 20:49:35.000000000 -0500
+++ linux002/mm/Makefile 2006-07-17 23:04:37.000000000 -0500
@@ -23,4 +23,5 @@ obj-$(CONFIG_SLAB) += slab.o
obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o
obj-$(CONFIG_FS_XIP) += filemap_xip.o
obj-$(CONFIG_MIGRATION) += migrate.o
+obj-$(CONFIG_FILE_TAILS) += file_tail.o
diff -Nurp linux001/mm/file_tail.c linux002/mm/file_tail.c
--- linux001/mm/file_tail.c 1969-12-31 18:00:00.000000000 -0600
+++ linux002/mm/file_tail.c 2006-07-17 23:04:37.000000000 -0500
@@ -0,0 +1,305 @@
+/*
+ * linux/mm/file_tail.c
+ *
+ * Copyright (C) International Business Machines Corp., 2006
+ */
+
+/*
+ * This file deals with storing tails of files in buffers smaller than a page
+ */
+
+#include <linux/file_tail.h>
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/pagemap.h>
+#include <linux/slab.h>
+#include <linux/buffer_head.h>
+#include <linux/swap.h>
+#include <linux/mm_inline.h>
+#include "internal.h"
+
+static struct kmem_cache *tail_page_cachep;
+
+/*
+ * Maybe this could become more generic, but for now, I need it here
+ */
+static void lru_cache_delete(struct page *page)
+{
+ if (PageLRU(page)) {
+ unsigned long flags;
+ struct zone *zone = page_zone(page);
+
+ spin_lock_irqsave(&zone->lru_lock, flags);
+ BUG_ON(!PageLRU(page));
+ __ClearPageLRU(page);
+ del_page_from_lru(zone, page);
+ spin_unlock_irqrestore(&zone->lru_lock, flags);
+ }
+}
+
+/*
+ * Caller must hold write lock on mapping->tree_lock
+ */
+void __unpack_file_tail(struct address_space *mapping)
+{
+ int error;
+ unsigned long index;
+ char *kaddr;
+ struct page *full_page = NULL, *short_page;
+ char *tail;
+ int tail_length;
+
+ while(mapping->tail) {
+ index = FILE_TAIL_INDEX(mapping);
+ write_unlock_irq(&mapping->tree_lock);
+
+ /* Allocate full page */
+ if (!full_page)
+ full_page = page_cache_alloc(mapping);
+ BUG_ON(!full_page);
+
+ /* Get & lock short page */
+ short_page = find_lock_page(mapping, index);
+ if (!short_page || !PageTail(short_page)) {
+ if (short_page) {
+ unlock_page(short_page);
+ page_cache_release(short_page);
+ }
+ /* anything can happen since we released the lock */
+ write_lock_irq(&mapping->tree_lock);
+ continue;
+ }
+ /* We have the tail page locked, so this shouldn't go away */
+ BUG_ON(!mapping->tail);
+
+ BUG_ON(page_has_buffers(short_page) || PageDirty(short_page));
+
+ /* This is the equivalent of remove_from_page_cache and
+ * add_to_page_cache_lru, without dropping tree_lock
+ */
+ error = radix_tree_preload(mapping_gfp_mask(mapping));
+ BUG_ON(error);
+ write_lock_irq(&mapping->tree_lock);
+ lru_cache_delete(short_page);
+ radix_tree_delete(&mapping->page_tree, index);
+ short_page->mapping = NULL;
+ tail = mapping->tail;
+ mapping->tail = NULL;
+
+ error = radix_tree_insert(&mapping->page_tree, index,
+ full_page);
+ BUG_ON(error);
+ page_cache_get(full_page);
+ SetPageLocked(full_page);
+ full_page->mapping = mapping;
+ full_page->index = index;
+
+ write_unlock_irq(&mapping->tree_lock);
+ radix_tree_preload_end();
+ page_cache_release(short_page); /* page cache ref */
+
+ /*
+ * Now that the short page has been replaced by the full
+ * page in the radix tree, we need to wait until all of
+ * the references on the short page are gone.
+ */
+ unlock_page(short_page);
+
+ /*
+ * This still needs work. We occasionally get caught in
+ * this loop.
+ */
+ while (page_count(short_page) > 1)
+ schedule();
+ /*
+ * ToDo: Figure out where this is getting added back to
+ * lru
+ */
+ lru_cache_delete(short_page);
+
+ /* Copy data from tail to full page */
+ if (PageUptodate(short_page)) {
+ kaddr = kmap_atomic(full_page, KM_USER0);
+ tail_length = FILE_TAIL_LENGTH(mapping);
+ memcpy(kaddr, tail, tail_length);
+ memset(kaddr+tail_length, 0,
+ PAGE_CACHE_SIZE - tail_length);
+ kunmap_atomic(kaddr, KM_USER0);
+ SetPageUptodate(full_page);
+ }
+ kfree(tail);
+
+ /* finalize full_page */
+ lru_cache_add(full_page);
+ unlock_page(full_page);
+ page_cache_release(full_page);
+ full_page = NULL;
+
+ /* free short_page */
+ WARN_ON(PageLRU(short_page));
+ kmem_cache_free(tail_page_cachep, short_page);
+
+ /*
+ * unlikely, but check to see if there was no tail added
+ * back. We need to return with tree_lock held.
+ */
+ write_lock_irq(&mapping->tree_lock);
+
+ }
+ if (full_page)
+ page_cache_release(full_page);
+ return;
+}
+EXPORT_SYMBOL(__unpack_file_tail);
+
+void i_size_write(struct inode *inode, loff_t i_size)
+{
+ struct address_space *mapping = inode->i_mapping;
+
+ write_lock_irq(&mapping->tree_lock);
+ if (mapping->tail && (i_size > i_size_read(inode)))
+ __unpack_file_tail(mapping);
+ _i_size_write(inode, i_size);
+ write_unlock_irq(&mapping->tree_lock);
+}
+EXPORT_SYMBOL(i_size_write);
+
+static void init_once(void *ptr, kmem_cache_t *cachep, unsigned long flags)
+{
+ struct page *page = (struct page *)ptr;
+
+ if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) ==
+ SLAB_CTOR_CONSTRUCTOR) {
+ memset(page, 0, sizeof(struct page));
+ reset_page_mapcount(page);
+ INIT_LIST_HEAD(&page->lru);
+ SetPageTail(page);
+ }
+}
+
+static __init int file_tail_init(void)
+{
+ tail_page_cachep = kmem_cache_create("tail_page_cache",
+ sizeof(struct page), 0, 0,
+ init_once, NULL);
+ if (tail_page_cachep == NULL)
+ return -ENOMEM;
+ return 0;
+}
+__initcall(file_tail_init);
+
+/*
+ * If the page is clean, in use by no one else, and the data is sufficiently
+ * small, allocate a tail page, copy it's data, and replace the page with
+ * the tail page in the page cache.
+ *
+ * Caller must hold reference on the page.
+ */
+void pack_file_tail(struct page *full_page)
+{
+ int error;
+ pgoff_t index;
+ void *kaddr;
+ struct address_space *mapping = full_page->mapping;
+ struct page *short_page;
+ int size;
+ void *tail;
+
+ if (!mapping)
+ return;
+
+ if (TestSetPageLocked(full_page))
+ return;
+
+ size = FILE_TAIL_LENGTH(mapping);
+ index = FILE_TAIL_INDEX(mapping);
+
+ if ((size > PAGE_CACHE_SIZE / 2) || PageDirty(full_page) ||
+ !PageUptodate(full_page) || mapping_mapped(mapping) ||
+ (page_count(full_page) > 2) || page_has_buffers(full_page) ||
+ PageWriteback(full_page)) {
+ unlock_page(full_page);
+ return;
+ }
+
+ short_page = kmem_cache_alloc(tail_page_cachep, SLAB_KERNEL);
+ if (!short_page) {
+ unlock_page(full_page);
+ return;
+ }
+
+ tail = kmalloc(size, SLAB_KERNEL);
+
+ if (!tail) {
+ kmem_cache_free(tail_page_cachep, short_page);
+ unlock_page(full_page);
+ return;
+ }
+ set_page_count(short_page, 1);
+ short_page->flags = 0;
+ SetPageTail(short_page);
+
+ /* Copy the data into the tail */
+ kaddr = kmap_atomic(full_page, KM_USER0);
+ memcpy(tail, kaddr, size);
+ kunmap_atomic(kaddr,KM_USER0);
+ SetPageUptodate(short_page);
+
+ error = radix_tree_preload(mapping_gfp_mask(mapping));
+ if (error) {
+ kfree(tail);
+ kmem_cache_free(tail_page_cachep, short_page);
+ unlock_page(full_page);
+ return;
+ }
+ /*
+ * Take tree lock. Recheck that nobody else is using full_page,
+ * remove it from the page cache and add short page, all while holding
+ * the lock
+ */
+ write_lock_irq(&mapping->tree_lock);
+ /*
+ * Make sure the file size didn't change
+ */
+ if (mapping->tail || (full_page->index != FILE_TAIL_INDEX(mapping)) ||
+ (size != FILE_TAIL_LENGTH(mapping)) || mapping_mapped(mapping) ||
+ page_count(full_page) > 2) {
+ write_unlock_irq(&mapping->tree_lock);
+ radix_tree_preload_end();
+ kfree(tail);
+ kmem_cache_free(tail_page_cachep, short_page);
+ unlock_page(full_page);
+ return;
+ }
+ /* out with the old */
+ lru_cache_delete(full_page);
+ radix_tree_delete(&mapping->page_tree, index);
+ full_page->mapping = NULL;
+
+ /* in with the new */
+ mapping->tail = tail;
+ error = radix_tree_insert(&mapping->page_tree, index, short_page);
+ BUG_ON(error);
+ page_cache_get(short_page);
+ SetPageLocked(short_page);
+ short_page->mapping = mapping;
+ short_page->index = index;
+
+ write_unlock_irq(&mapping->tree_lock);
+ radix_tree_preload_end();
+
+ unlock_page(full_page);
+ page_cache_release(full_page); /* page cache reference */
+
+ /* We're done with this now */
+ lru_cache_add(short_page);
+ unlock_page(short_page);
+ page_cache_release(short_page);
+
+ return;
+}
+
+void page_cache_free_tail(struct page *page)
+{
+ kmem_cache_free(tail_page_cachep, page);
+}
--
David Kleikamp
IBM Linux Technology Center
--
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/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 9+ messages in thread* [RFC:PATCH 003/008] Handle tail pages in kmap & kmap_atomic
2006-07-18 4:08 [RFC:PATCH 000/008] Tail Packing in the the Page Cache Dave Kleikamp
2006-07-18 4:08 ` [RFC:PATCH 001/008] Changes to common header files Dave Kleikamp
2006-07-18 4:08 ` [RFC:PATCH 002/008] Base file tail function Dave Kleikamp
@ 2006-07-18 4:08 ` Dave Kleikamp
2006-07-18 4:08 ` [RFC:PATCH 004/008] Wrap i_size_write Dave Kleikamp
` (4 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Dave Kleikamp @ 2006-07-18 4:08 UTC (permalink / raw)
To: linux-mm; +Cc: Dave Kleikamp, Dave McCracken, Badari Pulavarty
Handle tail pages in kmap & kmap_atomic
TODO: possibly move to mm.h: lowmem_page_address()
Signed-off-by: Dave Kleikamp <shaggy@austin.ibm.com>
---
diff -Nurp linux002/include/asm-powerpc/io.h linux003/include/asm-powerpc/io.h
--- linux002/include/asm-powerpc/io.h 2006-06-17 20:49:35.000000000 -0500
+++ linux003/include/asm-powerpc/io.h 2006-07-17 23:04:38.000000000 -0500
@@ -250,7 +250,9 @@ static inline void * phys_to_virt(unsign
/*
* Change "struct page" to physical address.
*/
-#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
+#define page_to_phys(page) (PageTail(page) ? \
+ __pa((page)->mapping->tail) : \
+ page_to_pfn(page) << PAGE_SHIFT)
/* We do NOT want virtual merging, it would put too much pressure on
* our iommu allocator. Instead, we want drivers to be smart enough
diff -Nurp linux002/include/linux/highmem.h linux003/include/linux/highmem.h
--- linux002/include/linux/highmem.h 2006-06-17 20:49:35.000000000 -0500
+++ linux003/include/linux/highmem.h 2006-07-17 23:04:38.000000000 -0500
@@ -33,12 +33,21 @@ static inline unsigned int nr_free_highp
static inline void *kmap(struct page *page)
{
might_sleep();
+#ifdef CONFIG_FILE_TAILS
+ return PageTail(page) ? page->mapping->tail : page_address(page);
+#else
return page_address(page);
+#endif
}
#define kunmap(page) do { (void) (page); } while (0)
+#ifdef CONFIG_FILE_TAILS
+#define kmap_atomic(page, idx) \
+ (PageTail(page) ? (page)->mapping->tail : page_address(page))
+#else
#define kmap_atomic(page, idx) page_address(page)
+#endif
#define kunmap_atomic(addr, idx) do { } while (0)
#define kmap_atomic_pfn(pfn, idx) page_address(pfn_to_page(pfn))
#define kmap_atomic_to_page(ptr) virt_to_page(ptr)
--
David Kleikamp
IBM Linux Technology Center
--
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/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 9+ messages in thread* [RFC:PATCH 004/008] Wrap i_size_write
2006-07-18 4:08 [RFC:PATCH 000/008] Tail Packing in the the Page Cache Dave Kleikamp
` (2 preceding siblings ...)
2006-07-18 4:08 ` [RFC:PATCH 003/008] Handle tail pages in kmap & kmap_atomic Dave Kleikamp
@ 2006-07-18 4:08 ` Dave Kleikamp
2006-07-18 4:08 ` [RFC:PATCH 005/008] unpack tail page to avoid memory mapping Dave Kleikamp
` (3 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Dave Kleikamp @ 2006-07-18 4:08 UTC (permalink / raw)
To: linux-mm; +Cc: Dave Kleikamp, Dave McCracken, Badari Pulavarty
Wrap i_size_write
Signed-off-by: Dave Kleikamp <shaggy@austin.ibm.com>
---
diff -Nurp linux003/include/linux/fs.h linux004/include/linux/fs.h
--- linux003/include/linux/fs.h 2006-07-17 23:04:37.000000000 -0500
+++ linux004/include/linux/fs.h 2006-07-17 23:04:38.000000000 -0500
@@ -578,8 +578,13 @@ static inline loff_t i_size_read(struct
#endif
}
+#ifdef CONFIG_FILE_TAILS
+extern void i_size_write(struct inode *, loff_t); /* defined in file_tail.c */
+static inline void _i_size_write(struct inode *inode, loff_t i_size)
+#else
static inline void i_size_write(struct inode *inode, loff_t i_size)
+#endif
{
#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
write_seqcount_begin(&inode->i_size_seqcount);
--
David Kleikamp
IBM Linux Technology Center
--
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/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 9+ messages in thread* [RFC:PATCH 005/008] unpack tail page to avoid memory mapping
2006-07-18 4:08 [RFC:PATCH 000/008] Tail Packing in the the Page Cache Dave Kleikamp
` (3 preceding siblings ...)
2006-07-18 4:08 ` [RFC:PATCH 004/008] Wrap i_size_write Dave Kleikamp
@ 2006-07-18 4:08 ` Dave Kleikamp
2006-07-18 4:08 ` [RFC:PATCH 006/008] Don't need to zero past end-of-file in file tail Dave Kleikamp
` (2 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Dave Kleikamp @ 2006-07-18 4:08 UTC (permalink / raw)
To: linux-mm; +Cc: Dave Kleikamp, Dave McCracken, Badari Pulavarty
unpack tail page to avoid memory mapping
Signed-off-by: Dave Kleikamp <shaggy@austin.ibm.com>
---
diff -Nurp linux004/mm/memory.c linux005/mm/memory.c
--- linux004/mm/memory.c 2006-06-17 20:49:35.000000000 -0500
+++ linux005/mm/memory.c 2006-07-17 23:04:38.000000000 -0500
@@ -48,6 +48,7 @@
#include <linux/rmap.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/file_tail.h>
#include <asm/pgalloc.h>
#include <asm/uaccess.h>
@@ -2071,6 +2072,15 @@ retry:
if (new_page == NOPAGE_OOM)
return VM_FAULT_OOM;
+#ifdef CONFIG_FILE_TAILS
+ if (PageTail(new_page)) {
+ /* Can new_page->mapping be different from mapping? */
+ struct address_space *mapping2 = new_page->mapping;
+ page_cache_release(new_page);
+ unpack_file_tail(mapping2);
+ goto retry;
+ }
+#endif
/*
* Should we do an early C-O-W break?
*/
--
David Kleikamp
IBM Linux Technology Center
--
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/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 9+ messages in thread* [RFC:PATCH 006/008] Don't need to zero past end-of-file in file tail
2006-07-18 4:08 [RFC:PATCH 000/008] Tail Packing in the the Page Cache Dave Kleikamp
` (4 preceding siblings ...)
2006-07-18 4:08 ` [RFC:PATCH 005/008] unpack tail page to avoid memory mapping Dave Kleikamp
@ 2006-07-18 4:08 ` Dave Kleikamp
2006-07-18 4:09 ` [RFC:PATCH 007/008] Make sure tail page is freed correctly Dave Kleikamp
2006-07-18 4:09 ` [RFC:PATCH 008/008] Handle file tails in mm/filemap.c Dave Kleikamp
7 siblings, 0 replies; 9+ messages in thread
From: Dave Kleikamp @ 2006-07-18 4:08 UTC (permalink / raw)
To: linux-mm; +Cc: Dave Kleikamp, Dave McCracken, Badari Pulavarty
Don't need to zero past end-of-file in file tail
It will always be unpacked if the file is later grown
Signed-off-by: Dave Kleikamp <shaggy@austin.ibm.com>
---
diff -Nurp linux005/mm/truncate.c linux006/mm/truncate.c
--- linux005/mm/truncate.c 2006-06-17 20:49:35.000000000 -0500
+++ linux006/mm/truncate.c 2006-07-17 23:04:38.000000000 -0500
@@ -14,11 +14,16 @@
#include <linux/pagevec.h>
#include <linux/buffer_head.h> /* grr. try_to_release_page,
do_invalidatepage */
+#include <linux/file_tail.h>
static inline void truncate_partial_page(struct page *page, unsigned partial)
{
- memclear_highpage_flush(page, partial, PAGE_CACHE_SIZE-partial);
+#ifdef CONFIG_FILE_TAILS
+ if (PageTail(page))
+ return;
+#endif
+ memclear_highpage_flush(page, partial, PAGE_CACHE_SIZE - partial);
if (PagePrivate(page))
do_invalidatepage(page, partial);
}
--
David Kleikamp
IBM Linux Technology Center
--
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/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 9+ messages in thread* [RFC:PATCH 007/008] Make sure tail page is freed correctly
2006-07-18 4:08 [RFC:PATCH 000/008] Tail Packing in the the Page Cache Dave Kleikamp
` (5 preceding siblings ...)
2006-07-18 4:08 ` [RFC:PATCH 006/008] Don't need to zero past end-of-file in file tail Dave Kleikamp
@ 2006-07-18 4:09 ` Dave Kleikamp
2006-07-18 4:09 ` [RFC:PATCH 008/008] Handle file tails in mm/filemap.c Dave Kleikamp
7 siblings, 0 replies; 9+ messages in thread
From: Dave Kleikamp @ 2006-07-18 4:09 UTC (permalink / raw)
To: linux-mm; +Cc: Dave Kleikamp, Dave McCracken, Badari Pulavarty
Make sure tail page is freed correctly
Signed-off-by: Dave Kleikamp <shaggy@austin.ibm.com>
---
diff -Nurp linux006/mm/page_alloc.c linux007/mm/page_alloc.c
--- linux006/mm/page_alloc.c 2006-06-17 20:49:35.000000000 -0500
+++ linux007/mm/page_alloc.c 2006-07-17 23:04:38.000000000 -0500
@@ -37,6 +37,7 @@
#include <linux/nodemask.h>
#include <linux/vmalloc.h>
#include <linux/mempolicy.h>
+#include <linux/file_tail.h>
#include <asm/tlbflush.h>
#include <asm/div64.h>
@@ -733,6 +734,13 @@ static void fastcall free_hot_cold_page(
struct per_cpu_pages *pcp;
unsigned long flags;
+#ifdef CONFIG_FILE_TAILS
+ if (PageTail(page)) {
+ /* Not a real page */
+ page_cache_free_tail(page);
+ return;
+ }
+#endif
arch_free_page(page, 0);
if (PageAnon(page))
--
David Kleikamp
IBM Linux Technology Center
--
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/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 9+ messages in thread* [RFC:PATCH 008/008] Handle file tails in mm/filemap.c
2006-07-18 4:08 [RFC:PATCH 000/008] Tail Packing in the the Page Cache Dave Kleikamp
` (6 preceding siblings ...)
2006-07-18 4:09 ` [RFC:PATCH 007/008] Make sure tail page is freed correctly Dave Kleikamp
@ 2006-07-18 4:09 ` Dave Kleikamp
7 siblings, 0 replies; 9+ messages in thread
From: Dave Kleikamp @ 2006-07-18 4:09 UTC (permalink / raw)
To: linux-mm; +Cc: Dave Kleikamp, Dave McCracken, Badari Pulavarty
Handle file tails in mm/filemap.c
Signed-off-by: Dave Kleikamp <shaggy@austin.ibm.com>
---
diff -Nurp linux007/mm/filemap.c linux008/mm/filemap.c
--- linux007/mm/filemap.c 2006-06-17 20:49:35.000000000 -0500
+++ linux008/mm/filemap.c 2006-07-17 23:04:38.000000000 -0500
@@ -30,6 +30,7 @@
#include <linux/security.h>
#include <linux/syscalls.h>
#include <linux/cpuset.h>
+#include <linux/file_tail.h>
#include "filemap.h"
#include "internal.h"
@@ -117,6 +118,12 @@ void __remove_from_page_cache(struct pag
{
struct address_space *mapping = page->mapping;
+#ifdef CONFIG_FILE_TAILS
+ if (PageTail(page)) {
+ kfree(mapping->tail);
+ mapping->tail = NULL;
+ }
+#endif
radix_tree_delete(&mapping->page_tree, page->index);
page->mapping = NULL;
mapping->nrpages--;
@@ -885,6 +892,11 @@ page_ok:
index += offset >> PAGE_CACHE_SHIFT;
offset &= ~PAGE_CACHE_MASK;
+#ifdef CONFIG_FILE_TAILS
+ if (!mapping->tail && page->index == FILE_TAIL_INDEX(mapping) &&
+ !PageDirty(page))
+ pack_file_tail(page);
+#endif
page_cache_release(page);
if (ret == nr && desc->count)
continue;
@@ -2030,6 +2042,16 @@ generic_file_buffered_write(struct kiocb
break;
}
+#ifdef CONFIG_FILE_TAILS
+ if (PageTail(page)) {
+ /* Can't unpack the tail while holding the tail page */
+ unlock_page(page);
+ page_cache_release(page);
+ unpack_file_tail(mapping);
+ continue;
+ }
+#endif
+
status = a_ops->prepare_write(file, page, offset, offset+bytes);
if (unlikely(status)) {
loff_t isize = i_size_read(inode);
--
David Kleikamp
IBM Linux Technology Center
--
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/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 9+ messages in thread