20 Jul, 2007

28 commits

  • Slab destructors were no longer supported after Christoph's
    c59def9f222d44bb7e2f0a559f2906191a0862d7 change. They've been
    BUGs for both slab and slub, and slob never supported them
    either.

    This rips out support for the dtor pointer from kmem_cache_create()
    completely and fixes up every single callsite in the kernel (there were
    about 224, not including the slab allocator definitions themselves,
    or the documentation references).

    Signed-off-by: Paul Mundt

    Paul Mundt
     
  • The slab and slob allocators already did this right, but slub would call
    "get_object_page()" on the magic ZERO_SIZE_PTR, with all kinds of nasty
    end results.

    Noted by Ingo Molnar.

    Cc: Ingo Molnar
    Cc: Christoph Lameter
    Cc: Andrew Morton
    Signed-off-by: Linus Torvalds

    Linus Torvalds
     
  • I suspect Christoph tested his code only in the NUMA configuration, for
    the combination of SLAB+non-NUMA the zero-sized kmalloc's would not work.

    Of course, this would only trigger in configurations where those zero-
    sized allocations happen (not very common), so that may explain why it
    wasn't more widely noticed.

    Seen by by Andi Kleen under qemu, and there seems to be a report by
    Michael Tsirkin on it too.

    Cc: Andi Kleen
    Cc: Roland Dreier
    Cc: Michael S. Tsirkin
    Cc: Pekka Enberg
    Cc: Christoph Lameter
    Cc: Andrew Morton
    Signed-off-by: Linus Torvalds

    Linus Torvalds
     
  • lguest does some fairly lowlevel things to support a host, which
    normal modules don't need:

    math_state_restore:
    When the guest triggers a Device Not Available fault, we need
    to be able to restore the FPU

    __put_task_struct:
    We need to hold a reference to another task for inter-guest
    I/O, and put_task_struct() is an inline function which calls
    __put_task_struct.

    access_process_vm:
    We need to access another task for inter-guest I/O.

    map_vm_area & __get_vm_area:
    We need to map the switcher shim (ie. monitor) at 0xFFC01000.

    Signed-off-by: Rusty Russell
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Rusty Russell
     
  • page-writeback accounting is presently performed in the page-flags macros.
    This is inconsistent and a bit ugly and makes it awkward to implement
    per-backing_dev under-writeback page accounting.

    So move this accounting down to the callsite(s).

    Acked-by: Peter Zijlstra
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Andrew Morton
     
  • Use appropriate accessor function to set compound page destructor
    function.

    Cc: William Irwin
    Signed-off-by: Akinobu Mita
    Acked-by: Adam Litke
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Akinobu Mita
     
  • The fix to that race in alloc_fresh_huge_page() which could give an illegal
    node ID did not need nid_lock at all: the fix was to replace static int nid
    by static int prev_nid and do the work on local int nid. nid_lock did make
    sure that racers strictly roundrobin the nodes, but that's not something we
    need to enforce strictly. Kill nid_lock.

    Signed-off-by: Hugh Dickins
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Hugh Dickins
     
  • I've noticed lots of failures of vmalloc_32 on machines where it
    shouldn't have failed unless it was doing an atomic operation.

    Looking closely, I noticed that:

    #if defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA32)
    #define GFP_VMALLOC32 GFP_DMA32
    #elif defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA)
    #define GFP_VMALLOC32 GFP_DMA
    #else
    #define GFP_VMALLOC32 GFP_KERNEL
    #endif

    Which seems to be incorrect, it should always -or- in the DMA flags
    on top of GFP_KERNEL, thus this patch.

    This fixes frequent errors launchin X with the nouveau DRM for example.

    Signed-off-by: Benjamin Herrenschmidt
    Cc: Andi Kleen
    Cc: Dave Airlie
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Benjamin Herrenschmidt
     
  • Work around a possible bug in the FRV compiler.

    What appears to be happening is that gcc resolves the
    __builtin_constant_p() in kmalloc() to true, but then fails to reduce the
    therefore constant conditions in the if-statements it guards to constant
    results.

    When compiling with -O2 or -Os, one single spurious error crops up in
    cpuup_callback() in mm/slab.c. This can be avoided by making the memsize
    variable const.

    Signed-off-by: David Howells
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    David Howells
     
  • mm/hugetlb.c: In function `dequeue_huge_page':
    mm/hugetlb.c:72: warning: 'nid' might be used uninitialized in this function

    Cc: Christoph Lameter
    Cc: Adam Litke
    Cc: David Gibson
    Cc: William Lee Irwin III
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Andrew Morton
     
  • Remove the arg+env limit of MAX_ARG_PAGES by copying the strings directly from
    the old mm into the new mm.

    We create the new mm before the binfmt code runs, and place the new stack at
    the very top of the address space. Once the binfmt code runs and figures out
    where the stack should be, we move it downwards.

    It is a bit peculiar in that we have one task with two mm's, one of which is
    inactive.

    [a.p.zijlstra@chello.nl: limit stack size]
    Signed-off-by: Ollie Wild
    Signed-off-by: Peter Zijlstra
    Cc:
    Cc: Hugh Dickins
    [bunk@stusta.de: unexport bprm_mm_init]
    Signed-off-by: Adrian Bunk
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ollie Wild
     
  • Rename some file_ra_state variables and remove some accessors.

    It results in much simpler code.
    Kudos to Rusty!

    Signed-off-by: Fengguang Wu
    Cc: Rusty Russell
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Fengguang Wu
     
  • Split ondemand readahead interface into two functions. I think this makes it
    a little clearer for non-readahead experts (like Rusty).

    Internally they both call ondemand_readahead(), but the page argument is
    changed to an obvious boolean flag.

    Signed-off-by: Rusty Russell
    Signed-off-by: Fengguang Wu
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Rusty Russell
     
  • Share the same page flag bit for PG_readahead and PG_reclaim.

    One is used only on file reads, another is only for emergency writes. One
    is used mostly for fresh/young pages, another is for old pages.

    Combinations of possible interactions are:

    a) clear PG_reclaim => implicit clear of PG_readahead
    it will delay an asynchronous readahead into a synchronous one
    it actually does _good_ for readahead:
    the pages will be reclaimed soon, it's readahead thrashing!
    in this case, synchronous readahead makes more sense.

    b) clear PG_readahead => implicit clear of PG_reclaim
    one(and only one) page will not be reclaimed in time
    it can be avoided by checking PageWriteback(page) in readahead first

    c) set PG_reclaim => implicit set of PG_readahead
    will confuse readahead and make it restart the size rampup process
    it's a trivial problem, and can mostly be avoided by checking
    PageWriteback(page) first in readahead

    d) set PG_readahead => implicit set of PG_reclaim
    PG_readahead will never be set on already cached pages.
    PG_reclaim will always be cleared on dirtying a page.
    so not a problem.

    In summary,
    a) we get better behavior
    b,d) possible interactions can be avoided
    c) racy condition exists that might affect readahead, but the chance
    is _really_ low, and the hurt on readahead is trivial.

    Compound pages also use PG_reclaim, but for now they do not interact with
    reclaim/readahead code.

    Signed-off-by: Fengguang Wu
    Cc: Rusty Russell
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Fengguang Wu
     
  • Remove the old readahead algorithm.

    Signed-off-by: Fengguang Wu
    Cc: Steven Pratt
    Cc: Ram Pai
    Cc: Rusty Russell
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Fengguang Wu
     
  • Convert filemap reads to use on-demand readahead.

    The new call scheme is to
    - call readahead on non-cached page
    - call readahead on look-ahead page
    - update prev_index when finished with the read request

    Signed-off-by: Fengguang Wu
    Cc: Steven Pratt
    Cc: Ram Pai
    Cc: Rusty Russell
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Fengguang Wu
     
  • This is a minimal readahead algorithm that aims to replace the current one.
    It is more flexible and reliable, while maintaining almost the same behavior
    and performance. Also it is full integrated with adaptive readahead.

    It is designed to be called on demand:
    - on a missing page, to do synchronous readahead
    - on a lookahead page, to do asynchronous readahead

    In this way it eliminated the awkward workarounds for cache hit/miss,
    readahead thrashing, retried read, and unaligned read. It also adopts the
    data structure introduced by adaptive readahead, parameterizes readahead
    pipelining with `lookahead_index', and reduces the current/ahead windows to
    one single window.

    HEURISTICS

    The logic deals with four cases:

    - sequential-next
    found a consistent readahead window, so push it forward

    - random
    standalone small read, so read as is

    - sequential-first
    create a new readahead window for a sequential/oversize request

    - lookahead-clueless
    hit a lookahead page not associated with the readahead window,
    so create a new readahead window and ramp it up

    In each case, three parameters are determined:

    - readahead index: where the next readahead begins
    - readahead size: how much to readahead
    - lookahead size: when to do the next readahead (for pipelining)

    BEHAVIORS

    The old behaviors are maximally preserved for trivial sequential/random reads.
    Notable changes are:

    - It no longer imposes strict sequential checks.
    It might help some interleaved cases, and clustered random reads.
    It does introduce risks of a random lookahead hit triggering an
    unexpected readahead. But in general it is more likely to do good
    than to do evil.

    - Interleaved reads are supported in a minimal way.
    Their chances of being detected and proper handled are still low.

    - Readahead thrashings are better handled.
    The current readahead leads to tiny average I/O sizes, because it
    never turn back for the thrashed pages. They have to be fault in
    by do_generic_mapping_read() one by one. Whereas the on-demand
    readahead will redo readahead for them.

    OVERHEADS

    The new code reduced the overheads of

    - excessively calling the readahead routine on small sized reads
    (the current readahead code insists on seeing all requests)

    - doing a lot of pointless page-cache lookups for small cached files
    (the current readahead only turns itself off after 256 cache hits,
    unfortunately most files are < 1MB, so never see that chance)

    That accounts for speedup of
    - 0.3% on 1-page sequential reads on sparse file
    - 1.2% on 1-page cache hot sequential reads
    - 3.2% on 256-page cache hot sequential reads
    - 1.3% on cache hot `tar /lib`

    However, it does introduce one extra page-cache lookup per cache miss, which
    impacts random reads slightly. That's 1% overheads for 1-page random reads on
    sparse file.

    PERFORMANCE

    The basic benchmark setup is
    - 2.6.20 kernel with on-demand readahead
    - 1MB max readahead size
    - 2.9GHz Intel Core 2 CPU
    - 2GB memory
    - 160G/8M Hitachi SATA II 7200 RPM disk

    The benchmarks show that
    - it maintains the same performance for trivial sequential/random reads
    - sysbench/OLTP performance on MySQL gains up to 8%
    - performance on readahead thrashing gains up to 3 times

    iozone throughput (KB/s): roughly the same
    ==========================================
    iozone -c -t1 -s 4096m -r 64k

    2.6.20 on-demand gain
    first run
    " Initial write " 61437.27 64521.53 +5.0%
    " Rewrite " 47893.02 48335.20 +0.9%
    " Read " 62111.84 62141.49 +0.0%
    " Re-read " 62242.66 62193.17 -0.1%
    " Reverse Read " 50031.46 49989.79 -0.1%
    " Stride read " 8657.61 8652.81 -0.1%
    " Random read " 13914.28 13898.23 -0.1%
    " Mixed workload " 19069.27 19033.32 -0.2%
    " Random write " 14849.80 14104.38 -5.0%
    " Pwrite " 62955.30 65701.57 +4.4%
    " Pread " 62209.99 62256.26 +0.1%

    second run
    " Initial write " 60810.31 66258.69 +9.0%
    " Rewrite " 49373.89 57833.66 +17.1%
    " Read " 62059.39 62251.28 +0.3%
    " Re-read " 62264.32 62256.82 -0.0%
    " Reverse Read " 49970.96 50565.72 +1.2%
    " Stride read " 8654.81 8638.45 -0.2%
    " Random read " 13901.44 13949.91 +0.3%
    " Mixed workload " 19041.32 19092.04 +0.3%
    " Random write " 14019.99 14161.72 +1.0%
    " Pwrite " 64121.67 68224.17 +6.4%
    " Pread " 62225.08 62274.28 +0.1%

    In summary, writes are unstable, reads are pretty close on average:

    access pattern 2.6.20 on-demand gain
    Read 62085.61 62196.38 +0.2%
    Re-read 62253.49 62224.99 -0.0%
    Reverse Read 50001.21 50277.75 +0.6%
    Stride read 8656.21 8645.63 -0.1%
    Random read 13907.86 13924.07 +0.1%
    Mixed workload 19055.29 19062.68 +0.0%
    Pread 62217.53 62265.27 +0.1%

    aio-stress: roughly the same
    ============================
    aio-stress -l -s4096 -r128 -t1 -o1 knoppix511-dvd-cn.iso
    aio-stress -l -s4096 -r128 -t1 -o3 knoppix511-dvd-cn.iso

    2.6.20 on-demand delta
    sequential 92.57s 92.54s -0.0%
    random 311.87s 312.15s +0.1%

    sysbench fileio: roughly the same
    =================================
    sysbench --test=fileio --file-io-mode=async --file-test-mode=rndrw \
    --file-total-size=4G --file-block-size=64K \
    --num-threads=001 --max-requests=10000 --max-time=900 run

    threads 2.6.20 on-demand delta
    first run
    1 59.1974s 59.2262s +0.0%
    2 58.0575s 58.2269s +0.3%
    4 48.0545s 47.1164s -2.0%
    8 41.0684s 41.2229s +0.4%
    16 35.8817s 36.4448s +1.6%
    32 32.6614s 32.8240s +0.5%
    64 23.7601s 24.1481s +1.6%
    128 24.3719s 23.8225s -2.3%
    256 23.2366s 22.0488s -5.1%

    second run
    1 59.6720s 59.5671s -0.2%
    8 41.5158s 41.9541s +1.1%
    64 25.0200s 23.9634s -4.2%
    256 22.5491s 20.9486s -7.1%

    Note that the numbers are not very stable because of the writes.
    The overall performance is close when we sum all seconds up:

    sum all up 495.046s 491.514s -0.7%

    sysbench oltp (trans/sec): up to 8% gain
    ========================================
    sysbench --test=oltp --oltp-table-size=10000000 --oltp-read-only \
    --mysql-socket=/var/run/mysqld/mysqld.sock \
    --mysql-user=root --mysql-password=readahead \
    --num-threads=064 --max-requests=10000 --max-time=900 run

    10000-transactions run
    threads 2.6.20 on-demand gain
    1 62.81 64.56 +2.8%
    2 67.97 70.93 +4.4%
    4 81.81 85.87 +5.0%
    8 94.60 97.89 +3.5%
    16 99.07 104.68 +5.7%
    32 95.93 104.28 +8.7%
    64 96.48 103.68 +7.5%
    5000-transactions run
    1 48.21 48.65 +0.9%
    8 68.60 70.19 +2.3%
    64 70.57 74.72 +5.9%
    2000-transactions run
    1 37.57 38.04 +1.3%
    2 38.43 38.99 +1.5%
    4 45.39 46.45 +2.3%
    8 51.64 52.36 +1.4%
    16 54.39 55.18 +1.5%
    32 52.13 54.49 +4.5%
    64 54.13 54.61 +0.9%

    That's interesting results. Some investigations show that
    - MySQL is accessing the db file non-uniformly: some parts are
    more hot than others
    - It is mostly doing 4-page random reads, and sometimes doing two
    reads in a row, the latter one triggers a 16-page readahead.
    - The on-demand readahead leaves many lookahead pages (flagged
    PG_readahead) there. Many of them will be hit, and trigger
    more readahead pages. Which might save more seeks.
    - Naturally, the readahead windows tend to lie in hot areas,
    and the lookahead pages in hot areas is more likely to be hit.
    - The more overall read density, the more possible gain.

    That also explains the adaptive readahead tricks for clustered random reads.

    readahead thrashing: 3 times better
    ===================================
    We boot kernel with "mem=128m single", and start a 100KB/s stream on every
    second, until reaching 200 streams.

    max throughput min avg I/O size
    2.6.20: 5MB/s 16KB
    on-demand: 15MB/s 140KB

    Signed-off-by: Fengguang Wu
    Cc: Steven Pratt
    Cc: Ram Pai
    Cc: Rusty Russell
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Fengguang Wu
     
  • Extend struct file_ra_state to support the on-demand readahead logic. Also
    define some helpers for it.

    Signed-off-by: Fengguang Wu
    Cc: Steven Pratt
    Cc: Ram Pai
    Cc: Rusty Russell
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Fengguang Wu
     
  • Define two convenient macros for read-ahead:
    - MAX_RA_PAGES: rounded down counterpart of VM_MAX_READAHEAD
    - MIN_RA_PAGES: rounded _up_ counterpart of VM_MIN_READAHEAD

    Note that the rounded up MIN_RA_PAGES will work flawlessly with _large_
    page sizes like 64k.

    Signed-off-by: Fengguang Wu
    Cc: Steven Pratt
    Cc: Ram Pai
    Cc: Rusty Russell
    Cc:
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Fengguang Wu
     
  • Add look-ahead support to __do_page_cache_readahead().

    It works by
    - mark the Nth backwards page with PG_readahead,
    (which instructs the page's first reader to invoke readahead)
    - and only do the marking for newly allocated pages.
    (to prevent blindly doing readahead on already cached pages)

    Look-ahead is a technique to achieve I/O pipelining:

    While the application is working through a chunk of cached pages, the kernel
    reads-ahead the next chunk of pages _before_ time of need. It effectively
    hides low level I/O latencies to high level applications.

    Signed-off-by: Fengguang Wu
    Cc: Steven Pratt
    Cc: Ram Pai
    Cc: Rusty Russell
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Fengguang Wu
     
  • Introduce a new page flag: PG_readahead.

    It acts as a look-ahead mark, which tells the page reader: Hey, it's time to
    invoke the read-ahead logic. For the sake of I/O pipelining, don't wait until
    it runs out of cached pages!

    Signed-off-by: Fengguang Wu
    Cc: Steven Pratt
    Cc: Ram Pai
    Cc: Rusty Russell
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Fengguang Wu
     
  • page_mkclean() doesn't re-protect ptes for non-linear mappings, so a later
    re-dirty through such a mapping will not generate a fault, PG_dirty will
    not reflect the dirty state and the dirty count will be skewed. This
    implies that msync() is also currently broken for nonlinear mappings.

    The easiest solution is to emulate remap_file_pages on non-linear mappings
    with simple mmap() for non ram-backed filesystems. Applications continue
    to work (albeit slower), as long as the number of remappings remain below
    the maximum vma count.

    However all currently known real uses of non-linear mappings are for ram
    backed filesystems, which this patch doesn't affect.

    Signed-off-by: Miklos Szeredi
    Acked-by: Peter Zijlstra
    Cc: William Lee Irwin III
    Cc: Nick Piggin
    Cc: Ingo Molnar
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Miklos Szeredi
     
  • Fix msync data loss and (less importantly) dirty page accounting
    inaccuracies due to the race remaining in clear_page_dirty_for_io().

    The deleted comment explains what the race was, and the added comments
    explain how it is fixed.

    Signed-off-by: Nick Piggin
    Acked-by: Linus Torvalds
    Cc: Miklos Szeredi
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Nick Piggin
     
  • This patch completes Linus's wish that the fault return codes be made into
    bit flags, which I agree makes everything nicer. This requires requires
    all handle_mm_fault callers to be modified (possibly the modifications
    should go further and do things like fault accounting in handle_mm_fault --
    however that would be for another patch).

    [akpm@linux-foundation.org: fix alpha build]
    [akpm@linux-foundation.org: fix s390 build]
    [akpm@linux-foundation.org: fix sparc build]
    [akpm@linux-foundation.org: fix sparc64 build]
    [akpm@linux-foundation.org: fix ia64 build]
    Signed-off-by: Nick Piggin
    Cc: Richard Henderson
    Cc: Ivan Kokshaysky
    Cc: Russell King
    Cc: Ian Molton
    Cc: Bryan Wu
    Cc: Mikael Starvik
    Cc: David Howells
    Cc: Yoshinori Sato
    Cc: "Luck, Tony"
    Cc: Hirokazu Takata
    Cc: Geert Uytterhoeven
    Cc: Roman Zippel
    Cc: Greg Ungerer
    Cc: Matthew Wilcox
    Cc: Paul Mackerras
    Cc: Benjamin Herrenschmidt
    Cc: Heiko Carstens
    Cc: Martin Schwidefsky
    Cc: Paul Mundt
    Cc: Kazumoto Kojima
    Cc: Richard Curnow
    Cc: William Lee Irwin III
    Cc: "David S. Miller"
    Cc: Jeff Dike
    Cc: Paolo 'Blaisorblade' Giarrusso
    Cc: Miles Bader
    Cc: Chris Zankel
    Acked-by: Kyle McMartin
    Acked-by: Haavard Skinnemoen
    Acked-by: Ralf Baechle
    Acked-by: Andi Kleen
    Signed-off-by: Andrew Morton
    [ Still apparently needs some ARM and PPC loving - Linus ]
    Signed-off-by: Linus Torvalds

    Nick Piggin
     
  • Change ->fault prototype. We now return an int, which contains
    VM_FAULT_xxx code in the low byte, and FAULT_RET_xxx code in the next byte.
    FAULT_RET_ code tells the VM whether a page was found, whether it has been
    locked, and potentially other things. This is not quite the way he wanted
    it yet, but that's changed in the next patch (which requires changes to
    arch code).

    This means we no longer set VM_CAN_INVALIDATE in the vma in order to say
    that a page is locked which requires filemap_nopage to go away (because we
    can no longer remain backward compatible without that flag), but we were
    going to do that anyway.

    struct fault_data is renamed to struct vm_fault as Linus asked. address
    is now a void __user * that we should firmly encourage drivers not to use
    without really good reason.

    The page is now returned via a page pointer in the vm_fault struct.

    Signed-off-by: Nick Piggin
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Nick Piggin
     
  • __do_fault() was calling ->page_mkwrite() with the page lock held, which
    violates the locking rules for that callback. Release and retake the page
    lock around the callback to avoid deadlocking file systems which manually
    take it.

    Signed-off-by: Mark Fasheh
    Cc: Nick Piggin
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Mark Fasheh
     
  • Nonlinear mappings are (AFAIKS) simply a virtual memory concept that encodes
    the virtual address -> file offset differently from linear mappings.

    ->populate is a layering violation because the filesystem/pagecache code
    should need to know anything about the virtual memory mapping. The hitch here
    is that the ->nopage handler didn't pass down enough information (ie. pgoff).
    But it is more logical to pass pgoff rather than have the ->nopage function
    calculate it itself anyway (because that's a similar layering violation).

    Having the populate handler install the pte itself is likewise a nasty thing
    to be doing.

    This patch introduces a new fault handler that replaces ->nopage and
    ->populate and (later) ->nopfn. Most of the old mechanism is still in place
    so there is a lot of duplication and nice cleanups that can be removed if
    everyone switches over.

    The rationale for doing this in the first place is that nonlinear mappings are
    subject to the pagefault vs invalidate/truncate race too, and it seemed stupid
    to duplicate the synchronisation logic rather than just consolidate the two.

    After this patch, MAP_NONBLOCK no longer sets up ptes for pages present in
    pagecache. Seems like a fringe functionality anyway.

    NOPAGE_REFAULT is removed. This should be implemented with ->fault, and no
    users have hit mainline yet.

    [akpm@linux-foundation.org: cleanup]
    [randy.dunlap@oracle.com: doc. fixes for readahead]
    [akpm@linux-foundation.org: build fix]
    Signed-off-by: Nick Piggin
    Signed-off-by: Randy Dunlap
    Cc: Mark Fasheh
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Nick Piggin
     
  • Fix the race between invalidate_inode_pages and do_no_page.

    Andrea Arcangeli identified a subtle race between invalidation of pages from
    pagecache with userspace mappings, and do_no_page.

    The issue is that invalidation has to shoot down all mappings to the page,
    before it can be discarded from the pagecache. Between shooting down ptes to
    a particular page, and actually dropping the struct page from the pagecache,
    do_no_page from any process might fault on that page and establish a new
    mapping to the page just before it gets discarded from the pagecache.

    The most common case where such invalidation is used is in file truncation.
    This case was catered for by doing a sort of open-coded seqlock between the
    file's i_size, and its truncate_count.

    Truncation will decrease i_size, then increment truncate_count before
    unmapping userspace pages; do_no_page will read truncate_count, then find the
    page if it is within i_size, and then check truncate_count under the page
    table lock and back out and retry if it had subsequently been changed (ptl
    will serialise against unmapping, and ensure a potentially updated
    truncate_count is actually visible).

    Complexity and documentation issues aside, the locking protocol fails in the
    case where we would like to invalidate pagecache inside i_size. do_no_page
    can come in anytime and filemap_nopage is not aware of the invalidation in
    progress (as it is when it is outside i_size). The end result is that
    dangling (->mapping == NULL) pages that appear to be from a particular file
    may be mapped into userspace with nonsense data. Valid mappings to the same
    place will see a different page.

    Andrea implemented two working fixes, one using a real seqlock, another using
    a page->flags bit. He also proposed using the page lock in do_no_page, but
    that was initially considered too heavyweight. However, it is not a global or
    per-file lock, and the page cacheline is modified in do_no_page to increment
    _count and _mapcount anyway, so a further modification should not be a large
    performance hit. Scalability is not an issue.

    This patch implements this latter approach. ->nopage implementations return
    with the page locked if it is possible for their underlying file to be
    invalidated (in that case, they must set a special vm_flags bit to indicate
    so). do_no_page only unlocks the page after setting up the mapping
    completely. invalidation is excluded because it holds the page lock during
    invalidation of each page (and ensures that the page is not mapped while
    holding the lock).

    This also allows significant simplifications in do_no_page, because we have
    the page locked in the right place in the pagecache from the start.

    Signed-off-by: Nick Piggin
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Nick Piggin
     

18 Jul, 2007

12 commits

  • Allocate/release a chunk of vmalloc address space:
    alloc_vm_area reserves a chunk of address space, and makes sure all
    the pagetables are constructed for that address range - but no pages.

    free_vm_area releases the address space range.

    Signed-off-by: Jeremy Fitzhardinge
    Signed-off-by: Ian Pratt
    Signed-off-by: Christian Limpach
    Signed-off-by: Chris Wright
    Cc: "Jan Beulich"
    Cc: "Andi Kleen"

    Jeremy Fitzhardinge
     
  • Add a kstrndup function, modelled on strndup. Like strndup this
    returns a string copied into its own allocated memory, but it copies
    no more than the specified number of bytes from the source.

    Remove private strndup() from irda code.

    Signed-off-by: Jeremy Fitzhardinge
    Signed-off-by: Chris Wright
    Cc: Andrew Morton
    Cc: Randy Dunlap
    Cc: YOSHIFUJI Hideaki
    Cc: Akinobu Mita
    Cc: Arnaldo Carvalho de Melo
    Cc: Al Viro
    Cc: Panagiotis Issaris
    Cc: Rene Scharfe

    Jeremy Fitzhardinge
     
  • Our original NFSv4 delegation policy was to give out a read delegation on any
    open when it was possible to.

    Since the lifetime of a delegation isn't limited to that of an open, a client
    may quite reasonably hang on to a delegation as long as it has the inode
    cached. This becomes an obvious problem the first time a client's inode cache
    approaches the size of the server's total memory.

    Our first quick solution was to add a hard-coded limit. This patch makes a
    mild incremental improvement by varying that limit according to the server's
    total memory size, allowing at most 4 delegations per megabyte of RAM.

    My quick back-of-the-envelope calculation finds that in the worst case (where
    every delegation is for a different inode), a delegation could take about
    1.5K, which would make the worst case usage about 6% of memory. The new limit
    works out to be about the same as the old on a 1-gig server.

    [akpm@linux-foundation.org: Don't needlessly bloat vmlinux]
    [akpm@linux-foundation.org: Make it right for highmem machines]
    Signed-off-by: "J. Bruce Fields"
    Signed-off-by: Neil Brown
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Meelap Shah
     
  • currently the export_operation structure and helpers related to it are in
    fs.h. fs.h is already far too large and there are very few places needing the
    export bits, so split them off into a separate header.

    [akpm@linux-foundation.org: fix cifs build]
    Signed-off-by: Christoph Hellwig
    Signed-off-by: Neil Brown
    Cc: Steven French
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Christoph Hellwig
     
  • KSYM_NAME_LEN is peculiar in that it does not include the space for the
    trailing '\0', forcing all users to use KSYM_NAME_LEN + 1 when allocating
    buffer. This is nonsense and error-prone. Moreover, when the caller
    forgets that it's very likely to subtly bite back by corrupting the stack
    because the last position of the buffer is always cleared to zero.

    This patch increments KSYM_NAME_LEN by one and updates code accordingly.

    * off-by-one bug in asm-powerpc/kprobes.h::kprobe_lookup_name() macro
    is fixed.

    * Where MODULE_NAME_LEN and KSYM_NAME_LEN were used together,
    MODULE_NAME_LEN was treated as if it didn't include space for the
    trailing '\0'. Fix it.

    Signed-off-by: Tejun Heo
    Acked-by: Paulo Marques
    Cc: Benjamin Herrenschmidt
    Cc: Paul Mackerras
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Tejun Heo
     
  • The bounce buffer logic is included on systems that do not need it. If a
    system does not have zones like ZONE_DMA and ZONE_HIGHMEM that can lead to
    the use of bounce buffers then there is no need to reserve memory pools etc
    etc. This is true f.e. for SGI Altix.

    Also nicifies the Makefile and gets rid of the tricky "and" there.

    Signed-off-by: Christoph Lameter
    Acked-by: Jens Axboe
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Christoph Lameter
     
  • Currently, the freezer treats all tasks as freezable, except for the kernel
    threads that explicitly set the PF_NOFREEZE flag for themselves. This
    approach is problematic, since it requires every kernel thread to either
    set PF_NOFREEZE explicitly, or call try_to_freeze(), even if it doesn't
    care for the freezing of tasks at all.

    It seems better to only require the kernel threads that want to or need to
    be frozen to use some freezer-related code and to remove any
    freezer-related code from the other (nonfreezable) kernel threads, which is
    done in this patch.

    The patch causes all kernel threads to be nonfreezable by default (ie. to
    have PF_NOFREEZE set by default) and introduces the set_freezable()
    function that should be called by the freezable kernel threads in order to
    unset PF_NOFREEZE. It also makes all of the currently freezable kernel
    threads call set_freezable(), so it shouldn't cause any (intentional)
    change of behaviour to appear. Additionally, it updates documentation to
    describe the freezing of tasks more accurately.

    [akpm@linux-foundation.org: build fixes]
    Signed-off-by: Rafael J. Wysocki
    Acked-by: Nigel Cunningham
    Cc: Pavel Machek
    Cc: Oleg Nesterov
    Cc: Gautham R Shenoy
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Rafael J. Wysocki
     
  • It is a bug to set a page dirty if it is not uptodate unless it has
    buffers. If the page has buffers, then the page may be dirty (some buffers
    dirty) but not uptodate (some buffers not uptodate). The exception to this
    rule is if the set_page_dirty caller is racing with truncate or invalidate.

    A buffer can not be set dirty if it is not uptodate.

    If either of these situations occurs, it indicates there could be some data
    loss problem. Some of these warnings could be a harmless one where the
    page or buffer is set uptodate immediately after it is dirtied, however we
    should fix those up, and enforce this ordering.

    Bring the order of operations for truncate into line with those of
    invalidate. This will prevent a page from being able to go !uptodate while
    we're holding the tree_lock, which is probably a good thing anyway.

    Signed-off-by: Nick Piggin
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Nick Piggin
     
  • Signed-off-by: Robert P. J. Day
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Robert P. J. Day
     
  • We currently cannot disable CONFIG_SLUB_DEBUG for CONFIG_NUMA. Now that
    embedded systems start to use NUMA we may need this.

    Put an #ifdef around places where NUMA only code uses fields only valid
    for CONFIG_SLUB_DEBUG.

    Signed-off-by: Christoph Lameter
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Christoph Lameter
     
  • Sysfs can do a gazillion things when called. Make sure that we do not call
    any sysfs functions while holding the slub_lock.

    Just protect the essentials:

    1. The list of all slab caches
    2. The kmalloc_dma array
    3. The ref counters of the slabs.

    Signed-off-by: Christoph Lameter
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Christoph Lameter
     
  • The objects per slab increase with the current patches in mm since we allow up
    to order 3 allocs by default. More patches in mm actually allow to use 2M or
    higher sized slabs. For slab validation we need per object bitmaps in order
    to check a slab. We end up with up to 64k objects per slab resulting in a
    potential requirement of 8K stack space. That does not look good.

    Allocate the bit arrays via kmalloc.

    Signed-off-by: Christoph Lameter
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Christoph Lameter