)]}'
{
  "commit": "201a15428bd54f83eccec8b7c64a04b8f9431204",
  "tree": "326fcce64ce96657253fd141a3f4a767ac95418a",
  "parents": [
    "e3d4d28b1c8cc7c26536a50b43d86ccd39878550"
  ],
  "author": {
    "name": "David Howells",
    "email": "dhowells@redhat.com",
    "time": "Thu Nov 19 18:11:35 2009 +0000"
  },
  "committer": {
    "name": "David Howells",
    "email": "dhowells@redhat.com",
    "time": "Thu Nov 19 18:11:35 2009 +0000"
  },
  "message": "FS-Cache: Handle pages pending storage that get evicted under OOM conditions\n\nHandle netfs pages that the vmscan algorithm wants to evict from the pagecache\nunder OOM conditions, but that are waiting for write to the cache.  Under these\nconditions, vmscan calls the releasepage() function of the netfs, asking if a\npage can be discarded.\n\nThe problem is typified by the following trace of a stuck process:\n\n\tkslowd005     D 0000000000000000     0  4253      2 0x00000080\n\t ffff88001b14f370 0000000000000046 ffff880020d0d000 0000000000000007\n\t 0000000000000006 0000000000000001 ffff88001b14ffd8 ffff880020d0d2a8\n\t 000000000000ddf0 00000000000118c0 00000000000118c0 ffff880020d0d2a8\n\tCall Trace:\n\t [\u003cffffffffa00782d8\u003e] __fscache_wait_on_page_write+0x8b/0xa7 [fscache]\n\t [\u003cffffffff8104c0f1\u003e] ? autoremove_wake_function+0x0/0x34\n\t [\u003cffffffffa0078240\u003e] ? __fscache_check_page_write+0x63/0x70 [fscache]\n\t [\u003cffffffffa00b671d\u003e] nfs_fscache_release_page+0x4e/0xc4 [nfs]\n\t [\u003cffffffffa00927f0\u003e] nfs_release_page+0x3c/0x41 [nfs]\n\t [\u003cffffffff810885d3\u003e] try_to_release_page+0x32/0x3b\n\t [\u003cffffffff81093203\u003e] shrink_page_list+0x316/0x4ac\n\t [\u003cffffffff8109372b\u003e] shrink_inactive_list+0x392/0x67c\n\t [\u003cffffffff813532fa\u003e] ? __mutex_unlock_slowpath+0x100/0x10b\n\t [\u003cffffffff81058df0\u003e] ? trace_hardirqs_on_caller+0x10c/0x130\n\t [\u003cffffffff8135330e\u003e] ? mutex_unlock+0x9/0xb\n\t [\u003cffffffff81093aa2\u003e] shrink_list+0x8d/0x8f\n\t [\u003cffffffff81093d1c\u003e] shrink_zone+0x278/0x33c\n\t [\u003cffffffff81052d6c\u003e] ? ktime_get_ts+0xad/0xba\n\t [\u003cffffffff81094b13\u003e] try_to_free_pages+0x22e/0x392\n\t [\u003cffffffff81091e24\u003e] ? isolate_pages_global+0x0/0x212\n\t [\u003cffffffff8108e743\u003e] __alloc_pages_nodemask+0x3dc/0x5cf\n\t [\u003cffffffff81089529\u003e] grab_cache_page_write_begin+0x65/0xaa\n\t [\u003cffffffff8110f8c0\u003e] ext3_write_begin+0x78/0x1eb\n\t [\u003cffffffff81089ec5\u003e] generic_file_buffered_write+0x109/0x28c\n\t [\u003cffffffff8103cb69\u003e] ? current_fs_time+0x22/0x29\n\t [\u003cffffffff8108a509\u003e] __generic_file_aio_write+0x350/0x385\n\t [\u003cffffffff8108a588\u003e] ? generic_file_aio_write+0x4a/0xae\n\t [\u003cffffffff8108a59e\u003e] generic_file_aio_write+0x60/0xae\n\t [\u003cffffffff810b2e82\u003e] do_sync_write+0xe3/0x120\n\t [\u003cffffffff8104c0f1\u003e] ? autoremove_wake_function+0x0/0x34\n\t [\u003cffffffff810b18e1\u003e] ? __dentry_open+0x1a5/0x2b8\n\t [\u003cffffffff810b1a76\u003e] ? dentry_open+0x82/0x89\n\t [\u003cffffffffa00e693c\u003e] cachefiles_write_page+0x298/0x335 [cachefiles]\n\t [\u003cffffffffa0077147\u003e] fscache_write_op+0x178/0x2c2 [fscache]\n\t [\u003cffffffffa0075656\u003e] fscache_op_execute+0x7a/0xd1 [fscache]\n\t [\u003cffffffff81082093\u003e] slow_work_execute+0x18f/0x2d1\n\t [\u003cffffffff8108239a\u003e] slow_work_thread+0x1c5/0x308\n\t [\u003cffffffff8104c0f1\u003e] ? autoremove_wake_function+0x0/0x34\n\t [\u003cffffffff810821d5\u003e] ? slow_work_thread+0x0/0x308\n\t [\u003cffffffff8104be91\u003e] kthread+0x7a/0x82\n\t [\u003cffffffff8100beda\u003e] child_rip+0xa/0x20\n\t [\u003cffffffff8100b87c\u003e] ? restore_args+0x0/0x30\n\t [\u003cffffffff8102ef83\u003e] ? tg_shares_up+0x171/0x227\n\t [\u003cffffffff8104be17\u003e] ? kthread+0x0/0x82\n\t [\u003cffffffff8100bed0\u003e] ? child_rip+0x0/0x20\n\nIn the above backtrace, the following is happening:\n\n (1) A page storage operation is being executed by a slow-work thread\n     (fscache_write_op()).\n\n (2) FS-Cache farms the operation out to the cache to perform\n     (cachefiles_write_page()).\n\n (3) CacheFiles is then calling Ext3 to perform the actual write, using Ext3\u0027s\n     standard write (do_sync_write()) under KERNEL_DS directly from the netfs\n     page.\n\n (4) However, for Ext3 to perform the write, it must allocate some memory, in\n     particular, it must allocate at least one page cache page into which it\n     can copy the data from the netfs page.\n\n (5) Under OOM conditions, the memory allocator can\u0027t immediately come up with\n     a page, so it uses vmscan to find something to discard\n     (try_to_free_pages()).\n\n (6) vmscan finds a clean netfs page it might be able to discard (possibly the\n     one it\u0027s trying to write out).\n\n (7) The netfs is called to throw the page away (nfs_release_page()) - but it\u0027s\n     called with __GFP_WAIT, so the netfs decides to wait for the store to\n     complete (__fscache_wait_on_page_write()).\n\n (8) This blocks a slow-work processing thread - possibly against itself.\n\nThe system ends up stuck because it can\u0027t write out any netfs pages to the\ncache without allocating more memory.\n\nTo avoid this, we make FS-Cache cancel some writes that aren\u0027t in the middle of\nactually being performed.  This means that some data won\u0027t make it into the\ncache this time.  To support this, a new FS-Cache function is added\nfscache_maybe_release_page() that replaces what the netfs releasepage()\nfunctions used to do with respect to the cache.\n\nThe decisions fscache_maybe_release_page() makes are counted and displayed\nthrough /proc/fs/fscache/stats on a line labelled \"VmScan\".  There are four\ncounters provided: \"nos\u003dN\" - pages that weren\u0027t pending storage; \"gon\u003dN\" -\npages that were pending storage when we first looked, but weren\u0027t by the time\nwe got the object lock; \"bsy\u003dN\" - pages that we ignored as they were actively\nbeing written when we looked; and \"can\u003dN\" - pages that we cancelled the storage\nof.\n\nWhat I\u0027d really like to do is alter the behaviour of the cancellation\nheuristics, depending on how necessary it is to expel pages.  If there are\nplenty of other pages that aren\u0027t waiting to be written to the cache that\ncould be ejected first, then it would be nice to hold up on immediate\ncancellation of cache writes - but I don\u0027t see a way of doing that.\n\nSigned-off-by: David Howells \u003cdhowells@redhat.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "057a3c71d524925fe500961ffdd01947d08e5a14",
      "old_mode": 33188,
      "old_path": "Documentation/filesystems/caching/fscache.txt",
      "new_id": "7097fd29fb3d190f6d7fdb02ff549422d6e14907",
      "new_mode": 33188,
      "new_path": "Documentation/filesystems/caching/fscache.txt"
    },
    {
      "type": "modify",
      "old_id": "2666b1ed5e9e6515cdda71c878f846438167a0b1",
      "old_mode": 33188,
      "old_path": "Documentation/filesystems/caching/netfs-api.txt",
      "new_id": "1902c57b72ef7e103a07856dd520aef772c1e684",
      "new_mode": 33188,
      "new_path": "Documentation/filesystems/caching/netfs-api.txt"
    },
    {
      "type": "modify",
      "old_id": "51c94e26a346f1de790e4f3cac3e039d097c5494",
      "old_mode": 33188,
      "old_path": "fs/9p/cache.c",
      "new_id": "bcc5357a906987147269ba9c020ba6ed642a9ec9",
      "new_mode": 33188,
      "new_path": "fs/9p/cache.c"
    },
    {
      "type": "modify",
      "old_id": "681c2a7b013fc3c06bfa2d0d75d05804eafb8ffb",
      "old_mode": 33188,
      "old_path": "fs/afs/file.c",
      "new_id": "39b301662f22449e0896e77bf9a964e68bd9a9f0",
      "new_mode": 33188,
      "new_path": "fs/afs/file.c"
    },
    {
      "type": "modify",
      "old_id": "a0769872b19cc03da608508716862432e1e262bb",
      "old_mode": 33188,
      "old_path": "fs/fscache/internal.h",
      "new_id": "e5046519b153bc729647faf85e8cf4c5d66609b7",
      "new_mode": 33188,
      "new_path": "fs/fscache/internal.h"
    },
    {
      "type": "modify",
      "old_id": "022a5da8e130a5538caad2887c0431135723a3b6",
      "old_mode": 33188,
      "old_path": "fs/fscache/page.c",
      "new_id": "fc76798bd968f1bf9b9ebe4bb94d0a206d12d914",
      "new_mode": 33188,
      "new_path": "fs/fscache/page.c"
    },
    {
      "type": "modify",
      "old_id": "045ba396dbf23b4da43b797acbb98e2a0c72c330",
      "old_mode": 33188,
      "old_path": "fs/fscache/stats.c",
      "new_id": "cda69994e06dbcfb743ce47a98cc103a7441cd9e",
      "new_mode": 33188,
      "new_path": "fs/fscache/stats.c"
    },
    {
      "type": "modify",
      "old_id": "70fad69eb9593a41894102164e26db60eb13fa56",
      "old_mode": 33188,
      "old_path": "fs/nfs/fscache.c",
      "new_id": "fa588006588dd3403bb9a883eedc79ddc4588655",
      "new_mode": 33188,
      "new_path": "fs/nfs/fscache.c"
    },
    {
      "type": "modify",
      "old_id": "f3aa4bdafef6b946290013c62ab10f563f73c0e5",
      "old_mode": 33188,
      "old_path": "include/linux/fscache-cache.h",
      "new_id": "4750d5fb419fde6f2dd55b566be39759f39caa76",
      "new_mode": 33188,
      "new_path": "include/linux/fscache-cache.h"
    },
    {
      "type": "modify",
      "old_id": "6d8ee466e0a00a8b3f4e98927a373869dfee9726",
      "old_mode": 33188,
      "old_path": "include/linux/fscache.h",
      "new_id": "595ce49288b7807f0f42c40a6c2dcde9ed354d36",
      "new_mode": 33188,
      "new_path": "include/linux/fscache.h"
    }
  ]
}
