Re: Document about page and buffer cache.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Swapcache is for swap file, which is for anonymous pages.   And for
non-anonymous pages, it should be pagecache, as the intermediary
buffer between lower filesystem and memory.   Since it is
non-anonymous, u would expect a name to be associated with every
buffer, so that it can be flush out for synchronization.

Let me try....I started off not knowing much like u....just want to
share...any mistakes please correct me:

first all the declaration here (include/linux subdir):

readahead implementation:

mm.h:int do_page_cache_readahead(struct address_space *mapping, struct
file *filp,
mm.h:int force_page_cache_readahead(struct address_space *mapping,
struct file *filp,
mm.h:void page_cache_sync_readahead(struct address_space *mapping,

pagecache get and put:

pagemap.h:#define page_cache_get(page)          get_page(page)
pagemap.h:#define page_cache_release(page)      put_page(page)

allocation of pagecache:

pagemap.h:extern struct page *__page_cache_alloc(gfp_t gfp);
pagemap.h:static inline struct page *__page_cache_alloc(gfp_t gfp)
pagemap.h:static inline struct page *page_cache_alloc(struct address_space *x)
pagemap.h:      return __page_cache_alloc(mapping_gfp_mask(x));
pagemap.h:static inline struct page *page_cache_alloc_cold(struct
address_space *x)
pagemap.h:      return __page_cache_alloc(mapping_gfp_mask(x)|__GFP_COLD);
pagemap.h:int add_to_page_cache(struct page *page, struct
address_space *mapping,
pagemap.h:int add_to_page_cache_lru(struct page *page, struct
address_space *mapping,

Pagecache is organized as a RB tree (check wiki for details):

rbtree.h:static inline struct page * rb_search_page_cache(struct inode * inode,
rbtree.h:       struct rb_node * n = inode->i_rb_page_cache.rb_node;
rbtree.h:               page = rb_entry(n, struct page, rb_page_cache);
rbtree.h:static inline struct page * __rb_insert_page_cache(struct
inode * inode,
rbtree.h:       struct rb_node ** p = &inode->i_rb_page_cache.rb_node;
rbtree.h:               page = rb_entry(parent, struct page, rb_page_cache);
rbtree.h:static inline struct page * rb_insert_page_cache(struct inode * inode,
rbtree.h:       if ((ret = __rb_insert_page_cache(inode, offset, node)))
rbtree.h:       rb_insert_color(node, &inode->i_rb_page_cache);
swap.h: * so leave page_cache_release and release_pages undeclared... */
swap.h: page_cache_release(page)


drop_caches
-----------

Writing to this will cause the kernel to drop clean caches, dentries and
inodes from memory, causing that memory to become free.

To free pagecache:
        echo 1 > /proc/sys/vm/drop_caches
To free dentries and inodes:
        echo 2 > /proc/sys/vm/drop_caches
To free pagecache, dentries and inodes:
        echo 3 > /proc/sys/vm/drop_caches

Implementation:

fs/drop_cache.c:   drop_pagecache().

pagecache allocation done here (any other place?):

./mm/readahead.c:
                page = page_cache_alloc_cold(mapping);

./mm/filemap.c: find_or_create_page()

But I think the KEY function is filemap_fault():

/**
 * filemap_fault - read in file data for page fault handling
 * @vma:        vma in which the fault was taken
 * @vmf:        struct vm_fault containing details of the fault
 *
 * filemap_fault() is invoked via the vma operations vector for a
 * mapped memory region to read in file data during a page fault.
 *
 * The goto's are kind of ugly, but this streamlines the normal case of having
 * it in the page cache, and handles the special cases reasonably without
 * having a lot of duplicated code.
 */

which implement the page cache readahead algo:

        if (VM_SequentialReadHint(vma)) {
                if (!page) {
                        page_cache_sync_readahead(mapping, ra, file,
                                                           vmf->pgoff, 1);
                        page = find_lock_page(mapping, vmf->pgoff);
                        if (!page)
                                goto no_cached_page;
                }
                if (PageReadahead(page)) {
                        page_cache_async_readahead(mapping, ra, file, page,
                                                           vmf->pgoff, 1);
                }
        }

and:
                               start = vmf->pgoff - ra_pages / 2;
                        do_page_cache_readahead(mapping, file, start, ra_pages);
                }
                page = find_lock_page(mapping, vmf->pgoff);

So these are the various parts to your questions.


On Sun, Mar 9, 2008 at 1:45 PM, Manish Katiyar <mkatiyar@xxxxxxxxx> wrote:
> Hi,
>
>  Are there any good documentation on the interaction of buffer cache
>  and page cache. What I am particularly interested in is :
>
>  a) How the buffer_heads interact with page cache to submit read/write requests.
>  b) How are they mapped in a page.
>
>  Any/all of the other gory details. Any links/pointers will be useful.
>  Even if someone can point me to the code piece from where I should
>  start learning about this.
>
>  Also I couldnt find the definitions of some commonly used
>  functions/macros in the source like.
>
>  test_set_buffer_req(bh)
>  buffer_mapped(bh)
>  buffer_locked(bh)
>  buffer_ordered(bh)
>
>  etc.... what am i missing ??
>
>
>
>  --
>  Thanks & Regards,
>  ********************************************
>  Manish Katiyar  ( http://mkatiyar.googlepages.com )
>  3rd Floor, Fair Winds Block
>  EGL Software Park
>  Off Intermediate Ring Road
>  Bangalore 560071, India
>  ***********************************************
>
>  --
>  To unsubscribe from this list: send an email with
>  "unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
>  Please read the FAQ at http://kernelnewbies.org/FAQ
>
>



-- 
Regards,
Peter Teoh

--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux