29 Jul, 2008

9 commits

  • The original "Pass the bus number we expect the S3C24XX SPI driver to
    attach to via the platform data." [1] patch was mis-sent, and missed two
    important parts of the diff, which was to actually set the bus_num field
    and add the relevant field to the platform data.

    The previous commit 50f426b55d919dd017af35bb6a08753d1f262920 promised to
    add a bus_num field, but failed to include the two hunks that added this
    field to include/asm-arm/arch-s3c2410/spi.h and then pass it to the spi
    core when creating the new master field in drivers/spi/spi_s3c24xx.c.

    [1] git commit 50f426b55d919dd017af35bb6a08753d1f262920

    Signed-off-by: Ben Dooks
    Signed-off-by: David Brownell
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ben Dooks
     
  • With KVM/GFP/XPMEM there isn't just the primary CPU MMU pointing to pages.
    There are secondary MMUs (with secondary sptes and secondary tlbs) too.
    sptes in the kvm case are shadow pagetables, but when I say spte in
    mmu-notifier context, I mean "secondary pte". In GRU case there's no
    actual secondary pte and there's only a secondary tlb because the GRU
    secondary MMU has no knowledge about sptes and every secondary tlb miss
    event in the MMU always generates a page fault that has to be resolved by
    the CPU (this is not the case of KVM where the a secondary tlb miss will
    walk sptes in hardware and it will refill the secondary tlb transparently
    to software if the corresponding spte is present). The same way
    zap_page_range has to invalidate the pte before freeing the page, the spte
    (and secondary tlb) must also be invalidated before any page is freed and
    reused.

    Currently we take a page_count pin on every page mapped by sptes, but that
    means the pages can't be swapped whenever they're mapped by any spte
    because they're part of the guest working set. Furthermore a spte unmap
    event can immediately lead to a page to be freed when the pin is released
    (so requiring the same complex and relatively slow tlb_gather smp safe
    logic we have in zap_page_range and that can be avoided completely if the
    spte unmap event doesn't require an unpin of the page previously mapped in
    the secondary MMU).

    The mmu notifiers allow kvm/GRU/XPMEM to attach to the tsk->mm and know
    when the VM is swapping or freeing or doing anything on the primary MMU so
    that the secondary MMU code can drop sptes before the pages are freed,
    avoiding all page pinning and allowing 100% reliable swapping of guest
    physical address space. Furthermore it avoids the code that teardown the
    mappings of the secondary MMU, to implement a logic like tlb_gather in
    zap_page_range that would require many IPI to flush other cpu tlbs, for
    each fixed number of spte unmapped.

    To make an example: if what happens on the primary MMU is a protection
    downgrade (from writeable to wrprotect) the secondary MMU mappings will be
    invalidated, and the next secondary-mmu-page-fault will call
    get_user_pages and trigger a do_wp_page through get_user_pages if it
    called get_user_pages with write=1, and it'll re-establishing an updated
    spte or secondary-tlb-mapping on the copied page. Or it will setup a
    readonly spte or readonly tlb mapping if it's a guest-read, if it calls
    get_user_pages with write=0. This is just an example.

    This allows to map any page pointed by any pte (and in turn visible in the
    primary CPU MMU), into a secondary MMU (be it a pure tlb like GRU, or an
    full MMU with both sptes and secondary-tlb like the shadow-pagetable layer
    with kvm), or a remote DMA in software like XPMEM (hence needing of
    schedule in XPMEM code to send the invalidate to the remote node, while no
    need to schedule in kvm/gru as it's an immediate event like invalidating
    primary-mmu pte).

    At least for KVM without this patch it's impossible to swap guests
    reliably. And having this feature and removing the page pin allows
    several other optimizations that simplify life considerably.

    Dependencies:

    1) mm_take_all_locks() to register the mmu notifier when the whole VM
    isn't doing anything with "mm". This allows mmu notifier users to keep
    track if the VM is in the middle of the invalidate_range_begin/end
    critical section with an atomic counter incraese in range_begin and
    decreased in range_end. No secondary MMU page fault is allowed to map
    any spte or secondary tlb reference, while the VM is in the middle of
    range_begin/end as any page returned by get_user_pages in that critical
    section could later immediately be freed without any further
    ->invalidate_page notification (invalidate_range_begin/end works on
    ranges and ->invalidate_page isn't called immediately before freeing
    the page). To stop all page freeing and pagetable overwrites the
    mmap_sem must be taken in write mode and all other anon_vma/i_mmap
    locks must be taken too.

    2) It'd be a waste to add branches in the VM if nobody could possibly
    run KVM/GRU/XPMEM on the kernel, so mmu notifiers will only enabled if
    CONFIG_KVM=m/y. In the current kernel kvm won't yet take advantage of
    mmu notifiers, but this already allows to compile a KVM external module
    against a kernel with mmu notifiers enabled and from the next pull from
    kvm.git we'll start using them. And GRU/XPMEM will also be able to
    continue the development by enabling KVM=m in their config, until they
    submit all GRU/XPMEM GPLv2 code to the mainline kernel. Then they can
    also enable MMU_NOTIFIERS in the same way KVM does it (even if KVM=n).
    This guarantees nobody selects MMU_NOTIFIER=y if KVM and GRU and XPMEM
    are all =n.

    The mmu_notifier_register call can fail because mm_take_all_locks may be
    interrupted by a signal and return -EINTR. Because mmu_notifier_reigster
    is used when a driver startup, a failure can be gracefully handled. Here
    an example of the change applied to kvm to register the mmu notifiers.
    Usually when a driver startups other allocations are required anyway and
    -ENOMEM failure paths exists already.

    struct kvm *kvm_arch_create_vm(void)
    {
    struct kvm *kvm = kzalloc(sizeof(struct kvm), GFP_KERNEL);
    + int err;

    if (!kvm)
    return ERR_PTR(-ENOMEM);

    INIT_LIST_HEAD(&kvm->arch.active_mmu_pages);

    + kvm->arch.mmu_notifier.ops = &kvm_mmu_notifier_ops;
    + err = mmu_notifier_register(&kvm->arch.mmu_notifier, current->mm);
    + if (err) {
    + kfree(kvm);
    + return ERR_PTR(err);
    + }
    +
    return kvm;
    }

    mmu_notifier_unregister returns void and it's reliable.

    The patch also adds a few needed but missing includes that would prevent
    kernel to compile after these changes on non-x86 archs (x86 didn't need
    them by luck).

    [akpm@linux-foundation.org: coding-style fixes]
    [akpm@linux-foundation.org: fix mm/filemap_xip.c build]
    [akpm@linux-foundation.org: fix mm/mmu_notifier.c build]
    Signed-off-by: Andrea Arcangeli
    Signed-off-by: Nick Piggin
    Signed-off-by: Christoph Lameter
    Cc: Jack Steiner
    Cc: Robin Holt
    Cc: Nick Piggin
    Cc: Peter Zijlstra
    Cc: Kanoj Sarcar
    Cc: Roland Dreier
    Cc: Steve Wise
    Cc: Avi Kivity
    Cc: Hugh Dickins
    Cc: Rusty Russell
    Cc: Anthony Liguori
    Cc: Chris Wright
    Cc: Marcelo Tosatti
    Cc: Eric Dumazet
    Cc: "Paul E. McKenney"
    Cc: Izik Eidus
    Cc: Anthony Liguori
    Cc: Rik van Riel
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Andrea Arcangeli
     
  • mm_take_all_locks holds off reclaim from an entire mm_struct. This allows
    mmu notifiers to register into the mm at any time with the guarantee that
    no mmu operation is in progress on the mm.

    This operation locks against the VM for all pte/vma/mm related operations
    that could ever happen on a certain mm. This includes vmtruncate,
    try_to_unmap, and all page faults.

    The caller must take the mmap_sem in write mode before calling
    mm_take_all_locks(). The caller isn't allowed to release the mmap_sem
    until mm_drop_all_locks() returns.

    mmap_sem in write mode is required in order to block all operations that
    could modify pagetables and free pages without need of altering the vma
    layout (for example populate_range() with nonlinear vmas). It's also
    needed in write mode to avoid new anon_vmas to be associated with existing
    vmas.

    A single task can't take more than one mm_take_all_locks() in a row or it
    would deadlock.

    mm_take_all_locks() and mm_drop_all_locks are expensive operations that
    may have to take thousand of locks.

    mm_take_all_locks() can fail if it's interrupted by signals.

    When mmu_notifier_register returns, we must be sure that the driver is
    notified if some task is in the middle of a vmtruncate for the 'mm' where
    the mmu notifier was registered (mmu_notifier_invalidate_range_start/end
    is run around the vmtruncation but mmu_notifier_register can run after
    mmu_notifier_invalidate_range_start and before
    mmu_notifier_invalidate_range_end). Same problem for rmap paths. And
    we've to remove page pinning to avoid replicating the tlb_gather logic
    inside KVM (and GRU doesn't work well with page pinning regardless of
    needing tlb_gather), so without mm_take_all_locks when vmtruncate frees
    the page, kvm would have no way to notice that it mapped into sptes a page
    that is going into the freelist without a chance of any further
    mmu_notifier notification.

    [akpm@linux-foundation.org: coding-style fixes]
    Signed-off-by: Andrea Arcangeli
    Acked-by: Linus Torvalds
    Cc: Christoph Lameter
    Cc: Jack Steiner
    Cc: Robin Holt
    Cc: Nick Piggin
    Cc: Peter Zijlstra
    Cc: Kanoj Sarcar
    Cc: Roland Dreier
    Cc: Steve Wise
    Cc: Avi Kivity
    Cc: Hugh Dickins
    Cc: Rusty Russell
    Cc: Anthony Liguori
    Cc: Chris Wright
    Cc: Marcelo Tosatti
    Cc: Eric Dumazet
    Cc: "Paul E. McKenney"
    Cc: Izik Eidus
    Cc: Anthony Liguori
    Cc: Rik van Riel
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Andrea Arcangeli
     
  • Introduce list_del_init_rcu() and document it.

    Signed-off-by: Andrea Arcangeli
    Acked-by: Linus Torvalds
    Cc: "Paul E. McKenney"
    Cc: Ingo Molnar
    Cc: Christoph Lameter
    Cc: Jack Steiner
    Cc: Robin Holt
    Cc: Nick Piggin
    Cc: Peter Zijlstra
    Cc: Kanoj Sarcar
    Cc: Roland Dreier
    Cc: Steve Wise
    Cc: Avi Kivity
    Cc: Hugh Dickins
    Cc: Rusty Russell
    Cc: Anthony Liguori
    Cc: Chris Wright
    Cc: Marcelo Tosatti
    Cc: Eric Dumazet
    Cc: "Paul E. McKenney"
    Cc: Izik Eidus
    Cc: Anthony Liguori
    Cc: Rik van Riel
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Andrea Arcangeli
     
  • Conflicts:

    kernel/stop_machine.c

    Signed-off-by: Ingo Molnar

    Ingo Molnar
     
  • Clean up and optimize cpumask_of_cpu(), by sharing all the zero words.

    Instead of stupidly generating all possible i=0...NR_CPUS 2^i patterns
    creating a huge array of constant bitmasks, realize that the zero words
    can be shared.

    In other words, on a 64-bit architecture, we only ever need 64 of these
    arrays - with a different bit set in one single world (with enough zero
    words around it so that we can create any bitmask by just offsetting in
    that big array). And then we just put enough zeroes around it that we
    can point every single cpumask to be one of those things.

    So when we have 4k CPU's, instead of having 4k arrays (of 4k bits each,
    with one bit set in each array - 2MB memory total), we have exactly 64
    arrays instead, each 8k bits in size (64kB total).

    And then we just point cpumask(n) to the right position (which we can
    calculate dynamically). Once we have the right arrays, getting
    "cpumask(n)" ends up being:

    static inline const cpumask_t *get_cpu_mask(unsigned int cpu)
    {
    const unsigned long *p = cpu_bit_bitmap[1 + cpu % BITS_PER_LONG];
    p -= cpu / BITS_PER_LONG;
    return (const cpumask_t *)p;
    }

    This brings other advantages and simplifications as well:

    - we are not wasting memory that is just filled with a single bit in
    various different places

    - we don't need all those games to re-create the arrays in some dense
    format, because they're already going to be dense enough.

    if we compile a kernel for up to 4k CPU's, "wasting" that 64kB of memory
    is a non-issue (especially since by doing this "overlapping" trick we
    probably get better cache behaviour anyway).

    [ mingo@elte.hu:

    Converted Linus's mails into a commit. See:

    http://lkml.org/lkml/2008/7/27/156
    http://lkml.org/lkml/2008/7/28/320

    Also applied a family filter - which also has the side-effect of leaving
    out the bits where Linus calls me an idio... Oh, never mind ;-)
    ]

    Signed-off-by: Ingo Molnar
    Cc: Rusty Russell
    Cc: Andrew Morton
    Cc: Al Viro
    Cc: Mike Travis
    Signed-off-by: Ingo Molnar

    Linus Torvalds
     
  • Ingo Molnar
     
  • * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
    Input: add driver for Atmel integrated touchscreen controller
    Input: ads7846 - optimize order of calculating Rt in ads7846_rx()
    Input: ads7846 - fix sparse endian warnings
    Input: uinput - remove duplicate include
    Input: serio - offload resume to kseriod
    Input: serio - mark serio_register_driver() __must_check

    Linus Torvalds
     
  • * 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (25 commits)
    powerpc: Disable 64K hugetlb support when doing 64K SPU mappings
    powerpc/powermac: Fixup default serial port device for pmac_zilog
    powerpc/powermac: Use sane default baudrate for SCC debugging
    powerpc/mm: Implement _PAGE_SPECIAL & pte_special() for 64-bit
    powerpc: Show processor cache information in sysfs
    powerpc: Make core id information available to userspace
    powerpc: Make core sibling information available to userspace
    powerpc/vio: More fallout from dma_mapping_error API change
    ibmveth: Fix multiple errors with dma_mapping_error conversion
    powerpc/pseries: Fix CMO sysdev attribute API change fallout
    powerpc: Enable tracehook for the architecture
    powerpc: Add TIF_NOTIFY_RESUME support for tracehook
    powerpc: Add asm/syscall.h with the tracehook entry points
    powerpc: Make syscall tracing use tracehook.h helpers
    powerpc: Call tracehook_signal_handler() when setting up signal frames
    powerpc: Update cpu_sibling_maps dynamically
    powerpc: register_cpu_online should be __cpuinit
    powerpc: kill useless SMT code in prom_hold_cpus
    powerpc: Fix 8xx build failure
    powerpc: Fix vio build warnings
    ...

    Linus Torvalds
     

28 Jul, 2008

31 commits