• Oleg Nesterov's avatar
    uprobes: Rework register_for_each_vma() to make it O(n) · 26872090
    Oleg Nesterov authored
    Currently register_for_each_vma() is O(n ** 2) + O(n ** 3),
    every time find_next_vma_info() "restarts" the
    vma_prio_tree_foreach() loop and each iteration rechecks the
    whole try_list. This also means that try_list can grow
    "indefinitely" if register/unregister races with munmap/mmap
    activity even if the number of mapping is bounded at any time.
    
    With this patch register_for_each_vma() builds the list of
    mm/vaddr structures only once and does install_breakpoint() for
    each entry.
    
    We do not care about the new mappings which can be created after
    build_map_info() drops mapping->i_mmap_mutex, uprobe_mmap()
    should do its work.
    
    Note that we do not allocate map_info under i_mmap_mutex, this
    can deadlock with page reclaim (but see the next patch). So we
    use 2 lists, "curr" which we are going to return, and "prev"
    which holds the already allocated memory. The main loop deques
    the entry from "prev" (initially it is empty), and if "prev"
    becomes empty again it counts the number of entries we need to
    pre-allocate outside of i_mmap_mutex.
    Signed-off-by: default avatarOleg Nesterov <oleg@redhat.com>
    Acked-by: default avatarSrikar Dronamraju <srikar@linux.vnet.ibm.com>
    Acked-by: default avatarPeter Zijlstra <peterz@infradead.org>
    Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
    Cc: Anton Arapov <anton@redhat.com>
    Link: http://lkml.kernel.org/r/20120615154333.GA9581@redhat.comSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
    26872090
uprobes.c 38.6 KB