lkml.org 
[lkml]   [2003]   [Mar]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [PATCH] swap 13/13 may_enter_fs?
    On Tue, 25 Mar 2003, Andrew Morton wrote:
    >
    > For example, a memory-backed filesystem may be trying to allocate GFP_NOFS
    > memory while holding filesystem locks which are taken by its writepage.
    >
    > How about adding a new field to backing_dev_info for this case? Damned if I
    > can think of a name for it though.

    I think you're overcomplicating it. Of the existing memory_backed bdis
    (ramdisk, hugetlbfs, ramfs, sysfs, tmpfs, swap) only two have non-NULL
    writepage, and both of those two go (indirectly and directly) to swap
    (and neither holds FS lock while waiting to allocate memory).

    If we were looking for a correct solution, I don't think backing_dev_info
    would be the right place: we're talking about GFP_ needed for writepage,
    which should be specified in the struct address_space filled in by the
    FS: I think it's more a limitation of the FS than its backing device.

    But I don't really want to add another obscure gfp_mask initialization
    all over the place. So how about this? As I say, "swap_backed" is
    (for the foreseeable future) unnecessary, but does help to correct
    mistaken impressions arising from the term "memory_backed".

    I've conceded to your delicate sensibility by using if-else rather
    than ?: (I used it rather too compactly there, but see nothing wrong
    with the construct in general); but you'll be disgusted at my defiance
    in not adding a comment in the place you indicated - what would I say?

    Hugh

    --- 2.5.66-mm1/mm/shmem.c Wed Mar 26 11:51:01 2003
    +++ swap13/mm/shmem.c Wed Mar 26 16:35:08 2003
    @@ -123,7 +123,8 @@

    static struct backing_dev_info shmem_backing_dev_info = {
    .ra_pages = 0, /* No readahead */
    - .memory_backed = 1, /* Does not contribute to dirty memory */
    + .memory_backed = 1, /* Do not count its dirty pages in nr_dirty */
    + .swap_backed = 1, /* Its memory_backed writepage goes to swap */
    };

    LIST_HEAD (shmem_inodes);
    --- 2.5.66-mm1/mm/swap_state.c Wed Mar 26 11:51:01 2003
    +++ swap13/mm/swap_state.c Wed Mar 26 16:35:08 2003
    @@ -27,7 +27,8 @@

    static struct backing_dev_info swap_backing_dev_info = {
    .ra_pages = 0, /* No readahead */
    - .memory_backed = 1, /* Does not contribute to dirty memory */
    + .memory_backed = 1, /* Do not count its dirty pages in nr_dirty */
    + .swap_backed = 1, /* Its memory_backed writepage goes to swap */
    };

    extern struct address_space_operations swap_aops;
    --- 2.5.66-mm1/mm/vmscan.c Wed Mar 26 11:51:01 2003
    +++ swap13/mm/vmscan.c Wed Mar 26 16:35:08 2003
    @@ -235,7 +235,6 @@
    pagevec_init(&freed_pvec, 1);
    while (!list_empty(page_list)) {
    struct page *page;
    - int may_enter_fs;

    page = list_entry(page_list->prev, struct page, lru);
    list_del(&page->lru);
    @@ -248,8 +247,6 @@
    (*nr_mapped)++;

    BUG_ON(PageActive(page));
    - may_enter_fs = (gfp_mask & __GFP_FS) ||
    - (PageSwapCache(page) && (gfp_mask & __GFP_IO));

    if (PageWriteback(page))
    goto keep_locked;
    @@ -315,15 +312,23 @@
    * See swapfile.c:page_queue_congested().
    */
    if (PageDirty(page)) {
    + struct backing_dev_info *bdi;
    + unsigned int gfp_needed_for_writepage;
    +
    if (!is_page_cache_freeable(page))
    goto keep_locked;
    if (!mapping)
    goto keep_locked;
    if (mapping->a_ops->writepage == NULL)
    goto activate_locked;
    - if (!may_enter_fs)
    + bdi = mapping->backing_dev_info;
    + if (bdi->swap_backed)
    + gfp_needed_for_writepage = __GFP_IO;
    + else
    + gfp_needed_for_writepage = __GFP_FS;
    + if (!(gfp_mask & gfp_needed_for_writepage))
    goto keep_locked;
    - if (!may_write_to_queue(mapping->backing_dev_info))
    + if (!may_write_to_queue(bdi))
    goto keep_locked;
    write_lock(&mapping->page_lock);
    if (test_clear_page_dirty(page)) {
    --- 2.5.66-mm1/include/linux/backing-dev.h Wed Mar 26 11:50:36 2003
    +++ swap13/include/linux/backing-dev.h Wed Mar 26 16:35:08 2003
    @@ -23,7 +23,9 @@
    struct backing_dev_info {
    unsigned long ra_pages; /* max readahead in PAGE_CACHE_SIZE units */
    unsigned long state; /* Always use atomic bitops on this */
    - int memory_backed; /* Cannot clean pages with writepage */
    + unsigned int
    + memory_backed:1,/* Do not count its dirty pages in nr_dirty */
    + swap_backed:1; /* Its memory_backed writepage goes to swap */
    };

    extern struct backing_dev_info default_backing_dev_info;
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 13:34    [W:0.025 / U:150.848 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site