Skip to content
Snippets Groups Projects
  1. Jun 19, 2019
  2. Jun 14, 2018
  3. Apr 16, 2018
  4. Jul 26, 2016
    • Vlastimil Babka's avatar
      mm, frontswap: convert frontswap_enabled to static key · 8ea1d2a1
      Vlastimil Babka authored
      I have noticed that frontswap.h first declares "frontswap_enabled" as
      extern bool variable, and then overrides it with "#define
      frontswap_enabled (1)" for CONFIG_FRONTSWAP=Y or (0) when disabled.  The
      bool variable isn't actually instantiated anywhere.
      
      This all looks like an unfinished attempt to make frontswap_enabled
      reflect whether a backend is instantiated.  But in the current state,
      all frontswap hooks call unconditionally into frontswap.c just to check
      if frontswap_ops is non-NULL.  This should at least be checked inline,
      but we can further eliminate the overhead when CONFIG_FRONTSWAP is
      enabled and no backend registered, using a static key that is initially
      disabled, and gets enabled only upon first backend registration.
      
      Thus, checks for "frontswap_enabled" are replaced with
      "frontswap_enabled()" wrapping the static key check.  There are two
      exceptions:
      
      - xen's selfballoon_process() was testing frontswap_enabled in code guarded
        by #ifdef CONFIG_FRONTSWAP, which was effectively always true when reachable.
        The patch just removes this check. Using frontswap_enabled() does not sound
        correct here, as this can be true even without xen's own backend being
        registered.
      
      - in SYSCALL_DEFINE2(swapon), change the check to IS_ENABLED(CONFIG_FRONTSWAP)
        as it seems the bitmap allocation cannot currently be postponed until a
        backend is registered. This means that frontswap will still have some
        memory overhead by being configured, but without a backend.
      
      After the patch, we can expect that some functions in frontswap.c are
      called only when frontswap_ops is non-NULL.  Change the checks there to
      VM_BUG_ONs.  While at it, convert other BUG_ONs to VM_BUG_ONs as
      frontswap has been stable for some time.
      
      [akpm@linux-foundation.org: coding-style fixes]
      Link: http://lkml.kernel.org/r/1463152235-9717-1-git-send-email-vbabka@suse.cz
      
      
      Signed-off-by: default avatarVlastimil Babka <vbabka@suse.cz>
      Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
      Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
      Cc: David Vrabel <david.vrabel@citrix.com>
      Cc: Juergen Gross <jgross@suse.com>
      Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
      Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
      8ea1d2a1
  5. Jun 25, 2015
    • Dan Streetman's avatar
      frontswap: allow multiple backends · d1dc6f1b
      Dan Streetman authored
      
      Change frontswap single pointer to a singly linked list of frontswap
      implementations.  Update Xen tmem implementation as register no longer
      returns anything.
      
      Frontswap only keeps track of a single implementation; any
      implementation that registers second (or later) will replace the
      previously registered implementation, and gets a pointer to the previous
      implementation that the new implementation is expected to pass all
      frontswap functions to if it can't handle the function itself.  However
      that method doesn't really make much sense, as passing that work on to
      every implementation adds unnecessary work to implementations; instead,
      frontswap should simply keep a list of all registered implementations
      and try each implementation for any function.  Most importantly, neither
      of the two currently existing frontswap implementations in the kernel
      actually do anything with any previous frontswap implementation that
      they replace when registering.
      
      This allows frontswap to successfully manage multiple implementations by
      keeping a list of them all.
      
      Signed-off-by: default avatarDan Streetman <ddstreet@ieee.org>
      Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
      Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
      Cc: David Vrabel <david.vrabel@citrix.com>
      Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
      d1dc6f1b
  6. Dec 11, 2014
  7. Dec 03, 2014
    • Weijie Yang's avatar
      mm: frontswap: invalidate expired data on a dup-store failure · fb993fa1
      Weijie Yang authored
      
      If a frontswap dup-store failed, it should invalidate the expired page
      in the backend, or it could trigger some data corruption issue.
      Such as:
       1. use zswap as the frontswap backend with writeback feature
       2. store a swap page(version_1) to entry A, success
       3. dup-store a newer page(version_2) to the same entry A, fail
       4. use __swap_writepage() write version_2 page to swapfile, success
       5. zswap do shrink, writeback version_1 page to swapfile
       6. version_2 page is overwrited by version_1, data corrupt.
      
      This patch fixes this issue by invalidating expired data immediately
      when meet a dup-store failure.
      
      Signed-off-by: default avatarWeijie Yang <weijie.yang@samsung.com>
      Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
      Cc: Seth Jennings <sjennings@variantweb.net>
      Cc: Dan Streetman <ddstreet@ieee.org>
      Cc: Minchan Kim <minchan@kernel.org>
      Cc: Bob Liu <bob.liu@oracle.com>
      Cc: <stable@vger.kernel.org>
      Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
      fb993fa1
  8. Jun 04, 2014
    • Dan Streetman's avatar
      swap: change swap_list_head to plist, add swap_avail_head · 18ab4d4c
      Dan Streetman authored
      
      Originally get_swap_page() started iterating through the singly-linked
      list of swap_info_structs using swap_list.next or highest_priority_index,
      which both were intended to point to the highest priority active swap
      target that was not full.  The first patch in this series changed the
      singly-linked list to a doubly-linked list, and removed the logic to start
      at the highest priority non-full entry; it starts scanning at the highest
      priority entry each time, even if the entry is full.
      
      Replace the manually ordered swap_list_head with a plist, swap_active_head.
      Add a new plist, swap_avail_head.  The original swap_active_head plist
      contains all active swap_info_structs, as before, while the new
      swap_avail_head plist contains only swap_info_structs that are active and
      available, i.e. not full.  Add a new spinlock, swap_avail_lock, to protect
      the swap_avail_head list.
      
      Mel Gorman suggested using plists since they internally handle ordering
      the list entries based on priority, which is exactly what swap was doing
      manually.  All the ordering code is now removed, and swap_info_struct
      entries and simply added to their corresponding plist and automatically
      ordered correctly.
      
      Using a new plist for available swap_info_structs simplifies and
      optimizes get_swap_page(), which no longer has to iterate over full
      swap_info_structs.  Using a new spinlock for swap_avail_head plist
      allows each swap_info_struct to add or remove themselves from the
      plist when they become full or not-full; previously they could not
      do so because the swap_info_struct->lock is held when they change
      from full<->not-full, and the swap_lock protecting the main
      swap_active_head must be ordered before any swap_info_struct->lock.
      
      Signed-off-by: default avatarDan Streetman <ddstreet@ieee.org>
      Acked-by: default avatarMel Gorman <mgorman@suse.de>
      Cc: Shaohua Li <shli@fusionio.com>
      Cc: Steven Rostedt <rostedt@goodmis.org>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Cc: Hugh Dickins <hughd@google.com>
      Cc: Dan Streetman <ddstreet@ieee.org>
      Cc: Michal Hocko <mhocko@suse.cz>
      Cc: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
      Cc: Weijie Yang <weijieut@gmail.com>
      Cc: Rik van Riel <riel@redhat.com>
      Cc: Johannes Weiner <hannes@cmpxchg.org>
      Cc: Bob Liu <bob.liu@oracle.com>
      Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
      18ab4d4c
    • Dan Streetman's avatar
      swap: change swap_info singly-linked list to list_head · adfab836
      Dan Streetman authored
      The logic controlling the singly-linked list of swap_info_struct entries
      for all active, i.e.  swapon'ed, swap targets is rather complex, because:
      
       - it stores the entries in priority order
       - there is a pointer to the highest priority entry
       - there is a pointer to the highest priority not-full entry
       - there is a highest_priority_index variable set outside the swap_lock
       - swap entries of equal priority should be used equally
      
      this complexity leads to bugs such as: https://lkml.org/lkml/2014/2/13/181
      where different priority swap targets are incorrectly used equally.
      
      That bug probably could be solved with the existing singly-linked lists,
      but I think it would only add more complexity to the already difficult to
      understand get_swap_page() swap_list iteration logic.
      
      The first patch changes from a singly-linked list to a doubly-linked list
      using list_heads; the highest_priority_index and related code are removed
      and get_swap_page() starts each iteration at the highest priority
      swap_info entry, even if it's full.  While this does introduce unnecessary
      list iteration (i.e.  Schlemiel the painter's algorithm) in the case where
      one or more of the highest priority entries are full, the iteration and
      manipulation code is much simpler and behaves correctly re: the above bug;
      and the fourth patch removes the unnecessary iteration.
      
      The second patch adds some minor plist helper functions; nothing new
      really, just functions to match existing regular list functions.  These
      are used by the next two patches.
      
      The third patch adds plist_requeue(), which is used by get_swap_page() in
      the next patch - it performs the requeueing of same-priority entries
      (which moves the entry to the end of its priority in the plist), so that
      all equal-priority swap_info_structs get used equally.
      
      The fourth patch converts the main list into a plist, and adds a new plist
      that contains only swap_info entries that are both active and not full.
      As Mel suggested using plists allows removing all the ordering code from
      swap - plists handle ordering automatically.  The list naming is also
      clarified now that there are two lists, with the original list changed
      from swap_list_head to swap_active_head and the new list named
      swap_avail_head.  A new spinlock is also added for the new list, so
      swap_info entries can be added or removed from the new list immediately as
      they become full or not full.
      
      This patch (of 4):
      
      Replace the singly-linked list tracking active, i.e.  swapon'ed,
      swap_info_struct entries with a doubly-linked list using struct
      list_heads.  Simplify the logic iterating and manipulating the list of
      entries, especially get_swap_page(), by using standard list_head
      functions, and removing the highest priority iteration logic.
      
      The change fixes the bug:
      https://lkml.org/lkml/2014/2/13/181
      
      
      in which different priority swap entries after the highest priority entry
      are incorrectly used equally in pairs.  The swap behavior is now as
      advertised, i.e. different priority swap entries are used in order, and
      equal priority swap targets are used concurrently.
      
      Signed-off-by: default avatarDan Streetman <ddstreet@ieee.org>
      Acked-by: default avatarMel Gorman <mgorman@suse.de>
      Cc: Shaohua Li <shli@fusionio.com>
      Cc: Hugh Dickins <hughd@google.com>
      Cc: Dan Streetman <ddstreet@ieee.org>
      Cc: Michal Hocko <mhocko@suse.cz>
      Cc: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
      Cc: Weijie Yang <weijieut@gmail.com>
      Cc: Rik van Riel <riel@redhat.com>
      Cc: Johannes Weiner <hannes@cmpxchg.org>
      Cc: Bob Liu <bob.liu@oracle.com>
      Cc: Steven Rostedt <rostedt@goodmis.org>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
      adfab836
  9. Jun 12, 2013
    • Akinobu Mita's avatar
      frontswap: fix incorrect zeroing and allocation size for frontswap_map · 7b57976d
      Akinobu Mita authored
      
      The bitmap accessed by bitops must have enough size to hold the required
      numbers of bits rounded up to a multiple of BITS_PER_LONG.  And the
      bitmap must not be zeroed by memset() if the number of bits cleared is
      not a multiple of BITS_PER_LONG.
      
      This fixes incorrect zeroing and allocation size for frontswap_map.  The
      incorrect zeroing part doesn't cause any problem because frontswap_map
      is freed just after zeroing.  But the wrongly calculated allocation size
      may cause the problem.
      
      For 32bit systems, the allocation size of frontswap_map is about twice
      as large as required size.  For 64bit systems, the allocation size is
      smaller than requeired if the number of bits is not a multiple of
      BITS_PER_LONG.
      
      Signed-off-by: default avatarAkinobu Mita <akinobu.mita@gmail.com>
      Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
      Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
      7b57976d
  10. May 01, 2013
  11. Sep 21, 2012
    • Dan Magenheimer's avatar
      frontswap: support exclusive gets if tmem backend is capable · e3483a5f
      Dan Magenheimer authored
      
      Tmem, as originally specified, assumes that "get" operations
      performed on persistent pools never flush the page of data out
      of tmem on a successful get, waiting instead for a flush
      operation.  This is intended to mimic the model of a swap
      disk, where a disk read is non-destructive.  Unlike a
      disk, however, freeing up the RAM can be valuable.  Over
      the years that frontswap was in the review process, several
      reviewers (and notably Hugh Dickins in 2010) pointed out that
      this would result, at least temporarily, in two copies of the
      data in RAM: one (compressed for zcache) copy in tmem,
      and one copy in the swap cache.  We wondered if this could
      be done differently, at least optionally.
      
      This patch allows tmem backends to instruct the frontswap
      code that this backend performs exclusive gets.  Zcache2
      already contains hooks to support this feature.  Other
      backends are completely unaffected unless/until they are
      updated to support this feature.
      
      While it is not clear that exclusive gets are a performance
      win on all workloads at all times, this small patch allows for
      experimentation by backends.
      
      P.S. Let's not quibble about the naming of "get" vs "read" vs
      "load" etc.  The naming is currently horribly inconsistent between
      cleancache and frontswap and existing tmem backends, so will need
      to be straightened out as a separate patch.  "Get" is used
      by the tmem architecture spec, existing backends, and
      all documentation and presentation material so I am
      using it in this patch.
      
      Signed-off-by: default avatarDan Magenheimer <dan.magenheimer@oracle.com>
      Signed-off-by: default avatarKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
      e3483a5f
    • Zhenzhong Duan's avatar
      mm: frontswap: fix a wrong if condition in frontswap_shrink · a00bb1e9
      Zhenzhong Duan authored
      
      pages_to_unuse is set to 0 to unuse all frontswap pages
      But that doesn't happen since a wrong condition in frontswap_shrink
      cancel it.
      
      -v2: Add comment to explain return value of __frontswap_shrink,
      as suggested by Dan Carpenter, thanks
      
      Signed-off-by: default avatarZhenzhong Duan <zhenzhong.duan@oracle.com>
      Signed-off-by: default avatarKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
      a00bb1e9
  12. Aug 13, 2012
  13. Jul 23, 2012
  14. Jul 19, 2012
  15. Jun 11, 2012
  16. May 15, 2012
    • Konrad Rzeszutek Wilk's avatar
      frontswap: s/put_page/store/g s/get_page/load · 165c8aed
      Konrad Rzeszutek Wilk authored
      
      Sounds so much more natural.
      
      Suggested-by: default avatarAndrea Arcangeli <aarcange@redhat.com>
      Signed-off-by: default avatarKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
      165c8aed
    • Dan Magenheimer's avatar
      mm: frontswap: core frontswap functionality · 29f233cf
      Dan Magenheimer authored
      
      This patch, 3of4, provides the core frontswap code that interfaces between
      the hooks in the swap subsystem and a frontswap backend via frontswap_ops.
      
      ---
      New file added: mm/frontswap.c
      
      [v14: add support for writethrough, per suggestion by aarcange@redhat.com]
      [v11: sjenning@linux.vnet.ibm.com: s/puts/failed_puts/]
      [v10: sjenning@linux.vnet.ibm.com: fix debugfs calls on 32-bit]
      [v9: akpm@linux-foundation.org: change "flush" to "invalidate", part 1]
      [v9: akpm@linux-foundation.org: mark some statics __read_mostly]
      [v9: akpm@linux-foundation.org: add clarifying comments]
      [v9: akpm@linux-foundation.org: no need to loop repeating try_to_unuse]
      [v9: error27@gmail.com: remove superfluous check for NULL]
      [v8: rebase to 3.0-rc4]
      [v8: kamezawa.hiroyu@jp.fujitsu.com: add comment to clarify find_next_to_unuse]
      [v7: rebase to 3.0-rc3]
      [v7: JBeulich@novell.com: use new static inlines, no-ops if not config'd]
      [v6: rebase to 3.1-rc1]
      [v6: lliubbo@gmail.com: use vzalloc]
      [v6: lliubbo@gmail.com: fix null pointer deref if vzalloc fails]
      [v6: konrad.wilk@oracl.com: various checks and code clarifications/comments]
      [v4: rebase to 2.6.39]
      Signed-off-by: default avatarDan Magenheimer <dan.magenheimer@oracle.com>
      Acked-by: default avatarJan Beulich <JBeulich@novell.com>
      Acked-by: default avatarSeth Jennings <sjenning@linux.vnet.ibm.com>
      Cc: Jeremy Fitzhardinge <jeremy@goop.org>
      Cc: Hugh Dickins <hughd@google.com>
      Cc: Johannes Weiner <hannes@cmpxchg.org>
      Cc: Nitin Gupta <ngupta@vflare.org>
      Cc: Matthew Wilcox <matthew@wil.cx>
      Cc: Chris Mason <chris.mason@oracle.com>
      Cc: Rik Riel <riel@redhat.com>
      Cc: Andrew Morton <akpm@linux-foundation.org>
      [v12: Squashed s/flush/invalidate/ in]
      [v15: A bit of cleanup and seperate DEBUGFS]
      Signed-off-by: default avatarKonrad Wilk <konrad.wilk@oracle.com>
      29f233cf
Loading